From d086651c12508487a9cb0e3c994b91a9815e557c Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Wed, 8 Mar 2023 22:17:25 +0800 Subject: [PATCH 01/34] feat(trie): add state trie --- .../org/tron/core/actuator/VMActuator.java | 33 +- .../org/tron/core/vm/config/ConfigLoader.java | 6 +- .../DelegateResourceProcessor.java | 8 +- .../UnDelegateResourceProcessor.java | 15 +- .../tron/core/vm/program/ContractState.java | 6 + .../org/tron/core/vm/program/Program.java | 6 +- .../org/tron/core/vm/program/Storage.java | 17 +- .../tron/core/vm/repository/Repository.java | 2 + .../vm/repository/RepositoryStateImpl.java | 1061 ++++++++++ build.gradle | 2 +- chainbase/build.gradle | 1 + .../java/org/tron/core/ChainBaseManager.java | 40 + .../org/tron/core/capsule/AccountCapsule.java | 13 +- .../org/tron/core/capsule/BlockCapsule.java | 14 + .../tron/core/capsule/utils/AssetUtil.java | 69 +- .../org/tron/core/db/BandwidthProcessor.java | 106 +- .../org/tron/core/db/EnergyProcessor.java | 14 - .../org/tron/core/db/ResourceProcessor.java | 15 + .../tron/core/db/TronStoreWithRevoking.java | 23 +- .../java/org/tron/core/state/StateType.java | 65 + .../src/main/java/org/tron/core/state/TODO.md | 17 + .../tron/core/state/WorldStateCallBack.java | 90 + .../core/state/WorldStateCallBackUtils.java | 142 ++ .../tron/core/state/WorldStateGenesis.java | 315 +++ .../core/state/WorldStateQueryInstance.java | 213 ++ .../tron/core/state/WorldStateTrieStore.java | 46 + .../core/state/store/AccountStateStore.java | 123 ++ .../state/store/AssetIssueV2StateStore.java | 123 ++ .../state/store/DelegationStateStore.java | 119 ++ .../store/DynamicPropertiesStateStore.java | 120 ++ .../org/tron/core/state/store/StateStore.java | 20 + .../java/org/tron/core/state/trie/Trie.java | 30 + .../org/tron/core/state/trie/TrieImpl2.java | 188 ++ .../org/tron/core/store/AccountStore.java | 6 +- .../org/tron/core/store/AssetIssueStore.java | 3 + .../tron/core/store/AssetIssueV2Store.java | 5 +- .../tron/core/store/ContractStateStore.java | 11 - .../org/tron/core/store/ContractStore.java | 5 +- .../org/tron/core/store/DelegationStore.java | 4 + .../core/store/DynamicPropertiesStore.java | 9 +- .../org/tron/common/cache/CacheManager.java | 8 + .../tron/common/cache/CacheStrategies.java | 3 +- .../java/org/tron/common/cache/CacheType.java | 5 +- .../java/org/tron/common/cache/TronCache.java | 10 +- .../java/org/tron/common/utils/FileUtil.java | 49 + .../java/org/tron/common/utils/PropUtil.java | 19 + .../org/tron/core/config/args/Storage.java | 22 + .../src/main/java/org/tron/core/Wallet.java | 135 +- .../java/org/tron/core/config/args/Args.java | 3 + .../main/java/org/tron/core/db/Manager.java | 46 +- .../core/services/jsonrpc/TronJsonRpc.java | 9 + .../services/jsonrpc/TronJsonRpcImpl.java | 105 +- .../tool/litefullnode/LiteFullNodeTool.java | 6 +- .../src/main/resources/config-localtest.conf | 3 + framework/src/main/resources/config.conf | 4 + .../tron/common/runtime/VmStateTestUtil.java | 66 + .../tron/common/runtime/vm/FreezeV2Test.java | 9 + .../common/runtime/vm/RewardBalanceTest.java | 53 + .../runtime/vm/TransferToAccountTest.java | 61 +- .../org/tron/common/runtime/vm/VoteTest.java | 10 + .../DelegateResourceActuatorTest.java | 62 +- .../actuator/FreezeBalanceActuatorTest.java | 84 + .../actuator/FreezeBalanceV2ActuatorTest.java | 50 + .../core/actuator/TransferActuatorTest.java | 39 + .../actuator/TransferAssetActuatorTest.java | 118 ++ .../actuator/UnfreezeAssetActuatorTest.java | 33 + .../actuator/UnfreezeBalanceActuatorTest.java | 75 + .../UnfreezeBalanceV2ActuatorTest.java | 90 + .../db2/RevokingDbWithCacheNewValueTest.java | 2 + .../state/WorldStateQueryInstanceTest.java | 228 +++ .../tron/core/state/WorldStateQueryTest.java | 290 +++ .../java/org/tron/core/tire/Trie2Test.java | 543 ++++++ .../src/test/resources/config-localtest.conf | 2 + framework/src/test/resources/config-test.conf | 1 + protocol/src/main/protos/core/Tron.proto | 1 + settings.gradle | 1 + state-trie-jdk8/build.gradle | 50 + .../apache/tuweni/bytes/AbstractBytes.java | 78 + .../tuweni/bytes/ArrayWrappingBytes.java | 165 ++ .../tuweni/bytes/ArrayWrappingBytes32.java | 56 + .../tuweni/bytes/ArrayWrappingBytes48.java | 56 + .../tuweni/bytes/BufferWrappingBytes.java | 109 ++ .../tuweni/bytes/ByteBufWrappingBytes.java | 113 ++ .../tuweni/bytes/ByteBufferWrappingBytes.java | 133 ++ .../bytes/ByteBufferWrappingBytes32.java | 43 + .../java/org/apache/tuweni/bytes/Bytes.java | 1706 +++++++++++++++++ .../java/org/apache/tuweni/bytes/Bytes32.java | 340 ++++ .../java/org/apache/tuweni/bytes/Bytes48.java | 284 +++ .../org/apache/tuweni/bytes/BytesValues.java | 83 + .../java/org/apache/tuweni/bytes/Checks.java | 39 + .../tuweni/bytes/ConcatenatedBytes.java | 270 +++ .../tuweni/bytes/ConstantBytes32Value.java | 58 + .../tuweni/bytes/ConstantBytesValue.java | 57 + .../apache/tuweni/bytes/DelegatingBytes.java | 322 ++++ .../tuweni/bytes/DelegatingBytes32.java | 43 + .../tuweni/bytes/DelegatingBytes48.java | 44 + .../tuweni/bytes/DelegatingMutableBytes.java | 286 +++ .../bytes/DelegatingMutableBytes32.java | 39 + .../bytes/DelegatingMutableBytes48.java | 38 + .../tuweni/bytes/GuardedByteArrayBytes.java | 191 ++ .../tuweni/bytes/GuardedByteArrayBytes32.java | 53 + .../bytes/MutableArrayWrappingBytes.java | 103 + .../bytes/MutableArrayWrappingBytes32.java | 34 + .../bytes/MutableArrayWrappingBytes48.java | 34 + .../bytes/MutableBufferWrappingBytes.java | 87 + .../bytes/MutableByteBufWrappingBytes.java | 92 + .../bytes/MutableByteBufferWrappingBytes.java | 86 + .../org/apache/tuweni/bytes/MutableBytes.java | 374 ++++ .../apache/tuweni/bytes/MutableBytes32.java | 110 ++ .../apache/tuweni/bytes/MutableBytes48.java | 111 ++ .../units/bigints/BaseUInt256Value.java | 405 ++++ .../tuweni/units/bigints/BaseUInt32Value.java | 334 ++++ .../units/bigints/BaseUInt384Value.java | 335 ++++ .../tuweni/units/bigints/BaseUInt64Value.java | 334 ++++ .../units/bigints/BytesUInt256Value.java | 56 + .../apache/tuweni/units/bigints/UInt256.java | 970 ++++++++++ .../tuweni/units/bigints/UInt256Value.java | 597 ++++++ .../apache/tuweni/units/bigints/UInt256s.java | 42 + .../apache/tuweni/units/bigints/UInt32.java | 583 ++++++ .../tuweni/units/bigints/UInt32Value.java | 402 ++++ .../apache/tuweni/units/bigints/UInt32s.java | 42 + .../apache/tuweni/units/bigints/UInt384.java | 786 ++++++++ .../tuweni/units/bigints/UInt384Value.java | 421 ++++ .../apache/tuweni/units/bigints/UInt384s.java | 42 + .../apache/tuweni/units/bigints/UInt64.java | 581 ++++++ .../tuweni/units/bigints/UInt64Value.java | 415 ++++ .../apache/tuweni/units/bigints/UInt64s.java | 42 + .../hyperledger/besu/crypto/BesuProvider.java | 29 + .../org/hyperledger/besu/crypto/Hash.java | 68 + .../besu/crypto/MessageDigestFactory.java | 34 + .../besu/ethereum/rlp/AbstractRLPInput.java | 556 ++++++ .../besu/ethereum/rlp/AbstractRLPOutput.java | 208 ++ .../besu/ethereum/rlp/BytesValueRLPInput.java | 78 + .../ethereum/rlp/BytesValueRLPOutput.java | 37 + .../rlp/CorruptedRLPInputException.java | 22 + .../rlp/MalformedRLPInputException.java | 25 + .../hyperledger/besu/ethereum/rlp/RLP.java | 212 ++ .../besu/ethereum/rlp/RLPDecodingHelpers.java | 208 ++ .../besu/ethereum/rlp/RLPEncodingHelpers.java | 106 + .../besu/ethereum/rlp/RLPException.java | 25 + .../besu/ethereum/rlp/RLPInput.java | 356 ++++ .../besu/ethereum/rlp/RLPOutput.java | 302 +++ .../besu/ethereum/trie/AllNodesVisitor.java | 51 + .../besu/ethereum/trie/BranchNode.java | 267 +++ .../besu/ethereum/trie/CommitVisitor.java | 75 + .../besu/ethereum/trie/CompactEncoding.java | 123 ++ .../ethereum/trie/DefaultNodeFactory.java | 71 + .../besu/ethereum/trie/ExtensionNode.java | 192 ++ .../besu/ethereum/trie/GetVisitor.java | 62 + .../ethereum/trie/KeyValueMerkleStorage.java | 66 + .../besu/ethereum/trie/LeafNode.java | 177 ++ .../ethereum/trie/LocationNodeVisitor.java | 28 + .../ethereum/trie/MerklePatriciaTrie.java | 138 ++ .../besu/ethereum/trie/MerkleStorage.java | 52 + .../ethereum/trie/MerkleTrieException.java | 50 + .../besu/ethereum/trie/MissingNode.java | 53 + .../hyperledger/besu/ethereum/trie/Node.java | 86 + .../besu/ethereum/trie/NodeFactory.java | 31 + .../besu/ethereum/trie/NodeLoader.java | 24 + .../besu/ethereum/trie/NodeUpdater.java | 22 + .../besu/ethereum/trie/NodeVisitor.java | 26 + .../besu/ethereum/trie/NullNode.java | 109 ++ .../besu/ethereum/trie/PathNodeVisitor.java | 28 + .../besu/ethereum/trie/PersistVisitor.java | 86 + .../hyperledger/besu/ethereum/trie/Proof.java | 40 + .../besu/ethereum/trie/ProofVisitor.java | 63 + .../besu/ethereum/trie/PutVisitor.java | 107 ++ .../trie/RangeStorageEntriesCollector.java | 87 + .../besu/ethereum/trie/RemoveVisitor.java | 73 + .../besu/ethereum/trie/RestoreVisitor.java | 246 +++ .../trie/SimpleMerklePatriciaTrie.java | 162 ++ .../besu/ethereum/trie/SnapPutVisitor.java | 48 + .../trie/StorageEntriesCollector.java | 57 + .../trie/StoredMerklePatriciaTrie.java | 240 +++ .../besu/ethereum/trie/StoredNode.java | 159 ++ .../besu/ethereum/trie/StoredNodeFactory.java | 256 +++ .../besu/ethereum/trie/TrieIterator.java | 125 ++ .../besu/ethereum/trie/TrieNodeDecoder.java | 165 ++ .../besu/storage/InMemoryKeyValueStorage.java | 190 ++ .../InvalidConfigurationException.java | 21 + .../besu/storage/KeyValueStorage.java | 108 ++ .../storage/KeyValueStorageTransaction.java | 48 + ...ansactionTransitionValidatorDecorator.java | 55 + .../besu/storage/RocksDBConfiguration.java | 80 + .../storage/RocksDBConfigurationBuilder.java | 96 + .../storage/RocksDBFactoryConfiguration.java | 64 + .../besu/storage/RocksDBKeyValueStorage.java | 190 ++ .../besu/storage/RocksDBTransaction.java | 96 + .../besu/storage/RocksDbIterator.java | 140 ++ .../besu/storage/StorageException.java | 49 + .../hyperledger/besu/storage/Unstable.java | 30 + .../apache/tuweni/bytes/BufferBytesTest.java | 38 + .../apache/tuweni/bytes/ByteBufBytesTest.java | 38 + .../tuweni/bytes/ByteBufferBytesTest.java | 38 + .../org/apache/tuweni/bytes/Bytes32Test.java | 153 ++ .../org/apache/tuweni/bytes/Bytes48Test.java | 134 ++ .../org/apache/tuweni/bytes/BytesTest.java | 700 +++++++ .../apache/tuweni/bytes/CommonBytesTests.java | 687 +++++++ .../tuweni/bytes/ConcatenatedBytesTest.java | 143 ++ .../tuweni/bytes/DelegateBytes32Test.java | 63 + .../tuweni/bytes/DelegateBytes48Test.java | 63 + .../tuweni/bytes/DelegateBytesTest.java | 37 + .../bytes/DelegateMutableBytes32Test.java | 53 + .../bytes/DelegateMutableBytes48Test.java | 53 + .../apache/tuweni/bytes/MutableBytesTest.java | 143 ++ .../units/bigints/BaseUInt256ValueTest.java | 1035 ++++++++++ .../units/bigints/BaseUInt32ValueTest.java | 795 ++++++++ .../units/bigints/BaseUInt384ValueTest.java | 921 +++++++++ .../units/bigints/BaseUInt64ValueTest.java | 805 ++++++++ .../tuweni/units/bigints/UInt256Test.java | 1175 ++++++++++++ .../tuweni/units/bigints/UInt32Test.java | 867 +++++++++ .../tuweni/units/bigints/UInt384Test.java | 1103 +++++++++++ .../tuweni/units/bigints/UInt64Test.java | 855 +++++++++ .../trie/AbstractKeyValueStorageTest.java | 417 ++++ .../trie/AbstractMerklePatriciaTrieTest.java | 412 ++++ .../ethereum/trie/AllNodesVisitorTest.java | 47 + .../ethereum/trie/CompactEncodingTest.java | 68 + .../trie/RocksDBKeyValueStorageTest.java | 39 + .../trie/SimpleMerklePatriciaTrieTest.java | 27 + .../trie/StoredMerklePatriciaTrieTest.java | 215 +++ .../besu/ethereum/trie/TrieIteratorTest.java | 143 ++ .../ethereum/trie/TrieNodeDecoderTest.java | 245 +++ 222 files changed, 35802 insertions(+), 212 deletions(-) create mode 100644 actuator/src/main/java/org/tron/core/vm/repository/RepositoryStateImpl.java create mode 100644 chainbase/src/main/java/org/tron/core/state/StateType.java create mode 100644 chainbase/src/main/java/org/tron/core/state/TODO.md create mode 100644 chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java create mode 100644 chainbase/src/main/java/org/tron/core/state/WorldStateCallBackUtils.java create mode 100644 chainbase/src/main/java/org/tron/core/state/WorldStateGenesis.java create mode 100644 chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java create mode 100644 chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java create mode 100644 chainbase/src/main/java/org/tron/core/state/store/AccountStateStore.java create mode 100644 chainbase/src/main/java/org/tron/core/state/store/AssetIssueV2StateStore.java create mode 100644 chainbase/src/main/java/org/tron/core/state/store/DelegationStateStore.java create mode 100644 chainbase/src/main/java/org/tron/core/state/store/DynamicPropertiesStateStore.java create mode 100644 chainbase/src/main/java/org/tron/core/state/store/StateStore.java create mode 100644 chainbase/src/main/java/org/tron/core/state/trie/Trie.java create mode 100644 chainbase/src/main/java/org/tron/core/state/trie/TrieImpl2.java create mode 100644 framework/src/test/java/org/tron/common/runtime/VmStateTestUtil.java create mode 100644 framework/src/test/java/org/tron/core/state/WorldStateQueryInstanceTest.java create mode 100644 framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java create mode 100644 framework/src/test/java/org/tron/core/tire/Trie2Test.java create mode 100644 state-trie-jdk8/build.gradle create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/AbstractBytes.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ArrayWrappingBytes.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ArrayWrappingBytes32.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ArrayWrappingBytes48.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/BufferWrappingBytes.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ByteBufWrappingBytes.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ByteBufferWrappingBytes.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ByteBufferWrappingBytes32.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/Bytes.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/Bytes32.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/Bytes48.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/BytesValues.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/Checks.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ConcatenatedBytes.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ConstantBytes32Value.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ConstantBytesValue.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingBytes.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingBytes32.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingBytes48.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingMutableBytes.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingMutableBytes32.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingMutableBytes48.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/GuardedByteArrayBytes.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/GuardedByteArrayBytes32.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableArrayWrappingBytes.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableArrayWrappingBytes32.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableArrayWrappingBytes48.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableBufferWrappingBytes.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableByteBufWrappingBytes.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableByteBufferWrappingBytes.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableBytes.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableBytes32.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableBytes48.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BaseUInt256Value.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BaseUInt32Value.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BaseUInt384Value.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BaseUInt64Value.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BytesUInt256Value.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt256.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt256Value.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt256s.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt32.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt32Value.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt32s.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt384.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt384Value.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt384s.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt64.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt64Value.java create mode 100644 state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt64s.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/crypto/BesuProvider.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/crypto/Hash.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/crypto/MessageDigestFactory.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPOutput.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/BytesValueRLPInput.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/BytesValueRLPOutput.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/CorruptedRLPInputException.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/MalformedRLPInputException.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLP.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPDecodingHelpers.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPEncodingHelpers.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPException.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPInput.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPOutput.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/AllNodesVisitor.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/BranchNode.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/CommitVisitor.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/CompactEncoding.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/DefaultNodeFactory.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/ExtensionNode.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/GetVisitor.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/KeyValueMerkleStorage.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/LeafNode.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/LocationNodeVisitor.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/MerklePatriciaTrie.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/MerkleStorage.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/MerkleTrieException.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/MissingNode.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/Node.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NodeFactory.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NodeLoader.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NodeUpdater.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NodeVisitor.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NullNode.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/PathNodeVisitor.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/PersistVisitor.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/Proof.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/ProofVisitor.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/PutVisitor.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/RangeStorageEntriesCollector.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/RemoveVisitor.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/RestoreVisitor.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/SimpleMerklePatriciaTrie.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/SnapPutVisitor.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StorageEntriesCollector.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StoredMerklePatriciaTrie.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StoredNode.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StoredNodeFactory.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/TrieIterator.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/TrieNodeDecoder.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/InMemoryKeyValueStorage.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/InvalidConfigurationException.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/KeyValueStorage.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/KeyValueStorageTransaction.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/KeyValueStorageTransactionTransitionValidatorDecorator.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBConfiguration.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBConfigurationBuilder.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBFactoryConfiguration.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBKeyValueStorage.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBTransaction.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDbIterator.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/StorageException.java create mode 100644 state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/Unstable.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/BufferBytesTest.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/ByteBufBytesTest.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/ByteBufferBytesTest.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/Bytes32Test.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/Bytes48Test.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/BytesTest.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/CommonBytesTests.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/ConcatenatedBytesTest.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateBytes32Test.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateBytes48Test.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateBytesTest.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateMutableBytes32Test.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateMutableBytes48Test.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/MutableBytesTest.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/BaseUInt256ValueTest.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/BaseUInt32ValueTest.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/BaseUInt384ValueTest.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/BaseUInt64ValueTest.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/UInt256Test.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/UInt32Test.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/UInt384Test.java create mode 100644 state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/UInt64Test.java create mode 100644 state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/AbstractKeyValueStorageTest.java create mode 100644 state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/AbstractMerklePatriciaTrieTest.java create mode 100644 state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/AllNodesVisitorTest.java create mode 100644 state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/CompactEncodingTest.java create mode 100644 state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/RocksDBKeyValueStorageTest.java create mode 100644 state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/SimpleMerklePatriciaTrieTest.java create mode 100644 state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/StoredMerklePatriciaTrieTest.java create mode 100644 state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/TrieIteratorTest.java create mode 100644 state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/TrieNodeDecoderTest.java diff --git a/actuator/src/main/java/org/tron/core/actuator/VMActuator.java b/actuator/src/main/java/org/tron/core/actuator/VMActuator.java index 326e2472757..25098d17a68 100644 --- a/actuator/src/main/java/org/tron/core/actuator/VMActuator.java +++ b/actuator/src/main/java/org/tron/core/actuator/VMActuator.java @@ -26,7 +26,6 @@ import org.tron.common.utils.StorageUtils; import org.tron.common.utils.StringUtil; import org.tron.common.utils.WalletUtil; -import org.tron.core.ChainBaseManager; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.ContractCapsule; @@ -53,6 +52,7 @@ import org.tron.core.vm.program.invoke.ProgramInvokeFactory; import org.tron.core.vm.repository.Repository; import org.tron.core.vm.repository.RepositoryImpl; +import org.tron.core.vm.repository.RepositoryStateImpl; import org.tron.core.vm.utils.MUtil; import org.tron.protos.Protocol; import org.tron.protos.Protocol.Block; @@ -110,21 +110,34 @@ private static long getEnergyFee(long callerEnergyUsage, long callerEnergyFrozen @Override public void validate(Object object) throws ContractValidateException { - TransactionContext context = (TransactionContext) object; if (Objects.isNull(context)) { throw new RuntimeException("TransactionContext is null"); } - // Load Config - ConfigLoader.load(context.getStoreFactory()); // Warm up registry class OperationRegistry.init(); trx = context.getTrxCap().getInstance(); + + // check whether is state query + boolean stateQuery = context.getBlockCap() != null + && context.getBlockCap().getNum() < context.getStoreFactory() + .getChainBaseManager().getDynamicPropertiesStore().getLatestBlockHeaderNumber(); + + //Prepare Repository + if (!stateQuery) { + rootRepository = RepositoryImpl.createRoot(context.getStoreFactory()); + } else { + rootRepository = RepositoryStateImpl.createRoot(context.getStoreFactory(), + context.getBlockCap().getArchiveRoot()); + } + // Load Config + ConfigLoader.load(rootRepository); + // If tx`s fee limit is set, use it to calc max energy limit for constant call if (isConstantCall && trx.getRawData().getFeeLimit() > 0) { maxEnergyLimit = Math.min(maxEnergyLimit, trx.getRawData().getFeeLimit() - / context.getStoreFactory().getChainBaseManager() + / rootRepository .getDynamicPropertiesStore().getEnergyFee()); } blockCap = context.getBlockCap(); @@ -134,9 +147,6 @@ public void validate(Object object) throws ContractValidateException { } //Route Type ContractType contractType = this.trx.getRawData().getContract(0).getType(); - //Prepare Repository - rootRepository = RepositoryImpl.createRoot(context.getStoreFactory()); - enableEventListener = context.isEventPluginLoaded(); //set executorType type @@ -297,7 +307,6 @@ public void execute(Object object) throws ContractExeException { String txHash = Hex.toHexString(rootInternalTx.getHash()); VMUtils.saveProgramTraceFile(txHash, traceContent); } - } private void create() @@ -563,8 +572,7 @@ public long getAccountEnergyLimitWithFixRatio(AccountCapsule account, long feeLi long now = rootRepository.getHeadSlot(); EnergyProcessor energyProcessor = new EnergyProcessor( - rootRepository.getDynamicPropertiesStore(), - ChainBaseManager.getInstance().getAccountStore()); + rootRepository.getDynamicPropertiesStore(), rootRepository.getAccountStore()); energyProcessor.updateUsage(account); account.setLatestConsumeTimeForEnergy(now); receipt.setCallerEnergyUsage(account.getEnergyUsage()); @@ -726,8 +734,7 @@ public long getTotalEnergyLimitWithFixRatio(AccountCapsule creator, AccountCapsu long now = rootRepository.getHeadSlot(); EnergyProcessor energyProcessor = new EnergyProcessor( - rootRepository.getDynamicPropertiesStore(), - ChainBaseManager.getInstance().getAccountStore()); + rootRepository.getDynamicPropertiesStore(), rootRepository.getAccountStore()); energyProcessor.updateUsage(creator); creator.setLatestConsumeTimeForEnergy(now); receipt.setOriginEnergyUsage(creator.getEnergyUsage()); diff --git a/actuator/src/main/java/org/tron/core/vm/config/ConfigLoader.java b/actuator/src/main/java/org/tron/core/vm/config/ConfigLoader.java index 463d8c8995a..2c2acd9edf9 100644 --- a/actuator/src/main/java/org/tron/core/vm/config/ConfigLoader.java +++ b/actuator/src/main/java/org/tron/core/vm/config/ConfigLoader.java @@ -5,7 +5,7 @@ import lombok.extern.slf4j.Slf4j; import org.tron.common.parameter.CommonParameter; import org.tron.core.store.DynamicPropertiesStore; -import org.tron.core.store.StoreFactory; +import org.tron.core.vm.repository.Repository; @Slf4j(topic = "VMConfigLoader") public class ConfigLoader { @@ -13,9 +13,9 @@ public class ConfigLoader { //only for unit test public static boolean disable = false; - public static void load(StoreFactory storeFactory) { + public static void load(Repository repository) { if (!disable) { - DynamicPropertiesStore ds = storeFactory.getChainBaseManager().getDynamicPropertiesStore(); + DynamicPropertiesStore ds = repository.getDynamicPropertiesStore(); VMConfig.setVmTrace(CommonParameter.getInstance().isVmTrace()); if (ds != null) { VMConfig.initVmHardFork(checkForEnergyLimit(ds)); diff --git a/actuator/src/main/java/org/tron/core/vm/nativecontract/DelegateResourceProcessor.java b/actuator/src/main/java/org/tron/core/vm/nativecontract/DelegateResourceProcessor.java index 18eb543097b..d0778819f2d 100644 --- a/actuator/src/main/java/org/tron/core/vm/nativecontract/DelegateResourceProcessor.java +++ b/actuator/src/main/java/org/tron/core/vm/nativecontract/DelegateResourceProcessor.java @@ -11,7 +11,6 @@ import org.apache.commons.lang3.ArrayUtils; import org.tron.common.utils.DecodeUtil; import org.tron.common.utils.StringUtil; -import org.tron.core.ChainBaseManager; import org.tron.core.actuator.ActuatorConstant; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.DelegatedResourceAccountIndexCapsule; @@ -54,7 +53,9 @@ public void validate(DelegateResourceParam param, Repository repo) throws Contra switch (param.getResourceType()) { case BANDWIDTH: { - BandwidthProcessor processor = new BandwidthProcessor(ChainBaseManager.getInstance()); + BandwidthProcessor processor = new BandwidthProcessor(dynamicStore, + repo.getAccountStore(), repo.getAssetIssueStore(), + repo.getAssetIssueV2Store()); processor.updateUsageForDelegated(ownerCapsule); long netUsage = (long) (ownerCapsule.getNetUsage() * TRX_PRECISION * ((double) @@ -74,8 +75,7 @@ public void validate(DelegateResourceParam param, Repository repo) throws Contra } break; case ENERGY: { - EnergyProcessor processor = - new EnergyProcessor(dynamicStore, ChainBaseManager.getInstance().getAccountStore()); + EnergyProcessor processor = new EnergyProcessor(dynamicStore, repo.getAccountStore()); processor.updateUsage(ownerCapsule); long energyUsage = (long) (ownerCapsule.getEnergyUsage() * TRX_PRECISION * ((double) diff --git a/actuator/src/main/java/org/tron/core/vm/nativecontract/UnDelegateResourceProcessor.java b/actuator/src/main/java/org/tron/core/vm/nativecontract/UnDelegateResourceProcessor.java index d4cc2fcb8ce..62fd3c0635b 100644 --- a/actuator/src/main/java/org/tron/core/vm/nativecontract/UnDelegateResourceProcessor.java +++ b/actuator/src/main/java/org/tron/core/vm/nativecontract/UnDelegateResourceProcessor.java @@ -13,7 +13,6 @@ import org.apache.commons.lang3.ArrayUtils; import org.tron.common.utils.DecodeUtil; import org.tron.common.utils.StringUtil; -import org.tron.core.ChainBaseManager; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.DelegatedResourceAccountIndexCapsule; import org.tron.core.capsule.DelegatedResourceCapsule; @@ -101,7 +100,9 @@ public void execute(UnDelegateResourceParam param, Repository repo) { if (receiverCapsule != null) { switch (param.getResourceType()) { case BANDWIDTH: - BandwidthProcessor bandwidthProcessor = new BandwidthProcessor(ChainBaseManager.getInstance()); + BandwidthProcessor bandwidthProcessor = new BandwidthProcessor(dynamicStore, + repo.getAccountStore(), repo.getAssetIssueStore(), + repo.getAssetIssueV2Store()); bandwidthProcessor.updateUsageForDelegated(receiverCapsule); if (receiverCapsule.getAcquiredDelegatedFrozenV2BalanceForBandwidth() @@ -124,8 +125,8 @@ public void execute(UnDelegateResourceParam param, Repository repo) { receiverCapsule.setLatestConsumeTime(now); break; case ENERGY: - EnergyProcessor energyProcessor = - new EnergyProcessor(dynamicStore, ChainBaseManager.getInstance().getAccountStore()); + EnergyProcessor energyProcessor = new EnergyProcessor(dynamicStore, + repo.getAccountStore()); energyProcessor.updateUsage(receiverCapsule); if (receiverCapsule.getAcquiredDelegatedFrozenV2BalanceForEnergy() @@ -164,7 +165,9 @@ public void execute(UnDelegateResourceParam param, Repository repo) { ownerCapsule.addDelegatedFrozenV2BalanceForBandwidth(-unDelegateBalance); ownerCapsule.addFrozenBalanceForBandwidthV2(unDelegateBalance); - BandwidthProcessor processor = new BandwidthProcessor(ChainBaseManager.getInstance()); + BandwidthProcessor processor = new BandwidthProcessor(dynamicStore, + repo.getAccountStore(), repo.getAssetIssueStore(), + repo.getAssetIssueV2Store()); if (Objects.nonNull(receiverCapsule) && transferUsage > 0) { ownerCapsule.setNetUsage(processor.unDelegateIncrease(ownerCapsule, receiverCapsule, transferUsage, BANDWIDTH, now)); @@ -179,7 +182,7 @@ public void execute(UnDelegateResourceParam param, Repository repo) { ownerCapsule.addFrozenBalanceForEnergyV2(unDelegateBalance); EnergyProcessor processor = - new EnergyProcessor(dynamicStore, ChainBaseManager.getInstance().getAccountStore()); + new EnergyProcessor(dynamicStore, repo.getAccountStore()); if (Objects.nonNull(receiverCapsule) && transferUsage > 0) { ownerCapsule.setEnergyUsage(processor.unDelegateIncrease(ownerCapsule, receiverCapsule, transferUsage, ENERGY, now)); diff --git a/actuator/src/main/java/org/tron/core/vm/program/ContractState.java b/actuator/src/main/java/org/tron/core/vm/program/ContractState.java index 657558b3725..62f6b5c7f2b 100644 --- a/actuator/src/main/java/org/tron/core/vm/program/ContractState.java +++ b/actuator/src/main/java/org/tron/core/vm/program/ContractState.java @@ -12,6 +12,7 @@ import org.tron.core.capsule.DelegatedResourceCapsule; import org.tron.core.capsule.VotesCapsule; import org.tron.core.capsule.WitnessCapsule; +import org.tron.core.store.AccountStore; import org.tron.core.store.AssetIssueStore; import org.tron.core.store.AssetIssueV2Store; import org.tron.core.store.DelegationStore; @@ -46,6 +47,11 @@ public AssetIssueCapsule getAssetIssue(byte[] tokenId) { return repository.getAssetIssue(tokenId); } + @Override + public AccountStore getAccountStore() { + return repository.getAccountStore(); + } + @Override public AssetIssueV2Store getAssetIssueV2Store() { return repository.getAssetIssueV2Store(); diff --git a/actuator/src/main/java/org/tron/core/vm/program/Program.java b/actuator/src/main/java/org/tron/core/vm/program/Program.java index 90a59f53a36..6d5f87b91bb 100644 --- a/actuator/src/main/java/org/tron/core/vm/program/Program.java +++ b/actuator/src/main/java/org/tron/core/vm/program/Program.java @@ -35,7 +35,6 @@ import org.tron.common.utils.FastByteComparisons; import org.tron.common.utils.Utils; import org.tron.common.utils.WalletUtil; -import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.BlockCapsule; @@ -552,7 +551,8 @@ private long transferFrozenV2BalanceToInheritor(byte[] ownerAddr, byte[] inherit }); // merge usage - BandwidthProcessor bandwidthProcessor = new BandwidthProcessor(ChainBaseManager.getInstance()); + BandwidthProcessor bandwidthProcessor = new BandwidthProcessor(repo.getDynamicPropertiesStore() + , repo.getAccountStore(), repo.getAssetIssueStore(), repo.getAssetIssueV2Store()); bandwidthProcessor.updateUsageForDelegated(ownerCapsule); ownerCapsule.setLatestConsumeTime(now); if (ownerCapsule.getNetUsage() > 0) { @@ -569,7 +569,7 @@ private long transferFrozenV2BalanceToInheritor(byte[] ownerAddr, byte[] inherit EnergyProcessor energyProcessor = new EnergyProcessor( - repo.getDynamicPropertiesStore(), ChainBaseManager.getInstance().getAccountStore()); + repo.getDynamicPropertiesStore(), repo.getAccountStore()); energyProcessor.updateUsage(ownerCapsule); ownerCapsule.setLatestConsumeTimeForEnergy(now); if (ownerCapsule.getEnergyUsage() > 0) { diff --git a/actuator/src/main/java/org/tron/core/vm/program/Storage.java b/actuator/src/main/java/org/tron/core/vm/program/Storage.java index 572af048081..82d53b4d1bb 100644 --- a/actuator/src/main/java/org/tron/core/vm/program/Storage.java +++ b/actuator/src/main/java/org/tron/core/vm/program/Storage.java @@ -10,6 +10,7 @@ import org.tron.common.runtime.vm.DataWord; import org.tron.common.utils.ByteUtil; import org.tron.core.capsule.StorageRowCapsule; +import org.tron.core.state.WorldStateQueryInstance; import org.tron.core.store.StorageRowStore; public class Storage { @@ -19,13 +20,19 @@ public class Storage { private final Map rowCache = new HashMap<>(); @Getter private byte[] addrHash; - @Getter private StorageRowStore store; + private WorldStateQueryInstance worldStateQueryInstance; @Getter private byte[] address; @Setter private int contractVersion; + public Storage(byte[] address, WorldStateQueryInstance worldStateQueryInstance) { + addrHash = addrHash(address); + this.address = address; + this.worldStateQueryInstance = worldStateQueryInstance; + } + public Storage(byte[] address, StorageRowStore store) { addrHash = addrHash(address); this.address = address; @@ -36,6 +43,7 @@ public Storage(Storage storage) { this.addrHash = storage.addrHash.clone(); this.address = storage.getAddress().clone(); this.store = storage.store; + this.worldStateQueryInstance = storage.worldStateQueryInstance; this.contractVersion = storage.contractVersion; storage.getRowCache().forEach((DataWord rowKey, StorageRowCapsule row) -> { StorageRowCapsule newRow = new StorageRowCapsule(row); @@ -74,7 +82,9 @@ public DataWord getValue(DataWord key) { if (rowCache.containsKey(key)) { return new DataWord(rowCache.get(key).getValue()); } else { - StorageRowCapsule row = store.get(compose(key.getData(), addrHash)); + byte[] rowKey = compose(key.getData(), addrHash); + StorageRowCapsule row = worldStateQueryInstance == null + ? store.get(rowKey) : worldStateQueryInstance.getStorageRow(rowKey); if (row == null || row.getInstance() == null) { return null; } @@ -94,6 +104,9 @@ public void put(DataWord key, DataWord value) { } public void commit() { + if (store == null) { + throw new UnsupportedOperationException(); + } rowCache.forEach((DataWord rowKey, StorageRowCapsule row) -> { if (row.isDirty()) { if (new DataWord(row.getValue()).isZero()) { diff --git a/actuator/src/main/java/org/tron/core/vm/repository/Repository.java b/actuator/src/main/java/org/tron/core/vm/repository/Repository.java index b4324bb8d18..801fd6a1f92 100644 --- a/actuator/src/main/java/org/tron/core/vm/repository/Repository.java +++ b/actuator/src/main/java/org/tron/core/vm/repository/Repository.java @@ -9,6 +9,8 @@ public interface Repository { + AccountStore getAccountStore(); + AssetIssueCapsule getAssetIssue(byte[] tokenId); AssetIssueV2Store getAssetIssueV2Store(); diff --git a/actuator/src/main/java/org/tron/core/vm/repository/RepositoryStateImpl.java b/actuator/src/main/java/org/tron/core/vm/repository/RepositoryStateImpl.java new file mode 100644 index 00000000000..c7b12de9b80 --- /dev/null +++ b/actuator/src/main/java/org/tron/core/vm/repository/RepositoryStateImpl.java @@ -0,0 +1,1061 @@ +package org.tron.core.vm.repository; + +import static java.lang.Long.max; +import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; +import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION; + +import com.google.protobuf.ByteString; +import java.util.HashMap; +import java.util.Optional; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.tuweni.bytes.Bytes32; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.encoders.Hex; +import org.tron.common.crypto.Hash; +import org.tron.common.parameter.CommonParameter; +import org.tron.common.runtime.vm.DataWord; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.ByteUtil; +import org.tron.common.utils.StorageUtils; +import org.tron.common.utils.StringUtil; +import org.tron.core.ChainBaseManager; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.AssetIssueCapsule; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.capsule.BytesCapsule; +import org.tron.core.capsule.CodeCapsule; +import org.tron.core.capsule.ContractCapsule; +import org.tron.core.capsule.ContractStateCapsule; +import org.tron.core.capsule.DelegatedResourceAccountIndexCapsule; +import org.tron.core.capsule.DelegatedResourceCapsule; +import org.tron.core.capsule.VotesCapsule; +import org.tron.core.capsule.WitnessCapsule; +import org.tron.core.config.Parameter; +import org.tron.core.db.TransactionTrace; +import org.tron.core.exception.BadItemException; +import org.tron.core.exception.ItemNotFoundException; +import org.tron.core.exception.StoreException; +import org.tron.core.state.WorldStateQueryInstance; +import org.tron.core.state.store.AccountStateStore; +import org.tron.core.state.store.AssetIssueV2StateStore; +import org.tron.core.state.store.DelegationStateStore; +import org.tron.core.state.store.DynamicPropertiesStateStore; +import org.tron.core.store.AccountStore; +import org.tron.core.store.AssetIssueStore; +import org.tron.core.store.AssetIssueV2Store; +import org.tron.core.store.DelegationStore; +import org.tron.core.store.DynamicPropertiesStore; +import org.tron.core.store.StoreFactory; +import org.tron.core.vm.config.VMConfig; +import org.tron.core.vm.program.Program; +import org.tron.core.vm.program.Storage; +import org.tron.protos.Protocol; +import org.tron.protos.Protocol.Account; +import org.tron.protos.Protocol.AccountType; +import org.tron.protos.Protocol.DelegatedResource; +import org.tron.protos.Protocol.Votes; +import org.tron.protos.contract.AssetIssueContractOuterClass.AssetIssueContract; +import org.tron.protos.contract.Common; +import org.tron.protos.contract.SmartContractOuterClass; +import org.tron.protos.contract.SmartContractOuterClass.SmartContract; + +@Slf4j(topic = "Repository") +public class RepositoryStateImpl implements Repository { + + private final long precision = Parameter.ChainConstant.PRECISION; + + private static final byte[] TOTAL_NET_WEIGHT = "TOTAL_NET_WEIGHT".getBytes(); + private static final byte[] TOTAL_ENERGY_WEIGHT = "TOTAL_ENERGY_WEIGHT".getBytes(); + private static final byte[] TOTAL_TRON_POWER_WEIGHT = "TOTAL_TRON_POWER_WEIGHT".getBytes(); + + private final Bytes32 rootHash; + private StoreFactory storeFactory; + + @Getter + private final WorldStateQueryInstance worldStateQueryInstance; + + private final AccountStateStore accountStateStore; + private final AssetIssueV2StateStore assetIssueV2StateStore; + private final DelegationStateStore delegationStateStore; + private final DynamicPropertiesStateStore dynamicPropertiesStateStore; + + private Repository parent = null; + + private final HashMap> accountCache = new HashMap<>(); + private final HashMap> codeCache = new HashMap<>(); + private final HashMap> contractCache = new HashMap<>(); + private final HashMap> contractStateCache + = new HashMap<>(); + private final HashMap storageCache = new HashMap<>(); + + private final HashMap> assetIssueCache = new HashMap<>(); + private final HashMap> dynamicPropertiesCache = new HashMap<>(); + private final HashMap> delegatedResourceCache = new HashMap<>(); + private final HashMap> votesCache = new HashMap<>(); + private final HashMap> delegationCache = new HashMap<>(); + private final HashMap> + delegatedResourceAccountIndexCache = new HashMap<>(); + + public RepositoryStateImpl(StoreFactory storeFactory, RepositoryStateImpl repository, + Bytes32 rootHash) { + this.rootHash = rootHash; + this.worldStateQueryInstance = ChainBaseManager.fetch(rootHash); + this.accountStateStore = new AccountStateStore(); + this.assetIssueV2StateStore = new AssetIssueV2StateStore(); + this.delegationStateStore = new DelegationStateStore(); + this.dynamicPropertiesStateStore = new DynamicPropertiesStateStore(); + + init(storeFactory, repository); + } + + public static RepositoryStateImpl createRoot(StoreFactory storeFactory, Bytes32 rootHash) { + return new RepositoryStateImpl(storeFactory, null, rootHash); + } + + protected void init(StoreFactory storeFactory, RepositoryStateImpl parent) { + if (storeFactory != null) { + this.storeFactory = storeFactory; + } + this.parent = parent; + accountStateStore.init(this.worldStateQueryInstance); + assetIssueV2StateStore.init(this.worldStateQueryInstance); + delegationStateStore.init(this.worldStateQueryInstance); + dynamicPropertiesStateStore.init(this.worldStateQueryInstance); + } + + @Override + public Repository newRepositoryChild() { + return new RepositoryStateImpl(storeFactory, this, this.rootHash); + } + + @Override + public long getAccountLeftEnergyFromFreeze(AccountCapsule accountCapsule) { + long now = getHeadSlot(); + + long energyUsage = accountCapsule.getEnergyUsage(); + long latestConsumeTime = accountCapsule.getAccountResource().getLatestConsumeTimeForEnergy(); + long energyLimit = calculateGlobalEnergyLimit(accountCapsule); + + long windowSize = accountCapsule.getWindowSize(Common.ResourceCode.ENERGY); + long newEnergyUsage = recover(energyUsage, latestConsumeTime, now, windowSize); + + return max(energyLimit - newEnergyUsage, 0); // us + } + + @Override + public long getAccountEnergyUsage(AccountCapsule accountCapsule) { + long now = getHeadSlot(); + long energyUsage = accountCapsule.getEnergyUsage(); + long latestConsumeTime = accountCapsule.getAccountResource().getLatestConsumeTimeForEnergy(); + + long accountWindowSize = accountCapsule.getWindowSize(Common.ResourceCode.ENERGY); + + return recover(energyUsage, latestConsumeTime, now, accountWindowSize); + } + + @Override + public Pair getAccountEnergyUsageBalanceAndRestoreSeconds(AccountCapsule accountCapsule) { + long now = getHeadSlot(); + + long energyUsage = accountCapsule.getEnergyUsage(); + long latestConsumeTime = accountCapsule.getAccountResource().getLatestConsumeTimeForEnergy(); + long accountWindowSize = accountCapsule.getWindowSize(Common.ResourceCode.ENERGY); + + if (now >= latestConsumeTime + accountWindowSize) { + return Pair.of(0L, 0L); + } + + long restoreSlots = latestConsumeTime + accountWindowSize - now; + + long newEnergyUsage = recover(energyUsage, latestConsumeTime, now, accountWindowSize); + + long totalEnergyLimit = getDynamicPropertiesStore().getTotalEnergyCurrentLimit(); + long totalEnergyWeight = getTotalEnergyWeight(); + + long balance = (long) ((double) newEnergyUsage * totalEnergyWeight / totalEnergyLimit * TRX_PRECISION); + + return Pair.of(balance, restoreSlots * BLOCK_PRODUCED_INTERVAL / 1_000); + } + + @Override + public Pair getAccountNetUsageBalanceAndRestoreSeconds(AccountCapsule accountCapsule) { + long now = getHeadSlot(); + + long netUsage = accountCapsule.getNetUsage(); + long latestConsumeTime = accountCapsule.getLatestConsumeTime(); + long accountWindowSize = accountCapsule.getWindowSize(Common.ResourceCode.BANDWIDTH); + + if (now >= latestConsumeTime + accountWindowSize) { + return Pair.of(0L, 0L); + } + + long restoreSlots = latestConsumeTime + accountWindowSize - now; + + long newNetUsage = recover(netUsage, latestConsumeTime, now, accountWindowSize); + + long totalNetLimit = getDynamicPropertiesStore().getTotalNetLimit(); + long totalNetWeight = getTotalNetWeight(); + + long balance = (long) ((double) newNetUsage * totalNetWeight / totalNetLimit * TRX_PRECISION); + + return Pair.of(balance, restoreSlots * BLOCK_PRODUCED_INTERVAL / 1_000); + } + + @Override + public AssetIssueCapsule getAssetIssue(byte[] tokenId) { + byte[] tokenIdWithoutLeadingZero = ByteUtil.stripLeadingZeroes(tokenId); + Key key = Key.create(tokenIdWithoutLeadingZero); + if (assetIssueCache.containsKey(key)) { + return new AssetIssueCapsule(assetIssueCache.get(key).getValue()); + } + + AssetIssueCapsule assetIssueCapsule; + if (this.parent != null) { + assetIssueCapsule = parent.getAssetIssue(tokenIdWithoutLeadingZero); + } else { + assetIssueCapsule = worldStateQueryInstance.getAssetIssue(tokenIdWithoutLeadingZero); + } + if (assetIssueCapsule != null) { + assetIssueCache.put(key, Value.create(assetIssueCapsule)); + } + return assetIssueCapsule; + } + + @Override + public AccountStore getAccountStore() { + return accountStateStore; + } + + @Override + public AssetIssueV2Store getAssetIssueV2Store() { + return assetIssueV2StateStore; + } + + @Override + public AssetIssueStore getAssetIssueStore() { + return assetIssueV2StateStore; + } + + @Override + public DynamicPropertiesStore getDynamicPropertiesStore() { + return dynamicPropertiesStateStore; + } + + @Override + public DelegationStore getDelegationStore() { + return delegationStateStore; + } + + @Override + public AccountCapsule createAccount(byte[] address, Protocol.AccountType type) { + Key key = new Key(address); + AccountCapsule account = new AccountCapsule(ByteString.copyFrom(address), type); + accountCache.put(key, Value.create(account, Type.CREATE)); + return account; + } + + @Override + public AccountCapsule createAccount(byte[] address, String accountName, + Protocol.AccountType type) { + Key key = new Key(address); + AccountCapsule account = new AccountCapsule(ByteString.copyFrom(address), + ByteString.copyFromUtf8(accountName), + type); + accountCache.put(key, Value.create(account, Type.CREATE)); + return account; + } + + @Override + public AccountCapsule getAccount(byte[] address) { + Key key = new Key(address); + if (accountCache.containsKey(key)) { + return new AccountCapsule(accountCache.get(key).getValue()); + } + + AccountCapsule accountCapsule; + if (parent != null) { + accountCapsule = parent.getAccount(address); + } else { + accountCapsule = worldStateQueryInstance.getAccount(address); + } + + if (accountCapsule != null) { + accountCache.put(key, Value.create(accountCapsule)); + } + return accountCapsule; + } + + @Override + public BytesCapsule getDynamicProperty(byte[] word) { + Key key = Key.create(word); + if (dynamicPropertiesCache.containsKey(key)) { + return new BytesCapsule(dynamicPropertiesCache.get(key).getValue()); + } + + BytesCapsule bytesCapsule; + if (parent != null) { + bytesCapsule = parent.getDynamicProperty(word); + } else { + try { + bytesCapsule = getDynamicPropertiesStore().get(word); + } catch (BadItemException | ItemNotFoundException e) { + logger.warn("Not found dynamic property:" + Strings.fromUTF8ByteArray(word)); + bytesCapsule = null; + } + } + + if (bytesCapsule != null) { + dynamicPropertiesCache.put(key, Value.create(bytesCapsule.getData())); + } + return bytesCapsule; + } + + @Override + public DelegatedResourceCapsule getDelegatedResource(byte[] key) { + Key cacheKey = new Key(key); + if (delegatedResourceCache.containsKey(cacheKey)) { + return new DelegatedResourceCapsule(delegatedResourceCache.get(cacheKey).getValue()); + } + + DelegatedResourceCapsule delegatedResourceCapsule; + if (parent != null) { + delegatedResourceCapsule = parent.getDelegatedResource(key); + } else { + delegatedResourceCapsule = worldStateQueryInstance.getDelegatedResource(key); + } + + if (delegatedResourceCapsule != null) { + delegatedResourceCache.put(cacheKey, Value.create(delegatedResourceCapsule)); + } + return delegatedResourceCapsule; + } + + @Override + public VotesCapsule getVotes(byte[] address) { + Key cacheKey = new Key(address); + if (votesCache.containsKey(cacheKey)) { + return new VotesCapsule(votesCache.get(cacheKey).getValue()); + } + + VotesCapsule votesCapsule; + if (parent != null) { + votesCapsule = parent.getVotes(address); + } else { + votesCapsule = worldStateQueryInstance.getVotes(address); + } + + if (votesCapsule != null) { + votesCache.put(cacheKey, Value.create(votesCapsule)); + } + return votesCapsule; + } + + @Override + public WitnessCapsule getWitness(byte[] address) { + return worldStateQueryInstance.getWitness(address); + } + + @Override + public long getBeginCycle(byte[] address) { + Key cacheKey = new Key(address); + BytesCapsule bytesCapsule = getDelegation(cacheKey); + return bytesCapsule == null ? 0 : ByteArray.toLong(bytesCapsule.getData()); + } + + @Override + public long getEndCycle(byte[] address) { + byte[] key = ("end-" + Hex.toHexString(address)).getBytes(); + Key cacheKey = new Key(key); + BytesCapsule bytesCapsule = getDelegation(cacheKey); + return bytesCapsule == null ? DelegationStore.REMARK : ByteArray.toLong(bytesCapsule.getData()); + } + + @Override + public AccountCapsule getAccountVote(long cycle, byte[] address) { + byte[] key = (cycle + "-" + Hex.toHexString(address) + "-account-vote").getBytes(); + Key cacheKey = new Key(key); + BytesCapsule bytesCapsule = getDelegation(cacheKey); + if (bytesCapsule == null) { + return null; + } else { + return new AccountCapsule(bytesCapsule.getData()); + } + } + + @Override + public BytesCapsule getDelegation(Key key) { + if (delegationCache.containsKey(key)) { + return new BytesCapsule(delegationCache.get(key).getValue()); + } + BytesCapsule bytesCapsule; + if (parent != null) { + bytesCapsule = parent.getDelegation(key); + } else { + bytesCapsule = worldStateQueryInstance.getDelegation(key.getData()); + } + if (bytesCapsule != null) { + delegationCache.put(key, Value.create(bytesCapsule.getData())); + } + return bytesCapsule; + } + + @Override + public DelegatedResourceAccountIndexCapsule getDelegatedResourceAccountIndex(byte[] key) { + Key cacheKey = new Key(key); + if (delegatedResourceAccountIndexCache.containsKey(cacheKey)) { + return new DelegatedResourceAccountIndexCapsule( + delegatedResourceAccountIndexCache.get(cacheKey).getValue()); + } + + DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsule; + if (parent != null) { + delegatedResourceAccountIndexCapsule = parent.getDelegatedResourceAccountIndex(key); + } else { + delegatedResourceAccountIndexCapsule = worldStateQueryInstance + .getDelegatedResourceAccountIndex(key); + } + + if (delegatedResourceAccountIndexCapsule != null) { + delegatedResourceAccountIndexCache.put( + cacheKey, Value.create(delegatedResourceAccountIndexCapsule)); + } + return delegatedResourceAccountIndexCapsule; + } + + + @Override + public void deleteContract(byte[] address) { + throw new UnsupportedOperationException(); + + } + + @Override + public void createContract(byte[] address, ContractCapsule contractCapsule) { + contractCache.put(Key.create(address), + Value.create(contractCapsule, Type.CREATE)); + } + + @Override + public ContractCapsule getContract(byte[] address) { + Key key = Key.create(address); + if (contractCache.containsKey(key)) { + return new ContractCapsule(contractCache.get(key).getValue()); + } + + ContractCapsule contractCapsule; + if (parent != null) { + contractCapsule = parent.getContract(address); + } else { + contractCapsule = worldStateQueryInstance.getContract(address); + } + + if (contractCapsule != null) { + contractCache.put(key, Value.create(contractCapsule)); + } + return contractCapsule; + } + + @Override + public ContractStateCapsule getContractState(byte[] address) { + Key key = Key.create(address); + if (contractStateCache.containsKey(key)) { + return new ContractStateCapsule(contractStateCache.get(key).getValue()); + } + + ContractStateCapsule contractStateCapsule; + if (parent != null) { + contractStateCapsule = parent.getContractState(address); + } else { + contractStateCapsule = worldStateQueryInstance.getContractState(address); + } + + if (contractStateCapsule != null) { + contractStateCache.put(key, Value.create(contractStateCapsule)); + } + return contractStateCapsule; + } + + @Override + public void updateContract(byte[] address, ContractCapsule contractCapsule) { + contractCache.put(Key.create(address), + Value.create(contractCapsule, Type.DIRTY)); + } + + @Override + public void updateContractState(byte[] address, ContractStateCapsule contractStateCapsule) { + contractStateCache.put(Key.create(address), + Value.create(contractStateCapsule, Type.DIRTY)); + } + + @Override + public void updateAccount(byte[] address, AccountCapsule accountCapsule) { + accountCache.put(Key.create(address), + Value.create(accountCapsule, Type.DIRTY)); + } + + @Override + public void updateDynamicProperty(byte[] word, BytesCapsule bytesCapsule) { + dynamicPropertiesCache.put(Key.create(word), + Value.create(bytesCapsule.getData(), Type.DIRTY)); + } + + @Override + public void updateDelegatedResource(byte[] word, + DelegatedResourceCapsule delegatedResourceCapsule) { + delegatedResourceCache.put(Key.create(word), + Value.create(delegatedResourceCapsule, Type.DIRTY)); + } + + @Override + public void updateVotes(byte[] word, VotesCapsule votesCapsule) { + votesCache.put(Key.create(word), + Value.create(votesCapsule, Type.DIRTY)); + } + + @Override + public void updateBeginCycle(byte[] word, long cycle) { + updateDelegation(word, new BytesCapsule(ByteArray.fromLong(cycle))); + } + + @Override + public void updateEndCycle(byte[] word, long cycle) { + BytesCapsule bytesCapsule = new BytesCapsule(ByteArray.fromLong(cycle)); + byte[] key = ("end-" + Hex.toHexString(word)).getBytes(); + updateDelegation(key, bytesCapsule); + } + + @Override + public void updateAccountVote(byte[] word, long cycle, AccountCapsule accountCapsule) { + BytesCapsule bytesCapsule = new BytesCapsule(accountCapsule.getData()); + byte[] key = (cycle + "-" + Hex.toHexString(word) + "-account-vote").getBytes(); + updateDelegation(key, bytesCapsule); + } + + @Override + public void updateDelegation(byte[] word, BytesCapsule bytesCapsule) { + delegationCache.put(Key.create(word), + Value.create(bytesCapsule.getData(), Type.DIRTY)); + } + + @Override + public void updateDelegatedResourceAccountIndex(byte[] word, + DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsule) { + delegatedResourceAccountIndexCache.put( + Key.create(word), Value.create(delegatedResourceAccountIndexCapsule, Type.DIRTY)); + } + + @Override + public void saveCode(byte[] address, byte[] code) { + codeCache.put(Key.create(address), Value.create(code, Type.CREATE)); + + if (VMConfig.allowTvmConstantinople()) { + ContractCapsule contract = getContract(address); + byte[] codeHash = Hash.sha3(code); + contract.setCodeHash(codeHash); + updateContract(address, contract); + } + } + + @Override + public byte[] getCode(byte[] address) { + Key key = Key.create(address); + if (codeCache.containsKey(key)) { + return codeCache.get(key).getValue(); + } + + byte[] code; + if (parent != null) { + code = parent.getCode(address); + } else { + CodeCapsule c = worldStateQueryInstance.getCode(address); + code = null == c ? null : c.getData(); + } + if (code != null) { + codeCache.put(key, Value.create(code)); + } + return code; + } + + @Override + public void putStorageValue(byte[] address, DataWord key, DataWord value) { + Storage storage = getStorageInternal(address); + if (storage != null) { + storage.put(key, value); + } + } + + @Override + public DataWord getStorageValue(byte[] address, DataWord key) { + Storage storage = getStorageInternal(address); + return storage == null ? null : storage.getValue(key); + } + + private Storage getStorageInternal(byte[] address) { + address = TransactionTrace.convertToTronAddress(address); + if (getAccount(address) == null) { + return null; + } + Key addressKey = Key.create(address); + Storage storage; + if (storageCache.containsKey(addressKey)) { + storage = storageCache.get(addressKey); + } else { + storage = getStorage(address); + storageCache.put(addressKey, storage); + } + return storage; + } + + @Override + public Storage getStorage(byte[] address) { + Key key = Key.create(address); + if (storageCache.containsKey(key)) { + return storageCache.get(key); + } + Storage storage; + if (this.parent != null) { + Storage parentStorage = parent.getStorage(address); + if (StorageUtils.getEnergyLimitHardFork()) { + // deep copy + storage = new Storage(parentStorage); + } else { + storage = parentStorage; + } + } else { + storage = new Storage(address, worldStateQueryInstance); + } + ContractCapsule contract = getContract(address); + if (contract != null) { + storage.setContractVersion(contract.getContractVersion()); + if (!ByteUtil.isNullOrZeroArray(contract.getTrxHash())) { + storage.generateAddrHash(contract.getTrxHash()); + } + } + return storage; + } + + @Override + public long getBalance(byte[] address) { + AccountCapsule accountCapsule = getAccount(address); + return accountCapsule == null ? 0L : accountCapsule.getBalance(); + } + + @Override + public long addBalance(byte[] address, long value) { + AccountCapsule accountCapsule = getAccount(address); + if (accountCapsule == null) { + accountCapsule = createAccount(address, Protocol.AccountType.Normal); + } + + long balance = accountCapsule.getBalance(); + if (value == 0) { + return balance; + } + + if (value < 0 && balance < -value) { + throw new RuntimeException( + StringUtil.createReadableString(accountCapsule.createDbKey()) + + " insufficient balance"); + } + accountCapsule.setBalance(Math.addExact(balance, value)); + Key key = Key.create(address); + accountCache.put(key, Value.create(accountCapsule, + accountCache.get(key).getType().addType(Type.DIRTY))); + return accountCapsule.getBalance(); + } + + @Override + public void setParent(Repository repository) { + parent = repository; + } + + @Override + public void commit() { + Repository repository = null; + if (parent != null) { + repository = parent; + } + commitAccountCache(repository); + commitCodeCache(repository); + commitContractCache(repository); + commitContractStateCache(repository); + commitStorageCache(repository); + commitDynamicCache(repository); + commitDelegatedResourceCache(repository); + commitVotesCache(repository); + commitDelegationCache(repository); + commitDelegatedResourceAccountIndexCache(repository); + } + + @Override + public void putAccount(Key key, Value value) { + accountCache.put(key, value); + } + + @Override + public void putCode(Key key, Value value) { + codeCache.put(key, value); + } + + @Override + public void putContract(Key key, Value value) { + contractCache.put(key, value); + } + + @Override + public void putContractState(Key key, Value value) { + contractStateCache.put(key, value); + } + + @Override + public void putStorage(Key key, Storage cache) { + storageCache.put(key, cache); + } + + @Override + public void putAccountValue(byte[] address, AccountCapsule accountCapsule) { + accountCache.put(new Key(address), + Value.create(accountCapsule, Type.CREATE)); + } + + @Override + public void putDynamicProperty(Key key, Value value) { + dynamicPropertiesCache.put(key, value); + } + + @Override + public void putDelegatedResource(Key key, Value value) { + delegatedResourceCache.put(key, value); + } + + @Override + public void putVotes(Key key, Value value) { + votesCache.put(key, value); + } + + @Override + public void putDelegation(Key key, Value value) { + delegationCache.put(key, value); + } + + @Override + public void putDelegatedResourceAccountIndex(Key key, Value value) { + delegatedResourceAccountIndexCache.put(key, value); + } + + @Override + public long addTokenBalance(byte[] address, byte[] tokenId, long value) { + byte[] tokenIdWithoutLeadingZero = ByteUtil.stripLeadingZeroes(tokenId); + AccountCapsule accountCapsule = getAccount(address); + if (accountCapsule == null) { + accountCapsule = createAccount(address, Protocol.AccountType.Normal); + } + long balance = accountCapsule.getAssetV2(new String(tokenIdWithoutLeadingZero)); + if (value == 0) { + return balance; + } + + if (value < 0 && balance < -value) { + throw new RuntimeException( + StringUtil.createReadableString(accountCapsule.createDbKey()) + + " insufficient balance"); + } + if (value >= 0) { + accountCapsule.addAssetAmountV2(tokenIdWithoutLeadingZero, value, getDynamicPropertiesStore(), + getAssetIssueStore()); + } else { + accountCapsule + .reduceAssetAmountV2(tokenIdWithoutLeadingZero, -value, getDynamicPropertiesStore(), + getAssetIssueStore()); + } + Key key = Key.create(address); + accountCache.put(key, Value.create(accountCapsule, + accountCache.get(key).getType().addType(Type.DIRTY))); + return accountCapsule.getAssetV2(new String(tokenIdWithoutLeadingZero)); + } + + @Override + public long getTokenBalance(byte[] address, byte[] tokenId) { + AccountCapsule accountCapsule = getAccount(address); + if (accountCapsule == null) { + return 0; + } + String tokenStr = new String(ByteUtil.stripLeadingZeroes(tokenId)); + return accountCapsule.getAssetV2(tokenStr); + } + + @Override + public byte[] getBlackHoleAddress() { + return AccountStore.getBlackholeAddress(); + } + + @Override + public BlockCapsule getBlockByNum(long num) { + try { + return ChainBaseManager.getInstance().getBlockByNum(num); + } catch (StoreException e) { + throw new Program.IllegalOperationException("cannot find block num"); + } + } + + // new recover method, use personal window size. + private long recover(long lastUsage, long lastTime, long now, long personalWindowSize) { + return increase(lastUsage, 0, lastTime, now, personalWindowSize); + } + + private long increase(long lastUsage, long usage, long lastTime, long now, long windowSize) { + long averageLastUsage = divideCeil(lastUsage * precision, windowSize); + long averageUsage = divideCeil(usage * precision, windowSize); + + if (lastTime != now) { + assert now > lastTime; + if (lastTime + windowSize > now) { + long delta = now - lastTime; + double decay = (windowSize - delta) / (double) windowSize; + averageLastUsage = Math.round(averageLastUsage * decay); + } else { + averageLastUsage = 0; + } + } + averageLastUsage += averageUsage; + return getUsage(averageLastUsage, windowSize); + } + + private long divideCeil(long numerator, long denominator) { + return (numerator / denominator) + ((numerator % denominator) > 0 ? 1 : 0); + } + + private long getUsage(long usage, long windowSize) { + return usage * windowSize / precision; + } + + @Override + public long calculateGlobalEnergyLimit(AccountCapsule accountCapsule) { + long frozeBalance = accountCapsule.getAllFrozenBalanceForEnergy(); + if (frozeBalance < 1_000_000L) { + return 0; + } + long energyWeight = frozeBalance / 1_000_000L; + long totalEnergyLimit = getDynamicPropertiesStore().getTotalEnergyCurrentLimit(); + long totalEnergyWeight = getDynamicPropertiesStore().getTotalEnergyWeight(); + + assert totalEnergyWeight > 0; + + return (long) (energyWeight * ((double) totalEnergyLimit / totalEnergyWeight)); + } + + public long getHeadSlot() { + return getSlotByTimestampMs(getDynamicPropertiesStore().getLatestBlockHeaderTimestamp()); + } + + @Override + public long getSlotByTimestampMs(long timestamp) { + return (timestamp - Long.parseLong(CommonParameter.getInstance() + .getGenesisBlock().getTimestamp())) + / BLOCK_PRODUCED_INTERVAL; + } + + private void commitAccountCache(Repository deposit) { + accountCache.forEach((key, value) -> { + if (value.getType().isCreate() || value.getType().isDirty()) { + if (deposit != null) { + deposit.putAccount(key, value); + } else { + throw new UnsupportedOperationException(); + } + } + }); + } + + private void commitCodeCache(Repository deposit) { + codeCache.forEach(((key, value) -> { + if (value.getType().isDirty() || value.getType().isCreate()) { + if (deposit != null) { + deposit.putCode(key, value); + } else { + throw new UnsupportedOperationException(); + } + } + })); + } + + private void commitContractCache(Repository deposit) { + contractCache.forEach(((key, value) -> { + if (value.getType().isDirty() || value.getType().isCreate()) { + if (deposit != null) { + deposit.putContract(key, value); + } else { + throw new UnsupportedOperationException(); + } + } + })); + } + + private void commitContractStateCache(Repository deposit) { + contractStateCache.forEach(((key, value) -> { + if (value.getType().isDirty() || value.getType().isCreate()) { + if (deposit != null) { + deposit.putContractState(key, value); + } else { + throw new UnsupportedOperationException(); + } + } + })); + } + + private void commitStorageCache(Repository deposit) { + storageCache.forEach((Key address, Storage storage) -> { + if (deposit != null) { + // write to parent cache + deposit.putStorage(address, storage); + } else { + throw new UnsupportedOperationException(); + } + }); + + } + + private void commitDynamicCache(Repository deposit) { + dynamicPropertiesCache.forEach(((key, value) -> { + if (value.getType().isDirty() || value.getType().isCreate()) { + if (deposit != null) { + deposit.putDynamicProperty(key, value); + } else { + throw new UnsupportedOperationException(); + } + } + })); + } + + private void commitDelegatedResourceCache(Repository deposit) { + delegatedResourceCache.forEach(((key, value) -> { + if (value.getType().isDirty() || value.getType().isCreate()) { + if (deposit != null) { + deposit.putDelegatedResource(key, value); + } else { + throw new UnsupportedOperationException(); + } + } + })); + } + + private void commitVotesCache(Repository deposit) { + votesCache.forEach(((key, value) -> { + if (value.getType().isDirty() || value.getType().isCreate()) { + if (deposit != null) { + deposit.putVotes(key, value); + } else { + throw new UnsupportedOperationException(); + } + } + })); + } + + private void commitDelegationCache(Repository deposit) { + delegationCache.forEach((key, value) -> { + if (value.getType().isDirty() || value.getType().isCreate()) { + if (deposit != null) { + deposit.putDelegation(key, value); + } else { + throw new UnsupportedOperationException(); + } + } + }); + } + + private void commitDelegatedResourceAccountIndexCache(Repository deposit) { + delegatedResourceAccountIndexCache.forEach(((key, value) -> { + if (value.getType().isDirty() || value.getType().isCreate()) { + if (deposit != null) { + deposit.putDelegatedResourceAccountIndex(key, value); + } else { + throw new UnsupportedOperationException(); + } + } + })); + } + + @Override + public AccountCapsule createNormalAccount(byte[] address) { + boolean withDefaultPermission = + getDynamicPropertiesStore().getAllowMultiSign() == 1; + Key key = new Key(address); + AccountCapsule account = new AccountCapsule(ByteString.copyFrom(address), AccountType.Normal, + getDynamicPropertiesStore().getLatestBlockHeaderTimestamp(), withDefaultPermission, + getDynamicPropertiesStore()); + + accountCache.put(key, Value.create(account, Type.CREATE)); + return account; + } + + //The unit is trx + @Override + public void addTotalNetWeight(long amount) { + long totalNetWeight = getTotalNetWeight(); + totalNetWeight += amount; + saveTotalNetWeight(totalNetWeight); + } + + //The unit is trx + @Override + public void addTotalEnergyWeight(long amount) { + long totalEnergyWeight = getTotalEnergyWeight(); + totalEnergyWeight += amount; + saveTotalEnergyWeight(totalEnergyWeight); + } + + @Override + public void addTotalTronPowerWeight(long amount) { + long totalTronPowerWeight = getTotalTronPowerWeight(); + totalTronPowerWeight += amount; + saveTotalTronPowerWeight(totalTronPowerWeight); + } + + @Override + public void saveTotalNetWeight(long totalNetWeight) { + updateDynamicProperty(TOTAL_NET_WEIGHT, + new BytesCapsule(ByteArray.fromLong(totalNetWeight))); + } + + @Override + public void saveTotalEnergyWeight(long totalEnergyWeight) { + updateDynamicProperty(TOTAL_ENERGY_WEIGHT, + new BytesCapsule(ByteArray.fromLong(totalEnergyWeight))); + } + + @Override + public void saveTotalTronPowerWeight(long totalTronPowerWeight) { + updateDynamicProperty(TOTAL_TRON_POWER_WEIGHT, + new BytesCapsule(ByteArray.fromLong(totalTronPowerWeight))); + } + + @Override + public long getTotalNetWeight() { + return Optional.ofNullable(getDynamicProperty(TOTAL_NET_WEIGHT)) + .map(BytesCapsule::getData) + .map(ByteArray::toLong) + .orElseThrow( + () -> new IllegalArgumentException("not found TOTAL_NET_WEIGHT")); + } + + @Override + public long getTotalEnergyWeight() { + return Optional.ofNullable(getDynamicProperty(TOTAL_ENERGY_WEIGHT)) + .map(BytesCapsule::getData) + .map(ByteArray::toLong) + .orElseThrow( + () -> new IllegalArgumentException("not found TOTAL_ENERGY_WEIGHT")); + } + + @Override + public long getTotalTronPowerWeight() { + return Optional.ofNullable(getDynamicProperty(TOTAL_TRON_POWER_WEIGHT)) + .map(BytesCapsule::getData) + .map(ByteArray::toLong) + .orElseThrow( + () -> new IllegalArgumentException("not found TOTAL_TRON_POWER_WEIGHT")); + } + +} diff --git a/build.gradle b/build.gradle index a4d23e2184e..42c36101b44 100644 --- a/build.gradle +++ b/build.gradle @@ -48,7 +48,7 @@ subprojects { compile "com.google.code.findbugs:jsr305:3.0.0" compile group: 'org.springframework', name: 'spring-context', version: '5.3.18' compile group: 'org.springframework', name: 'spring-tx', version: '5.3.18' - compile "org.apache.commons:commons-lang3:3.4" + compile "org.apache.commons:commons-lang3:3.12.0" compile group: 'org.apache.commons', name: 'commons-math', version: '2.2' compile "org.apache.commons:commons-collections4:4.1" compile group: 'joda-time', name: 'joda-time', version: '2.3' diff --git a/chainbase/build.gradle b/chainbase/build.gradle index ed9911b0032..0a42c83fd9f 100644 --- a/chainbase/build.gradle +++ b/chainbase/build.gradle @@ -44,6 +44,7 @@ dependencies { compile project(":protocol") compile project(":common") compile project(":crypto") + compile project(":state-trie-jdk8") compile 'org.reflections:reflections:0.9.11' } diff --git a/chainbase/src/main/java/org/tron/core/ChainBaseManager.java b/chainbase/src/main/java/org/tron/core/ChainBaseManager.java index adf66527499..b7bf6d78769 100644 --- a/chainbase/src/main/java/org/tron/core/ChainBaseManager.java +++ b/chainbase/src/main/java/org/tron/core/ChainBaseManager.java @@ -2,15 +2,23 @@ import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; +import com.google.common.cache.CacheLoader; import com.google.protobuf.ByteString; import java.util.List; import javax.annotation.PostConstruct; +import java.util.concurrent.ExecutionException; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; +import org.apache.tuweni.bytes.Bytes32; +import org.hyperledger.besu.ethereum.trie.MerkleTrieException; +import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.common.cache.CacheManager; +import org.tron.common.cache.CacheType; +import org.tron.common.cache.TronCache; import org.tron.common.storage.metric.DbStatService; import org.tron.common.utils.ForkController; import org.tron.common.utils.Sha256Hash; @@ -34,6 +42,9 @@ import org.tron.core.exception.HeaderNotFound; import org.tron.core.exception.ItemNotFoundException; import org.tron.core.service.MortgageService; +import org.tron.core.state.WorldStateGenesis; +import org.tron.core.state.WorldStateQueryInstance; +import org.tron.core.state.WorldStateTrieStore; import org.tron.core.store.AbiStore; import org.tron.core.store.AccountAssetStore; import org.tron.core.store.AccountIdIndexStore; @@ -234,6 +245,14 @@ public class ChainBaseManager { @Getter private SectionBloomStore sectionBloomStore; + @Autowired + @Getter + private WorldStateTrieStore worldStateTrieStore; + + @Autowired + @Getter + private WorldStateGenesis worldStateGenesis; + @Autowired private DbStatService dbStatService; @@ -423,6 +442,14 @@ public static ChainBaseManager getInstance() { public static synchronized void init(ChainBaseManager manager) { chainBaseManager = manager; + cache = CacheManager.allocate(CacheType.worldStateQueryInstance, + new CacheLoader() { + @Override + public WorldStateQueryInstance load(@NotNull Bytes32 key) throws Exception { + return new WorldStateQueryInstance(key, chainBaseManager); + } + }); + AssetUtil.setAccountAssetStore(manager.getAccountAssetStore()); AssetUtil.setDynamicPropertiesStore(manager.getDynamicPropertiesStore()); } @@ -449,5 +476,18 @@ public enum NodeType { this.type = type; } } + + private static TronCache cache; + + public static WorldStateQueryInstance fetch(Bytes32 root) { + try { + if (root == null || root.isEmpty()) { + throw new IllegalStateException("root can not be empty"); + } + return cache.get(root); + } catch (ExecutionException e) { + throw new MerkleTrieException("fetch worldStateQueryInstance", e); + } + } } diff --git a/chainbase/src/main/java/org/tron/core/capsule/AccountCapsule.java b/chainbase/src/main/java/org/tron/core/capsule/AccountCapsule.java index 13f3cf576f1..4473f3e32b4 100644 --- a/chainbase/src/main/java/org/tron/core/capsule/AccountCapsule.java +++ b/chainbase/src/main/java/org/tron/core/capsule/AccountCapsule.java @@ -18,8 +18,11 @@ import com.google.common.collect.Maps; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; +import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; +import org.apache.tuweni.bytes.Bytes32; import org.tron.common.utils.ByteArray; import org.tron.core.capsule.utils.AssetUtil; import org.tron.core.store.AssetIssueStore; @@ -57,6 +60,10 @@ public class AccountCapsule implements ProtoCapsule, Comparable map = new HashMap<>(); - map.putAll(account.getAssetV2Map()); - map.put(sKey, balance); + Map map = new HashMap<>(account.getAssetV2Map()); + map.put(tokenId, balance); return account.toBuilder().clearAssetV2().putAllAssetV2(map).build(); } - public static Account importAllAsset(Account account) { - if (!isAllowAssetOptimization()) { + public static Account importAllAsset(Account account, Bytes32 root) { + if (!isAllowAssetOptimization(root)) { + return account; + } + + if (!account.getAssetOptimized()) { return account; } - Map map = accountAssetStore.getAllAssets(account); + Map map; + if (Bytes32.ZERO.equals(root)) { + map = accountAssetStore.getAllAssets(account); + } else { + map = ChainBaseManager.fetch(root).importAllAsset(account); + } return account.toBuilder().clearAssetV2().putAllAssetV2(map).build(); } @@ -60,8 +85,12 @@ public static void setDynamicPropertiesStore(DynamicPropertiesStore dynamicPrope AssetUtil.dynamicPropertiesStore = dynamicPropertiesStore; } - public static boolean isAllowAssetOptimization() { - return dynamicPropertiesStore.supportAllowAssetOptimization(); + public static boolean isAllowAssetOptimization(Bytes32 root) { + if (Bytes32.ZERO.equals(root)) { + return dynamicPropertiesStore.supportAllowAssetOptimization(); + } + return ChainBaseManager.fetch(root).supportAllowAssetOptimization(); + } } diff --git a/chainbase/src/main/java/org/tron/core/db/BandwidthProcessor.java b/chainbase/src/main/java/org/tron/core/db/BandwidthProcessor.java index f13002f2dfa..9f94fba68d8 100644 --- a/chainbase/src/main/java/org/tron/core/db/BandwidthProcessor.java +++ b/chainbase/src/main/java/org/tron/core/db/BandwidthProcessor.java @@ -20,6 +20,10 @@ import org.tron.core.exception.AccountResourceInsufficientException; import org.tron.core.exception.ContractValidateException; import org.tron.core.exception.TooBigTransactionResultException; +import org.tron.core.store.AccountStore; +import org.tron.core.store.AssetIssueStore; +import org.tron.core.store.AssetIssueV2Store; +import org.tron.core.store.DynamicPropertiesStore; import org.tron.protos.Protocol.Transaction.Contract; import org.tron.protos.contract.AssetIssueContractOuterClass.TransferAssetContract; import org.tron.protos.contract.BalanceContract.TransferContract; @@ -29,22 +33,32 @@ @Slf4j(topic = "DB") public class BandwidthProcessor extends ResourceProcessor { - private ChainBaseManager chainBaseManager; + private AssetIssueStore assetIssueStore; + private AssetIssueV2Store assetIssueV2Store; public BandwidthProcessor(ChainBaseManager chainBaseManager) { super(chainBaseManager.getDynamicPropertiesStore(), chainBaseManager.getAccountStore()); - this.chainBaseManager = chainBaseManager; + this.assetIssueStore = chainBaseManager.getAssetIssueStore(); + this.assetIssueV2Store = chainBaseManager.getAssetIssueV2Store(); + } + + public BandwidthProcessor(DynamicPropertiesStore dynamicPropertiesStore, + AccountStore accountStore, AssetIssueStore assetIssueStore, + AssetIssueV2Store assetIssueV2Store) { + super(dynamicPropertiesStore, accountStore); + this.assetIssueStore = assetIssueStore; + this.assetIssueV2Store = assetIssueV2Store; } public void updateUsageForDelegated(AccountCapsule ac) { - long now = chainBaseManager.getHeadSlot(); + long now = getHeadSlot(); long oldNetUsage = ac.getNetUsage(); long latestConsumeTime = ac.getLatestConsumeTime(); ac.setNetUsage(increase(ac, BANDWIDTH, oldNetUsage, 0, latestConsumeTime, now)); } public void updateUsage(AccountCapsule accountCapsule) { - long now = chainBaseManager.getHeadSlot(); + long now = getHeadSlot(); long oldNetUsage = accountCapsule.getNetUsage(); long latestConsumeTime = accountCapsule.getLatestConsumeTime(); accountCapsule.setNetUsage(increase(accountCapsule, BANDWIDTH, @@ -53,7 +67,7 @@ public void updateUsage(AccountCapsule accountCapsule) { long latestConsumeFreeTime = accountCapsule.getLatestConsumeFreeTime(); accountCapsule.setFreeNetUsage(increase(oldFreeNetUsage, 0, latestConsumeFreeTime, now)); - if (chainBaseManager.getDynamicPropertiesStore().getAllowSameTokenName() == 0) { + if (dynamicPropertiesStore.getAllowSameTokenName() == 0) { Map assetMap = accountCapsule.getAssetMap(); assetMap.forEach((assetName, balance) -> { long oldFreeAssetNetUsage = accountCapsule.getFreeAssetNetUsage(assetName); @@ -79,7 +93,7 @@ public void updateUsage(AccountCapsule accountCapsule) { // update usage for asset issue public void updateUsage(AssetIssueCapsule assetIssueCapsule) { - long now = chainBaseManager.getHeadSlot(); + long now = getHeadSlot(); updateUsage(assetIssueCapsule, now); } @@ -103,7 +117,7 @@ public void consume(TransactionCapsule trx, TransactionTrace trace) long bytesSize; - if (chainBaseManager.getDynamicPropertiesStore().supportVM()) { + if (dynamicPropertiesStore.supportVM()) { bytesSize = trx.getInstance().toBuilder().clearRet().build().getSerializedSize(); } else { bytesSize = trx.getSerializedSize(); @@ -113,19 +127,19 @@ public void consume(TransactionCapsule trx, TransactionTrace trace) if (contract.getType() == ShieldedTransferContract) { continue; } - if (chainBaseManager.getDynamicPropertiesStore().supportVM()) { + if (dynamicPropertiesStore.supportVM()) { bytesSize += Constant.MAX_RESULT_SIZE_IN_TX; } logger.debug("TxId {}, bandwidth cost: {}.", trx.getTransactionId(), bytesSize); trace.setNetBill(bytesSize, 0); byte[] address = TransactionCapsule.getOwner(contract); - AccountCapsule accountCapsule = chainBaseManager.getAccountStore().get(address); + AccountCapsule accountCapsule = accountStore.get(address); if (accountCapsule == null) { throw new ContractValidateException(String.format("account [%s] does not exist", StringUtil.encode58Check(address))); } - long now = chainBaseManager.getHeadSlot(); + long now = getHeadSlot(); if (contractCreateNewAccount(contract)) { consumeForCreateNewAccount(accountCapsule, bytesSize, now, trace); continue; @@ -148,7 +162,7 @@ public void consume(TransactionCapsule trx, TransactionTrace trace) continue; } - long fee = chainBaseManager.getDynamicPropertiesStore().getTransactionFee() * bytesSize; + long fee = dynamicPropertiesStore.getTransactionFee() * bytesSize; throw new AccountResourceInsufficientException( String.format( "account [%s] has insufficient bandwidth[%d] and balance[%d] to create new account", @@ -158,10 +172,10 @@ public void consume(TransactionCapsule trx, TransactionTrace trace) private boolean useTransactionFee(AccountCapsule accountCapsule, long bytes, TransactionTrace trace) { - long fee = chainBaseManager.getDynamicPropertiesStore().getTransactionFee() * bytes; + long fee = dynamicPropertiesStore.getTransactionFee() * bytes; if (consumeFeeForBandwidth(accountCapsule, fee)) { trace.setNetBill(0, fee); - chainBaseManager.getDynamicPropertiesStore().addTotalTransactionCost(fee); + dynamicPropertiesStore.addTotalTransactionCost(fee); return true; } else { return false; @@ -179,7 +193,7 @@ private void consumeForCreateNewAccount(AccountCapsule accountCapsule, long byte throw new AccountResourceInsufficientException(String.format( "account [%s] has insufficient bandwidth[%d] and balance[%d] to create new account", StringUtil.encode58Check(accountCapsule.createDbKey()), bytes, - chainBaseManager.getDynamicPropertiesStore().getCreateAccountFee())); + dynamicPropertiesStore.getCreateAccountFee())); } } } @@ -187,7 +201,7 @@ private void consumeForCreateNewAccount(AccountCapsule accountCapsule, long byte public boolean consumeBandwidthForCreateNewAccount(AccountCapsule accountCapsule, long bytes, long now, TransactionTrace trace) { - long createNewAccountBandwidthRatio = chainBaseManager.getDynamicPropertiesStore() + long createNewAccountBandwidthRatio = dynamicPropertiesStore .getCreateNewAccountBandwidthRate(); long netUsage = accountCapsule.getNetUsage(); @@ -203,7 +217,7 @@ public boolean consumeBandwidthForCreateNewAccount(AccountCapsule accountCapsule long netCost = bytes * createNewAccountBandwidthRatio; if (netCost <= (netLimit - newNetUsage)) { - long latestOperationTime = chainBaseManager.getHeadBlockTimeStamp(); + long latestOperationTime = dynamicPropertiesStore.getLatestBlockHeaderTimestamp(); if (!dynamicPropertiesStore.supportUnfreezeDelay()) { newNetUsage = increase(newNetUsage, netCost, now, now); } else { @@ -216,7 +230,7 @@ public boolean consumeBandwidthForCreateNewAccount(AccountCapsule accountCapsule accountCapsule.setNetUsage(newNetUsage); trace.setNetBillForCreateNewAccount(netCost, 0); - chainBaseManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + accountStore.put(accountCapsule.createDbKey(), accountCapsule); return true; } @@ -225,10 +239,10 @@ public boolean consumeBandwidthForCreateNewAccount(AccountCapsule accountCapsule public boolean consumeFeeForCreateNewAccount(AccountCapsule accountCapsule, TransactionTrace trace) { - long fee = chainBaseManager.getDynamicPropertiesStore().getCreateAccountFee(); + long fee = dynamicPropertiesStore.getCreateAccountFee(); if (consumeFeeForNewAccount(accountCapsule, fee)) { trace.setNetBillForCreateNewAccount(0, fee); - chainBaseManager.getDynamicPropertiesStore().addTotalCreateAccountCost(fee); + dynamicPropertiesStore.addTotalCreateAccountCost(fee); return true; } else { return false; @@ -247,8 +261,7 @@ public boolean contractCreateNewAccount(Contract contract) { } catch (Exception ex) { throw new RuntimeException(ex.getMessage()); } - toAccount = - chainBaseManager.getAccountStore().get(transferContract.getToAddress().toByteArray()); + toAccount = accountStore.get(transferContract.getToAddress().toByteArray()); return toAccount == null; case TransferAssetContract: TransferAssetContract transferAssetContract; @@ -257,8 +270,7 @@ public boolean contractCreateNewAccount(Contract contract) { } catch (Exception ex) { throw new RuntimeException(ex.getMessage()); } - toAccount = chainBaseManager.getAccountStore() - .get(transferAssetContract.getToAddress().toByteArray()); + toAccount = accountStore.get(transferAssetContract.getToAddress().toByteArray()); return toAccount == null; default: return false; @@ -280,8 +292,7 @@ private boolean useAssetAccountNet(Contract contract, AccountCapsule accountCaps AssetIssueCapsule assetIssueCapsule; AssetIssueCapsule assetIssueCapsuleV2; assetIssueCapsule = Commons.getAssetIssueStoreFinal( - chainBaseManager.getDynamicPropertiesStore(), - chainBaseManager.getAssetIssueStore(), chainBaseManager.getAssetIssueV2Store()) + dynamicPropertiesStore, assetIssueStore, assetIssueV2Store) .get(assetName.toByteArray()); if (assetIssueCapsule == null) { throw new ContractValidateException(String.format("asset [%s] does not exist", assetName)); @@ -311,7 +322,7 @@ private boolean useAssetAccountNet(Contract contract, AccountCapsule accountCaps long freeAssetNetUsage; long latestAssetOperationTime; - if (chainBaseManager.getDynamicPropertiesStore().getAllowSameTokenName() == 0) { + if (dynamicPropertiesStore.getAllowSameTokenName() == 0) { freeAssetNetUsage = accountCapsule .getFreeAssetNetUsage(tokenName); latestAssetOperationTime = accountCapsule @@ -331,7 +342,7 @@ private boolean useAssetAccountNet(Contract contract, AccountCapsule accountCaps return false; } - AccountCapsule issuerAccountCapsule = chainBaseManager.getAccountStore() + AccountCapsule issuerAccountCapsule = accountStore .get(assetIssueCapsule.getOwnerAddress().toByteArray()); long issuerNetUsage = issuerAccountCapsule.getNetUsage(); @@ -355,7 +366,7 @@ private boolean useAssetAccountNet(Contract contract, AccountCapsule accountCaps latestAssetOperationTime = now; publicLatestFreeNetTime = now; - long latestOperationTime = chainBaseManager.getHeadBlockTimeStamp(); + long latestOperationTime = dynamicPropertiesStore.getLatestBlockHeaderTimestamp(); if (!dynamicPropertiesStore.supportUnfreezeDelay()) { newIssuerNetUsage = increase(newIssuerNetUsage, bytes, now, now); } else { @@ -376,7 +387,7 @@ private boolean useAssetAccountNet(Contract contract, AccountCapsule accountCaps assetIssueCapsule.setPublicLatestFreeNetTime(publicLatestFreeNetTime); accountCapsule.setLatestOperationTime(latestOperationTime); - if (chainBaseManager.getDynamicPropertiesStore().getAllowSameTokenName() == 0) { + if (dynamicPropertiesStore.getAllowSameTokenName() == 0) { accountCapsule.putLatestAssetOperationTimeMap(tokenName, latestAssetOperationTime); accountCapsule.putFreeAssetNetUsage(tokenName, newFreeAssetNetUsage); @@ -384,24 +395,23 @@ private boolean useAssetAccountNet(Contract contract, AccountCapsule accountCaps latestAssetOperationTime); accountCapsule.putFreeAssetNetUsageV2(tokenID, newFreeAssetNetUsage); - chainBaseManager.getAssetIssueStore().put(assetIssueCapsule.createDbKey(), assetIssueCapsule); + assetIssueStore.put(assetIssueCapsule.createDbKey(), assetIssueCapsule); - assetIssueCapsuleV2 = - chainBaseManager.getAssetIssueV2Store().get(assetIssueCapsule.createDbV2Key()); + assetIssueCapsuleV2 = assetIssueV2Store.get(assetIssueCapsule.createDbV2Key()); assetIssueCapsuleV2.setPublicFreeAssetNetUsage(newPublicFreeAssetNetUsage); assetIssueCapsuleV2.setPublicLatestFreeNetTime(publicLatestFreeNetTime); - chainBaseManager.getAssetIssueV2Store() + assetIssueV2Store .put(assetIssueCapsuleV2.createDbV2Key(), assetIssueCapsuleV2); } else { accountCapsule.putLatestAssetOperationTimeMapV2(tokenID, latestAssetOperationTime); accountCapsule.putFreeAssetNetUsageV2(tokenID, newFreeAssetNetUsage); - chainBaseManager.getAssetIssueV2Store() + assetIssueV2Store .put(assetIssueCapsule.createDbV2Key(), assetIssueCapsule); } - chainBaseManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); - chainBaseManager.getAccountStore().put(issuerAccountCapsule.createDbKey(), + accountStore.put(accountCapsule.createDbKey(), accountCapsule); + accountStore.put(issuerAccountCapsule.createDbKey(), issuerAccountCapsule); return true; @@ -417,8 +427,8 @@ public long calculateGlobalNetLimit(AccountCapsule accountCapsule) { return 0; } long netWeight = frozeBalance / TRX_PRECISION; - long totalNetLimit = chainBaseManager.getDynamicPropertiesStore().getTotalNetLimit(); - long totalNetWeight = chainBaseManager.getDynamicPropertiesStore().getTotalNetWeight(); + long totalNetLimit = dynamicPropertiesStore.getTotalNetLimit(); + long totalNetWeight = dynamicPropertiesStore.getTotalNetWeight(); if (dynamicPropertiesStore.allowNewReward() && totalNetWeight <= 0) { return 0; } @@ -460,7 +470,7 @@ private boolean useAccountNet(AccountCapsule accountCapsule, long bytes, long no return false; } - long latestOperationTime = chainBaseManager.getHeadBlockTimeStamp(); + long latestOperationTime = dynamicPropertiesStore.getLatestBlockHeaderTimestamp(); if (!dynamicPropertiesStore.supportUnfreezeDelay()) { newNetUsage = increase(newNetUsage, bytes, now, now); } else { @@ -472,13 +482,13 @@ private boolean useAccountNet(AccountCapsule accountCapsule, long bytes, long no accountCapsule.setLatestOperationTime(latestOperationTime); accountCapsule.setLatestConsumeTime(now); - chainBaseManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + accountStore.put(accountCapsule.createDbKey(), accountCapsule); return true; } private boolean useFreeNet(AccountCapsule accountCapsule, long bytes, long now) { - long freeNetLimit = chainBaseManager.getDynamicPropertiesStore().getFreeNetLimit(); + long freeNetLimit = dynamicPropertiesStore.getFreeNetLimit(); long freeNetUsage = accountCapsule.getFreeNetUsage(); long latestConsumeFreeTime = accountCapsule.getLatestConsumeFreeTime(); long newFreeNetUsage = increase(freeNetUsage, 0, latestConsumeFreeTime, now); @@ -490,9 +500,9 @@ private boolean useFreeNet(AccountCapsule accountCapsule, long bytes, long now) return false; } - long publicNetLimit = chainBaseManager.getDynamicPropertiesStore().getPublicNetLimit(); - long publicNetUsage = chainBaseManager.getDynamicPropertiesStore().getPublicNetUsage(); - long publicNetTime = chainBaseManager.getDynamicPropertiesStore().getPublicNetTime(); + long publicNetLimit = dynamicPropertiesStore.getPublicNetLimit(); + long publicNetUsage = dynamicPropertiesStore.getPublicNetUsage(); + long publicNetTime = dynamicPropertiesStore.getPublicNetTime(); long newPublicNetUsage = increase(publicNetUsage, 0, publicNetTime, now); @@ -504,7 +514,7 @@ private boolean useFreeNet(AccountCapsule accountCapsule, long bytes, long now) } latestConsumeFreeTime = now; - long latestOperationTime = chainBaseManager.getHeadBlockTimeStamp(); + long latestOperationTime = dynamicPropertiesStore.getLatestBlockHeaderTimestamp(); publicNetTime = now; newFreeNetUsage = increase(newFreeNetUsage, bytes, latestConsumeFreeTime, now); newPublicNetUsage = increase(newPublicNetUsage, bytes, publicNetTime, now); @@ -512,9 +522,9 @@ private boolean useFreeNet(AccountCapsule accountCapsule, long bytes, long now) accountCapsule.setLatestConsumeFreeTime(latestConsumeFreeTime); accountCapsule.setLatestOperationTime(latestOperationTime); - chainBaseManager.getDynamicPropertiesStore().savePublicNetUsage(newPublicNetUsage); - chainBaseManager.getDynamicPropertiesStore().savePublicNetTime(publicNetTime); - chainBaseManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); + dynamicPropertiesStore.savePublicNetUsage(newPublicNetUsage); + dynamicPropertiesStore.savePublicNetTime(publicNetTime); + accountStore.put(accountCapsule.createDbKey(), accountCapsule); return true; } diff --git a/chainbase/src/main/java/org/tron/core/db/EnergyProcessor.java b/chainbase/src/main/java/org/tron/core/db/EnergyProcessor.java index 5cd0f796374..865e0d7a949 100644 --- a/chainbase/src/main/java/org/tron/core/db/EnergyProcessor.java +++ b/chainbase/src/main/java/org/tron/core/db/EnergyProcessor.java @@ -1,11 +1,9 @@ package org.tron.core.db; import static java.lang.Long.max; -import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION; import lombok.extern.slf4j.Slf4j; -import org.tron.common.parameter.CommonParameter; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.TransactionCapsule; import org.tron.core.config.Parameter.AdaptiveResourceLimitConstants; @@ -24,13 +22,6 @@ public EnergyProcessor(DynamicPropertiesStore dynamicPropertiesStore, AccountSto super(dynamicPropertiesStore, accountStore); } - public static long getHeadSlot(DynamicPropertiesStore dynamicPropertiesStore) { - return (dynamicPropertiesStore.getLatestBlockHeaderTimestamp() - - Long.parseLong(CommonParameter.getInstance() - .getGenesisBlock().getTimestamp())) - / BLOCK_PRODUCED_INTERVAL; - } - public void updateUsage(AccountCapsule accountCapsule) { long now = getHeadSlot(); updateUsage(accountCapsule, now); @@ -181,11 +172,6 @@ public long getAccountLeftEnergyFromFreeze(AccountCapsule accountCapsule) { return max(energyLimit - newEnergyUsage, 0); // us } - private long getHeadSlot() { - return getHeadSlot(dynamicPropertiesStore); - } - - } diff --git a/chainbase/src/main/java/org/tron/core/db/ResourceProcessor.java b/chainbase/src/main/java/org/tron/core/db/ResourceProcessor.java index 87472b6212f..ee0142c9298 100644 --- a/chainbase/src/main/java/org/tron/core/db/ResourceProcessor.java +++ b/chainbase/src/main/java/org/tron/core/db/ResourceProcessor.java @@ -5,6 +5,7 @@ import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; import static org.tron.core.config.Parameter.ChainConstant.WINDOW_SIZE_PRECISION; +import org.tron.common.parameter.CommonParameter; import org.tron.common.utils.Commons; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.TransactionCapsule; @@ -36,6 +37,20 @@ protected ResourceProcessor(DynamicPropertiesStore dynamicPropertiesStore, AdaptiveResourceLimitConstants.PERIODS_MS / BLOCK_PRODUCED_INTERVAL; } + public long getHeadSlot() { + return (dynamicPropertiesStore.getLatestBlockHeaderTimestamp() + - Long.parseLong(CommonParameter.getInstance() + .getGenesisBlock().getTimestamp())) + / BLOCK_PRODUCED_INTERVAL; + } + + public static long getHeadSlot(DynamicPropertiesStore dynamicPropertiesStore) { + return (dynamicPropertiesStore.getLatestBlockHeaderTimestamp() + - Long.parseLong(CommonParameter.getInstance() + .getGenesisBlock().getTimestamp())) + / BLOCK_PRODUCED_INTERVAL; + } + abstract void consume(TransactionCapsule trx, TransactionTrace trace) throws ContractValidateException, AccountResourceInsufficientException, TooBigTransactionResultException; diff --git a/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java b/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java index c1da54d84f4..3b671cb1bc4 100644 --- a/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java +++ b/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java @@ -29,12 +29,15 @@ import org.tron.core.db2.common.IRevokingDB; import org.tron.core.db2.common.LevelDB; import org.tron.core.db2.common.RocksDB; +import org.tron.core.db2.common.Value; import org.tron.core.db2.common.WrappedByteArray; import org.tron.core.db2.core.Chainbase; import org.tron.core.db2.core.ITronChainBase; import org.tron.core.db2.core.SnapshotRoot; import org.tron.core.exception.BadItemException; import org.tron.core.exception.ItemNotFoundException; +import org.tron.core.state.StateType; +import org.tron.core.state.WorldStateCallBackUtils; @Slf4j(topic = "DB") @@ -54,6 +57,11 @@ public abstract class TronStoreWithRevoking implements I @Getter private final DB db; + private StateType type; + + @Autowired + protected WorldStateCallBackUtils worldStateCallBackUtils; + protected TronStoreWithRevoking(String dbName) { String dbEngine = CommonParameter.getInstance().getStorage().getDbEngine(); if ("LEVELDB".equals(dbEngine.toUpperCase())) { @@ -75,6 +83,10 @@ protected TronStoreWithRevoking(String dbName) { throw new RuntimeException(String.format("db engine %s is error", dbEngine)); } this.revokingDB = new Chainbase(new SnapshotRoot(this.db)); + type = StateType.get(getDbName()); + } + + protected TronStoreWithRevoking() { } protected org.iq80.leveldb.Options getOptionsByDbNameForLevelDB(String dbName) { @@ -88,11 +100,12 @@ protected DirectComparator getDirectComparator() { protected TronStoreWithRevoking(DB db) { this.db = db; this.revokingDB = new Chainbase(new SnapshotRoot(db)); + type = StateType.get(getDbName()); } @Override public String getDbName() { - return null; + return db.getDbName(); } @PostConstruct @@ -106,12 +119,16 @@ public void put(byte[] key, T item) { if (Objects.isNull(key) || Objects.isNull(item)) { return; } - - revokingDB.put(key, item.getData()); + byte[] value = item.getData(); + revokingDB.put(key, value); + worldStateCallBackUtils.callBack(type, key, value, Value.Operator.PUT); } @Override public void delete(byte[] key) { + worldStateCallBackUtils.callBack(type, key, + StateType.Account == type ? revokingDB.getUnchecked(key) : null, + Value.Operator.DELETE); revokingDB.delete(key); } diff --git a/chainbase/src/main/java/org/tron/core/state/StateType.java b/chainbase/src/main/java/org/tron/core/state/StateType.java new file mode 100644 index 00000000000..356b2664576 --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/StateType.java @@ -0,0 +1,65 @@ +package org.tron.core.state; + +import com.google.common.primitives.Bytes; +import java.util.Arrays; +import lombok.Getter; + +public enum StateType { + + UNDEFINED((byte) 0x00, "undefined"), + + Account((byte) 0x01, "account"), + AccountAsset((byte) 0x02, "account-asset"), + AccountIndex((byte) 0x03, "account-index"), + AccountIdIndex((byte) 0x04, "accountid-index"), + AssetIssue((byte) 0x05, "asset-issue-v2"), + Code((byte) 0x07, "code"), + Contract((byte) 0x08, "contract"), + Delegation((byte) 0x09, "delegation"), + DelegatedResource((byte) 0x0a, "DelegatedResource"), + DelegatedResourceAccountIndex((byte) 0x0b, "DelegatedResourceAccountIndex"), + Exchange((byte) 0x0c, "exchange"), + ExchangeV2((byte) 0x0d, "exchange-v2"), + IncrementalMerkleTree((byte) 0x0e, "IncrementalMerkleTree"), + MarketAccount((byte) 0x0f, "market_account"), + MarketOrder((byte) 0x10, "market_order"), + MarketPairPriceToOrder((byte) 0x11, "market_pair_price_to_order"), + MarketPairToPrice((byte) 0x12, "market_pair_to_price"), + Nullifier((byte) 0x13, "nullifier"), + Properties((byte) 0x14, "properties"), + Proposal((byte) 0x15, "proposal"), + StorageRow((byte) 0x16, "storage-row"), + Votes((byte) 0x17, "votes"), + Witness((byte) 0x18, "witness"), + WitnessSchedule((byte) 0x19, "witness_schedule"), + ContractState((byte) 0x20, "contract-state"); + + + private final byte value; + @Getter + private final String name; + + StateType(byte value, String name) { + this.value = value; + this.name = name; + } + + public byte value() { + return this.value; + } + + public static StateType get(String name) { + return Arrays.stream(StateType.values()).filter(type -> type.name.equals(name)) + .findFirst().orElse(UNDEFINED); + } + + public static byte[] encodeKey(StateType type, byte[] key) { + byte[] p = new byte[]{type.value}; + return Bytes.concat(p, key); + } + + public static byte[] decodeKey(byte[] key) { + return Arrays.copyOfRange(key, 1, key.length); + } + +} \ No newline at end of file diff --git a/chainbase/src/main/java/org/tron/core/state/TODO.md b/chainbase/src/main/java/org/tron/core/state/TODO.md new file mode 100644 index 00000000000..a5a3f153c92 --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/TODO.md @@ -0,0 +1,17 @@ +This is the todo list: + +- filter the keys that are not the state data in `DynamicPropertiesStore`, method: `public void put(byte[] key, BytesCapsule item)` +- design the logic that decouple the asset10 from account struct, in `WorldStateCallBackUtils` +- design contract state query + - create another implementation of `Repositoty` + - create another implementation of `StorageFactory` +- add the state query interface +- make the world state tree switch as a config, e.g: `worldState = true` in `config.conf` +- make the trie prune as a config, e.g: `stateTriePrune = true` in `config.conf` +or +``` +worldstate { + open = true; + prune = false; +} +``` \ No newline at end of file diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java b/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java new file mode 100644 index 00000000000..4f131779752 --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java @@ -0,0 +1,90 @@ +package org.tron.core.state; + +import com.google.common.annotations.VisibleForTesting; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.apache.tuweni.bytes.Bytes32; +import org.hyperledger.besu.ethereum.trie.MerkleTrieException; +import org.springframework.stereotype.Component; +import org.tron.common.parameter.CommonParameter; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.state.trie.TrieImpl2; + +@Slf4j(topic = "State") +@Component +public class WorldStateCallBack extends WorldStateCallBackUtils { + + private BlockCapsule blockCapsule; + + @Getter + @VisibleForTesting + private volatile TrieImpl2 trie; + + public WorldStateCallBack() { + this.execute = true; + this.allowGenerateRoot = CommonParameter.getInstance().getStorage().isAllowStateRoot(); + } + + @VisibleForTesting + public void clear() { + if (!exe()) { + return; + } + trieEntryList.forEach(trie::put); + trieEntryList.clear(); + } + + public void preExeTrans() { + clear(); + } + + public void exeTransFinish() { + clear(); + } + + public void preExecute(BlockCapsule blockCapsule) { + this.blockCapsule = blockCapsule; + this.execute = true; + if (!exe()) { + return; + } + try { + BlockCapsule parentBlockCapsule = + chainBaseManager.getBlockById(blockCapsule.getParentBlockId()); + Bytes32 rootHash = parentBlockCapsule.getArchiveRoot(); + trie = new TrieImpl2(chainBaseManager.getWorldStateTrieStore(), rootHash); + } catch (Exception e) { + throw new MerkleTrieException(e.getMessage()); + } + } + + public void executePushFinish() { + if (!exe()) { + return; + } + clear(); + trie.commit(); + trie.flush(); + Bytes32 newRoot = trie.getRootHashByte32(); + blockCapsule.setArchiveRoot(newRoot.toArray()); + execute = false; + } + + public void initGenesis(BlockCapsule blockCapsule) { + if (!exe()) { + return; + } + trie = new TrieImpl2(chainBaseManager.getWorldStateTrieStore()); + clear(); + trie.commit(); + trie.flush(); + Bytes32 newRoot = trie.getRootHashByte32(); + blockCapsule.setArchiveRoot(newRoot.toArray()); + execute = false; + } + + public void exceptionFinish() { + execute = false; + } + +} diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateCallBackUtils.java b/chainbase/src/main/java/org/tron/core/state/WorldStateCallBackUtils.java new file mode 100644 index 00000000000..c498cbd48b4 --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateCallBackUtils.java @@ -0,0 +1,142 @@ +package org.tron.core.state; + +import com.google.common.base.Objects; +import com.google.common.primitives.Longs; +import java.util.HashMap; +import java.util.Map; + +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.tron.core.ChainBaseManager; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.db2.common.Value; + +@Slf4j(topic = "DB") +public class WorldStateCallBackUtils { + + @Setter + protected volatile boolean execute = false; + protected volatile boolean allowGenerateRoot = false; + protected Map trieEntryList = new HashMap<>(); + @Setter + protected ChainBaseManager chainBaseManager; + + public void callBack(StateType type, byte[] key, byte[] value, Value.Operator op) { + if (!exe() || type == StateType.UNDEFINED) { + return; + } + if (op == Value.Operator.DELETE || ArrayUtils.isEmpty(value)) { + if (type == StateType.Account) { + // @see org.tron.core.db2.core.SnapshotRoot#remove(byte[] key) + AccountCapsule accountCapsule = new AccountCapsule(value); + if (accountCapsule.getAssetOptimized()) { + accountCapsule.getAssetMapV2().keySet().forEach(tokenId -> addFix32( + StateType.AccountAsset, com.google.common.primitives.Bytes.concat(key, + Longs.toByteArray(Long.parseLong(tokenId))), + WorldStateQueryInstance.DELETE)); + } + } + add(type, key, WorldStateQueryInstance.DELETE); + return; + } + if (type == StateType.Account && chainBaseManager.getDynamicPropertiesStore() + .getAllowAccountAssetOptimizationFromRoot() == 1) { + // @see org.tron.core.db2.core.SnapshotRoot#put(byte[] key, byte[] value) + AccountCapsule accountCapsule = new AccountCapsule(value); + if (accountCapsule.getAssetOptimized()) { + accountCapsule.getInstance().getAssetV2Map().forEach((tokenId, amount) -> addFix32( + StateType.AccountAsset, com.google.common.primitives.Bytes.concat(key, + Longs.toByteArray(Long.parseLong(tokenId))), + Longs.toByteArray(amount))); + } else { + accountCapsule.getAssetMapV2().forEach((tokenId, amount) -> addFix32( + StateType.AccountAsset, com.google.common.primitives.Bytes.concat(key, + Longs.toByteArray(Long.parseLong(tokenId))), + Longs.toByteArray(amount))); + accountCapsule.setAssetOptimized(true); + } + value = accountCapsule.getInstance().toBuilder() + .clearAsset() + .clearAssetV2() + .build().toByteArray(); + + } + add(type, key, value); + } + + private void add(StateType type, byte[] key, byte[] value) { + trieEntryList.put(Bytes.of(StateType.encodeKey(type, key)), Bytes.of(value)); + } + + private void addFix32(StateType type, byte[] key, byte[] value) { + trieEntryList.put(fix32(StateType.encodeKey(type, key)), Bytes.of(value)); + } + + public static Bytes32 fix32(byte[] key) { + return Bytes32.rightPad(Bytes.wrap(key)); + } + + public static Bytes32 fix32(Bytes key) { + return Bytes32.rightPad(key); + } + + + protected boolean exe() { + if (!execute || !allowGenerateRoot) { + //Agreement same block high to generate archive root + execute = false; + return false; + } + return true; + } + + public static class TrieEntry { + + private Bytes key; + private Bytes data; + + public static TrieEntry build(Bytes key, Bytes data) { + TrieEntry trieEntry = new TrieEntry(); + return trieEntry.setKey(key).setData(data); + } + + public org.apache.tuweni.bytes.Bytes getKey() { + return key; + } + + public TrieEntry setKey(Bytes key) { + this.key = key; + return this; + } + + public Bytes getData() { + return data; + } + + public TrieEntry setData(Bytes data) { + this.data = data; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TrieEntry trieEntry = (TrieEntry) o; + return Objects.equal(key, trieEntry.key); + } + + @Override + public int hashCode() { + return Objects.hashCode(key); + } + } + +} diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateGenesis.java b/chainbase/src/main/java/org/tron/core/state/WorldStateGenesis.java new file mode 100644 index 00000000000..388cc0cc5f9 --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateGenesis.java @@ -0,0 +1,315 @@ +package org.tron.core.state; + +import com.google.common.collect.Maps; +import java.io.Closeable; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.apache.tuweni.bytes.Bytes; +import org.rocksdb.BlockBasedTableConfig; +import org.rocksdb.BloomFilter; +import org.rocksdb.ComparatorOptions; +import org.rocksdb.LRUCache; +import org.rocksdb.Options; +import org.rocksdb.ReadOptions; +import org.rocksdb.RocksDBException; +import org.rocksdb.RocksIterator; +import org.springframework.stereotype.Component; +import org.tron.common.parameter.CommonParameter; +import org.tron.common.utils.FileUtil; +import org.tron.common.utils.MarketOrderPriceComparatorForRockDB; +import org.tron.common.utils.PropUtil; +import org.tron.core.ChainBaseManager; +import org.tron.core.capsule.BlockCapsule; + +@Component("worldStateGenesis") +@Slf4j(topic = "DB") +public class WorldStateGenesis { + + private ChainBaseManager chainBaseManager; + + private final boolean allowStateRoot = CommonParameter.getInstance().getStorage() + .isAllowStateRoot(); + + private Path stateGenesisPath = Paths.get(CommonParameter.getInstance().getStorage() + .getStateGenesisDirectory()); + + @Getter + private long stateGenesisHeight; + + private long genesisHeight; + + private static final String STATE_GENESIS_PROPERTIES = "genesis.properties"; + + private static final String STATE_GENESIS_HEIGHT = "height"; + private static final String STATE_GENESIS_HASH = "hash"; + private static final String STATE_GENESIS_TIME = "time"; + + private final Map genesisDBs = Maps.newConcurrentMap(); + + private volatile boolean inited = false; + + public synchronized void init(ChainBaseManager chainBaseManager) { + if (!allowStateRoot) { + return; + } + if (inited) { + return; + } + this.chainBaseManager = chainBaseManager; + genesisHeight = chainBaseManager.getGenesisBlockId().getNum(); + tryInitGenesis(); + initGenesisDBs(); + inited = true; + } + + @PostConstruct + private void open() { + if (!stateGenesisPath.isAbsolute()) { + stateGenesisPath = Paths.get(CommonParameter.getInstance().getOutputDirectory(), + CommonParameter.getInstance().getStorage().getStateGenesisDirectory()); + } + } + + @PreDestroy + private void close() { + if (!inited) { + return; + } + genesisDBs.values().forEach(db -> { + try { + db.close(); + } catch (IOException e) { + logger.warn(db.name(), e.getMessage()); + } + }); + genesisDBs.clear(); + } + + public byte[] get(StateType type, byte[] key) { + if (!allowStateRoot) { + throw new IllegalStateException("StateRoot is not allowed."); + } + if (!inited) { + throw new IllegalStateException("StateRoot is not inited."); + } + + if (stateGenesisHeight == 0) { + return null; + } + + if (stateGenesisHeight > genesisHeight) { + try { + return genesisDBs.get(type).get(key); + } catch (RocksDBException e) { + throw new RuntimeException(type.getName(), e); + } + } else { + throw new IllegalStateException("stateGenesis is not available."); + } + } + + public Map prefixQuery(StateType type, byte[] key) { + if (!allowStateRoot) { + throw new IllegalStateException("StateRoot is not allowed."); + } + if (!inited) { + throw new IllegalStateException("StateRoot is not inited."); + } + + if (stateGenesisHeight == 0) { + return Collections.emptyMap(); + } + + if (stateGenesisHeight > genesisHeight) { + return genesisDBs.get(type).prefixQuery(key); + } else { + throw new IllegalStateException("stateGenesis is not available."); + } + } + + private void tryInitGenesis() { + if ((this.stateGenesisHeight = tryFindStateGenesisHeight()) > -1) { + return; + } + // copy state db + initGenesis(); + // init genesis properties + initGenesisProperties(); + } + + private void initGenesisDBs() { + if (this.stateGenesisHeight == genesisHeight) { + return; + } + Arrays.stream(StateType.values()).filter(type -> type != StateType.UNDEFINED) + .parallel().forEach(type -> { + try { + genesisDBs.put(type, new RocksDB(stateGenesisPath, type.getName())); + } catch (RocksDBException e) { + throw new RuntimeException(e); + } + }); + } + + private void initGenesis() { + logger.info("State genesis init start"); + FileUtil.createDirIfNotExists(stateGenesisPath.toString()); + long height = chainBaseManager.getHeadBlockNum(); + if (height == genesisHeight) { + logger.info("Skip state genesis init since head is {}", height); + return; + } + List dbs = Arrays.stream(StateType.values()) + .filter(type -> type != StateType.UNDEFINED) + .map(StateType::getName).collect(Collectors.toList()); + Path source = Paths.get(CommonParameter.getInstance().getOutputDirectory(), + CommonParameter.getInstance().getStorage().getDbDirectory()); + // check dbs if exist + List miss = dbs.stream().map(db -> Paths.get(source.toString(), db) + .toFile()).filter(db -> !db.exists()).map(File::getName).collect(Collectors.toList()); + if (!miss.isEmpty()) { + logger.error("Corrupted source path, miss : {}", miss); + throw new IllegalArgumentException(String.format("Corrupted source path: %s", miss)); + } + // delete if exit + dbs.stream().map(db -> Paths.get(stateGenesisPath.toString(), db).toFile()) + .filter(File::exists).forEach(dir -> { + logger.info("Delete corrupted state genesis path : {}", dir); + FileUtil.deleteDir(dir); + }); + FileUtil.copyDatabases(source, stateGenesisPath, dbs); + logger.info("State genesis init end, {}, {}", stateGenesisPath, dbs); + } + + private void initGenesisProperties() { + logger.info("State genesis properties init start"); + long height = chainBaseManager.getHeadBlockNum(); + long time = chainBaseManager.getHeadBlockTimeStamp(); + BlockCapsule.BlockId hash = chainBaseManager.getHeadBlockId(); + Map properties = new HashMap<>(); + properties.put(STATE_GENESIS_HEIGHT, String.valueOf(height)); + properties.put(STATE_GENESIS_TIME, String.valueOf(time)); + properties.put(STATE_GENESIS_HASH, hash.toString()); + String genesisFile = new File(stateGenesisPath.toString(), STATE_GENESIS_PROPERTIES).toString(); + PropUtil.writeProperties(genesisFile, properties); + this.stateGenesisHeight = height; + logger.info("State genesis properties init end, detail: {}", properties); + + } + + private long tryFindStateGenesisHeight() { + // Read "genesis.properties" file, which contains a pointer to the current header + File genesisFile = new File(stateGenesisPath.toString(), STATE_GENESIS_PROPERTIES); + if (!genesisFile.exists()) { + return -1; + } + + String height = PropUtil.readProperty(genesisFile.toString(), STATE_GENESIS_HEIGHT); + if (height.isEmpty()) { + return -1; + } + long header = Long.parseLong(height); + logger.info("State genesis header :{}", header); + return header; + } + + + interface DB extends Closeable { + byte[] get(byte[] key) throws RocksDBException; + + Map prefixQuery(byte[] key); + + String name(); + } + + static class RocksDB implements DB { + + private final org.rocksdb.RocksDB rocksDB; + private final String name; + + private static final String MARKET_PAIR_PRICE_TO_ORDER = "market_pair_price_to_order"; + + private static final LRUCache CACHE = new LRUCache(128 * 1024 * 1024L); + + public RocksDB(Path path, String name) throws RocksDBException { + this.name = name; + this.rocksDB = newRocksDbReadOnly(Paths.get(path.toString(), name)); + } + + @Override + public byte[] get(byte[] key) throws RocksDBException { + return this.rocksDB.get(key); + } + + @Override + public Map prefixQuery(byte[] key) { + try (ReadOptions readOptions = new ReadOptions().setFillCache(false)) { + RocksIterator iterator = this.rocksDB.newIterator(readOptions); + Map result = new HashMap<>(); + for (iterator.seek(key); iterator.isValid(); iterator.next()) { + if (com.google.common.primitives.Bytes.indexOf(iterator.key(), key) == 0) { + result.put(Bytes.wrap(iterator.key()), Bytes.wrap(iterator.value())); + } else { + return result; + } + } + return result; + } + } + + @Override + public String name() { + return this.name; + } + + private org.rocksdb.RocksDB newRocksDbReadOnly(Path db) throws RocksDBException { + try (Options options = newDefaultRocksDbOptions()) { + if (MARKET_PAIR_PRICE_TO_ORDER.equalsIgnoreCase(db.getFileName().toString())) { + options.setComparator(new MarketOrderPriceComparatorForRockDB(new ComparatorOptions())); + } + return org.rocksdb.RocksDB.openReadOnly(options, db.toString()); + } + } + + private Options newDefaultRocksDbOptions() { + Options options = new Options(); + options.setCreateIfMissing(false); + options.setIncreaseParallelism(1); + options.setNumLevels(7); + options.setMaxOpenFiles(100); + options.setTargetFileSizeBase(64 * 1024 * 1024); + options.setTargetFileSizeMultiplier(1); + options.setMaxBytesForLevelBase(512 * 1024 * 1024); + options.setMaxBackgroundCompactions(Math.max(1, Runtime.getRuntime().availableProcessors())); + options.setLevel0FileNumCompactionTrigger(4); + options.setLevelCompactionDynamicLevelBytes(true); + final BlockBasedTableConfig tableCfg; + options.setTableFormatConfig(tableCfg = new BlockBasedTableConfig()); + tableCfg.setBlockSize(64 * 1024); + tableCfg.setBlockCache(CACHE); + tableCfg.setCacheIndexAndFilterBlocks(true); + tableCfg.setPinL0FilterAndIndexBlocksInCache(true); + tableCfg.setFilter(new BloomFilter(10, false)); + return options; + } + + @Override + public void close() throws IOException { + this.rocksDB.close(); + } + } + + +} diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java b/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java new file mode 100644 index 00000000000..30577b5b2e4 --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java @@ -0,0 +1,213 @@ +package org.tron.core.state; + +import static org.tron.core.state.WorldStateCallBackUtils.fix32; + +import com.google.common.primitives.Longs; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.TreeMap; +import java.util.stream.Collectors; + +import lombok.Getter; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.apache.tuweni.units.bigints.UInt256; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.DecodeUtil; +import org.tron.core.ChainBaseManager; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.AssetIssueCapsule; +import org.tron.core.capsule.BytesCapsule; +import org.tron.core.capsule.CodeCapsule; +import org.tron.core.capsule.ContractCapsule; +import org.tron.core.capsule.ContractStateCapsule; +import org.tron.core.capsule.DelegatedResourceAccountIndexCapsule; +import org.tron.core.capsule.DelegatedResourceCapsule; +import org.tron.core.capsule.StorageRowCapsule; +import org.tron.core.capsule.VotesCapsule; +import org.tron.core.capsule.WitnessCapsule; +import org.tron.core.state.trie.TrieImpl2; +import org.tron.protos.Protocol; + +public class WorldStateQueryInstance { + + private final TrieImpl2 trieImpl; + + @Getter + private final Bytes32 rootHash; + + public static final byte[] DELETE = UInt256.ZERO.toArray(); + public static final int ADDRESS_SIZE = DecodeUtil.ADDRESS_SIZE >> 1; + public static final Bytes MAX_ASSET_ID = Bytes.ofUnsignedLong(Long.MAX_VALUE); + public static final Bytes MIN_ASSET_ID = Bytes.ofUnsignedLong(0); + private static final byte[] ALLOW_ASSET_OPTIMIZATION = + "ALLOW_ASSET_OPTIMIZATION".getBytes(); + + private final WorldStateGenesis worldStateGenesis; + + public WorldStateQueryInstance(Bytes32 rootHash, ChainBaseManager chainBaseManager) { + this.rootHash = rootHash; + this.trieImpl = new TrieImpl2(chainBaseManager.getWorldStateTrieStore(), rootHash); + this.worldStateGenesis = chainBaseManager.getWorldStateGenesis(); + } + + private byte[] get(StateType type, byte[] key) { + byte[] encodeKey = StateType.encodeKey(type, key); + Bytes value = trieImpl.get(encodeKey); + + if (Objects.nonNull(value)) { + if (Objects.equals(value, UInt256.ZERO)) { + return null; + } + return value.toArrayUnsafe(); + } + return worldStateGenesis.get(type, key); + } + + public AccountCapsule getAccount(byte[] address) { + byte[] value = get(StateType.Account, address); + AccountCapsule accountCapsule = null; + if (Objects.nonNull(value)) { + accountCapsule = new AccountCapsule(value); + accountCapsule.setRoot(rootHash); + } + return accountCapsule; + } + + public Long getAccountAsset(byte[] address, long tokenId) { + byte[] key = com.google.common.primitives.Bytes.concat(address, + Bytes.ofUnsignedLong(tokenId).toArray()); + byte[] encodeKey = StateType.encodeKey(StateType.AccountAsset, key); + Bytes value = trieImpl.get(fix32(encodeKey)); + if (Objects.nonNull(value)) { + if (Objects.equals(value, UInt256.ZERO)) { + return null; + } + return value.toLong(); + } + byte[] v = worldStateGenesis.get(StateType.AccountAsset, key); + return Objects.nonNull(v) ? Longs.fromByteArray(v) : null; + } + + public long getAccountAsset(Protocol.Account account, long tokenId) { + Long amount = getAccountAsset(account.getAddress().toByteArray(), tokenId); + return amount == null ? 0 : amount; + } + + public boolean hasAssetV2(Protocol.Account account, long tokenId) { + return getAccountAsset(account.getAddress().toByteArray(), tokenId) != null; + } + + public Map importAllAsset(Protocol.Account account) { + Map assets = new HashMap<>(); + Map genesis = worldStateGenesis.prefixQuery(StateType.AccountAsset, + account.getAddress().toByteArray()); + genesis.forEach((k, v) -> assets.put( + ByteArray.toStr(k.slice(ADDRESS_SIZE).toArray()), + v.toLong()) + ); + Bytes address = Bytes.of(account.getAddress().toByteArray()); + Bytes32 min = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), address, + MIN_ASSET_ID)); + + Bytes32 max = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), address, + MAX_ASSET_ID)); + TreeMap state = trieImpl.entriesFrom(min, max); + state.forEach((k, v) -> assets.put( + String.valueOf(k.slice(Byte.BYTES + ADDRESS_SIZE, Long.BYTES).toLong()), + v.toLong()) + ); + // remove asset = 0 + return assets.entrySet().stream().filter(e -> e.getValue() > 0) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + } + + // contract + public ContractCapsule getContract(byte[] address) { + byte[] value = get(StateType.Contract, address); + return Objects.nonNull(value) ? new ContractCapsule(value) : null; + } + + public ContractStateCapsule getContractState(byte[] address) { + byte[] value = get(StateType.ContractState, address); + return Objects.nonNull(value) ? new ContractStateCapsule(value) : null; + } + + public CodeCapsule getCode(byte[] address) { + byte[] value = get(StateType.Code, address); + return Objects.nonNull(value) ? new CodeCapsule(value) : null; + } + + public StorageRowCapsule getStorageRow(byte[] key) { + byte[] value = get(StateType.StorageRow, key); + if (Objects.nonNull(value)) { + StorageRowCapsule storageRowCapsule = new StorageRowCapsule(value); + storageRowCapsule.setRowKey(key); + return storageRowCapsule; + } + return null; + } + + // asset + public AssetIssueCapsule getAssetIssue(byte[] tokenId) { + byte[] value = get(StateType.AssetIssue, tokenId); + return Objects.nonNull(value) ? new AssetIssueCapsule(value) : null; + } + + // witness + public WitnessCapsule getWitness(byte[] address) { + byte[] value = get(StateType.Witness, address); + return Objects.nonNull(value) ? new WitnessCapsule(value) : null; + } + + // delegate + public DelegatedResourceCapsule getDelegatedResource(byte[] key) { + byte[] value = get(StateType.DelegatedResource, key); + return Objects.nonNull(value) ? new DelegatedResourceCapsule(value) : null; + } + + public BytesCapsule getDelegation(byte[] key) { + byte[] value = get(StateType.Delegation, key); + return Objects.nonNull(value) ? new BytesCapsule(value) : null; + } + + // TODO prefix query + public DelegatedResourceAccountIndexCapsule getDelegatedResourceAccountIndex(byte[] key) { + byte[] value = get(StateType.DelegatedResourceAccountIndex, key); + return Objects.nonNull(value) ? new DelegatedResourceAccountIndexCapsule(value) : null; + } + + // vote + public VotesCapsule getVotes(byte[] address) { + byte[] value = get(StateType.Votes, address); + return Objects.nonNull(value) ? new VotesCapsule(value) : null; + } + + // properties + public BytesCapsule getDynamicProperty(byte[] key) { + BytesCapsule value = getUncheckedDynamicProperty(key); + if (Objects.nonNull(value)) { + return value; + } else { + throw new IllegalArgumentException("not found: " + ByteArray.toStr(key)); + } + } + + public BytesCapsule getUncheckedDynamicProperty(byte[] key) { + byte[] value = get(StateType.Properties, key); + if (Objects.nonNull(value)) { + return new BytesCapsule(value); + } + return null; + } + + public long getDynamicPropertyLong(byte[] key) { + return ByteArray.toLong(getDynamicProperty(key).getData()); + } + + public boolean supportAllowAssetOptimization() { + return getDynamicPropertyLong(ALLOW_ASSET_OPTIMIZATION) == 1L; + } +} diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java b/chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java new file mode 100644 index 00000000000..41137c9082f --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java @@ -0,0 +1,46 @@ +package org.tron.core.state; + +import java.nio.file.Paths; +import javax.annotation.PreDestroy; +import lombok.extern.slf4j.Slf4j; +import org.hyperledger.besu.storage.RocksDBConfigurationBuilder; +import org.hyperledger.besu.storage.RocksDBKeyValueStorage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.tron.common.parameter.CommonParameter; +import org.tron.common.utils.FileUtil; + + +@Slf4j(topic = "State") +@Component +public class WorldStateTrieStore extends RocksDBKeyValueStorage { + + @Autowired + private WorldStateTrieStore(@Value("world-state-trie") String dbName) { + super(new RocksDBConfigurationBuilder().databaseDir(Paths.get(calDbParentPath(), + dbName)).build()); + } + + @PreDestroy + public void clearUp() { + try { + this.close(); + } catch (Exception e) { + logger.warn("WorldStateTrieStore close error", e); + } + } + + + private static String calDbParentPath() { + String stateGenesis = CommonParameter.getInstance().getStorage() + .getStateGenesisDirectory(); + if (!Paths.get(stateGenesis).isAbsolute()) { + stateGenesis = Paths.get(CommonParameter.getInstance().getOutputDirectory(), + stateGenesis).toString(); + } + FileUtil.createDirIfNotExists(stateGenesis); + return stateGenesis; + } + +} diff --git a/chainbase/src/main/java/org/tron/core/state/store/AccountStateStore.java b/chainbase/src/main/java/org/tron/core/state/store/AccountStateStore.java new file mode 100644 index 00000000000..2a058d79466 --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/store/AccountStateStore.java @@ -0,0 +1,123 @@ +package org.tron.core.state.store; + +import lombok.Getter; +import org.rocksdb.DirectComparator; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.db2.common.WrappedByteArray; +import org.tron.core.db2.core.Chainbase; +import org.tron.core.exception.BadItemException; +import org.tron.core.state.WorldStateQueryInstance; +import org.tron.core.store.AccountStore; + +import java.util.Iterator; +import java.util.Map; + +public class AccountStateStore extends AccountStore implements StateStore { + + private WorldStateQueryInstance worldStateQueryInstance; + @Getter + private boolean init; + + @Override + public void init(WorldStateQueryInstance worldStateQueryInstance) { + this.worldStateQueryInstance = worldStateQueryInstance; + this.init = true; + } + + //**** Override Operation For StateDB + + @Override + public String getDbName() { + return worldStateQueryInstance.getRootHash().toHexString(); + } + + @Override + public AccountCapsule get(byte[] key) { + return getFromRoot(key); + } + + @Override + public AccountCapsule getFromRoot(byte[] key) { + return getUnchecked(key); + + } + + @Override + public AccountCapsule getUnchecked(byte[] key) { + throwIfNotInit(); + return worldStateQueryInstance.getAccount(key); + } + + @Override + public boolean has(byte[] key) { + return get(key) != null; + } + + @Override + public void close() { + } + + @Override + public void reset() { + } + + //**** Override Operation For StateDB + + //**** Unsupported Operation For StateDB + + public static void setAccount(com.typesafe.config.Config config) { + throw new UnsupportedOperationException(); + } + + protected org.iq80.leveldb.Options getOptionsByDbNameForLevelDB(String dbName) { + throw new UnsupportedOperationException(); + } + + protected DirectComparator getDirectComparator() { + throw new UnsupportedOperationException(); + } + + @Override + public void put(byte[] key, AccountCapsule item) { + throwIfError(); + } + + @Override + public void delete(byte[] key) { + throwIfError(); + } + + @Override + public AccountCapsule of(byte[] value) throws BadItemException { + throwIfError(); + return null; + } + + @Override + public boolean isNotEmpty() { + throwIfError(); + return false; + } + + @Override + public Iterator> iterator() { + throwIfError(); + return null; + } + + public long size() { + throwIfError(); + return 0; + } + + public void setCursor(Chainbase.Cursor cursor) { + throwIfError(); + } + + public Map prefixQuery(byte[] key) { + throwIfError(); + return null; + } + + //**** Unsupported Operation For StateDB +} diff --git a/chainbase/src/main/java/org/tron/core/state/store/AssetIssueV2StateStore.java b/chainbase/src/main/java/org/tron/core/state/store/AssetIssueV2StateStore.java new file mode 100644 index 00000000000..84b266e8f1e --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/store/AssetIssueV2StateStore.java @@ -0,0 +1,123 @@ +package org.tron.core.state.store; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.rocksdb.DirectComparator; +import org.tron.core.capsule.AssetIssueCapsule; +import org.tron.core.db2.common.WrappedByteArray; +import org.tron.core.db2.core.Chainbase; +import org.tron.core.exception.BadItemException; +import org.tron.core.state.WorldStateQueryInstance; +import org.tron.core.store.AssetIssueV2Store; + +import java.util.Iterator; +import java.util.Map; + +@Slf4j(topic = "DB") + +public class AssetIssueV2StateStore extends AssetIssueV2Store implements StateStore { + + private WorldStateQueryInstance worldStateQueryInstance; + @Getter + private boolean init; + + @Override + public void init(WorldStateQueryInstance worldStateQueryInstance) { + this.worldStateQueryInstance = worldStateQueryInstance; + this.init = true; + } + + //**** Override Operation For StateDB + + @Override + public String getDbName() { + return worldStateQueryInstance.getRootHash().toHexString(); + } + + @Override + public AssetIssueCapsule get(byte[] key) { + return getFromRoot(key); + } + + @Override + public AssetIssueCapsule getFromRoot(byte[] key) { + return getUnchecked(key); + + } + + @Override + public AssetIssueCapsule getUnchecked(byte[] key) { + throwIfNotInit(); + return worldStateQueryInstance.getAssetIssue(key); + } + + @Override + public boolean has(byte[] key) { + return get(key) != null; + } + + @Override + public void close() { + } + + @Override + public void reset() { + } + + //**** Override Operation For StateDB + + //**** Unsupported Operation For StateDB + + protected org.iq80.leveldb.Options getOptionsByDbNameForLevelDB(String dbName) { + throw new UnsupportedOperationException(); + } + + protected DirectComparator getDirectComparator() { + throw new UnsupportedOperationException(); + } + + @Override + public void put(byte[] key, AssetIssueCapsule item) { + throwIfError(); + } + + @Override + public void delete(byte[] key) { + throwIfError(); + } + + @Override + public AssetIssueCapsule of(byte[] value) throws BadItemException { + throwIfError(); + return null; + } + + @Override + public boolean isNotEmpty() { + throwIfError(); + return false; + } + + @Override + public Iterator> iterator() { + throwIfError(); + return null; + } + + public long size() { + throwIfError(); + return 0; + } + + public void setCursor(Chainbase.Cursor cursor) { + throwIfError(); + } + + public Map prefixQuery(byte[] key) { + throwIfError(); + return null; + } + + //**** Unsupported Operation For StateDB + +} diff --git a/chainbase/src/main/java/org/tron/core/state/store/DelegationStateStore.java b/chainbase/src/main/java/org/tron/core/state/store/DelegationStateStore.java new file mode 100644 index 00000000000..cfa9da54eaf --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/store/DelegationStateStore.java @@ -0,0 +1,119 @@ +package org.tron.core.state.store; + +import lombok.Getter; +import org.rocksdb.DirectComparator; +import org.tron.core.capsule.BytesCapsule; +import org.tron.core.db2.common.WrappedByteArray; +import org.tron.core.db2.core.Chainbase; +import org.tron.core.exception.BadItemException; +import org.tron.core.state.WorldStateQueryInstance; +import org.tron.core.store.DelegationStore; + +import java.util.Iterator; +import java.util.Map; + +public class DelegationStateStore extends DelegationStore implements StateStore { + + private WorldStateQueryInstance worldStateQueryInstance; + @Getter + private boolean init; + + @Override + public void init(WorldStateQueryInstance worldStateQueryInstance) { + this.worldStateQueryInstance = worldStateQueryInstance; + this.init = true; + } + + //**** Override Operation For StateDB + + @Override + public String getDbName() { + return worldStateQueryInstance.getRootHash().toHexString(); + } + + @Override + public BytesCapsule get(byte[] key) { + return getFromRoot(key); + } + + @Override + public BytesCapsule getFromRoot(byte[] key) { + return getUnchecked(key); + + } + + @Override + public BytesCapsule getUnchecked(byte[] key) { + throwIfNotInit(); + return worldStateQueryInstance.getDelegation(key); + } + + @Override + public boolean has(byte[] key) { + return get(key) != null; + } + + @Override + public void close() { + } + + @Override + public void reset() { + } + + //**** Override Operation For StateDB + + //**** Unsupported Operation For StateDB + + protected org.iq80.leveldb.Options getOptionsByDbNameForLevelDB(String dbName) { + throw new UnsupportedOperationException(); + } + + protected DirectComparator getDirectComparator() { + throw new UnsupportedOperationException(); + } + + @Override + public void put(byte[] key, BytesCapsule item) { + throwIfError(); + } + + @Override + public void delete(byte[] key) { + throwIfError(); + } + + @Override + public BytesCapsule of(byte[] value) throws BadItemException { + throwIfError(); + return null; + } + + @Override + public boolean isNotEmpty() { + throwIfError(); + return false; + } + + @Override + public Iterator> iterator() { + throwIfError(); + return null; + } + + public long size() { + throwIfError(); + return 0; + } + + public void setCursor(Chainbase.Cursor cursor) { + throwIfError(); + } + + public Map prefixQuery(byte[] key) { + throwIfError(); + return null; + } + + //**** Unsupported Operation For StateDB +} diff --git a/chainbase/src/main/java/org/tron/core/state/store/DynamicPropertiesStateStore.java b/chainbase/src/main/java/org/tron/core/state/store/DynamicPropertiesStateStore.java new file mode 100644 index 00000000000..6c64d53d949 --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/store/DynamicPropertiesStateStore.java @@ -0,0 +1,120 @@ +package org.tron.core.state.store; + +import lombok.Getter; +import org.rocksdb.DirectComparator; +import org.tron.core.capsule.BytesCapsule; +import org.tron.core.db2.common.WrappedByteArray; +import org.tron.core.db2.core.Chainbase; +import org.tron.core.exception.BadItemException; +import org.tron.core.state.WorldStateQueryInstance; +import org.tron.core.store.DynamicPropertiesStore; + +import java.util.Iterator; +import java.util.Map; + +public class DynamicPropertiesStateStore extends DynamicPropertiesStore implements StateStore { + + private WorldStateQueryInstance worldStateQueryInstance; + @Getter + private boolean init; + + @Override + public void init(WorldStateQueryInstance worldStateQueryInstance) { + this.worldStateQueryInstance = worldStateQueryInstance; + init = true; + } + + //**** Override Operation For StateDB + + @Override + public String getDbName() { + return worldStateQueryInstance.getRootHash().toHexString(); + } + + @Override + public BytesCapsule get(byte[] key) { + return getFromRoot(key); + } + + @Override + public BytesCapsule getFromRoot(byte[] key) { + throwIfNotInit(); + return worldStateQueryInstance.getDynamicProperty(key); + + } + + @Override + public BytesCapsule getUnchecked(byte[] key) { + throwIfNotInit(); + return worldStateQueryInstance.getUncheckedDynamicProperty(key); + } + + @Override + public boolean has(byte[] key) { + return get(key) != null; + } + + @Override + public void close() { + } + + @Override + public void reset() { + } + + //**** Override Operation For StateDB + + //**** Unsupported Operation For StateDB + + protected org.iq80.leveldb.Options getOptionsByDbNameForLevelDB(String dbName) { + throw new UnsupportedOperationException(); + } + + protected DirectComparator getDirectComparator() { + throw new UnsupportedOperationException(); + } + + @Override + public void put(byte[] key, BytesCapsule item) { + throwIfError(); + } + + @Override + public void delete(byte[] key) { + throwIfError(); + } + + @Override + public BytesCapsule of(byte[] value) throws BadItemException { + throwIfError(); + return null; + } + + @Override + public boolean isNotEmpty() { + throwIfError(); + return false; + } + + @Override + public Iterator> iterator() { + throwIfError(); + return null; + } + + public long size() { + throwIfError(); + return 0; + } + + public void setCursor(Chainbase.Cursor cursor) { + throwIfError(); + } + + public Map prefixQuery(byte[] key) { + throwIfError(); + return null; + } + + //**** Unsupported Operation For StateDB +} diff --git a/chainbase/src/main/java/org/tron/core/state/store/StateStore.java b/chainbase/src/main/java/org/tron/core/state/store/StateStore.java new file mode 100644 index 00000000000..27900b2848d --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/store/StateStore.java @@ -0,0 +1,20 @@ +package org.tron.core.state.store; + +import org.tron.core.state.WorldStateQueryInstance; + +public interface StateStore { + + void init(WorldStateQueryInstance worldStateQueryInstance); + + boolean isInit(); + + default void throwIfError() { + throw new UnsupportedOperationException(); + } + + default void throwIfNotInit() { + if (!isInit()) { + throw new IllegalStateException(); + } + } +} diff --git a/chainbase/src/main/java/org/tron/core/state/trie/Trie.java b/chainbase/src/main/java/org/tron/core/state/trie/Trie.java new file mode 100644 index 00000000000..c80910829de --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/trie/Trie.java @@ -0,0 +1,30 @@ +package org.tron.core.state.trie; + +/** + * + */ +public interface Trie { + + byte[] getRootHash(); + + void setRoot(byte[] root); + + /** + * Recursively delete all nodes from root. + */ + void clear(); + + void put(byte[] key, V val); + + V get(byte[] key); + + void delete(byte[] key); + + /** + * Commits any pending changes to the underlying storage. + */ + default void commit() {} + + /** Persist accumulated changes to underlying storage. */ + boolean flush(); +} diff --git a/chainbase/src/main/java/org/tron/core/state/trie/TrieImpl2.java b/chainbase/src/main/java/org/tron/core/state/trie/TrieImpl2.java new file mode 100644 index 00000000000..426f420a63a --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/trie/TrieImpl2.java @@ -0,0 +1,188 @@ +package org.tron.core.state.trie; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Map; +import java.util.Objects; +import java.util.TreeMap; +import java.util.function.Consumer; +import java.util.function.Function; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.hyperledger.besu.ethereum.trie.KeyValueMerkleStorage; +import org.hyperledger.besu.ethereum.trie.MerklePatriciaTrie; +import org.hyperledger.besu.ethereum.trie.MerkleStorage; +import org.hyperledger.besu.ethereum.trie.Node; +import org.hyperledger.besu.ethereum.trie.RangeStorageEntriesCollector; +import org.hyperledger.besu.ethereum.trie.StoredMerklePatriciaTrie; +import org.hyperledger.besu.ethereum.trie.TrieIterator; +import org.hyperledger.besu.storage.InMemoryKeyValueStorage; +import org.hyperledger.besu.storage.KeyValueStorage; +import org.hyperledger.besu.storage.RocksDBConfiguration; +import org.hyperledger.besu.storage.RocksDBConfigurationBuilder; +import org.hyperledger.besu.storage.RocksDBKeyValueStorage; + +/** + * + */ +@Slf4j(topic = "db") +public class TrieImpl2 implements Trie { + + private final MerklePatriciaTrie trie; + @Getter + private final MerkleStorage merkleStorage; + + public TrieImpl2() { + this(Bytes32.ZERO); + } + + public TrieImpl2(Bytes32 root) { + this(new KeyValueMerkleStorage(new InMemoryKeyValueStorage()), root); + } + + public TrieImpl2(String keyValueStore) { + this(keyValueStore, Bytes32.ZERO); + } + + public TrieImpl2(String keyValueStore, Bytes32 root) { + this(createStore(keyValueStore), root); + } + + public TrieImpl2(KeyValueStorage keyValueStore) { + this(keyValueStore, Bytes32.ZERO); + } + + public TrieImpl2(KeyValueStorage keyValueStore, Bytes32 root) { + this(new KeyValueMerkleStorage(keyValueStore), root); + } + + public TrieImpl2(MerkleStorage merkleStorage) { + this(merkleStorage, Bytes32.ZERO); + } + + public TrieImpl2(MerkleStorage merkleStorage, Bytes32 root) { + this.merkleStorage = merkleStorage; + + if (root.isZero()) { + trie = new StoredMerklePatriciaTrie<>(merkleStorage::get, + Function.identity(), + Function.identity()); + } else { + trie = new StoredMerklePatriciaTrie<>(merkleStorage::get, root, + Function.identity(), + Function.identity()); + } + } + + private static KeyValueStorage createStore(String store) { + try { + return new RocksDBKeyValueStorage(config(Paths.get(store))); + } catch (IOException e) { + logger.error("{}", e); + return null; + } + } + + private static RocksDBConfiguration config(Path store) throws IOException { + return new RocksDBConfigurationBuilder().databaseDir(store).build(); + } + + public void visitAll(Consumer> nodeConsumer) { + trie.visitAll(nodeConsumer); + } + + @Override + public Bytes get(byte[] key) { + return trie.get(Bytes.wrap(key)).orElse(null); + } + + public Bytes get(Bytes key) { + return trie.get(key).orElse(null); + } + + @Override + public void put(byte[] key, Bytes value) { + trie.put(Bytes.wrap(key), value); + } + + public void put(Bytes key, Bytes value) { + trie.put(key, value); + } + + @Override + public void delete(byte[] key) { + trie.remove(Bytes.wrap(key)); + } + + @Override + public void commit() { + trie.commit(merkleStorage::put); + } + + @Override + public byte[] getRootHash() { + return trie.getRootHash().toArrayUnsafe(); + } + + public Bytes32 getRootHashByte32() { + return trie.getRootHash(); + } + + @Override + public void setRoot(byte[] root) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new RuntimeException("Not implemented yet"); + } + + public TreeMap entriesFrom(Bytes32 startKeyHash, Bytes32 endKeyHash) { + final RangeStorageEntriesCollector collector = RangeStorageEntriesCollector.createCollector( + startKeyHash, endKeyHash, Integer.MAX_VALUE, Integer.MAX_VALUE); + final TrieIterator visitor = RangeStorageEntriesCollector.createVisitor(collector); + return (TreeMap) + this.entriesFrom(root -> RangeStorageEntriesCollector.collectEntries(collector, visitor, + root, startKeyHash)); + } + + public Map entriesFrom(final Function, Map> handler) { + return trie.entriesFrom(handler); + } + + @Override + public boolean flush() { + merkleStorage.commit(); + return true; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + TrieImpl2 trieImpl1 = (TrieImpl2) o; + + return Objects.equals(getRootHashByte32(), trieImpl1.getRootHashByte32()); + + } + + @Override + public int hashCode() { + return Arrays.hashCode(getRootHash()); + } + + @Override + public String toString() { + return getClass().getSimpleName() + "[" + trie.getRootHash() + "]"; + } +} diff --git a/chainbase/src/main/java/org/tron/core/store/AccountStore.java b/chainbase/src/main/java/org/tron/core/store/AccountStore.java index 4d39049ee79..6414e2959c9 100644 --- a/chainbase/src/main/java/org/tron/core/store/AccountStore.java +++ b/chainbase/src/main/java/org/tron/core/store/AccountStore.java @@ -42,6 +42,10 @@ private AccountStore(@Value("account") String dbName) { super(dbName); } + protected AccountStore() { + super(); + } + public static void setAccount(com.typesafe.config.Config config) { List list = config.getObjectList("genesis.block.assets"); for (int i = 0; i < list.size(); i++) { @@ -113,7 +117,7 @@ public AccountCapsule getBlackhole() { } - public byte[] getBlackholeAddress() { + public static byte[] getBlackholeAddress() { return assertsAddress.get("Blackhole"); } diff --git a/chainbase/src/main/java/org/tron/core/store/AssetIssueStore.java b/chainbase/src/main/java/org/tron/core/store/AssetIssueStore.java index d38a5f0677e..14c6ce94110 100644 --- a/chainbase/src/main/java/org/tron/core/store/AssetIssueStore.java +++ b/chainbase/src/main/java/org/tron/core/store/AssetIssueStore.java @@ -22,6 +22,9 @@ protected AssetIssueStore(@Value("asset-issue") String dbName) { super(dbName); } + protected AssetIssueStore() { + super(); + } @Override public AssetIssueCapsule get(byte[] key) { diff --git a/chainbase/src/main/java/org/tron/core/store/AssetIssueV2Store.java b/chainbase/src/main/java/org/tron/core/store/AssetIssueV2Store.java index a2109767e9f..1c0a6a2659c 100644 --- a/chainbase/src/main/java/org/tron/core/store/AssetIssueV2Store.java +++ b/chainbase/src/main/java/org/tron/core/store/AssetIssueV2Store.java @@ -10,8 +10,11 @@ public class AssetIssueV2Store extends AssetIssueStore { @Autowired - private AssetIssueV2Store(@Value("asset-issue-v2") String dbName) { + protected AssetIssueV2Store(@Value("asset-issue-v2") String dbName) { super(dbName); } + protected AssetIssueV2Store() { + super(); + } } diff --git a/chainbase/src/main/java/org/tron/core/store/ContractStateStore.java b/chainbase/src/main/java/org/tron/core/store/ContractStateStore.java index 19dfb11cdcd..c3052f5d14c 100644 --- a/chainbase/src/main/java/org/tron/core/store/ContractStateStore.java +++ b/chainbase/src/main/java/org/tron/core/store/ContractStateStore.java @@ -1,7 +1,5 @@ package org.tron.core.store; -import java.util.Objects; - import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -23,13 +21,4 @@ public ContractStateCapsule get(byte[] key) { return getUnchecked(key); } - @Override - public void put(byte[] key, ContractStateCapsule item) { - if (Objects.isNull(key) || Objects.isNull(item)) { - return; - } - - revokingDB.put(key, item.getData()); - } - } diff --git a/chainbase/src/main/java/org/tron/core/store/ContractStore.java b/chainbase/src/main/java/org/tron/core/store/ContractStore.java index 169d2b9c67e..763186920ff 100644 --- a/chainbase/src/main/java/org/tron/core/store/ContractStore.java +++ b/chainbase/src/main/java/org/tron/core/store/ContractStore.java @@ -2,14 +2,11 @@ import com.google.common.collect.Streams; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.ArrayUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import org.tron.core.capsule.AbiCapsule; import org.tron.core.capsule.ContractCapsule; import org.tron.core.db.TronStoreWithRevoking; -import org.tron.protos.contract.SmartContractOuterClass.SmartContract; import java.util.Objects; @@ -36,7 +33,7 @@ public void put(byte[] key, ContractCapsule item) { if (item.getInstance().hasAbi()) { item = new ContractCapsule(item.getInstance().toBuilder().clearAbi().build()); } - revokingDB.put(key, item.getData()); + super.put(key, item); } /** diff --git a/chainbase/src/main/java/org/tron/core/store/DelegationStore.java b/chainbase/src/main/java/org/tron/core/store/DelegationStore.java index 4e95e480cfd..a347b8e9119 100644 --- a/chainbase/src/main/java/org/tron/core/store/DelegationStore.java +++ b/chainbase/src/main/java/org/tron/core/store/DelegationStore.java @@ -26,6 +26,10 @@ public DelegationStore(@Value("delegation") String dbName) { super(dbName); } + protected DelegationStore() { + super(); + } + @Override public BytesCapsule get(byte[] key) { byte[] value = revokingDB.getUnchecked(key); diff --git a/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java b/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java index 5f8c9ff89fc..eea9a0c423d 100644 --- a/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java +++ b/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java @@ -20,6 +20,7 @@ import org.tron.core.db.TronStoreWithRevoking; import org.tron.core.exception.BadItemException; import org.tron.core.exception.ItemNotFoundException; +import org.tron.core.state.WorldStateCallBackUtils; @Slf4j(topic = "DB") @Component @@ -217,8 +218,10 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking "MAX_DELEGATE_LOCK_PERIOD".getBytes(); @Autowired - private DynamicPropertiesStore(@Value("properties") String dbName) { + private DynamicPropertiesStore(@Value("properties") String dbName, + @Autowired WorldStateCallBackUtils worldStateCallBackUtils) { super(dbName); + this.worldStateCallBackUtils = worldStateCallBackUtils; try { this.getTotalSignNum(); @@ -953,6 +956,10 @@ private DynamicPropertiesStore(@Value("properties") String dbName) { } } + protected DynamicPropertiesStore () { + super(); + } + public String intArrayToString(int[] a) { StringBuilder sb = new StringBuilder(); for (int i : a) { diff --git a/common/src/main/java/org/tron/common/cache/CacheManager.java b/common/src/main/java/org/tron/common/cache/CacheManager.java index fa1fbff193b..3ffb224a84b 100644 --- a/common/src/main/java/org/tron/common/cache/CacheManager.java +++ b/common/src/main/java/org/tron/common/cache/CacheManager.java @@ -24,6 +24,14 @@ public static TronCache allocate(CacheType name, String strategy) return cache; } + public static TronCache allocate(CacheType name, + CacheLoader loader) { + TronCache cache = new TronCache<>(name, CommonParameter.getInstance() + .getStorage().getCacheStrategy(name), loader); + CACHES.put(name, cache); + return cache; + } + public static TronCache allocate(CacheType name, String strategy, CacheLoader loader) { TronCache cache = new TronCache<>(name, strategy, loader); diff --git a/common/src/main/java/org/tron/common/cache/CacheStrategies.java b/common/src/main/java/org/tron/common/cache/CacheStrategies.java index b282ca1a687..6cf0bb98935 100644 --- a/common/src/main/java/org/tron/common/cache/CacheStrategies.java +++ b/common/src/main/java/org/tron/common/cache/CacheStrategies.java @@ -14,6 +14,7 @@ import static org.tron.common.cache.CacheType.votes; import static org.tron.common.cache.CacheType.witness; import static org.tron.common.cache.CacheType.witnessSchedule; +import static org.tron.common.cache.CacheType.worldStateQueryInstance; import java.util.Arrays; import java.util.Collection; @@ -35,7 +36,7 @@ public class CacheStrategies { String.format(PATTERNS, 100, 100, "30s", CPUS); private static final List CACHE_SMALL_DBS = Arrays.asList(recentBlock, witness, witnessSchedule, delegatedResource, delegatedResourceAccountIndex, - votes, abi); + votes, abi, worldStateQueryInstance); private static final String CACHE_STRATEGY_NORMAL_DEFAULT = String.format(PATTERNS, 500, 500, "30s", CPUS); private static final List CACHE_NORMAL_DBS = Arrays.asList(code, contract, diff --git a/common/src/main/java/org/tron/common/cache/CacheType.java b/common/src/main/java/org/tron/common/cache/CacheType.java index b9b28d0bd7c..a959a07b3d8 100644 --- a/common/src/main/java/org/tron/common/cache/CacheType.java +++ b/common/src/main/java/org/tron/common/cache/CacheType.java @@ -19,9 +19,12 @@ public enum CacheType { properties("properties"), delegation("delegation"), storageRow("storage-row"), - account("account"); + account("account"), // for leveldb or rocksdb cache + // archive node + worldStateQueryInstance("worldStateQueryInstance"); + public final String type; CacheType(String type) { diff --git a/common/src/main/java/org/tron/common/cache/TronCache.java b/common/src/main/java/org/tron/common/cache/TronCache.java index 4faf73f864a..44ffb9ffec0 100644 --- a/common/src/main/java/org/tron/common/cache/TronCache.java +++ b/common/src/main/java/org/tron/common/cache/TronCache.java @@ -5,9 +5,10 @@ import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheStats; +import com.google.common.cache.LoadingCache; +import lombok.Getter; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; -import lombok.Getter; public class TronCache { @@ -37,6 +38,13 @@ public V get(K k, Callable loader) throws ExecutionException { return this.cache.get(k, loader); } + public V get(K k) throws ExecutionException { + if (this.cache instanceof LoadingCache) { + return ((LoadingCache) this.cache).get(k); + } + return this.cache.getIfPresent(k); + } + public CacheStats stats() { return this.cache.stats(); } diff --git a/common/src/main/java/org/tron/common/utils/FileUtil.java b/common/src/main/java/org/tron/common/utils/FileUtil.java index 8031c764019..19cd48054c5 100644 --- a/common/src/main/java/org/tron/common/utils/FileUtil.java +++ b/common/src/main/java/org/tron/common/utils/FileUtil.java @@ -21,11 +21,14 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.nio.file.FileSystemException; +import java.nio.file.FileVisitOption; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Arrays; @@ -149,4 +152,50 @@ public static boolean isExists(String path) { File file = new File(path); return file.exists(); } + + + /** + * Copy src to dest, if dest is a directory and already exists, throw Exception. + * + *

Note: This method is not rigorous, because all the dirs that its FileName + * is contained in List(subDirs) will be filtered, this may result in unpredictable result. + * just used in LiteFullNodeTool. + * + * @param src Path or File + * @param dest Path or File + * @param subDirs only the subDirs in {@code src} will be copied + * @throws IOException IOException + */ + public static void copyDatabases(Path src, Path dest, List subDirs) { + // create subdirs, as using parallel() to run, so should create dirs first. + subDirs.parallelStream().forEach(dir -> { + if (FileUtil.isExists(Paths.get(src.toString(), dir).toString())) { + try { + Files.walk(Paths.get(src.toString(), dir), FileVisitOption.FOLLOW_LINKS) + .forEach(source -> copy(source, dest.resolve(src.relativize(source)))); + } catch (IOException e) { + logger.error("copy database failed, src: {}, dest: {}, error: {}", + Paths.get(src.toString(), dir), Paths.get(dest.toString(), dir), e.getMessage()); + throw new RuntimeException(e); + } + } + }); + } + + private static void copy(Path source, Path dest) { + try { + // create hard link when file is .sst + if (source.toString().endsWith(".sst")) { + try { + Files.createLink(dest, source); + } catch (FileSystemException e) { + Files.copy(source, dest, StandardCopyOption.REPLACE_EXISTING); + } + } else { + Files.copy(source, dest, StandardCopyOption.REPLACE_EXISTING); + } + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } } diff --git a/common/src/main/java/org/tron/common/utils/PropUtil.java b/common/src/main/java/org/tron/common/utils/PropUtil.java index 93f47380e35..8149bb58b2d 100644 --- a/common/src/main/java/org/tron/common/utils/PropUtil.java +++ b/common/src/main/java/org/tron/common/utils/PropUtil.java @@ -10,6 +10,8 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; +import java.util.Map; import java.util.Properties; import lombok.extern.slf4j.Slf4j; @@ -106,4 +108,21 @@ public static boolean writeProperty(String file, String key, String value) { return true; } + public static boolean writeProperties(String file, Map kv) { + try (OutputStream o = new FileOutputStream(file); + FileInputStream f = new FileInputStream(file); + BufferedWriter w = new BufferedWriter(new OutputStreamWriter(o, StandardCharsets.UTF_8)); + BufferedReader r = new BufferedReader(new InputStreamReader(f, StandardCharsets.UTF_8)) + ) { + Properties properties = new Properties(); + properties.load(r); + kv.forEach(properties::setProperty); + properties.store(w, "Generated by the application. PLEASE DO NOT EDIT! "); + } catch (Exception e) { + logger.warn("writeProperty", e); + return false; + } + return true; + } + } \ No newline at end of file diff --git a/common/src/main/java/org/tron/core/config/args/Storage.java b/common/src/main/java/org/tron/core/config/args/Storage.java index 778d4d0141c..ba02c391e5d 100644 --- a/common/src/main/java/org/tron/core/config/args/Storage.java +++ b/common/src/main/java/org/tron/core/config/args/Storage.java @@ -78,6 +78,9 @@ public class Storage { private static final String CACHE_STRATEGIES = "storage.cache.strategies"; + private static final String STATE_ROOT_SWITCH_KEY = "storage.stateRoot.switch"; + private static final String STATE_GENESIS_DIRECTORY_KEY = "storage.stateGenesis.directory"; + /** * Default values of directory */ @@ -91,6 +94,7 @@ public class Storage { private static final boolean DEFAULT_CHECKPOINT_SYNC = true; private static final int DEFAULT_ESTIMATED_TRANSACTIONS = 1000; private static final int DEFAULT_SNAPSHOT_MAX_FLUSH_COUNT = 1; + private static final String DEFAULT_STATE_GENESIS_DIRECTORY = "state-genesis"; private Config storage; /** @@ -152,6 +156,12 @@ public class Storage { private final List cacheDbs = CacheStrategies.CACHE_DBS; // second cache + @Getter + private boolean allowStateRoot; + + @Getter + private String stateGenesisDirectory = DEFAULT_STATE_GENESIS_DIRECTORY; + /** * Key: dbName, Value: Property object of that database */ @@ -248,6 +258,18 @@ public String getCacheStrategy(CacheType dbName) { return this.cacheStrategies.getOrDefault(dbName, CacheStrategies.getCacheStrategy(dbName)); } + public void setAllowStateRoot(final Config config) { + if (config.hasPath(STATE_ROOT_SWITCH_KEY)) { + this.allowStateRoot = config.getBoolean(STATE_ROOT_SWITCH_KEY); + } + } + + public void setStateGenesisDirectory(final Config config) { + if (config.hasPath(STATE_GENESIS_DIRECTORY_KEY)) { + this.stateGenesisDirectory = config.getString(STATE_GENESIS_DIRECTORY_KEY); + } + } + private Property createProperty(final ConfigObject conf) { Property property = new Property(); diff --git a/framework/src/main/java/org/tron/core/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java index b866ab54001..e92738fe073 100755 --- a/framework/src/main/java/org/tron/core/Wallet.java +++ b/framework/src/main/java/org/tron/core/Wallet.java @@ -54,6 +54,7 @@ import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; +import org.apache.tuweni.bytes.Bytes32; import org.bouncycastle.util.encoders.DecoderException; import org.bouncycastle.util.encoders.Hex; import org.springframework.beans.factory.annotation.Autowired; @@ -105,6 +106,7 @@ import org.tron.common.crypto.SignUtils; import org.tron.common.parameter.CommonParameter; import org.tron.common.runtime.ProgramResult; +import org.tron.common.runtime.vm.DataWord; import org.tron.common.runtime.vm.LogInfo; import org.tron.common.utils.ByteArray; import org.tron.common.utils.ByteUtil; @@ -181,6 +183,7 @@ import org.tron.core.net.TronNetDelegate; import org.tron.core.net.TronNetService; import org.tron.core.net.message.adv.TransactionMessage; +import org.tron.core.state.WorldStateQueryInstance; import org.tron.core.store.AccountIdIndexStore; import org.tron.core.store.AccountStore; import org.tron.core.store.AccountTraceStore; @@ -192,6 +195,7 @@ import org.tron.core.store.MarketPairToPriceStore; import org.tron.core.store.StoreFactory; import org.tron.core.vm.program.Program; +import org.tron.core.vm.program.Storage; import org.tron.core.zen.ShieldedTRC20ParametersBuilder; import org.tron.core.zen.ShieldedTRC20ParametersBuilder.ShieldedTRC20ParametersType; import org.tron.core.zen.ZenTransactionBuilder; @@ -341,6 +345,18 @@ public Account getAccount(Account account) { return accountCapsule.getInstance(); } + + public Account getAccount(byte[] address, long blockNumber) { + Bytes32 rootHash = getRootHashByNumber(blockNumber); + WorldStateQueryInstance worldStateQueryInstance = initWorldStateQueryInstance(rootHash); + AccountCapsule accountCapsule = worldStateQueryInstance.getAccount(address); + if (accountCapsule == null) { + return null; + } + return accountCapsule.getInstance(); + } + + private void sortFrozenV2List(AccountCapsule accountCapsule) { List oldFreezeV2List = accountCapsule.getFrozenV2List(); accountCapsule.clearFrozenV2(); @@ -361,6 +377,17 @@ private void sortFrozenV2List(AccountCapsule accountCapsule) { } } + public Account getAccountToken10(byte[] address, long blockNumber) { + Bytes32 rootHash = getRootHashByNumber(blockNumber); + WorldStateQueryInstance worldStateQueryInstance = initWorldStateQueryInstance(rootHash); + AccountCapsule accountCapsule = worldStateQueryInstance.getAccount(address); + if (accountCapsule == null) { + return null; + } + accountCapsule.importAllAsset(); + return accountCapsule.getInstance(); + } + public Account getAccountById(Account account) { AccountStore accountStore = chainBaseManager.getAccountStore(); AccountIdIndexStore accountIdIndexStore = chainBaseManager.getAccountIdIndexStore(); @@ -2860,7 +2887,7 @@ public Transaction triggerContract(TriggerSmartContract triggerSmartContract.getData().toByteArray()); if (isConstant(abi, selector)) { - return callConstantContract(trxCap, builder, retBuilder, false); + return callConstantContract(trxCap, builder, retBuilder, false, -1); } else { return trxCap.getInstance(); } @@ -2978,18 +3005,19 @@ private Transaction cleanContextAndTriggerConstantContract( txExtBuilder.clear(); txRetBuilder.clear(); transaction = triggerConstantContract( - triggerSmartContract, txCap, txExtBuilder, txRetBuilder, true); + triggerSmartContract, txCap, txExtBuilder, txRetBuilder, true, -1); return transaction; } public Transaction triggerConstantContract(TriggerSmartContract triggerSmartContract, TransactionCapsule trxCap, Builder builder, Return.Builder retBuilder) throws ContractValidateException, ContractExeException, HeaderNotFound, VMIllegalException { - return triggerConstantContract(triggerSmartContract, trxCap, builder, retBuilder, false); + return triggerConstantContract(triggerSmartContract, trxCap, builder, retBuilder, false, -1); } public Transaction triggerConstantContract(TriggerSmartContract triggerSmartContract, - TransactionCapsule trxCap, Builder builder, Return.Builder retBuilder, boolean isEstimating) + TransactionCapsule trxCap, Builder builder, Return.Builder retBuilder, boolean isEstimating, + long blockNum) throws ContractValidateException, ContractExeException, HeaderNotFound, VMIllegalException { if (triggerSmartContract.getContractAddress().isEmpty()) { // deploy contract @@ -3009,17 +3037,25 @@ public Transaction triggerConstantContract(TriggerSmartContract triggerSmartCont trxCap = createTransactionCapsule(deployBuilder.build(), ContractType.CreateSmartContract); trxCap.setFeeLimit(feeLimit); } else { // call contract - ContractStore contractStore = chainBaseManager.getContractStore(); + ContractCapsule contractCapsule; byte[] contractAddress = triggerSmartContract.getContractAddress().toByteArray(); - if (contractStore.get(contractAddress) == null) { + if (blockNum == -1) { + ContractStore contractStore = chainBaseManager.getContractStore(); + contractCapsule = contractStore.get(contractAddress); + } else { + Bytes32 rootHash = getRootHashByNumber(blockNum); + WorldStateQueryInstance worldStateQueryInstance = initWorldStateQueryInstance(rootHash); + contractCapsule = worldStateQueryInstance.getContract(contractAddress); + } + if (contractCapsule == null) { throw new ContractValidateException("Smart contract is not exist."); } } - return callConstantContract(trxCap, builder, retBuilder, isEstimating); + return callConstantContract(trxCap, builder, retBuilder, isEstimating, blockNum); } public Transaction callConstantContract(TransactionCapsule trxCap, - Builder builder, Return.Builder retBuilder, boolean isEstimating) + Builder builder, Return.Builder retBuilder, boolean isEstimating, long blockNum) throws ContractValidateException, ContractExeException, HeaderNotFound, VMIllegalException { if (!Args.getInstance().isSupportConstant()) { @@ -3027,12 +3063,21 @@ public Transaction callConstantContract(TransactionCapsule trxCap, } Block headBlock; - List blockCapsuleList = chainBaseManager.getBlockStore() - .getBlockByLatestNum(1); - if (CollectionUtils.isEmpty(blockCapsuleList)) { - throw new HeaderNotFound("latest block not found"); + if (blockNum == -1) { + List blockCapsuleList = chainBaseManager.getBlockStore() + .getBlockByLatestNum(1); + if (CollectionUtils.isEmpty(blockCapsuleList)) { + throw new HeaderNotFound("latest block not found"); + } else { + headBlock = blockCapsuleList.get(0).getInstance(); + } } else { - headBlock = blockCapsuleList.get(0).getInstance(); + try { + headBlock = chainBaseManager.getBlockByNum(blockNum).getInstance(); + } catch (ItemNotFoundException | BadItemException e) { + logger.error("Block not found, number: {}, err: {}", blockNum, e.getMessage()); + throw new HeaderNotFound(String.format("Block not found, number: %d", blockNum)); + } } BlockCapsule headBlockCapsule = new BlockCapsule(headBlock); @@ -3097,6 +3142,23 @@ public SmartContract getContract(GrpcAPI.BytesMessage bytesMessage) { return null; } + public SmartContract getContract(byte[] address, long blockNumber) { + Bytes32 rootHash = getRootHashByNumber(blockNumber); + WorldStateQueryInstance worldStateQueryInstance = initWorldStateQueryInstance(rootHash); + AccountCapsule accountCapsule = worldStateQueryInstance.getAccount(address); + if (accountCapsule == null) { + logger.error( + "Get contract failed, the account does not exist or the account " + + "does not have a code hash!"); + return null; + } + ContractCapsule contractCapsule = worldStateQueryInstance.getContract(address); + if (contractCapsule == null) { + return null; + } + return contractCapsule.getInstance(); + } + /** * Add a wrapper for smart contract. Current additional information including runtime code for a * smart contract. @@ -4448,5 +4510,52 @@ public String getMemoFeePrices() { } return null; } + + public byte[] getCode(byte[] address, long blockNumber) { + Bytes32 rootHash = getRootHashByNumber(blockNumber); + WorldStateQueryInstance worldStateQueryInstance = initWorldStateQueryInstance(rootHash); + CodeCapsule codeCapsule = worldStateQueryInstance.getCode(address); + if (codeCapsule == null) { + return null; + } + return codeCapsule.getInstance(); + } + + public byte[] getStorageAt(byte[] address, String storageIdx, long blockNumber) { + Bytes32 rootHash = getRootHashByNumber(blockNumber); + WorldStateQueryInstance worldStateQueryInstance = initWorldStateQueryInstance(rootHash); + ContractCapsule contractCapsule = worldStateQueryInstance.getContract(address); + if (contractCapsule == null) { + return null; + } + Storage storage = new Storage(address, worldStateQueryInstance); + storage.setContractVersion(contractCapsule.getInstance().getVersion()); + DataWord value = storage.getValue(new DataWord(ByteArray.fromHexString(storageIdx))); + return value == null ? new byte[32] : value.getData(); + } + + private Bytes32 getRootHashByNumber(long blockNumber) { + if (!CommonParameter.getInstance().getStorage().isAllowStateRoot()) { + throw new IllegalArgumentException("Unsupported query, this is not a archive node"); + } + long stateStartHeight = chainBaseManager.getWorldStateGenesis().getStateGenesisHeight(); + if (blockNumber < stateStartHeight) { + throw new IllegalArgumentException( + "block number is lower than state genesis height, genesis height: " + stateStartHeight); + } + if (blockNumber > chainBaseManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber()) { + throw new IllegalArgumentException("block number is larger than current header"); + } + + try { + return chainBaseManager.getBlockByNum(blockNumber).getArchiveRoot(); + } catch (ItemNotFoundException | BadItemException e) { + throw new IllegalArgumentException("block not found, block number: " + blockNumber); + } + } + + private WorldStateQueryInstance initWorldStateQueryInstance(Bytes32 rootHash) { + return ChainBaseManager.fetch(rootHash); + } } diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java index 50e4dacf6a9..3851a48d003 100644 --- a/framework/src/main/java/org/tron/core/config/args/Args.java +++ b/framework/src/main/java/org/tron/core/config/args/Args.java @@ -531,6 +531,9 @@ public static void setParam(final String[] args, final String confFileName) { PARAMETER.storage.setPropertyMapFromConfig(config); PARAMETER.storage.setCacheStrategies(config); + PARAMETER.storage.setAllowStateRoot(config); + PARAMETER.storage.setStateGenesisDirectory(config); + PARAMETER.seedNode = new SeedNode(); PARAMETER.seedNode.setAddressList(loadSeeds(config)); diff --git a/framework/src/main/java/org/tron/core/db/Manager.java b/framework/src/main/java/org/tron/core/db/Manager.java index 3928f657e44..b16b561f5d1 100644 --- a/framework/src/main/java/org/tron/core/db/Manager.java +++ b/framework/src/main/java/org/tron/core/db/Manager.java @@ -131,6 +131,8 @@ import org.tron.core.metrics.MetricsKey; import org.tron.core.metrics.MetricsUtil; import org.tron.core.service.MortgageService; +import org.tron.core.state.WorldStateCallBack; +import org.tron.core.state.WorldStateGenesis; import org.tron.core.store.AccountAssetStore; import org.tron.core.store.AccountIdIndexStore; import org.tron.core.store.AccountIndexStore; @@ -216,6 +218,8 @@ public class Manager { @Autowired private AccountStateCallBack accountStateCallBack; @Autowired + private WorldStateCallBack worldStateCallBack; + @Autowired private TrieService trieService; private Set ownerAddressSet = new HashSet<>(); @Getter @@ -226,6 +230,8 @@ public class Manager { @Autowired @Getter private ChainBaseManager chainBaseManager; + @Autowired + private WorldStateGenesis worldStateGenesis; // transactions cache private BlockingQueue pendingTransactions; @Getter @@ -447,6 +453,7 @@ public void init() { .initStore(chainBaseManager.getWitnessStore(), chainBaseManager.getDelegationStore(), chainBaseManager.getDynamicPropertiesStore(), chainBaseManager.getAccountStore()); accountStateCallBack.setChainBaseManager(chainBaseManager); + worldStateCallBack.setChainBaseManager(chainBaseManager); trieService.setChainBaseManager(chainBaseManager); revokingStore.disable(); revokingStore.check(); @@ -513,7 +520,8 @@ public void init() { // init liteFullNode initLiteNode(); - + // init worldState + worldStateGenesis.init(chainBaseManager); long headNum = chainBaseManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber(); logger.info("Current headNum is: {}.", headNum); boolean isLite = chainBaseManager.isLiteNode(); @@ -555,6 +563,7 @@ public void init() { } maxFlushCount = CommonParameter.getInstance().getStorage().getMaxFlushCount(); + worldStateCallBack.setExecute(false); } /** @@ -575,11 +584,6 @@ public void initGenesis() { } else { logger.info("Create genesis block."); Args.getInstance().setChainId(genesisBlock.getBlockId().toString()); - - chainBaseManager.getBlockStore().put(genesisBlock.getBlockId().getBytes(), genesisBlock); - chainBaseManager.getBlockIndexStore().put(genesisBlock.getBlockId()); - - logger.info(SAVE_BLOCK, genesisBlock); // init Dynamic Properties Store chainBaseManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(0); chainBaseManager.getDynamicPropertiesStore().saveLatestBlockHeaderHash( @@ -591,6 +595,13 @@ public void initGenesis() { this.khaosDb.start(genesisBlock); this.updateRecentBlock(genesisBlock); initAccountHistoryBalance(); + // init genesis state + worldStateCallBack.initGenesis(genesisBlock); + + chainBaseManager.getBlockStore().put(genesisBlock.getBlockId().getBytes(), genesisBlock); + chainBaseManager.getBlockIndexStore().put(genesisBlock.getBlockId()); + + logger.info(SAVE_BLOCK, genesisBlock); } } } @@ -1009,15 +1020,20 @@ private void applyBlock(BlockCapsule block, List txs) TooBigTransactionException, DupTransactionException, TaposException, ValidateScheduleException, ReceiptCheckErrException, VMIllegalException, TooBigTransactionResultException, ZksnarkException, BadBlockException, EventBloomException { - processBlock(block, txs); - chainBaseManager.getBlockStore().put(block.getBlockId().getBytes(), block); - chainBaseManager.getBlockIndexStore().put(block.getBlockId()); - if (block.getTransactions().size() != 0) { - chainBaseManager.getTransactionRetStore() - .put(ByteArray.fromLong(block.getNum()), block.getResult()); + try { + worldStateCallBack.preExecute(block); + processBlock(block, txs); + updateFork(block); + worldStateCallBack.executePushFinish(); + chainBaseManager.getBlockStore().put(block.getBlockId().getBytes(), block); + chainBaseManager.getBlockIndexStore().put(block.getBlockId()); + if (block.getTransactions().size() != 0) { + chainBaseManager.getTransactionRetStore() + .put(ByteArray.fromLong(block.getNum()), block.getResult()); + } + } finally { + worldStateCallBack.exceptionFinish(); } - - updateFork(block); if (System.currentTimeMillis() - block.getTimeStamp() >= 60_000) { revokingStore.setMaxFlushCount(maxFlushCount); if (Args.getInstance().getShutdownBlockTime() != null @@ -1724,9 +1740,11 @@ private void processBlock(BlockCapsule block, List txs) if (block.generatedByMyself) { transactionCapsule.setVerified(true); } + worldStateCallBack.preExeTrans(); accountStateCallBack.preExeTrans(); TransactionInfo result = processTransaction(transactionCapsule, block); accountStateCallBack.exeTransFinish(); + worldStateCallBack.exeTransFinish(); if (Objects.nonNull(result)) { results.add(result); } diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java index 52a3a2380d1..0274e7fc560 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java @@ -7,6 +7,7 @@ import com.googlecode.jsonrpc4j.JsonRpcMethod; import java.io.IOException; import java.util.List; +import java.util.Map; import java.util.concurrent.ExecutionException; import lombok.AllArgsConstructor; import lombok.Getter; @@ -88,6 +89,14 @@ BlockResult ethGetBlockByNumber(String bnOrId, Boolean fullTransactionObjects) }) String getTrxBalance(String address, String blockNumOrTag) throws JsonRpcInvalidParamsException; + + @JsonRpcMethod("tron_getToken10") + @JsonRpcErrors({ + @JsonRpcError(exception = JsonRpcInvalidParamsException.class, code = -32602, data = "{}"), + }) + Map getToken10(String address, String blockNumOrTag) + throws JsonRpcInvalidParamsException; + @JsonRpcMethod("eth_getStorageAt") @JsonRpcErrors({ @JsonRpcError(exception = JsonRpcInvalidParamsException.class, code = -32602, data = "{}"), diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index 9b9dbbdfe70..8fddf024383 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -13,12 +13,15 @@ import com.alibaba.fastjson.JSON; import com.google.protobuf.ByteString; import com.google.protobuf.GeneratedMessageV3; + +import java.math.BigInteger; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -135,8 +138,6 @@ public enum RequestSource { private static final String JSON_ERROR = "invalid json request"; private static final String BLOCK_NUM_ERROR = "invalid block number"; private static final String TAG_NOT_SUPPORT_ERROR = "TAG [earliest | pending] not supported"; - private static final String QUANTITY_NOT_SUPPORT_ERROR = - "QUANTITY not supported, just support TAG as latest"; private static final String NO_BLOCK_HEADER = "header not found"; private static final String NO_BLOCK_HEADER_BY_HASH = "header for hash not found"; @@ -342,34 +343,63 @@ public String getLatestBlockNum() { @Override public String getTrxBalance(String address, String blockNumOrTag) throws JsonRpcInvalidParamsException { + byte[] addressData = addressCompatibleToByteArray(address); + Account reply; if (EARLIEST_STR.equalsIgnoreCase(blockNumOrTag) || PENDING_STR.equalsIgnoreCase(blockNumOrTag)) { throw new JsonRpcInvalidParamsException(TAG_NOT_SUPPORT_ERROR); } else if (LATEST_STR.equalsIgnoreCase(blockNumOrTag)) { - byte[] addressData = addressCompatibleToByteArray(address); - Account account = Account.newBuilder().setAddress(ByteString.copyFrom(addressData)).build(); - Account reply = wallet.getAccount(account); - long balance = 0; - - if (reply != null) { - balance = reply.getBalance(); + reply = wallet.getAccount(account); + } else { + BigInteger blockNumber; + try { + blockNumber = ByteArray.hexToBigInteger(blockNumOrTag); + } catch (Exception e) { + throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR); } - return ByteArray.toJsonHex(balance); + reply = wallet.getAccount(addressData, blockNumber.longValue()); + } + + long balance = 0; + if (reply != null) { + balance = reply.getBalance(); + } + return ByteArray.toJsonHex(balance); + } + + @Override + public Map getToken10(String address, String blockNumOrTag) + throws JsonRpcInvalidParamsException { + byte[] addressData = addressCompatibleToByteArray(address); + Account reply; + if (EARLIEST_STR.equalsIgnoreCase(blockNumOrTag) + || PENDING_STR.equalsIgnoreCase(blockNumOrTag)) { + throw new JsonRpcInvalidParamsException(TAG_NOT_SUPPORT_ERROR); + } else if (LATEST_STR.equalsIgnoreCase(blockNumOrTag)) { + Account account = Account.newBuilder().setAddress(ByteString.copyFrom(addressData)).build(); + reply = wallet.getAccount(account); } else { + BigInteger blockNumber; try { - ByteArray.hexToBigInteger(blockNumOrTag); + blockNumber = ByteArray.hexToBigInteger(blockNumOrTag); } catch (Exception e) { throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR); } + reply = wallet.getAccountToken10(addressData, blockNumber.longValue()); + } - throw new JsonRpcInvalidParamsException(QUANTITY_NOT_SUPPORT_ERROR); + Map token10s = new TreeMap<>(); + if (reply != null) { + reply.getAssetV2Map().forEach((k, v) -> token10s.put(ByteArray.toJsonHex(k), + ByteArray.toJsonHex(v))); } + return token10s; } private void callTriggerConstantContract(byte[] ownerAddressByte, byte[] contractAddressByte, long value, byte[] data, TransactionExtention.Builder trxExtBuilder, - Return.Builder retBuilder) + Return.Builder retBuilder, long blockNumber) throws ContractValidateException, ContractExeException, HeaderNotFound, VMIllegalException { TriggerSmartContract triggerContract = triggerCallContract( @@ -383,8 +413,8 @@ private void callTriggerConstantContract(byte[] ownerAddressByte, byte[] contrac TransactionCapsule trxCap = wallet.createTransactionCapsule(triggerContract, ContractType.TriggerSmartContract); - Transaction trx = - wallet.triggerConstantContract(triggerContract, trxCap, trxExtBuilder, retBuilder); + Transaction trx = wallet.triggerConstantContract( + triggerContract, trxCap, trxExtBuilder, retBuilder, blockNumber); trxExtBuilder.setTransaction(trx); trxExtBuilder.setTxid(trxCap.getTransactionId().getByteString()); @@ -422,7 +452,8 @@ private void estimateEnergy(byte[] ownerAddressByte, byte[] contractAddressByte, * getMethodSign(methodName(uint256,uint256)) || data1 || data2 */ private String call(byte[] ownerAddressByte, byte[] contractAddressByte, long value, - byte[] data) throws JsonRpcInvalidRequestException, JsonRpcInternalException { + byte[] data, long blockNumber) + throws JsonRpcInvalidRequestException, JsonRpcInternalException { TransactionExtention.Builder trxExtBuilder = TransactionExtention.newBuilder(); Return.Builder retBuilder = Return.newBuilder(); @@ -430,7 +461,7 @@ private String call(byte[] ownerAddressByte, byte[] contractAddressByte, long va try { callTriggerConstantContract(ownerAddressByte, contractAddressByte, value, data, - trxExtBuilder, retBuilder); + trxExtBuilder, retBuilder, blockNumber); } catch (ContractValidateException | VMIllegalException e) { String errString = CONTRACT_VALIDATE_ERROR; @@ -479,12 +510,11 @@ private String call(byte[] ownerAddressByte, byte[] contractAddressByte, long va @Override public String getStorageAt(String address, String storageIdx, String blockNumOrTag) throws JsonRpcInvalidParamsException { + byte[] addressByte = addressCompatibleToByteArray(address); if (EARLIEST_STR.equalsIgnoreCase(blockNumOrTag) || PENDING_STR.equalsIgnoreCase(blockNumOrTag)) { throw new JsonRpcInvalidParamsException(TAG_NOT_SUPPORT_ERROR); } else if (LATEST_STR.equalsIgnoreCase(blockNumOrTag)) { - byte[] addressByte = addressCompatibleToByteArray(address); - // get contract from contractStore BytesMessage.Builder build = BytesMessage.newBuilder(); BytesMessage bytesMessage = build.setValue(ByteString.copyFrom(addressByte)).build(); @@ -501,25 +531,25 @@ public String getStorageAt(String address, String storageIdx, String blockNumOrT DataWord value = storage.getValue(new DataWord(ByteArray.fromHexString(storageIdx))); return ByteArray.toJsonHex(value == null ? new byte[32] : value.getData()); } else { + BigInteger blockNumber; try { - ByteArray.hexToBigInteger(blockNumOrTag); + blockNumber = ByteArray.hexToBigInteger(blockNumOrTag); } catch (Exception e) { throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR); } - - throw new JsonRpcInvalidParamsException(QUANTITY_NOT_SUPPORT_ERROR); + byte[] value = wallet.getStorageAt(addressByte, storageIdx, blockNumber.longValue()); + return ByteArray.toJsonHex(value == null ? new byte[32] : value); } } @Override public String getABIOfSmartContract(String contractAddress, String blockNumOrTag) throws JsonRpcInvalidParamsException { + byte[] addressData = addressCompatibleToByteArray(contractAddress); if (EARLIEST_STR.equalsIgnoreCase(blockNumOrTag) || PENDING_STR.equalsIgnoreCase(blockNumOrTag)) { throw new JsonRpcInvalidParamsException(TAG_NOT_SUPPORT_ERROR); } else if (LATEST_STR.equalsIgnoreCase(blockNumOrTag)) { - byte[] addressData = addressCompatibleToByteArray(contractAddress); - BytesMessage.Builder build = BytesMessage.newBuilder(); BytesMessage bytesMessage = build.setValue(ByteString.copyFrom(addressData)).build(); SmartContractDataWrapper contractDataWrapper = wallet.getContractInfo(bytesMessage); @@ -531,13 +561,14 @@ public String getABIOfSmartContract(String contractAddress, String blockNumOrTag } } else { + BigInteger blockNumber; try { - ByteArray.hexToBigInteger(blockNumOrTag); + blockNumber = ByteArray.hexToBigInteger(blockNumOrTag); } catch (Exception e) { throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR); } - - throw new JsonRpcInvalidParamsException(QUANTITY_NOT_SUPPORT_ERROR); + byte[] code = wallet.getCode(addressData, blockNumber.longValue()); + return code != null ? ByteArray.toJsonHex(code) : "0x"; } } @@ -599,7 +630,8 @@ public String estimateGas(CallArguments args) throws JsonRpcInvalidRequestExcept args.parseValue(), ByteArray.fromHexString(args.getData()), trxExtBuilder, - retBuilder); + retBuilder, + -1); } } catch (ContractValidateException e) { @@ -799,15 +831,14 @@ public String getCall(CallArguments transactionCall, Object blockParamObj) } catch (ClassCastException e) { throw new JsonRpcInvalidParamsException(JSON_ERROR); } - - if (getBlockByJsonHash(blockNumOrTag) == null) { + Block block = getBlockByJsonHash(blockNumOrTag); + if (block == null) { throw new JsonRpcInternalException(NO_BLOCK_HEADER_BY_HASH); } + blockNumOrTag = ByteArray.toJsonHex(block.getBlockHeader().getRawData().getNumber()); } else { throw new JsonRpcInvalidRequestException(JSON_ERROR); } - - blockNumOrTag = LATEST_STR; } else if (blockParamObj instanceof String) { blockNumOrTag = (String) blockParamObj; } else { @@ -822,15 +853,19 @@ public String getCall(CallArguments transactionCall, Object blockParamObj) byte[] contractAddressData = addressCompatibleToByteArray(transactionCall.getTo()); return call(addressData, contractAddressData, transactionCall.parseValue(), - ByteArray.fromHexString(transactionCall.getData())); + ByteArray.fromHexString(transactionCall.getData()), -1); } else { + long blockNumber; try { - ByteArray.hexToBigInteger(blockNumOrTag); + blockNumber = ByteArray.hexToBigInteger(blockNumOrTag).longValue(); } catch (Exception e) { throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR); } + byte[] addressData = addressCompatibleToByteArray(transactionCall.getFrom()); + byte[] contractAddressData = addressCompatibleToByteArray(transactionCall.getTo()); - throw new JsonRpcInvalidParamsException(QUANTITY_NOT_SUPPORT_ERROR); + return call(addressData, contractAddressData, transactionCall.parseValue(), + ByteArray.fromHexString(transactionCall.getData()), blockNumber); } } diff --git a/framework/src/main/java/org/tron/tool/litefullnode/LiteFullNodeTool.java b/framework/src/main/java/org/tron/tool/litefullnode/LiteFullNodeTool.java index f2535c7caa5..4c60e8a7e11 100644 --- a/framework/src/main/java/org/tron/tool/litefullnode/LiteFullNodeTool.java +++ b/framework/src/main/java/org/tron/tool/litefullnode/LiteFullNodeTool.java @@ -193,7 +193,7 @@ private void split(String sourceDir, String destDir, List dbs) throws IO if (!destPath.mkdirs()) { throw new RuntimeException(String.format("destDir: %s create failed, please check", destDir)); } - Util.copyDatabases(Paths.get(sourceDir), Paths.get(destDir), dbs); + FileUtil.copyDatabases(Paths.get(sourceDir), Paths.get(destDir), dbs); } private void mergeCheckpoint(String sourceDir, String destDir, List destDbs) { @@ -397,13 +397,13 @@ private void backupArchiveDbs(String databaseDir) throws IOException { if (!FileUtil.createDirIfNotExists(bakDir)) { throw new RuntimeException(String.format("create bak dir %s failed", bakDir)); } - Util.copyDatabases(Paths.get(databaseDir), Paths.get(bakDir), archiveDbs); + FileUtil.copyDatabases(Paths.get(databaseDir), Paths.get(bakDir), archiveDbs); archiveDbs.forEach(db -> FileUtil.deleteDir(new File(databaseDir, db))); } private void copyHistory2Database(String historyDir, String databaseDir) throws IOException { logger.info("Begin to copy history to database."); - Util.copyDatabases(Paths.get(historyDir), Paths.get(databaseDir), archiveDbs); + FileUtil.copyDatabases(Paths.get(historyDir), Paths.get(databaseDir), archiveDbs); } private void trimHistory(String databaseDir, BlockNumInfo blockNumInfo) diff --git a/framework/src/main/resources/config-localtest.conf b/framework/src/main/resources/config-localtest.conf index 32f57481463..1898ea53087 100644 --- a/framework/src/main/resources/config-localtest.conf +++ b/framework/src/main/resources/config-localtest.conf @@ -52,6 +52,9 @@ storage { ] checkpoint.version = 2 checkpoint.sync = true + + stateRoot.switch = true +# stateGenesis.directory = state-genesis } node.discovery = { diff --git a/framework/src/main/resources/config.conf b/framework/src/main/resources/config.conf index 67aa374eec3..55beb71a7e5 100644 --- a/framework/src/main/resources/config.conf +++ b/framework/src/main/resources/config.conf @@ -95,6 +95,10 @@ storage { # the estimated number of block transactions (default 1000, min 100, max 10000). # so the total number of cached transactions is 65536 * txCache.estimatedTransactions # txCache.estimatedTransactions = 1000 + + # world state + # stateRoot.switch = false + # stateGenesis.directory = "state-genesis" } node.discovery = { diff --git a/framework/src/test/java/org/tron/common/runtime/VmStateTestUtil.java b/framework/src/test/java/org/tron/common/runtime/VmStateTestUtil.java new file mode 100644 index 00000000000..9ed42139457 --- /dev/null +++ b/framework/src/test/java/org/tron/common/runtime/VmStateTestUtil.java @@ -0,0 +1,66 @@ +package org.tron.common.runtime; + +import com.google.protobuf.ByteString; +import org.tron.common.utils.ByteArray; +import org.tron.core.ChainBaseManager; +import org.tron.core.Wallet; +import org.tron.core.actuator.VMActuator; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.capsule.TransactionCapsule; +import org.tron.core.db.TransactionContext; +import org.tron.core.exception.ContractExeException; +import org.tron.core.exception.ContractValidateException; +import org.tron.core.state.WorldStateCallBack; +import org.tron.core.state.trie.TrieImpl2; +import org.tron.core.store.StoreFactory; +import org.tron.protos.Protocol; + +public class VmStateTestUtil { + + private static String OWNER_ADDRESS = Wallet.getAddressPreFixString() + + "abd4b9367799eaa3197fecb144eb71de1e049abc"; + + public static ProgramResult runConstantCall( + ChainBaseManager chainBaseManager, + WorldStateCallBack worldStateCallBack, Protocol.Transaction tx) + throws ContractExeException, ContractValidateException { + BlockCapsule block = mockBlock(chainBaseManager, worldStateCallBack); + TransactionCapsule trxCap = new TransactionCapsule(tx); + TransactionContext context = new TransactionContext(block, trxCap, + StoreFactory.getInstance(), true, false); + VMActuator vmActuator = new VMActuator(true); + + vmActuator.validate(context); + vmActuator.execute(context); + return context.getProgramResult(); + } + + public static BlockCapsule mockBlock(ChainBaseManager chainBaseManager, + WorldStateCallBack worldStateCallBack) { + chainBaseManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(1000); + TrieImpl2 trie = flushTrie(worldStateCallBack); + BlockCapsule blockCap = new BlockCapsule(Protocol.Block.newBuilder().build()); + Protocol.BlockHeader.raw blockHeaderRaw = + blockCap.getInstance().getBlockHeader().getRawData().toBuilder() + .setNumber(100) + .setTimestamp(System.currentTimeMillis()) + .setWitnessAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .build(); + Protocol.BlockHeader blockHeader = blockCap.getInstance().getBlockHeader().toBuilder() + .setRawData(blockHeaderRaw) + .setArchiveRoot(ByteString.copyFrom(trie.getRootHash())) + .build(); + blockCap = new BlockCapsule( + blockCap.getInstance().toBuilder().setBlockHeader(blockHeader).build()); + blockCap.generatedByMyself = true; + return blockCap; + } + + public static TrieImpl2 flushTrie(WorldStateCallBack worldStateCallBack) { + worldStateCallBack.clear(); + TrieImpl2 trie = worldStateCallBack.getTrie(); + trie.commit(); + trie.flush(); + return trie; + } +} diff --git a/framework/src/test/java/org/tron/common/runtime/vm/FreezeV2Test.java b/framework/src/test/java/org/tron/common/runtime/vm/FreezeV2Test.java index 78096564e48..ba4e1233c59 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/FreezeV2Test.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/FreezeV2Test.java @@ -25,6 +25,7 @@ import org.tron.common.runtime.RuntimeImpl; import org.tron.common.runtime.TVMTestResult; import org.tron.common.runtime.TvmTestUtils; +import org.tron.common.runtime.VmStateTestUtil; import org.tron.common.utils.Commons; import org.tron.common.utils.FastByteComparisons; import org.tron.common.utils.FileUtil; @@ -45,6 +46,7 @@ import org.tron.core.db.EnergyProcessor; import org.tron.core.db.Manager; import org.tron.core.db.TransactionTrace; +import org.tron.core.state.WorldStateCallBack; import org.tron.core.store.AccountStore; import org.tron.core.store.DelegatedResourceStore; import org.tron.core.store.DynamicPropertiesStore; @@ -161,6 +163,8 @@ public class FreezeV2Test { private static Manager manager; private static byte[] owner; private static Repository rootRepository; + private static ChainBaseManager chainBaseManager; + private static WorldStateCallBack worldStateCallBack; @Before public void init() throws Exception { @@ -168,6 +172,9 @@ public void init() throws Exception { Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); context = new TronApplicationContext(DefaultConfig.class); manager = context.getBean(Manager.class); + chainBaseManager = context.getBean(ChainBaseManager.class); + worldStateCallBack = context.getBean(WorldStateCallBack.class); + worldStateCallBack.setExecute(true); owner = Hex.decode(Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"); rootRepository = RepositoryImpl.createRoot(StoreFactory.getInstance()); @@ -228,6 +235,8 @@ private TVMTestResult triggerContract(byte[] callerAddr, TransactionCapsule trxCap = new TransactionCapsule( TvmTestUtils.generateTriggerSmartContractAndGetTransaction( callerAddr, contractAddr, Hex.decode(hexInput), 0, feeLimit)); + VmStateTestUtil.runConstantCall( + chainBaseManager, worldStateCallBack, trxCap.getInstance()); TransactionTrace trace = new TransactionTrace(trxCap, StoreFactory.getInstance(), new RuntimeImpl()); trxCap.setTrxTrace(trace); diff --git a/framework/src/test/java/org/tron/common/runtime/vm/RewardBalanceTest.java b/framework/src/test/java/org/tron/common/runtime/vm/RewardBalanceTest.java index b9fa24712c9..6a504b9f857 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/RewardBalanceTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/RewardBalanceTest.java @@ -2,6 +2,7 @@ import java.util.Collections; import lombok.extern.slf4j.Slf4j; +import org.apache.tuweni.bytes.Bytes32; import org.bouncycastle.util.encoders.Hex; import org.junit.Test; import org.testng.Assert; @@ -16,6 +17,8 @@ import org.tron.core.exception.ContractValidateException; import org.tron.core.exception.ReceiptCheckErrException; import org.tron.core.exception.VMIllegalException; +import org.tron.core.state.WorldStateCallBack; +import org.tron.core.state.trie.TrieImpl2; import org.tron.core.store.StoreFactory; import org.tron.core.vm.config.ConfigLoader; import org.tron.core.vm.config.VMConfig; @@ -24,6 +27,7 @@ import org.tron.core.vm.program.invoke.ProgramInvokeFactory; import org.tron.core.vm.repository.Repository; import org.tron.core.vm.repository.RepositoryImpl; +import org.tron.core.vm.repository.RepositoryStateImpl; import org.tron.protos.Protocol; import org.tron.protos.Protocol.Transaction; @@ -75,10 +79,16 @@ function payableAddrTest(address payable addr) view public returns (uint256) { } */ + private WorldStateCallBack worldStateCallBack; + @Test public void testRewardBalance() throws ContractExeException, ReceiptCheckErrException, VMIllegalException, ContractValidateException { + // state query test init + worldStateCallBack = context.getBean(WorldStateCallBack.class); + TrieImpl2 trie = worldStateCallBack.getTrie(); + ConfigLoader.disable = true; VMConfig.initAllowTvmTransferTrc10(1); VMConfig.initAllowTvmConstantinople(1); @@ -176,6 +186,10 @@ public void testRewardBalance() "0000000000000000000000000000000000000000000000000000000000000000"); repository.commit(); + // test state query + testStateQuery(trie, storeFactory, blockCap, + new DataWord(Base58.decode(nonexistentAccount)), rootInternalTransaction, trx); + // trigger deployed contract hexInput = AbiUtil.parseMethod(methodByAddr, Collections.singletonList(factoryAddressStr)); trx = TvmTestUtils.generateTriggerSmartContractAndGetTransaction(Hex.decode(OWNER_ADDRESS), @@ -194,6 +208,10 @@ public void testRewardBalance() "0000000000000000000000000000000000000000000000000000000000000000"); repository.commit(); + // test state query + testStateQuery(trie, storeFactory, blockCap, + new DataWord(Base58.decode(factoryAddressStr)), rootInternalTransaction, trx); + // trigger deployed contract String witnessAccount = "27Ssb1WE8FArwJVRRb8Dwy3ssVGuLY8L3S1"; hexInput = AbiUtil.parseMethod(methodByAddr, Collections.singletonList(witnessAccount)); @@ -213,6 +231,10 @@ public void testRewardBalance() "0000000000000000000000000000000000000000000000000000000000000000"); repository.commit(); + // test state query + testStateQuery(trie, storeFactory, blockCap, + new DataWord(Base58.decode(witnessAccount)), rootInternalTransaction, trx); + // Trigger contract method: nullAddressTest(address) methodByAddr = "nullAddressTest()"; hexInput = AbiUtil.parseMethod(methodByAddr, Collections.singletonList("")); @@ -232,6 +254,10 @@ public void testRewardBalance() "0000000000000000000000000000000000000000000000000000000000000000"); repository.commit(); + // test state query + testStateQuery(trie, storeFactory, blockCap, + DataWord.ZERO(), rootInternalTransaction, trx); + // Trigger contract method: localContractAddrTest() methodByAddr = "localContractAddrTest()"; hexInput = AbiUtil.parseMethod(methodByAddr, Collections.singletonList("")); @@ -251,8 +277,35 @@ public void testRewardBalance() "0000000000000000000000000000000000000000000000000000000000000000"); repository.commit(); + // test state query + testStateQuery(trie, storeFactory, blockCap, + new DataWord(Base58.decode(factoryAddressStr)), rootInternalTransaction, trx); + + ConfigLoader.disable = false; } + + private void testStateQuery(TrieImpl2 trie, StoreFactory storeFactory, + BlockCapsule blockCap, DataWord address, + InternalTransaction rootInternalTransaction, + Transaction trx) throws ContractValidateException { + + worldStateCallBack.clear(); + trie.commit(); + trie.flush(); + byte[] root = trie.getRootHash(); + Repository repositoryState = RepositoryStateImpl.createRoot(storeFactory, Bytes32.wrap(root)); + ProgramInvoke programInvoke = ProgramInvokeFactory + .createProgramInvoke(InternalTransaction.TrxType.TRX_CONTRACT_CALL_TYPE, + InternalTransaction.ExecutorType.ET_PRE_TYPE, trx, + 0, 0, blockCap.getInstance(), repositoryState, System.nanoTime() / 1000, + System.nanoTime() / 1000 + 50000, 3_000_000L); + Program program = new Program(null, null, programInvoke, rootInternalTransaction); + byte[] result = program.getRewardBalance(address) + .getData(); + Assert.assertEquals(Hex.toHexString(result), + "0000000000000000000000000000000000000000000000000000000000000000"); + } } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java b/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java index 13f01847c81..fda82e2c801 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java @@ -11,6 +11,7 @@ import org.tron.common.runtime.ProgramResult; import org.tron.common.runtime.Runtime; import org.tron.common.runtime.TvmTestUtils; +import org.tron.common.runtime.VmStateTestUtil; import org.tron.common.utils.ByteArray; import org.tron.common.utils.StringUtil; import org.tron.common.utils.Utils; @@ -29,9 +30,13 @@ import org.tron.core.exception.ContractValidateException; import org.tron.core.exception.ReceiptCheckErrException; import org.tron.core.exception.VMIllegalException; +import org.tron.core.state.WorldStateCallBack; +import org.tron.core.state.WorldStateQueryInstance; +import org.tron.core.state.trie.TrieImpl2; import org.tron.core.store.StoreFactory; import org.tron.core.vm.EnergyCost; import org.tron.core.vm.repository.RepositoryImpl; +import org.tron.core.vm.repository.RepositoryStateImpl; import org.tron.protos.Protocol.AccountType; import org.tron.protos.Protocol.Transaction; import org.tron.protos.contract.AssetIssueContractOuterClass.AssetIssueContract; @@ -51,7 +56,9 @@ public class TransferToAccountTest extends BaseTest { private static final String URL = "https://tron.network"; private static Runtime runtime; private static RepositoryImpl repository; + private static RepositoryStateImpl repositoryState; private static AccountCapsule ownerCapsule; + private static WorldStateCallBack worldStateCallBack; static { dbPath = "output_TransferToAccountTest"; @@ -73,6 +80,7 @@ public void before() { AccountType.AssetIssue); ownerCapsule.setBalance(1000_1000_1000L); + worldStateCallBack = context.getBean(WorldStateCallBack.class); } private long createAsset(String tokenName) { @@ -117,15 +125,26 @@ private long createAsset(String tokenName) { public void TransferTokenTest() throws ContractExeException, ReceiptCheckErrException, VMIllegalException, ContractValidateException { + worldStateCallBack.setExecute(true); + // open account asset optimize + chainBaseManager.getDynamicPropertiesStore().setAllowAssetOptimization(1); + // 1. Test deploy with tokenValue and tokenId */ long id = createAsset("testToken1"); byte[] contractAddress = deployTransferContract(id); repository.commit(); + + WorldStateQueryInstance worldStateQueryInstance = flushTrieAndGetQueryInstance(); Assert.assertEquals(100, chainBaseManager.getAccountStore() .get(contractAddress).getAssetV2MapForTest().get(String.valueOf(id)).longValue()); + Assert.assertEquals(100, + worldStateQueryInstance.getAccount(contractAddress) + .getAssetV2MapForTest().get(String.valueOf(id)).longValue()); Assert.assertEquals(1000, chainBaseManager.getAccountStore().get(contractAddress).getBalance()); + Assert.assertEquals(1000, + worldStateQueryInstance.getAccount(contractAddress).getBalance()); String selectorStr = "transferTokenTo(address,trcToken,uint256)"; @@ -142,15 +161,23 @@ public void TransferTokenTest() .generateTriggerSmartContractAndGetTransaction(Hex.decode(OWNER_ADDRESS), contractAddress, input, triggerCallValue, feeLimit, tokenValue, id); + VmStateTestUtil.runConstantCall(chainBaseManager, worldStateCallBack, transaction); runtime = TvmTestUtils.processTransactionAndReturnRuntime(transaction, dbManager, null); + worldStateQueryInstance = flushTrieAndGetQueryInstance(); Assert.assertNull(runtime.getRuntimeError()); Assert.assertEquals(9, chainBaseManager.getAccountStore().get(Hex.decode(TRANSFER_TO)).getAssetV2MapForTest() .get(String.valueOf(id)).longValue()); + Assert.assertEquals(9, + worldStateQueryInstance.getAccount(Hex.decode(TRANSFER_TO)).getAssetV2MapForTest() + .get(String.valueOf(id)).longValue()); Assert.assertEquals(100 + tokenValue - 9, chainBaseManager.getAccountStore().get(contractAddress) .getAssetV2MapForTest().get(String.valueOf(id)).longValue()); + Assert.assertEquals(100 + tokenValue - 9, + worldStateQueryInstance.getAccount(contractAddress) + .getAssetV2MapForTest().get(String.valueOf(id)).longValue()); long energyCostWhenExist = runtime.getResult().getEnergyUsed(); // 3.Test transferToken To Non-exist address @@ -164,13 +191,20 @@ public void TransferTokenTest() triggerCallValue, feeLimit, tokenValue, id); runtime = TvmTestUtils.processTransactionAndReturnRuntime(transaction, dbManager, null); + worldStateQueryInstance = flushTrieAndGetQueryInstance(); Assert.assertNull(runtime.getRuntimeError()); Assert.assertEquals(100 + tokenValue * 2 - 18, chainBaseManager.getAccountStore().get(contractAddress).getAssetV2MapForTest() .get(String.valueOf(id)).longValue()); + Assert.assertEquals(100 + tokenValue * 2 - 18, + worldStateQueryInstance.getAccount(contractAddress).getAssetV2MapForTest() + .get(String.valueOf(id)).longValue()); Assert.assertEquals(9, chainBaseManager.getAccountStore().get(ecKey.getAddress()).getAssetV2MapForTest() .get(String.valueOf(id)).longValue()); + Assert.assertEquals(9, + worldStateQueryInstance.getAccount(ecKey.getAddress()).getAssetV2MapForTest() + .get(String.valueOf(id)).longValue()); long energyCostWhenNonExist = runtime.getResult().getEnergyUsed(); //4.Test Energy Assert.assertEquals(energyCostWhenNonExist - energyCostWhenExist, @@ -185,10 +219,16 @@ public void TransferTokenTest() .generateTriggerSmartContractAndGetTransaction(Hex.decode(OWNER_ADDRESS), contractAddress, input, triggerCallValue, feeLimit, 0, 0); + // test state call + VmStateTestUtil.runConstantCall(chainBaseManager, worldStateCallBack, transaction); runtime = TvmTestUtils.processTransactionAndReturnRuntime(transaction, dbManager, null); + + worldStateQueryInstance = flushTrieAndGetQueryInstance(); Assert.assertNull(runtime.getRuntimeError()); Assert.assertEquals(19, chainBaseManager.getAccountStore().get(Hex.decode(TRANSFER_TO)).getBalance()); + Assert.assertEquals(19, + worldStateQueryInstance.getAccount(Hex.decode(TRANSFER_TO)).getBalance()); energyCostWhenExist = runtime.getResult().getEnergyUsed(); //6. Test transfer Trx with non-exsit account @@ -201,10 +241,15 @@ public void TransferTokenTest() .generateTriggerSmartContractAndGetTransaction(Hex.decode(OWNER_ADDRESS), contractAddress, input, triggerCallValue, feeLimit, 0, 0); + VmStateTestUtil.runConstantCall(chainBaseManager, worldStateCallBack, transaction); runtime = TvmTestUtils.processTransactionAndReturnRuntime(transaction, dbManager, null); + + worldStateQueryInstance = flushTrieAndGetQueryInstance(); Assert.assertNull(runtime.getRuntimeError()); Assert.assertEquals(9, chainBaseManager.getAccountStore().get(ecKey.getAddress()).getBalance()); + Assert.assertEquals(9, + worldStateQueryInstance.getAccount(ecKey.getAddress()).getBalance()); energyCostWhenNonExist = runtime.getResult().getEnergyUsed(); //7.test energy @@ -220,6 +265,8 @@ public void TransferTokenTest() .generateTriggerSmartContractAndGetTransaction(Hex.decode(OWNER_ADDRESS), contractAddress, input, triggerCallValue, feeLimit, 0, 0); + Assert.assertTrue(VmStateTestUtil.runConstantCall( + chainBaseManager, worldStateCallBack, transaction).getRuntimeError().contains("failed")); runtime = TvmTestUtils.processTransactionAndReturnRuntime(transaction, dbManager, null); Assert.assertTrue(runtime.getRuntimeError().contains("failed")); @@ -235,6 +282,7 @@ public void TransferTokenTest() .generateTriggerSmartContractAndGetTransaction(Hex.decode(OWNER_ADDRESS), contractAddress, triggerData, triggerCallValue, feeLimit, tokenValue, id); + VmStateTestUtil.runConstantCall(chainBaseManager, worldStateCallBack, transaction); runtime = TvmTestUtils.processTransactionAndReturnRuntime(transaction, dbManager, null); Assert.assertEquals("endowment out of long range", runtime.getRuntimeError()); @@ -293,9 +341,20 @@ private byte[] deployTransferContract(long id) long tokenValue = 100; long tokenId = id; - return TvmTestUtils + // test state deploy contract + Transaction tx = TvmTestUtils.generateDeploySmartContractAndGetTransaction( + contractName, address, ABI, code, value, + feeLimit, consumeUserResourcePercent, tokenValue, tokenId, null); + VmStateTestUtil.runConstantCall(chainBaseManager, worldStateCallBack, tx); + + byte[] contractAddress = TvmTestUtils .deployContractWholeProcessReturnContractAddress(contractName, address, ABI, code, value, feeLimit, consumeUserResourcePercent, null, tokenValue, tokenId, repository, null); } + + private WorldStateQueryInstance flushTrieAndGetQueryInstance() { + TrieImpl2 trie = VmStateTestUtil.flushTrie(worldStateCallBack); + return new WorldStateQueryInstance(trie.getRootHashByte32(), chainBaseManager); + } } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/VoteTest.java b/framework/src/test/java/org/tron/common/runtime/vm/VoteTest.java index 22a33993589..52d46b27390 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/VoteTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/VoteTest.java @@ -26,6 +26,7 @@ import org.tron.common.runtime.RuntimeImpl; import org.tron.common.runtime.TVMTestResult; import org.tron.common.runtime.TvmTestUtils; +import org.tron.common.runtime.VmStateTestUtil; import org.tron.common.utils.Commons; import org.tron.common.utils.FileUtil; import org.tron.common.utils.StringUtil; @@ -33,6 +34,7 @@ import org.tron.common.utils.client.utils.AbiUtil; import org.tron.common.utils.client.utils.DataWord; import org.tron.consensus.dpos.MaintenanceManager; +import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; @@ -43,6 +45,7 @@ import org.tron.core.db.Manager; import org.tron.core.db.TransactionTrace; import org.tron.core.service.MortgageService; +import org.tron.core.state.WorldStateCallBack; import org.tron.core.store.StoreFactory; import org.tron.core.vm.config.ConfigLoader; import org.tron.core.vm.config.VMConfig; @@ -272,6 +275,8 @@ private static Consumer getSmallerConsumer(long expected) { private static MortgageService mortgageService; private static byte[] owner; private static Repository rootRepository; + private static ChainBaseManager chainBaseManager; + private static WorldStateCallBack worldStateCallBack; @Before public void init() throws Exception { @@ -282,6 +287,9 @@ public void init() throws Exception { manager = context.getBean(Manager.class); maintenanceManager = context.getBean(MaintenanceManager.class); consensusService = context.getBean(ConsensusService.class); + chainBaseManager = context.getBean(ChainBaseManager.class); + worldStateCallBack = context.getBean(WorldStateCallBack.class); + worldStateCallBack.setExecute(true); consensusService.start(); mortgageService = context.getBean(MortgageService.class); owner = Hex.decode(Wallet.getAddressPreFixString() @@ -348,6 +356,8 @@ private TVMTestResult triggerContract(byte[] contractAddr, TransactionCapsule trxCap = new TransactionCapsule( TvmTestUtils.generateTriggerSmartContractAndGetTransaction( owner, contractAddr, Hex.decode(hexInput), 0, fee)); + VmStateTestUtil.runConstantCall( + chainBaseManager, worldStateCallBack, trxCap.getInstance()); TransactionTrace trace = new TransactionTrace(trxCap, StoreFactory.getInstance(), new RuntimeImpl()); trxCap.setTrxTrace(trace); diff --git a/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java index b20d55fd983..0391e34caba 100644 --- a/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java @@ -13,11 +13,15 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; import lombok.extern.slf4j.Slf4j; +import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.tron.common.BaseTest; import org.tron.common.utils.ByteArray; +import org.tron.common.utils.FileUtil; +import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; @@ -27,6 +31,9 @@ import org.tron.core.config.args.Args; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; +import org.tron.core.state.WorldStateCallBack; +import org.tron.core.state.WorldStateQueryInstance; +import org.tron.core.state.store.DynamicPropertiesStateStore; import org.tron.core.store.DynamicPropertiesStore; import org.tron.protos.Protocol.AccountType; import org.tron.protos.Protocol.Transaction.Result.code; @@ -42,6 +49,10 @@ public class DelegateResourceActuatorTest extends BaseTest { private static final String OWNER_ADDRESS_INVALID = "aaaa"; private static final String OWNER_ACCOUNT_INVALID; private static final long initBalance = 10_000_000_000L; + private static Manager dbManager; + private static final TronApplicationContext context; + private static final WorldStateCallBack worldStateCallBack; + private static final ChainBaseManager chainBaseManager; static { dbPath = "output_delegate_resource_test"; @@ -50,6 +61,8 @@ public class DelegateResourceActuatorTest extends BaseTest { RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; + worldStateCallBack = context.getBean(WorldStateCallBack.class); + chainBaseManager = context.getBean(ChainBaseManager.class); } /** @@ -57,6 +70,7 @@ public class DelegateResourceActuatorTest extends BaseTest { */ @Before public void createAccountCapsule() { + worldStateCallBack.setExecute(true); dbManager.getDynamicPropertiesStore().saveUnfreezeDelayDays(1L); dbManager.getDynamicPropertiesStore().saveAllowNewResourceModel(1L); @@ -88,6 +102,11 @@ public void createAccountCapsule() { dbManager.getDelegatedResourceAccountIndexStore().unDelegateV2(owner, receiver); } + @After + public void reset() { + worldStateCallBack.setExecute(false); + } + public void freezeBandwidthForOwner() { AccountCapsule ownerCapsule = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -325,10 +344,17 @@ public void testDelegateResourceForBandwidth() { AccountCapsule ownerCapsule = dbManager.getAccountStore().get(owner); - assertEquals(delegateBalance, ownerCapsule.getDelegatedFrozenV2BalanceForBandwidth()); - assertEquals(initBalance - delegateBalance, + Assert.assertEquals(delegateBalance, ownerCapsule.getDelegatedFrozenV2BalanceForBandwidth()); + Assert.assertEquals(initBalance - delegateBalance, ownerCapsule.getFrozenV2BalanceForBandwidth()); - assertEquals(initBalance, ownerCapsule.getTronPower()); + Assert.assertEquals(initBalance, ownerCapsule.getTronPower()); + + WorldStateQueryInstance queryInstance = getQueryInstance(); + ownerCapsule = queryInstance.getAccount(owner); + Assert.assertEquals(delegateBalance, ownerCapsule.getDelegatedFrozenV2BalanceForBandwidth()); + Assert.assertEquals(initBalance - delegateBalance, + ownerCapsule.getFrozenV2BalanceForBandwidth()); + Assert.assertEquals(initBalance, ownerCapsule.getTronPower()); AccountCapsule receiverCapsule = dbManager.getAccountStore().get(receiver); @@ -337,14 +363,31 @@ public void testDelegateResourceForBandwidth() { assertEquals(0L, receiverCapsule.getAcquiredDelegatedFrozenV2BalanceForEnergy()); assertEquals(0L, receiverCapsule.getTronPower()); + receiverCapsule = queryInstance.getAccount(receiver); + Assert.assertEquals(delegateBalance, + receiverCapsule.getAcquiredDelegatedFrozenV2BalanceForBandwidth()); + Assert.assertEquals(0L, + receiverCapsule.getAcquiredDelegatedFrozenV2BalanceForEnergy()); + Assert.assertEquals(0L, receiverCapsule.getTronPower()); + DelegatedResourceCapsule delegatedResourceCapsule = dbManager.getDelegatedResourceStore() .get(DelegatedResourceCapsule .createDbKeyV2(ByteArray.fromHexString(OWNER_ADDRESS), ByteArray.fromHexString(RECEIVER_ADDRESS), false)); - assertEquals(delegateBalance, delegatedResourceCapsule.getFrozenBalanceForBandwidth()); + Assert.assertEquals(delegateBalance, delegatedResourceCapsule.getFrozenBalanceForBandwidth()); + + delegatedResourceCapsule = queryInstance.getDelegatedResource(DelegatedResourceCapsule + .createDbKeyV2(ByteArray.fromHexString(OWNER_ADDRESS), + ByteArray.fromHexString(RECEIVER_ADDRESS), false)); + Assert.assertEquals(delegateBalance, delegatedResourceCapsule.getFrozenBalanceForBandwidth()); + long totalNetWeightAfter = dbManager.getDynamicPropertiesStore().getTotalNetWeight(); - assertEquals(totalNetWeightBefore, totalNetWeightAfter); + Assert.assertEquals(totalNetWeightBefore, totalNetWeightAfter); + DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(); + stateStore.init(queryInstance); + Assert.assertEquals(totalNetWeightBefore, stateStore.getTotalNetWeight()); + //check DelegatedResourceAccountIndex DelegatedResourceAccountIndexCapsule ownerIndexCapsule = dbManager @@ -822,4 +865,13 @@ private Any getErrorContract() { ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))).build() ); } + + private WorldStateQueryInstance getQueryInstance() { + Assert.assertNotNull(worldStateCallBack.getTrie()); + worldStateCallBack.clear(); + worldStateCallBack.getTrie().commit(); + worldStateCallBack.getTrie().flush(); + return new WorldStateQueryInstance(worldStateCallBack.getTrie().getRootHashByte32(), + chainBaseManager); + } } diff --git a/framework/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java index abcaf538e93..bbfc2c1f9f9 100644 --- a/framework/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java @@ -7,6 +7,8 @@ import com.google.protobuf.ByteString; import java.util.List; import lombok.extern.slf4j.Slf4j; +import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -25,6 +27,9 @@ import org.tron.core.config.args.Args; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; +import org.tron.core.state.WorldStateCallBack; +import org.tron.core.state.WorldStateQueryInstance; +import org.tron.core.state.store.DynamicPropertiesStateStore; import org.tron.protos.Protocol.AccountType; import org.tron.protos.Protocol.Transaction.Result.code; import org.tron.protos.contract.AssetIssueContractOuterClass; @@ -39,6 +44,10 @@ public class FreezeBalanceActuatorTest extends BaseTest { private static final String OWNER_ADDRESS_INVALID = "aaaa"; private static final String OWNER_ACCOUNT_INVALID; private static final long initBalance = 10_000_000_000L; + private static Manager dbManager; + private static TronApplicationContext context; + private static WorldStateCallBack worldStateCallBack; + private static ChainBaseManager chainBaseManager; static { dbPath = "output_freeze_balance_test"; @@ -47,6 +56,8 @@ public class FreezeBalanceActuatorTest extends BaseTest { RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; + worldStateCallBack = context.getBean(WorldStateCallBack.class); + chainBaseManager = context.getBean(ChainBaseManager.class); } /** @@ -54,6 +65,7 @@ public class FreezeBalanceActuatorTest extends BaseTest { */ @Before public void createAccountCapsule() { + worldStateCallBack.setExecute(true); AccountCapsule ownerCapsule = new AccountCapsule( ByteString.copyFromUtf8("owner"), @@ -71,6 +83,11 @@ public void createAccountCapsule() { dbManager.getAccountStore().put(receiverCapsule.getAddress().toByteArray(), receiverCapsule); } + @After + public void reset() { + worldStateCallBack.setExecute(false); + } + private Any getContractForBandwidth(String ownerAddress, long frozenBalance, long duration) { return Any.pack( FreezeBalanceContract.newBuilder() @@ -145,6 +162,14 @@ public void testFreezeBalanceForBandwidth() { - TRANSFER_FEE); Assert.assertEquals(owner.getFrozenBalance(), frozenBalance); Assert.assertEquals(frozenBalance, owner.getTronPower()); + + WorldStateQueryInstance queryInstance = getQueryInstance(); + owner = queryInstance.getAccount(ByteArray.fromHexString(OWNER_ADDRESS)); + Assert.assertEquals(owner.getBalance(), initBalance - frozenBalance + - TRANSFER_FEE); + Assert.assertEquals(owner.getFrozenBalance(), frozenBalance); + Assert.assertEquals(frozenBalance, owner.getTronPower()); + } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -173,6 +198,14 @@ public void testFreezeBalanceForEnergy() { Assert.assertEquals(0L, owner.getFrozenBalance()); Assert.assertEquals(frozenBalance, owner.getEnergyFrozenBalance()); Assert.assertEquals(frozenBalance, owner.getTronPower()); + WorldStateQueryInstance queryInstance = getQueryInstance(); + owner = queryInstance.getAccount(ByteArray.fromHexString(OWNER_ADDRESS)); + Assert.assertEquals(owner.getBalance(), initBalance - frozenBalance + - TRANSFER_FEE); + Assert.assertEquals(0L, owner.getFrozenBalance()); + Assert.assertEquals(frozenBalance, owner.getEnergyFrozenBalance()); + Assert.assertEquals(frozenBalance, owner.getTronPower()); + } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -237,21 +270,44 @@ public void testFreezeDelegatedBalanceForBandwidth() { Assert.assertEquals(frozenBalance, owner.getDelegatedFrozenBalanceForBandwidth()); Assert.assertEquals(frozenBalance, owner.getTronPower()); + WorldStateQueryInstance queryInstance = getQueryInstance(); + owner = queryInstance.getAccount(ByteArray.fromHexString(OWNER_ADDRESS)); + Assert.assertEquals(owner.getBalance(), initBalance - frozenBalance - TRANSFER_FEE); + Assert.assertEquals(0L, owner.getFrozenBalance()); + Assert.assertEquals(frozenBalance, owner.getDelegatedFrozenBalanceForBandwidth()); + Assert.assertEquals(frozenBalance, owner.getTronPower()); + AccountCapsule receiver = dbManager.getAccountStore().get(ByteArray.fromHexString(RECEIVER_ADDRESS)); Assert.assertEquals(frozenBalance, receiver.getAcquiredDelegatedFrozenBalanceForBandwidth()); Assert.assertEquals(0L, receiver.getAcquiredDelegatedFrozenBalanceForEnergy()); Assert.assertEquals(0L, receiver.getTronPower()); + receiver = queryInstance.getAccount(ByteArray.fromHexString(RECEIVER_ADDRESS)); + Assert.assertEquals(frozenBalance, receiver.getAcquiredDelegatedFrozenBalanceForBandwidth()); + Assert.assertEquals(0L, receiver.getAcquiredDelegatedFrozenBalanceForEnergy()); + Assert.assertEquals(0L, receiver.getTronPower()); + DelegatedResourceCapsule delegatedResourceCapsule = dbManager.getDelegatedResourceStore() .get(DelegatedResourceCapsule .createDbKey(ByteArray.fromHexString(OWNER_ADDRESS), ByteArray.fromHexString(RECEIVER_ADDRESS))); Assert.assertEquals(frozenBalance, delegatedResourceCapsule.getFrozenBalanceForBandwidth()); + + delegatedResourceCapsule = queryInstance.getDelegatedResource(DelegatedResourceCapsule + .createDbKey(ByteArray.fromHexString(OWNER_ADDRESS), + ByteArray.fromHexString(RECEIVER_ADDRESS))); + Assert.assertEquals(frozenBalance, delegatedResourceCapsule.getFrozenBalanceForBandwidth()); + long totalNetWeightAfter = dbManager.getDynamicPropertiesStore().getTotalNetWeight(); Assert.assertEquals(totalNetWeightBefore + frozenBalance / 1000_000L, totalNetWeightAfter); + DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(); + stateStore.init(queryInstance); + Assert.assertEquals(totalNetWeightBefore + frozenBalance / 1000_000L, + stateStore.getTotalNetWeight()); + //check DelegatedResourceAccountIndex DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsuleOwner = dbManager .getDelegatedResourceAccountIndexStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -262,6 +318,17 @@ public void testFreezeDelegatedBalanceForBandwidth() { delegatedResourceAccountIndexCapsuleOwner.getToAccountsList() .contains(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS)))); + delegatedResourceAccountIndexCapsuleOwner = queryInstance.getDelegatedResourceAccountIndex( + ByteArray.fromHexString(OWNER_ADDRESS)); + + Assert.assertEquals(0, + delegatedResourceAccountIndexCapsuleOwner.getFromAccountsList().size()); + Assert.assertEquals(1, + delegatedResourceAccountIndexCapsuleOwner.getToAccountsList().size()); + Assert.assertEquals(true, + delegatedResourceAccountIndexCapsuleOwner.getToAccountsList() + .contains(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS)))); + DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsuleReceiver = dbManager .getDelegatedResourceAccountIndexStore().get(ByteArray.fromHexString(RECEIVER_ADDRESS)); Assert @@ -273,6 +340,15 @@ public void testFreezeDelegatedBalanceForBandwidth() { delegatedResourceAccountIndexCapsuleReceiver.getFromAccountsList() .contains(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)))); + delegatedResourceAccountIndexCapsuleReceiver = queryInstance.getDelegatedResourceAccountIndex( + ByteArray.fromHexString(RECEIVER_ADDRESS)); + Assert.assertEquals(0, + delegatedResourceAccountIndexCapsuleReceiver.getToAccountsList().size()); + Assert.assertEquals(1, + delegatedResourceAccountIndexCapsuleReceiver.getFromAccountsList().size()); + Assert.assertTrue(delegatedResourceAccountIndexCapsuleReceiver.getFromAccountsList() + .contains(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)))); + } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); @@ -790,5 +866,13 @@ public void testFreezeBalanceForTronPowerWithOldTronPowerAfterNewResourceModel() } } + private WorldStateQueryInstance getQueryInstance() { + Assert.assertNotNull(worldStateCallBack.getTrie()); + worldStateCallBack.clear(); + worldStateCallBack.getTrie().commit(); + worldStateCallBack.getTrie().flush(); + return new WorldStateQueryInstance(worldStateCallBack.getTrie().getRootHashByte32(), + chainBaseManager); + } } diff --git a/framework/src/test/java/org/tron/core/actuator/FreezeBalanceV2ActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/FreezeBalanceV2ActuatorTest.java index 082338df753..9fb6833ccd1 100644 --- a/framework/src/test/java/org/tron/core/actuator/FreezeBalanceV2ActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/FreezeBalanceV2ActuatorTest.java @@ -6,6 +6,8 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; import lombok.extern.slf4j.Slf4j; +import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -20,6 +22,8 @@ import org.tron.core.config.args.Args; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; +import org.tron.core.state.WorldStateCallBack; +import org.tron.core.state.WorldStateQueryInstance; import org.tron.protos.Protocol.AccountType; import org.tron.protos.Protocol.Transaction.Result.code; import org.tron.protos.contract.AssetIssueContractOuterClass; @@ -34,6 +38,10 @@ public class FreezeBalanceV2ActuatorTest extends BaseTest { private static final String OWNER_ADDRESS_INVALID = "aaaa"; private static final String OWNER_ACCOUNT_INVALID; private static final long initBalance = 10_000_000_000L; + private static Manager dbManager; + private static TronApplicationContext context; + private static final WorldStateCallBack worldStateCallBack; + private static final ChainBaseManager chainBaseManager; static { dbPath = "output_freeze_balance_v2_test"; @@ -42,6 +50,9 @@ public class FreezeBalanceV2ActuatorTest extends BaseTest { RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; + worldStateCallBack = context.getBean(WorldStateCallBack.class); + chainBaseManager = context.getBean(ChainBaseManager.class); + Assert.assertNotNull(worldStateCallBack.getTrie()); } /** @@ -49,6 +60,7 @@ public class FreezeBalanceV2ActuatorTest extends BaseTest { */ @Before public void createAccountCapsule() { + worldStateCallBack.setExecute(true); dbManager.getDynamicPropertiesStore().saveUnfreezeDelayDays(1L); dbManager.getDynamicPropertiesStore().saveAllowNewResourceModel(1L); @@ -69,6 +81,11 @@ public void createAccountCapsule() { dbManager.getAccountStore().put(receiverCapsule.getAddress().toByteArray(), receiverCapsule); } + @After + public void reset() { + worldStateCallBack.setExecute(false); + } + private Any getContractV2ForBandwidth(String ownerAddress, long frozenBalance) { return Any.pack( BalanceContract.FreezeBalanceV2Contract.newBuilder() @@ -137,6 +154,12 @@ public void testFreezeBalanceForBandwidth() { - TRANSFER_FEE); Assert.assertEquals(owner.getFrozenV2BalanceForBandwidth(), frozenBalance); Assert.assertEquals(frozenBalance, owner.getTronPower()); + WorldStateQueryInstance queryInstance = getQueryInstance(); + owner = queryInstance.getAccount(ByteArray.fromHexString(OWNER_ADDRESS)); + Assert.assertEquals(owner.getBalance(), initBalance - frozenBalance - TRANSFER_FEE); + Assert.assertEquals(owner.getFrozenV2BalanceForBandwidth(), frozenBalance); + Assert.assertEquals(frozenBalance, owner.getTronPower()); + } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -164,6 +187,12 @@ public void testFreezeBalanceForEnergy() { Assert.assertEquals(0L, owner.getAllFrozenBalanceForBandwidth()); Assert.assertEquals(frozenBalance, owner.getAllFrozenBalanceForEnergy()); Assert.assertEquals(frozenBalance, owner.getTronPower()); + WorldStateQueryInstance queryInstance = getQueryInstance(); + owner = queryInstance.getAccount(ByteArray.fromHexString(OWNER_ADDRESS)); + Assert.assertEquals(owner.getBalance(), initBalance - frozenBalance - TRANSFER_FEE); + Assert.assertEquals(0L, owner.getAllFrozenBalanceForBandwidth()); + Assert.assertEquals(frozenBalance, owner.getAllFrozenBalanceForEnergy()); + Assert.assertEquals(frozenBalance, owner.getTronPower()); } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -383,6 +412,11 @@ public void testFreezeBalanceForEnergyWithOldTronPowerAfterNewResourceModel() { Assert.assertEquals(100L, owner.getInstance().getOldTronPower()); Assert.assertEquals(100L, owner.getAllTronPower()); + WorldStateQueryInstance queryInstance = getQueryInstance(); + owner = queryInstance.getAccount(ByteArray.fromHexString(OWNER_ADDRESS)); + Assert.assertEquals(100L, owner.getInstance().getOldTronPower()); + Assert.assertEquals(100L, owner.getAllTronPower()); + } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -416,6 +450,13 @@ public void testFreezeBalanceForTronPowerWithOldTronPowerAfterNewResourceModel() Assert.assertEquals(100L, owner.getInstance().getOldTronPower()); Assert.assertEquals(100L, owner.getTronPower()); Assert.assertEquals(frozenBalance + 100, owner.getAllTronPower()); + + WorldStateQueryInstance queryInstance = getQueryInstance(); + owner = queryInstance.getAccount(ByteArray.fromHexString(OWNER_ADDRESS)); + + Assert.assertEquals(100L, owner.getInstance().getOldTronPower()); + Assert.assertEquals(100L, owner.getTronPower()); + Assert.assertEquals(frozenBalance + 100, owner.getAllTronPower()); } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -423,5 +464,14 @@ public void testFreezeBalanceForTronPowerWithOldTronPowerAfterNewResourceModel() } } + private WorldStateQueryInstance getQueryInstance() { + worldStateCallBack.clear(); + worldStateCallBack.getTrie().commit(); + worldStateCallBack.getTrie().flush(); + return new WorldStateQueryInstance( + worldStateCallBack.getTrie().getRootHashByte32(), + chainBaseManager); + } + } diff --git a/framework/src/test/java/org/tron/core/actuator/TransferActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/TransferActuatorTest.java index 05aea41e7c7..3839b81a5cf 100644 --- a/framework/src/test/java/org/tron/core/actuator/TransferActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/TransferActuatorTest.java @@ -8,12 +8,16 @@ import java.util.Date; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.tron.common.BaseTest; import org.tron.common.runtime.TvmTestUtils; import org.tron.common.utils.ByteArray; +import org.tron.common.utils.FileUtil; +import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; @@ -24,6 +28,8 @@ import org.tron.core.exception.ContractValidateException; import org.tron.core.exception.ReceiptCheckErrException; import org.tron.core.exception.VMIllegalException; +import org.tron.core.state.WorldStateCallBack; +import org.tron.core.state.WorldStateQueryInstance; import org.tron.core.store.StoreFactory; import org.tron.core.vm.repository.RepositoryImpl; import org.tron.protos.Protocol.AccountType; @@ -44,6 +50,10 @@ public class TransferActuatorTest extends BaseTest { private static final String OWNER_ACCOUNT_INVALID; private static final String OWNER_NO_BALANCE; private static final String To_ACCOUNT_INVALID; + private static Manager dbManager; + private static TronApplicationContext context; + private static final WorldStateCallBack worldStateCallBack; + private static final ChainBaseManager chainBaseManager; static { dbPath = "output_transfer_test"; @@ -55,6 +65,8 @@ public class TransferActuatorTest extends BaseTest { OWNER_NO_BALANCE = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3433"; To_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3422"; + worldStateCallBack = context.getBean(WorldStateCallBack.class); + chainBaseManager = context.getBean(ChainBaseManager.class); } /** @@ -62,6 +74,7 @@ public class TransferActuatorTest extends BaseTest { */ @Before public void createCapsule() { + worldStateCallBack.setExecute(true); AccountCapsule ownerCapsule = new AccountCapsule( ByteString.copyFromUtf8("owner"), @@ -78,6 +91,11 @@ public void createCapsule() { dbManager.getAccountStore().put(toAccountCapsule.getAddress().toByteArray(), toAccountCapsule); } + @After + public void reset() { + worldStateCallBack.setExecute(false); + } + private Any getContract(long count, byte[] address) { long nowTime = new Date().getTime(); return Any.pack( @@ -122,6 +140,12 @@ public void rightTransfer() { Assert.assertEquals(owner.getBalance(), OWNER_BALANCE - AMOUNT - TRANSFER_FEE); Assert.assertEquals(toAccount.getBalance(), TO_BALANCE + AMOUNT); + + WorldStateQueryInstance queryInstance = getQueryInstance(); + Assert.assertEquals(owner.getBalance(), + queryInstance.getAccount(owner.createDbKey()).getBalance()); + Assert.assertEquals(toAccount.getBalance(), + queryInstance.getAccount(toAccount.createDbKey()).getBalance()); Assert.assertTrue(true); } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); @@ -148,6 +172,11 @@ public void perfectTransfer() { Assert.assertEquals(owner.getBalance(), 0); Assert.assertEquals(toAccount.getBalance(), TO_BALANCE + OWNER_BALANCE); + WorldStateQueryInstance queryInstance = getQueryInstance(); + Assert.assertEquals(owner.getBalance(), + queryInstance.getAccount(owner.createDbKey()).getBalance()); + Assert.assertEquals(toAccount.getBalance(), + queryInstance.getAccount(toAccount.createDbKey()).getBalance()); Assert.assertTrue(true); } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); @@ -515,4 +544,14 @@ public void transferToSmartContractAddress() } } + private WorldStateQueryInstance getQueryInstance() { + Assert.assertNotNull(worldStateCallBack.getTrie()); + worldStateCallBack.clear(); + worldStateCallBack.getTrie().commit(); + worldStateCallBack.getTrie().flush(); + return new WorldStateQueryInstance( + worldStateCallBack.getTrie().getRootHashByte32(), + chainBaseManager); + } + } diff --git a/framework/src/test/java/org/tron/core/actuator/TransferAssetActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/TransferAssetActuatorTest.java index 07bb8415068..88e987ef79f 100755 --- a/framework/src/test/java/org/tron/core/actuator/TransferAssetActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/TransferAssetActuatorTest.java @@ -22,12 +22,16 @@ import com.google.protobuf.ByteString; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.tron.common.BaseTest; import org.tron.common.runtime.TvmTestUtils; import org.tron.common.utils.ByteArray; +import org.tron.common.utils.FileUtil; +import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; @@ -39,6 +43,8 @@ import org.tron.core.exception.ContractValidateException; import org.tron.core.exception.ReceiptCheckErrException; import org.tron.core.exception.VMIllegalException; +import org.tron.core.state.WorldStateCallBack; +import org.tron.core.state.WorldStateQueryInstance; import org.tron.core.store.StoreFactory; import org.tron.core.vm.config.VMConfig; import org.tron.core.vm.repository.RepositoryImpl; @@ -70,6 +76,11 @@ public class TransferAssetActuatorTest extends BaseTest { private static final int VOTE_SCORE = 2; private static final String DESCRIPTION = "TRX"; private static final String URL = "https://tron.network"; + private static TronApplicationContext context; + private static Manager dbManager; + private static Any contract; + private static final WorldStateCallBack worldStateCallBack; + private static final ChainBaseManager chainBaseManager; static { dbPath = "output_transferasset_test"; @@ -81,6 +92,8 @@ public class TransferAssetActuatorTest extends BaseTest { + "B56446E617E924805E4D6CA021D341FEF6E21234"; ownerAsset_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049010"; + worldStateCallBack = context.getBean(WorldStateCallBack.class); + chainBaseManager = context.getBean(ChainBaseManager.class); } /** @@ -88,6 +101,7 @@ public class TransferAssetActuatorTest extends BaseTest { */ @Before public void createCapsule() { + worldStateCallBack.setExecute(true); AccountCapsule toAccountCapsule = new AccountCapsule( ByteString.copyFrom(ByteArray.fromHexString(TO_ADDRESS)), @@ -97,6 +111,11 @@ public void createCapsule() { } + @After + public void reset() { + worldStateCallBack.setExecute(false); + } + private boolean isNullOrZero(Long value) { if (null == value || value == 0) { return true; @@ -293,6 +312,21 @@ public void SameTokenNameCloseSuccessTransfer() { toAccount.getAssetV2MapForTest().get(String.valueOf(tokenIdNum)).longValue(), 100L); + WorldStateQueryInstance queryInstance = getQueryInstance(); + Assert.assertEquals(OWNER_ASSET_BALANCE - 100, + queryInstance.getAccount(owner.createDbKey()).getAssetV2MapForTest() + .get(String.valueOf(tokenIdNum)).longValue()); + Assert.assertEquals(100L, + queryInstance.getAccount(toAccount.createDbKey()).getAssetV2MapForTest() + .get(String.valueOf(tokenIdNum)).longValue()); + + Assert.assertEquals(OWNER_ASSET_BALANCE - 100, + queryInstance.getAccount(owner.createDbKey()).getAssetV2( + String.valueOf(tokenIdNum))); + Assert.assertEquals(100L, + queryInstance.getAccount(toAccount.createDbKey()).getAssetV2( + String.valueOf(tokenIdNum))); + } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -330,6 +364,21 @@ public void SameTokenNameOpenSuccessTransfer() { toAccount.getInstance().getAssetV2Map().get(String.valueOf(tokenIdNum)).longValue(), 100L); + WorldStateQueryInstance queryInstance = getQueryInstance(); + Assert.assertEquals(OWNER_ASSET_BALANCE - 100, + queryInstance.getAccount(owner.createDbKey()).getAssetV2MapForTest() + .get(String.valueOf(tokenIdNum)).longValue()); + Assert.assertEquals(100L, + queryInstance.getAccount(toAccount.createDbKey()).getAssetV2MapForTest() + .get(String.valueOf(tokenIdNum)).longValue()); + + Assert.assertEquals(OWNER_ASSET_BALANCE - 100, + queryInstance.getAccount(owner.createDbKey()).getAssetV2( + String.valueOf(tokenIdNum))); + Assert.assertEquals(100L, + queryInstance.getAccount(toAccount.createDbKey()).getAssetV2( + String.valueOf(tokenIdNum))); + } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -367,6 +416,22 @@ public void SameTokenNameCloseSuccessTransfer2() { Assert.assertEquals( toAccount.getAssetV2MapForTest().get(String.valueOf(tokenIdNum)).longValue(), OWNER_ASSET_BALANCE); + + WorldStateQueryInstance queryInstance = getQueryInstance(); + Assert.assertEquals(0L, + queryInstance.getAccount(owner.createDbKey()).getAssetV2MapForTest() + .get(String.valueOf(tokenIdNum)).longValue()); + Assert.assertEquals(OWNER_ASSET_BALANCE, + queryInstance.getAccount(toAccount.createDbKey()).getAssetV2MapForTest() + .get(String.valueOf(tokenIdNum)).longValue()); + + Assert.assertEquals(0L, + queryInstance.getAccount(owner.createDbKey()).getAssetV2( + String.valueOf(tokenIdNum))); + Assert.assertEquals(OWNER_ASSET_BALANCE, + queryInstance.getAccount(toAccount.createDbKey()).getAssetV2( + String.valueOf(tokenIdNum))); + } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -406,6 +471,21 @@ public void OldNotUpdateSuccessTransfer2() { Assert.assertEquals( toAccount.getAssetV2MapForTest().get(String.valueOf(tokenIdNum)).longValue(), OWNER_ASSET_BALANCE); + WorldStateQueryInstance queryInstance = getQueryInstance(); + Assert.assertEquals(0L, + queryInstance.getAccount(owner.createDbKey()).getAssetV2MapForTest() + .get(String.valueOf(tokenIdNum)).longValue()); + Assert.assertEquals(OWNER_ASSET_BALANCE, + queryInstance.getAccount(toAccount.createDbKey()).getAssetV2MapForTest() + .get(String.valueOf(tokenIdNum)).longValue()); + + Assert.assertEquals(0L, + queryInstance.getAccount(owner.createDbKey()).getAssetV2( + String.valueOf(tokenIdNum))); + Assert.assertEquals(OWNER_ASSET_BALANCE, + queryInstance.getAccount(toAccount.createDbKey()).getAssetV2( + String.valueOf(tokenIdNum))); + } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -442,6 +522,20 @@ public void SameTokenNameOpenSuccessTransfer2() { Assert.assertEquals( toAccount.getAssetV2MapForTest().get(String.valueOf(tokenIdNum)).longValue(), OWNER_ASSET_BALANCE); + WorldStateQueryInstance queryInstance = getQueryInstance(); + Assert.assertEquals(0L, + queryInstance.getAccount(owner.createDbKey()).getAssetV2MapForTest() + .get(String.valueOf(tokenIdNum)).longValue()); + Assert.assertEquals(OWNER_ASSET_BALANCE, + queryInstance.getAccount(toAccount.createDbKey()).getAssetV2MapForTest() + .get(String.valueOf(tokenIdNum)).longValue()); + + Assert.assertEquals(0L, + queryInstance.getAccount(owner.createDbKey()).getAssetV2( + String.valueOf(tokenIdNum))); + Assert.assertEquals(OWNER_ASSET_BALANCE, + queryInstance.getAccount(toAccount.createDbKey()).getAssetV2( + String.valueOf(tokenIdNum))); } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -1432,10 +1526,34 @@ public void transferToContractAddress() Assert.assertEquals( toAccount.getInstance().getAssetV2Map().get(String.valueOf(tokenIdNum)).longValue(), 100L); + WorldStateQueryInstance queryInstance = getQueryInstance(); + Assert.assertEquals(OWNER_ASSET_BALANCE - 100, + queryInstance.getAccount(owner.createDbKey()).getAssetV2MapForTest() + .get(String.valueOf(tokenIdNum)).longValue()); + Assert.assertEquals(100L, + queryInstance.getAccount(toAccount.createDbKey()).getAssetV2MapForTest() + .get(String.valueOf(tokenIdNum)).longValue()); + + Assert.assertEquals(OWNER_ASSET_BALANCE - 100, + queryInstance.getAccount(owner.createDbKey()).getAssetV2( + String.valueOf(tokenIdNum))); + Assert.assertEquals(100L, + queryInstance.getAccount(toAccount.createDbKey()).getAssetV2( + String.valueOf(tokenIdNum))); } catch (ContractValidateException e) { Assert.assertTrue(e.getMessage().contains("Cannot transfer")); } catch (ContractExeException e) { Assert.assertFalse(e instanceof ContractExeException); } } + + + private WorldStateQueryInstance getQueryInstance() { + Assert.assertNotNull(worldStateCallBack.getTrie()); + worldStateCallBack.clear(); + worldStateCallBack.getTrie().commit(); + worldStateCallBack.getTrie().flush(); + return new WorldStateQueryInstance(worldStateCallBack.getTrie().getRootHashByte32(), + chainBaseManager); + } } diff --git a/framework/src/test/java/org/tron/core/actuator/UnfreezeAssetActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UnfreezeAssetActuatorTest.java index 0a624faf113..b943f325040 100644 --- a/framework/src/test/java/org/tron/core/actuator/UnfreezeAssetActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UnfreezeAssetActuatorTest.java @@ -3,12 +3,15 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; import lombok.extern.slf4j.Slf4j; +import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.tron.common.BaseTest; import org.tron.common.utils.ByteArray; import org.tron.common.utils.StringUtil; +import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; @@ -17,6 +20,8 @@ import org.tron.core.config.args.Args; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; +import org.tron.core.state.WorldStateCallBack; +import org.tron.core.state.WorldStateQueryInstance; import org.tron.protos.Protocol.Account; import org.tron.protos.Protocol.Account.Frozen; import org.tron.protos.Protocol.AccountType; @@ -34,6 +39,11 @@ public class UnfreezeAssetActuatorTest extends BaseTest { private static final long initBalance = 10_000_000_000L; private static final long frozenBalance = 1_000_000_000L; private static final String assetName = "testCoin"; + private static final String assetID = "123456"; + private static Manager dbManager; + private static TronApplicationContext context; + private static final WorldStateCallBack worldStateCallBack; + private static final ChainBaseManager chainBaseManager; static { dbPath = "output_unfreeze_asset_test"; @@ -41,6 +51,8 @@ public class UnfreezeAssetActuatorTest extends BaseTest { OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; + worldStateCallBack = context.getBean(WorldStateCallBack.class); + chainBaseManager = context.getBean(ChainBaseManager.class); } /** @@ -48,12 +60,18 @@ public class UnfreezeAssetActuatorTest extends BaseTest { */ @Before public void createAccountCapsule() { + worldStateCallBack.setExecute(true); } @Before public void createAsset() { } + @After + public void reset() { + worldStateCallBack.setExecute(false); + } + private Any getContract(String ownerAddress) { return Any.pack( UnfreezeAssetContract.newBuilder() @@ -243,7 +261,13 @@ public void SameTokenNameActiveInitAndAcitveUnfreezeAsset() { //V2 Assert.assertEquals(owner.getAssetV2MapForTest().get(String.valueOf(tokenId)).longValue(), frozenBalance); + WorldStateQueryInstance queryInstance = getQueryInstance(); + Assert.assertEquals(frozenBalance, + queryInstance.getAccount(owner.createDbKey()).getAssetV2MapForTest() + .get(String.valueOf(tokenId)).longValue()); Assert.assertEquals(owner.getFrozenSupplyCount(), 1); + Assert.assertEquals(1, + queryInstance.getAccount(owner.createDbKey()).getFrozenSupplyCount()); } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -399,4 +423,13 @@ public void commonErrorCheck() { actuatorTest.setNullDBManagerMsg("No account store or dynamic store!"); actuatorTest.nullDBManger(); } + + private WorldStateQueryInstance getQueryInstance() { + Assert.assertNotNull(worldStateCallBack.getTrie()); + worldStateCallBack.clear(); + worldStateCallBack.getTrie().commit(); + worldStateCallBack.getTrie().flush(); + return new WorldStateQueryInstance(worldStateCallBack.getTrie().getRootHashByte32(), + chainBaseManager); + } } \ No newline at end of file diff --git a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java index 3f9b999228c..1d0bc192aa8 100644 --- a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java @@ -7,11 +7,15 @@ import java.util.ArrayList; import java.util.List; import lombok.extern.slf4j.Slf4j; +import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.tron.common.BaseTest; import org.tron.common.utils.ByteArray; +import org.tron.common.utils.FileUtil; +import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; @@ -22,6 +26,9 @@ import org.tron.core.config.args.Args; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; +import org.tron.core.state.WorldStateCallBack; +import org.tron.core.state.WorldStateQueryInstance; +import org.tron.core.state.store.DynamicPropertiesStateStore; import org.tron.protos.Protocol.AccountType; import org.tron.protos.Protocol.Transaction.Result.code; import org.tron.protos.Protocol.Vote; @@ -38,6 +45,11 @@ public class UnfreezeBalanceActuatorTest extends BaseTest { private static final String OWNER_ACCOUNT_INVALID; private static final long initBalance = 10_000_000_000L; private static final long frozenBalance = 1_000_000_000L; + private static final long smallTatalResource = 100L; + private static Manager dbManager; + private static TronApplicationContext context; + private static final WorldStateCallBack worldStateCallBack; + private static final ChainBaseManager chainBaseManager; static { dbPath = "output_unfreeze_balance_test"; @@ -46,6 +58,8 @@ public class UnfreezeBalanceActuatorTest extends BaseTest { RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; + worldStateCallBack = context.getBean(WorldStateCallBack.class); + chainBaseManager = context.getBean(ChainBaseManager.class); } /** @@ -53,6 +67,7 @@ public class UnfreezeBalanceActuatorTest extends BaseTest { */ @Before public void createAccountCapsule() { + worldStateCallBack.setExecute(true); AccountCapsule ownerCapsule = new AccountCapsule(ByteString.copyFromUtf8("owner"), ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), AccountType.Normal, initBalance); @@ -64,6 +79,11 @@ public void createAccountCapsule() { dbManager.getAccountStore().put(receiverCapsule.getAddress().toByteArray(), receiverCapsule); } + @After + public void reset() { + worldStateCallBack.setExecute(false); + } + private Any getContractForBandwidth(String ownerAddress) { return Any.pack(UnfreezeBalanceContract.newBuilder() .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(ownerAddress))).build()); @@ -131,11 +151,24 @@ public void testUnfreezeBalanceForBandwidth() { Assert.assertEquals(owner.getBalance(), initBalance + frozenBalance); Assert.assertEquals(owner.getFrozenBalance(), 0); Assert.assertEquals(owner.getTronPower(), 0L); + WorldStateQueryInstance queryInstance = getQueryInstance(); + Assert.assertEquals(owner.getBalance(), + queryInstance.getAccount(owner.createDbKey()).getBalance()); + Assert.assertEquals(owner.getFrozenBalance(), + queryInstance.getAccount(owner.createDbKey()).getFrozenBalance()); + Assert.assertEquals(owner.getTronPower(), + queryInstance.getAccount(owner.createDbKey()).getTronPower()); + long totalNetWeightAfter = dbManager.getDynamicPropertiesStore().getTotalNetWeight(); Assert.assertEquals(totalNetWeightBefore, totalNetWeightAfter + frozenBalance / 1000_000L); + DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(); + stateStore.init(queryInstance); + Assert.assertEquals(totalNetWeightBefore, + stateStore.getTotalNetWeight() + frozenBalance / 1000_000L); + } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -203,6 +236,10 @@ public void testUnfreezeSelfAndOthersForBandwidth() { actuator1.validate(); actuator1.execute(ret1); long afterWeight1 = dbManager.getDynamicPropertiesStore().getTotalNetWeight(); + WorldStateQueryInstance queryInstance = getQueryInstance(); + DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(); + stateStore.init(queryInstance); + Assert.assertEquals(1, stateStore.getTotalNetWeight()); Assert.assertEquals(1, afterWeight1); Assert.assertEquals(ret1.getInstance().getRet(), code.SUCESS); } catch (ContractValidateException e) { @@ -221,6 +258,10 @@ public void testUnfreezeSelfAndOthersForBandwidth() { actuator.validate(); actuator.execute(ret); long afterWeight = dbManager.getDynamicPropertiesStore().getTotalNetWeight(); + WorldStateQueryInstance queryInstance = getQueryInstance(); + DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(); + stateStore.init(queryInstance); + Assert.assertEquals(0, stateStore.getTotalNetWeight()); Assert.assertEquals(0, afterWeight); Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); } catch (ContractValidateException e) { @@ -336,6 +377,17 @@ public void testUnfreezeDelegatedBalanceForBandwidth() { Assert.assertEquals(0L, ownerResult.getTronPower()); Assert.assertEquals(0L, ownerResult.getDelegatedFrozenBalanceForBandwidth()); Assert.assertEquals(0L, receiverResult.getAllFrozenBalanceForBandwidth()); + WorldStateQueryInstance queryInstance = getQueryInstance(); + Assert.assertEquals(initBalance + frozenBalance, queryInstance + .getAccount(ByteArray.fromHexString(OWNER_ADDRESS)).getBalance()); + Assert.assertEquals(0L, queryInstance + .getAccount(ByteArray.fromHexString(OWNER_ADDRESS)).getTronPower()); + Assert.assertEquals(0L, queryInstance + .getAccount(ByteArray.fromHexString(OWNER_ADDRESS)) + .getDelegatedFrozenBalanceForBandwidth()); + Assert.assertEquals(0L, queryInstance + .getAccount(ByteArray.fromHexString(RECEIVER_ADDRESS)) + .getAllFrozenBalanceForBandwidth()); //check DelegatedResourceAccountIndex DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsuleOwner = dbManager @@ -352,6 +404,20 @@ public void testUnfreezeDelegatedBalanceForBandwidth() { Assert.assertEquals(0, delegatedResourceAccountIndexCapsuleReceiver.getFromAccountsList().size()); + delegatedResourceAccountIndexCapsuleOwner = queryInstance + .getDelegatedResourceAccountIndex(ByteArray.fromHexString(OWNER_ADDRESS)); + Assert.assertEquals(0, + delegatedResourceAccountIndexCapsuleOwner.getFromAccountsList().size()); + Assert.assertEquals(0, + delegatedResourceAccountIndexCapsuleOwner.getToAccountsList().size()); + + delegatedResourceAccountIndexCapsuleReceiver = queryInstance + .getDelegatedResourceAccountIndex(ByteArray.fromHexString(RECEIVER_ADDRESS)); + Assert.assertEquals(0, + delegatedResourceAccountIndexCapsuleReceiver.getToAccountsList().size()); + Assert.assertEquals(0, + delegatedResourceAccountIndexCapsuleReceiver.getFromAccountsList().size()); + } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -1208,5 +1274,14 @@ public void testUnfreezeBalanceForTronPowerWithOldTronPowerAfterNewResourceModel } } + private WorldStateQueryInstance getQueryInstance() { + Assert.assertNotNull(worldStateCallBack.getTrie()); + worldStateCallBack.clear(); + worldStateCallBack.getTrie().commit(); + worldStateCallBack.getTrie().flush(); + return new WorldStateQueryInstance(worldStateCallBack.getTrie().getRootHashByte32(), + chainBaseManager); + } + } diff --git a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceV2ActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceV2ActuatorTest.java index 14a6de98606..57f99d8be1f 100644 --- a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceV2ActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceV2ActuatorTest.java @@ -7,11 +7,15 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; import lombok.extern.slf4j.Slf4j; +import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.tron.common.BaseTest; import org.tron.common.utils.ByteArray; +import org.tron.common.utils.FileUtil; +import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; @@ -20,6 +24,9 @@ import org.tron.core.config.args.Args; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; +import org.tron.core.state.WorldStateCallBack; +import org.tron.core.state.WorldStateQueryInstance; +import org.tron.core.state.store.DynamicPropertiesStateStore; import org.tron.protos.Protocol.AccountType; import org.tron.protos.Protocol.Transaction.Result.code; import org.tron.protos.Protocol.Vote; @@ -36,6 +43,10 @@ public class UnfreezeBalanceV2ActuatorTest extends BaseTest { private static final String OWNER_ACCOUNT_INVALID; private static final long initBalance = 10_000_000_000L; private static final long frozenBalance = 1_000_000_000L; + private static Manager dbManager; + private static final TronApplicationContext context; + private static final WorldStateCallBack worldStateCallBack; + private static final ChainBaseManager chainBaseManager; static { dbPath = "output_unfreeze_balance_v2_test"; @@ -44,6 +55,8 @@ public class UnfreezeBalanceV2ActuatorTest extends BaseTest { RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; + worldStateCallBack = context.getBean(WorldStateCallBack.class); + chainBaseManager = context.getBean(ChainBaseManager.class); } /** @@ -51,6 +64,7 @@ public class UnfreezeBalanceV2ActuatorTest extends BaseTest { */ @Before public void createAccountCapsule() { + worldStateCallBack.setExecute(true); dbManager.getDynamicPropertiesStore().saveUnfreezeDelayDays(1L); dbManager.getDynamicPropertiesStore().saveAllowNewResourceModel(1L); @@ -65,6 +79,11 @@ public void createAccountCapsule() { dbManager.getAccountStore().put(receiverCapsule.getAddress().toByteArray(), receiverCapsule); } + @After + public void reset() { + worldStateCallBack.setExecute(false); + } + private Any getContractForBandwidthV2(String ownerAddress, long unfreezeBalance) { return Any.pack( BalanceContract.UnfreezeBalanceV2Contract.newBuilder() @@ -156,9 +175,18 @@ public void testUnfreezeBalanceForBandwidth() { Assert.assertEquals(100, owner.getFrozenV2BalanceForBandwidth()); Assert.assertEquals(100L, owner.getTronPower()); + WorldStateQueryInstance queryInstance = getQueryInstance(); + owner = queryInstance.getAccount(ByteArray.fromHexString(OWNER_ADDRESS)); + Assert.assertEquals(100, owner.getFrozenV2BalanceForBandwidth()); + Assert.assertEquals(100L, owner.getTronPower()); + long totalNetWeightAfter = dbManager.getDynamicPropertiesStore().getTotalNetWeight(); Assert.assertEquals(totalNetWeightBefore - 1000, totalNetWeightAfter); + DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(); + stateStore.init(queryInstance); + Assert.assertEquals(totalNetWeightAfter, stateStore.getTotalNetWeight()); + } catch (Exception e) { Assert.assertFalse(e instanceof ContractValidateException); Assert.assertFalse(e instanceof ContractExeException); @@ -196,8 +224,19 @@ public void testUnfreezeBalanceForEnergy() { //Assert.assertEquals(owner.getBalance(), initBalance + frozenBalance); Assert.assertEquals(100, owner.getAllFrozenBalanceForEnergy()); Assert.assertEquals(100, owner.getTronPower()); + + WorldStateQueryInstance queryInstance = getQueryInstance(); + owner = queryInstance.getAccount(ByteArray.fromHexString(OWNER_ADDRESS)); + Assert.assertEquals(100, owner.getAllFrozenBalanceForEnergy()); + Assert.assertEquals(100, owner.getTronPower()); + long totalEnergyWeightAfter = dbManager.getDynamicPropertiesStore().getTotalEnergyWeight(); Assert.assertEquals(totalEnergyWeightBefore - 1000, totalEnergyWeightAfter); + + DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(); + stateStore.init(queryInstance); + Assert.assertEquals(totalEnergyWeightAfter, stateStore.getTotalEnergyWeight()); + } catch (Exception e) { Assert.assertFalse(e instanceof ContractValidateException); Assert.assertFalse(e instanceof ContractExeException); @@ -315,6 +354,20 @@ public void testVotes() { for (Vote vote : accountCapsule.getVotesList()) { Assert.assertEquals(vote.getVoteCount(), 250); } + WorldStateQueryInstance queryInstance = getQueryInstance(); + votesCapsule = queryInstance.getVotes(ownerAddressBytes); + Assert.assertNotNull(votesCapsule); + for (Vote vote : votesCapsule.getOldVotes()) { + Assert.assertEquals(vote.getVoteCount(), 500); + } + for (Vote vote : votesCapsule.getNewVotes()) { + Assert.assertEquals(vote.getVoteCount(), 250); + } + accountCapsule = queryInstance.getAccount(ownerAddressBytes); + for (Vote vote : accountCapsule.getVotesList()) { + Assert.assertEquals(vote.getVoteCount(), 250); + } + } catch (ContractValidateException | ContractExeException e) { Assert.fail("cannot run here."); } @@ -334,6 +387,17 @@ public void testVotes() { Assert.assertEquals(0, votesCapsule.getNewVotes().size()); accountCapsule = dbManager.getAccountStore().get(ownerAddressBytes); Assert.assertEquals(0, accountCapsule.getVotesList().size()); + + WorldStateQueryInstance queryInstance = getQueryInstance(); + votesCapsule = queryInstance.getVotes(ownerAddressBytes); + Assert.assertNotNull(votesCapsule); + for (Vote vote : votesCapsule.getOldVotes()) { + Assert.assertEquals(vote.getVoteCount(), 500); + } + Assert.assertEquals(0, votesCapsule.getNewVotes().size()); + accountCapsule = queryInstance.getAccount(ownerAddressBytes); + Assert.assertEquals(0, accountCapsule.getVotesList().size()); + } catch (ContractValidateException | ContractExeException e) { Assert.fail("cannot run here."); } @@ -403,6 +467,12 @@ public void testUnfreezeBalanceForEnergyWithOldTronPowerAfterNewResourceModel() Assert.assertEquals(owner.getVotesList().size(), 0L); Assert.assertEquals(owner.getInstance().getOldTronPower(), -1L); + + WorldStateQueryInstance queryInstance = getQueryInstance(); + owner = queryInstance.getAccount(ByteArray.fromHexString(OWNER_ADDRESS)); + Assert.assertEquals(owner.getVotesList().size(), 0L); + Assert.assertEquals(owner.getInstance().getOldTronPower(), -1L); + } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -440,6 +510,12 @@ public void testUnfreezeBalanceForEnergyWithoutOldTronPowerAfterNewResourceModel Assert.assertEquals(owner.getVotesList().size(), 1L); Assert.assertEquals(owner.getInstance().getOldTronPower(), -1L); + + WorldStateQueryInstance queryInstance = getQueryInstance(); + owner = queryInstance.getAccount(ByteArray.fromHexString(OWNER_ADDRESS)); + Assert.assertEquals(owner.getVotesList().size(), 1L); + Assert.assertEquals(owner.getInstance().getOldTronPower(), -1L); + } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -477,6 +553,11 @@ public void testUnfreezeBalanceForTronPowerWithOldTronPowerAfterNewResourceModel Assert.assertEquals(owner.getVotesList().size(), 0L); Assert.assertEquals(owner.getInstance().getOldTronPower(), -1L); + + WorldStateQueryInstance queryInstance = getQueryInstance(); + owner = queryInstance.getAccount(ByteArray.fromHexString(OWNER_ADDRESS)); + Assert.assertEquals(owner.getVotesList().size(), 0L); + Assert.assertEquals(owner.getInstance().getOldTronPower(), -1L); } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); } catch (ContractExeException e) { @@ -795,6 +876,15 @@ public void testUnfreezeBalanceUnfreezeCount() { } + private WorldStateQueryInstance getQueryInstance() { + Assert.assertNotNull(worldStateCallBack.getTrie()); + worldStateCallBack.clear(); + worldStateCallBack.getTrie().commit(); + worldStateCallBack.getTrie().flush(); + return new WorldStateQueryInstance(worldStateCallBack.getTrie().getRootHashByte32(), + chainBaseManager); + } + } diff --git a/framework/src/test/java/org/tron/core/db2/RevokingDbWithCacheNewValueTest.java b/framework/src/test/java/org/tron/core/db2/RevokingDbWithCacheNewValueTest.java index 2290df86978..de4b79e07e6 100644 --- a/framework/src/test/java/org/tron/core/db2/RevokingDbWithCacheNewValueTest.java +++ b/framework/src/test/java/org/tron/core/db2/RevokingDbWithCacheNewValueTest.java @@ -26,6 +26,7 @@ import org.tron.core.db2.SnapshotRootTest.ProtoCapsuleTest; import org.tron.core.db2.core.SnapshotManager; import org.tron.core.exception.RevokingStoreIllegalStateException; +import org.tron.core.state.WorldStateCallBack; @Slf4j public class RevokingDbWithCacheNewValueTest { @@ -472,6 +473,7 @@ public static class TestRevokingTronStore extends TronStoreWithRevoking blockCapsules = chainBaseManager + .getBlockStore().getBlockByLatestNum(1); + BlockCapsule blockCapsule = blockCapsules.get(0); + try { + manager.pushBlock(buildTransferBlock(blockCapsule)); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + Thread.sleep(3000); + blockCapsules = chainBaseManager.getBlockStore().getBlockByLatestNum(1); + blockCapsule = blockCapsules.get(0); + Bytes32 rootHash = blockCapsule.getArchiveRoot(); + WorldStateQueryInstance worldStateQueryInstance = ChainBaseManager.fetch(rootHash); + checkAccount(worldStateQueryInstance); + + try { + manager.pushBlock(buildTransferBlock(blockCapsule)); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + Thread.sleep(3000); + + blockCapsules = chainBaseManager.getBlockStore().getBlockByLatestNum(1); + blockCapsule = blockCapsules.get(0); + rootHash = blockCapsule.getArchiveRoot(); + worldStateQueryInstance = ChainBaseManager.fetch(rootHash); + checkAccount(worldStateQueryInstance); + } + + @Test + public void testContract() throws InterruptedException { + manager.initGenesis(); + List blockCapsules = chainBaseManager + .getBlockStore().getBlockByLatestNum(1); + BlockCapsule blockCapsule = blockCapsules.get(0); + try { + manager.pushBlock(buildContractBlock(blockCapsule)); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + Thread.sleep(3000); + blockCapsules = chainBaseManager.getBlockStore().getBlockByLatestNum(1); + blockCapsule = blockCapsules.get(0); + Bytes32 rootHash = blockCapsule.getArchiveRoot(); + WorldStateQueryInstance worldStateQueryInstance = ChainBaseManager.fetch(rootHash); + Assert.assertArrayEquals(chainBaseManager.getContractStore().get(contractAddress).getData(), + worldStateQueryInstance.getContract(contractAddress).getData()); + checkAccount(worldStateQueryInstance); + + try { + manager.pushBlock(buildTriggerBlock(blockCapsule)); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + Thread.sleep(3000); + + blockCapsules = chainBaseManager.getBlockStore().getBlockByLatestNum(1); + blockCapsule = blockCapsules.get(0); + rootHash = blockCapsule.getArchiveRoot(); + worldStateQueryInstance = ChainBaseManager.fetch(rootHash); + ContractCapsule contractCapsule = worldStateQueryInstance.getContract(contractAddress); + + Storage storage = new Storage(contractAddress, worldStateQueryInstance); + storage.setContractVersion(contractCapsule.getInstance().getVersion()); + + DataWord value1 = storage.getValue(new DataWord(ByteArray.fromHexString("0"))); + + DataWord value2 = storage.getValue(new DataWord(ByteArray.fromHexString("0"))); + Assert.assertArrayEquals(value1.getData(), value2.getData()); + checkAccount(worldStateQueryInstance); + } + + private void checkAccount(WorldStateQueryInstance worldStateQueryInstance) { + AccountCapsule account1Capsule = chainBaseManager.getAccountStore() + .get(account1Prikey.getAddress()); + account1Capsule.clearAsset(); + AccountCapsule account2Capsule = chainBaseManager.getAccountStore() + .get(account2Prikey.getAddress()); + account2Capsule.clearAsset(); + Assert.assertArrayEquals(account1Capsule.getInstance().toByteArray(), + worldStateQueryInstance.getAccount(account1Prikey.getAddress()) + .getInstance().toByteArray()); + Assert.assertArrayEquals(account2Capsule.getInstance().toByteArray(), + worldStateQueryInstance.getAccount(account2Prikey.getAddress()) + .getInstance().toByteArray()); + } + + private BlockCapsule buildTransferBlock(BlockCapsule parentBlock) { + BalanceContract.TransferContract transferContract = BalanceContract + .TransferContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(account1Prikey.getAddress())) + .setToAddress(ByteString.copyFrom(account2Prikey.getAddress())) + .setAmount(1).build(); + + Protocol.Transaction.raw.Builder transactionBuilder = Protocol + .Transaction.raw.newBuilder().addContract( + Protocol.Transaction.Contract.newBuilder() + .setType(ContractType.TransferContract).setParameter( + Any.pack(transferContract)).build()); + Protocol.Transaction transaction = Protocol.Transaction.newBuilder() + .setRawData(transactionBuilder.build()).build(); + + TransactionCapsule transactionCapsule = setAndSignTx(transaction, parentBlock, account1Prikey); + + BlockCapsule blockCapsule = + new BlockCapsule( + parentBlock.getNum() + 1, + Sha256Hash.wrap(parentBlock.getBlockId().getByteString()), + System.currentTimeMillis(), + ByteString.copyFrom( + ECKey.fromPrivate( + org.tron.common.utils.ByteArray.fromHexString( + Args.getLocalWitnesses().getPrivateKey())) + .getAddress())); + blockCapsule.addTransaction(transactionCapsule); + blockCapsule.setMerkleRoot(); + blockCapsule.sign( + ByteArray.fromHexString(Args.getLocalWitnesses().getPrivateKey())); + return blockCapsule; + } + + private BlockCapsule buildContractBlock(BlockCapsule parentBlock) { + long value = 0L; + long feeLimit = 1_000_000_000L; + long consumeUserResourcePercent = 0L; + String contractName = "increment"; + String ABI = "[]"; + String code = "60806040526000805534801561001457600080fd5b50610181806100246000396000f3fe608060" + + "405234801561001057600080fd5b50600436106100415760003560e01c806342cbb15c146100465780636d4c" + + "e63c14610064578063d09de08a14610082575b600080fd5b61004e61008c565b60405161005b91906100cd56" + + "5b60405180910390f35b61006c610094565b60405161007991906100cd565b60405180910390f35b61008a61" + + "009d565b005b600043905090565b60008054905090565b60016000546100ac9190610117565b600081905550" + + "565b6000819050919050565b6100c7816100b4565b82525050565b60006020820190506100e2600083018461" + + "00be565b92915050565b7f4e487b710000000000000000000000000000000000000000000000000000000060" + + "0052601160045260246000fd5b6000610122826100b4565b915061012d836100b4565b925082820190508082" + + "1115610145576101446100e8565b5b9291505056fea26469706673582212207c5e242c88722ac1f7f5f1ea67" + + "0cf1a784cad42b058651ceaf6fe0fc10ebff8264736f6c63430008110033"; + String libraryAddressPair = null; + Protocol.Transaction transaction = TvmTestUtils.generateDeploySmartContractAndGetTransaction( + contractName, account1Prikey.getAddress(), ABI, code, value, feeLimit, + consumeUserResourcePercent, libraryAddressPair); + TransactionCapsule transactionCapsule = new TransactionCapsule(transaction); + transactionCapsule.setResultCode(Protocol.Transaction.Result.contractResult.SUCCESS); + + transactionCapsule = setAndSignTx(transactionCapsule.getInstance(), + parentBlock, account1Prikey); + + + BlockCapsule blockCapsule = + new BlockCapsule( + parentBlock.getNum() + 1, + Sha256Hash.wrap(parentBlock.getBlockId().getByteString()), + System.currentTimeMillis(), + ByteString.copyFrom( + ECKey.fromPrivate( + org.tron.common.utils.ByteArray.fromHexString( + Args.getLocalWitnesses().getPrivateKey())) + .getAddress())); + blockCapsule.addTransaction(transactionCapsule); + blockCapsule.setMerkleRoot(); + blockCapsule.sign( + ByteArray.fromHexString(Args.getLocalWitnesses().getPrivateKey())); + contractAddress = WalletUtil.generateContractAddress(transactionCapsule.getInstance()); + return blockCapsule; + } + + private BlockCapsule buildTriggerBlock(BlockCapsule parentBlock) { + long value = 0L; + long feeLimit = 1_000_000_000L; + byte[] triggerData = TvmTestUtils.parseAbi("increment()", null); + Protocol.Transaction transaction = TvmTestUtils.generateTriggerSmartContractAndGetTransaction( + account1Prikey.getAddress(), contractAddress, triggerData, value, feeLimit); + + TransactionCapsule transactionCapsule = new TransactionCapsule(transaction); + transactionCapsule.setResultCode(Protocol.Transaction.Result.contractResult.SUCCESS); + + transactionCapsule = setAndSignTx(transactionCapsule.getInstance(), + parentBlock, account1Prikey); + + BlockCapsule blockCapsule = + new BlockCapsule( + parentBlock.getNum() + 1, + Sha256Hash.wrap(parentBlock.getBlockId().getByteString()), + System.currentTimeMillis(), + ByteString.copyFrom( + ECKey.fromPrivate( + org.tron.common.utils.ByteArray.fromHexString( + Args.getLocalWitnesses().getPrivateKey())) + .getAddress())); + blockCapsule.addTransaction(transactionCapsule); + blockCapsule.setMerkleRoot(); + blockCapsule.sign( + ByteArray.fromHexString(Args.getLocalWitnesses().getPrivateKey())); + return blockCapsule; + } + + private TransactionCapsule setAndSignTx(Protocol.Transaction transaction, + BlockCapsule parentBlock, ECKey account) { + TransactionCapsule transactionCapsule = new TransactionCapsule(transaction); + transactionCapsule.setReference(parentBlock.getNum(), parentBlock.getBlockId().getBytes()); + transactionCapsule.setExpiration(parentBlock.getTimeStamp() + 60 * 60 * 1000); + return new TransactionCapsule(PublicMethod.signTransaction(account, + transactionCapsule.getInstance())); + } + +} diff --git a/framework/src/test/java/org/tron/core/tire/Trie2Test.java b/framework/src/test/java/org/tron/core/tire/Trie2Test.java new file mode 100644 index 00000000000..4398e7e2f4c --- /dev/null +++ b/framework/src/test/java/org/tron/core/tire/Trie2Test.java @@ -0,0 +1,543 @@ +/* + * Copyright (c) [2016] [ ] + * This file is part of the ethereumJ library. + * + * The ethereumJ library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ethereumJ library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the ethereumJ library. If not, see . + */ + +package org.tron.core.tire; + +import static org.tron.core.state.WorldStateCallBackUtils.fix32; +import static org.tron.core.state.WorldStateQueryInstance.ADDRESS_SIZE; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.TreeMap; +import java.util.stream.Collectors; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.apache.tuweni.units.bigints.UInt256; +import org.bouncycastle.util.Arrays; +import org.hyperledger.besu.ethereum.trie.BranchNode; +import org.hyperledger.besu.ethereum.trie.CompactEncoding; +import org.hyperledger.besu.ethereum.trie.LeafNode; +import org.hyperledger.besu.ethereum.trie.MerkleStorage; +import org.hyperledger.besu.storage.KeyValueStorage; +import org.hyperledger.besu.storage.RocksDBConfiguration; +import org.hyperledger.besu.storage.RocksDBConfigurationBuilder; +import org.hyperledger.besu.storage.RocksDBKeyValueStorage; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.tron.common.utils.ByteArray; +import org.tron.core.state.StateType; +import org.tron.core.state.trie.TrieImpl2; + +public class Trie2Test { + + @Rule + public final TemporaryFolder folder = new TemporaryFolder(); + + private static final Bytes c = Bytes.wrap("c".getBytes(StandardCharsets.UTF_8)); + private static final Bytes ca = Bytes.wrap("ca".getBytes(StandardCharsets.UTF_8)); + private static final Bytes cat = Bytes.wrap("cat".getBytes(StandardCharsets.UTF_8)); + private static final Bytes dog = Bytes.wrap("dog".getBytes(StandardCharsets.UTF_8)); + private static final Bytes doge = Bytes.wrap("doge".getBytes(StandardCharsets.UTF_8)); + private static final Bytes test = Bytes.wrap("test".getBytes(StandardCharsets.UTF_8)); + private static final Bytes dude = Bytes.wrap("dude".getBytes(StandardCharsets.UTF_8)); + + private KeyValueStorage createStore() { + try { + return new RocksDBKeyValueStorage(config()); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + private RocksDBConfiguration config() throws IOException { + return new RocksDBConfigurationBuilder().databaseDir(folder.newFolder().toPath()).build(); + } + + @Test + public void test() { + TrieImpl2 trie = new TrieImpl2(createStore()); + trie.put(Bytes.of(1), c); + Assert.assertEquals(trie.get(new byte[]{1}), c); + trie.put(Bytes.of(1, 0), ca); + String hash1 = ByteArray.toHexString(trie.getRootHash()); + trie.commit(); + trie.put(new byte[]{1, 1}, cat); + String hash2 = ByteArray.toHexString(trie.getRootHash()); + trie.commit(); + Assert.assertNotEquals(hash1, hash2); + trie.put(new byte[]{1, 2}, dog); + String hash3 = ByteArray.toHexString(trie.getRootHash()); + trie.commit(); + trie.put(Bytes.of(5), doge); + String hash4 = ByteArray.toHexString(trie.getRootHash()); + trie.commit(); + Assert.assertNotEquals(hash3, hash4); + trie.put(Bytes.of(6).toArrayUnsafe(), doge); + String hash5 = ByteArray.toHexString(trie.getRootHash()); + trie.commit(); + Assert.assertNotEquals(hash4, hash5); + trie.put(Bytes.of(7).toArrayUnsafe(), doge); + trie.put(Bytes.of(11), doge); + trie.put(Bytes.of(12).toArrayUnsafe(), dude); + trie.put(Bytes.of(13).toArrayUnsafe(), test); + String hash9 = ByteArray.toHexString(trie.getRootHash()); + trie.commit(); + Assert.assertEquals(trie.get(new byte[]{1, 0}), ca); + trie.delete(Bytes.of(13).toArrayUnsafe()); + String hash10 = ByteArray.toHexString(trie.getRootHash()); + trie.commit(); + Assert.assertNotEquals(hash9, hash10); + byte[] rootHash = trie.getRootHash(); + trie.flush(); + TrieImpl2 trieCopy = new TrieImpl2(trie.getMerkleStorage(), + Bytes32.wrap(ByteArray.fromHexString(hash3))); + Assert.assertNull(trieCopy.get(Bytes.of(5).toArrayUnsafe())); + Assert.assertEquals(trieCopy.get(new byte[]{1, 2}), dog); + trieCopy.put(Bytes.of(5).toArrayUnsafe(), doge); + trieCopy.put(new byte[]{1, 2}, cat); + trieCopy.commit(); + byte[] rootHash2 = trieCopy.getRootHash(); + Assert.assertFalse(Arrays.areEqual(rootHash, rootHash2)); + Assert.assertEquals(trieCopy.get(Bytes.of(5).toArrayUnsafe()), doge); + Assert.assertEquals(trieCopy.get(new byte[]{1, 2}), cat); + Assert.assertEquals(trie.get(new byte[]{1, 2}), dog); + } + + @Test + public void canReloadTrieFromHash() { + final Bytes key1 = Bytes.of(1, 5, 8, 9); + final Bytes key2 = Bytes.of(1, 6, 1, 2); + final Bytes key3 = Bytes.of(1, 6, 1, 3); + + TrieImpl2 trie = new TrieImpl2(createStore()); + + // Push some values into the trie and commit changes so nodes are persisted + final Bytes value1 = Bytes.of("value1".getBytes(StandardCharsets.UTF_8)); + trie.put(key1, value1); + final byte[] hash1 = trie.getRootHash(); + // put data into pendingUpdates + trie.commit(); + + final Bytes value2 = Bytes.wrap("value2".getBytes(StandardCharsets.UTF_8)); + trie.put(key2, value2); + final Bytes value3 = Bytes.wrap("value3".getBytes(StandardCharsets.UTF_8)); + trie.put(key3, value3); + final byte[] hash2 = trie.getRootHash(); + // put data into pendingUpdates + trie.commit(); + + final Bytes value4 = Bytes.wrap("value4".getBytes(StandardCharsets.UTF_8)); + trie.put(key1, value4); + trie.put(Bytes.of(1, 2, 3, 4, 5), UInt256.ZERO); + final byte[] hash3 = trie.getRootHash(); + // put data into pendingUpdates + trie.commit(); + + // Check the root hashes for 3 tries are all distinct + Assert.assertNotEquals(Bytes.of(hash1), Bytes.of(hash2)); + Assert.assertNotEquals(Bytes.of(hash1), Bytes.of(hash3)); + Assert.assertNotEquals(Bytes.of(hash2), Bytes.of(hash3)); + + // And that we can retrieve the last value we set for key1 + Assert.assertEquals(trie.get(key1), value4); + + // Create new tries from root hashes and check that we find expected values + trie = new TrieImpl2(trie.getMerkleStorage(), Bytes32.wrap(hash1)); + Assert.assertEquals(trie.get(key1), value1); + Assert.assertNull(trie.get(key2)); + Assert.assertNull(trie.get(key3)); + + trie = new TrieImpl2(trie.getMerkleStorage(), Bytes32.wrap(hash2)); + Assert.assertEquals(trie.get(key1), value1); + Assert.assertEquals(trie.get(key2), value2); + Assert.assertEquals(trie.get(key3), value3); + + trie = new TrieImpl2(trie.getMerkleStorage(), Bytes32.wrap(hash3)); + Assert.assertEquals(trie.get(key1), value4); + Assert.assertEquals(trie.get(key2), value2); + Assert.assertEquals(trie.get(key3), value3); + + // Commit changes to storage, and create new tries from roothash and new storage instance + trie.flush(); + final MerkleStorage newMerkleStorage = trie.getMerkleStorage(); + trie = new TrieImpl2(newMerkleStorage, Bytes32.wrap(hash1)); + Assert.assertEquals(trie.get(key1), value1); + Assert.assertNull(trie.get(key2)); + Assert.assertNull(trie.get(key3)); + + trie = new TrieImpl2(newMerkleStorage, Bytes32.wrap(hash2)); + Assert.assertEquals(trie.get(key1), value1); + Assert.assertEquals(trie.get(key2), value2); + Assert.assertEquals(trie.get(key3), value3); + + trie = new TrieImpl2(newMerkleStorage, Bytes32.wrap(hash3)); + Assert.assertEquals(trie.get(key1), value4); + Assert.assertEquals(trie.get(key2), value2); + Assert.assertEquals(trie.get(key3), value3); + Assert.assertEquals(trie.get(Bytes.of(1, 2, 3, 4, 5)), UInt256.ZERO); + final byte[] key4 = Bytes.of(1, 3, 4, 6, 7, 9).toArray(); + final byte[] key5 = Bytes.of(1, 3, 4, 6, 3, 9).toArray(); + final byte[] key6 = Bytes.of(1, 3, 4, 6, 8, 9).toArray(); + final Bytes key7 = Bytes.of(2); + final Bytes key8 = Bytes32.random(); + final byte[] key9 = Bytes.wrap(key8, key7).toArray(); + trie.put(key4, Bytes.of("value5".getBytes(StandardCharsets.UTF_8))); + trie.put(key5, Bytes.of("value6".getBytes(StandardCharsets.UTF_8))); + trie.put(key6, Bytes.of("value7".getBytes(StandardCharsets.UTF_8))); + trie.put(key5, Bytes.of("value8".getBytes(StandardCharsets.UTF_8))); + trie.put(key7, Bytes.of("value9".getBytes(StandardCharsets.UTF_8))); + trie.put(key8, Bytes.of("value10".getBytes(StandardCharsets.UTF_8))); + trie.put(key9, Bytes.of("value11".getBytes(StandardCharsets.UTF_8))); + Random r = new SecureRandom(); + List rl = new ArrayList<>(); + for (int i = 1; i <= 1000; i++) { + byte[] array = new byte[i % 256 + 8]; + r.nextBytes(array); + Bytes bytes = Bytes.wrap(array); + rl.add(bytes); + trie.put(bytes, Bytes32.random()); + } + rl.addAll(java.util.Arrays.asList(Bytes.wrap(key1), Bytes.of(1, 2, 3, 4, 5), + Bytes.wrap(key2), Bytes.wrap(key3), Bytes.wrap(key4), + Bytes.wrap(key5), + Bytes.wrap(key6), key7, key8, Bytes.wrap(key9))); + trie.commit(); + trie.flush(); + + List keys = new ArrayList<>(); + trie.visitAll((N) -> { + if (N instanceof BranchNode && N.getValue().isPresent()) { + Bytes k = CompactEncoding.pathToBytes( + Bytes.concatenate(N.getLocation().orElse(Bytes.EMPTY), + Bytes.of(CompactEncoding.LEAF_TERMINATOR))); + keys.add(k); + } + + if (N instanceof LeafNode) { + Bytes k = CompactEncoding.pathToBytes( + Bytes.concatenate(N.getLocation().orElse(Bytes.EMPTY), + N.getPath())); + keys.add(k); + } + }); + + Collections.sort(keys); + Collections.sort(rl); + rl = rl.stream().distinct().collect(Collectors.toList()); + Assert.assertEquals(trie.get(key7), + Bytes.of("value9".getBytes(StandardCharsets.UTF_8))); + Assert.assertEquals(keys.size(), rl.size()); + Assert.assertEquals(keys, rl); + } + + @Test + public void test1() { + TrieImpl2 trie = new TrieImpl2(); + int n = 100; + for (int i = 1; i < n; i++) { + trie.put(Bytes.of(i), Bytes.of(i)); + } + byte[] rootHash1 = trie.getRootHash(); + + TrieImpl2 trie2 = new TrieImpl2(); + for (int i = 1; i < n; i++) { + trie2.put(Bytes.of(i), Bytes.of(i)); + } + byte[] rootHash2 = trie2.getRootHash(); + Assert.assertArrayEquals(rootHash1, rootHash2); + } + + @Test + public void test2() { + TrieImpl2 trie = new TrieImpl2(); + int n = 100; + for (int i = 1; i < n; i++) { + trie.put(Bytes.of(i), Bytes.of(i)); + } + trie.commit(); + trie.flush(); + byte[] rootHash = trie.getRootHash(); + TrieImpl2 trieCopy = new TrieImpl2(trie.getMerkleStorage(), Bytes32.wrap(rootHash)); + for (int i = 1; i < n; i++) { + Assert.assertEquals(trieCopy.get(Bytes.of(i)), Bytes.of(i)); + } + for (int i = 1; i < n; i++) { + for (int j = 1; j < n; j++) { + if (i != j) { + Assert.assertNotEquals(trieCopy.get(Bytes.of(i)), trieCopy.get(Bytes.of(j))); + } + } + } + } + + @Test + public void testOrder() { + TrieImpl2 trie = new TrieImpl2(); + int n = 100; + List value = new ArrayList<>(); + for (int i = 1; i < n; i++) { + value.add(i); + trie.put(Bytes.of(i), Bytes.of(i)); + } + trie.put(Bytes.of(10), Bytes.of(10)); + value.add(10); + trie.commit(); + trie.flush(); + byte[] rootHash1 = trie.getRootHash(); + Collections.shuffle(value); + TrieImpl2 trie2 = new TrieImpl2(); + for (int i : value) { + trie2.put(Bytes.of(i), Bytes.of(i)); + } + trie2.commit(); + trie2.flush(); + byte[] rootHash2 = trie2.getRootHash(); + Assert.assertArrayEquals(rootHash1, rootHash2); + } + + @Test + public void testRange() { + TrieImpl2 trie = new TrieImpl2(); + + Bytes add1 = Bytes.fromHexString("41548794500882809695a8a687866e76d4271a1abc"); + Bytes add2 = Bytes.fromHexString("41548794500882809695a8a687866e76d4271a3456"); + Bytes add3 = Bytes.fromHexString("41548794500882809695a8a687866e76d4271a3433"); + Bytes add4 = Bytes.fromHexString("41548794500882809695a8a687866e76d4271a3422"); + + Bytes asset1 = Bytes.ofUnsignedLong(100001); + Bytes asset2 = Bytes.ofUnsignedLong(100002); + Bytes asset3 = Bytes.ofUnsignedLong(700001); + Bytes asset4 = Bytes.ofUnsignedLong(130001); + Bytes asset5 = Bytes.ofUnsignedLong(105001); + + trie.put(Bytes.wrap(Bytes.of(StateType.UNDEFINED.value()), Bytes32.random()), Bytes32.random()); + trie.put(Bytes.wrap(Bytes.of(StateType.UNDEFINED.value()), add2), Bytes32.random()); + trie.put(Bytes.wrap(Bytes.of(StateType.UNDEFINED.value()), Bytes32.random()), Bytes32.random()); + trie.put(Bytes.wrap(Bytes.of(StateType.UNDEFINED.value()), add4), Bytes32.random()); + + trie.put(Bytes.wrap(Bytes.of(StateType.Account.value()), Bytes32.random()), Bytes32.random()); + trie.put(Bytes.wrap(Bytes.of(StateType.Account.value()), add2), Bytes32.random()); + trie.put(Bytes.wrap(Bytes.of(StateType.Account.value()), Bytes32.random()), Bytes32.random()); + + trie.put(Bytes.wrap(Bytes.of(StateType.Code.value()), Bytes32.random()), Bytes32.random()); + trie.put(Bytes.wrap(Bytes.of(StateType.Code.value()), add3), Bytes32.random()); + trie.put(Bytes.wrap(Bytes.of(StateType.Code.value()), add4), Bytes32.random()); + + trie.put(fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), add1, asset1)), + Bytes.ofUnsignedLong(5)); + trie.put(fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), add1, asset2)), + Bytes.ofUnsignedLong(10)); + trie.put(fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), add1, asset3)), + Bytes.ofUnsignedLong(15)); + trie.put(fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), add1, asset4)), + Bytes.ofUnsignedLong(25)); + + trie.put(fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), add2, asset4)), + Bytes.ofUnsignedLong(5)); + trie.put(fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), add2, asset5)), + Bytes.ofUnsignedLong(25)); + + + trie.put(fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), add3, asset2)), + Bytes.ofUnsignedLong(5)); + trie.put(fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), add3, asset4)), + Bytes.ofUnsignedLong(10)); + trie.put(fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), add4, asset1)), + Bytes.ofUnsignedLong(15)); + trie.put(fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), add4, asset3)), + Bytes.ofUnsignedLong(25)); + + + trie.put(Bytes.wrap(Bytes.of(StateType.UNDEFINED.value()), Bytes32.random()), Bytes32.random()); + trie.put(Bytes.wrap(Bytes.of(StateType.UNDEFINED.value()), Bytes32.random()), Bytes32.random()); + trie.put(Bytes.wrap(Bytes.of(StateType.UNDEFINED.value()), Bytes32.random()), Bytes32.random()); + + trie.commit(); + trie.flush(); + + Bytes32 hash = trie.getRootHashByte32(); + + trie.put(fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), add1, asset1)), + Bytes.ofUnsignedLong(50)); + trie.put(fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), add1, asset3)), + Bytes.ofUnsignedLong(20)); + + + Bytes32 min = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), add1, + Bytes.ofUnsignedLong(0))); + + Bytes32 max = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), add1, + Bytes.ofUnsignedLong(Long.MAX_VALUE))); + + TreeMap asset = new TrieImpl2(trie.getMerkleStorage(), hash) + .entriesFrom(min, max); + + Map assets = new TreeMap<>(); + assets.put(String.valueOf(asset1.toLong()), 5L); + assets.put(String.valueOf(asset2.toLong()), 10L); + assets.put(String.valueOf(asset3.toLong()), 15L); + assets.put(String.valueOf(asset4.toLong()), 25L); + + Map actual = new TreeMap<>(); + + asset.forEach((k, v) -> + actual.put(String.valueOf(k.slice(Byte.BYTES + ADDRESS_SIZE, Long.BYTES).toLong()), + v.toLong()) + ); + + Assert.assertEquals(assets, actual); + + assets.put(String.valueOf(asset1.toLong()), 50L); + assets.put(String.valueOf(asset3.toLong()), 20L); + + trie.commit(); + trie.flush(); + asset = trie.entriesFrom(min, max); + actual.clear(); + + asset.forEach((k, v) -> + actual.put(String.valueOf(k.slice(Byte.BYTES + ADDRESS_SIZE, Long.BYTES).toLong()), + v.toLong()) + ); + } + + @Test + public void testRange2() { + TrieImpl2 trie = new TrieImpl2(); + trie.put(Bytes.fromHexString("0x1445584348414e47455f42414c414e43455f4c494d4954"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x144d454d4f5f4645455f484953544f5259"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x01a0b070b2b58f4328e293dc9d6012f59c263d3a1df6"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x01a025a3aae39b24a257f95769c701e8d6978ebe9fc5"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x18a08beaa1a8e2d45367af7bae7c490b9932a4fa4301"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x01a0ec6525979a351a54fa09fea64beb4cce33ffbb7a"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x04"), Bytes32.random()); + trie.put(Bytes.fromHexString("0x01a05430a3f089154e9e182ddd6fe136a62321af22a7"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x14544f54414c5f4e45545f4c494d4954"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x01a00a9309758508413039e4bc5a3d113f3ecc55031d"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x01a0fab5fbf6afb681e4e37e9d33bddb7e923d6132e5"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x034465766163636f756e74"), Bytes32.random()); + trie.put(Bytes.fromHexString("0x01a08beaa1a8e2d45367af7bae7c490b9932a4fa4301"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x18a06a17a49648a8ad32055c06f60fa14ae46df94cc1"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x01a0807337f180b62a77576377c1d0c9c24df5c0dd62"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x18a05430a3f089154e9e182ddd6fe136a62321af22a7"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x03426c61636b686f6c65"), Bytes32.random()); + trie.put(Bytes.fromHexString("0x035a696f6e"), Bytes32.random()); + trie.put(Bytes.fromHexString("0x0353756e"), Bytes32.random()); + trie.put(Bytes.fromHexString("0x18a014eebe4d30a6acb505c8b00b218bdc4733433c68"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x18a00a9309758508413039e4bc5a3d113f3ecc55031d"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x18a0807337f180b62a77576377c1d0c9c24df5c0dd62"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x01a06a17a49648a8ad32055c06f60fa14ae46df94cc1"), Bytes32.ZERO); + trie.put(Bytes.fromHexString( + "0x02a0f9490505f11ffb8d7e3df9789e63ab8709cf457200000000000f42410000"), + Bytes.fromHexString("0x0000000000000064")); + trie.put(Bytes.fromHexString("0x07a0f9490505f11ffb8d7e3df9789e63ab8709cf4572"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x08a0f9490505f11ffb8d7e3df9789e63ab8709cf4572"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x0531303030303031"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x14414c4c4f575f54564d5f5452414e534645525f5452433130"), + Bytes32.ZERO); + trie.put(Bytes.fromHexString( + "0x02a0abd4b9367799eaa3197fecb144eb71de1e049abc00000000000f42410000"), + Bytes.fromHexString("0x0000000005f5e09c")); + trie.put(Bytes.fromHexString("0x14414c4c4f575f41535345545f4f5054494d495a4154494f4e"), + Bytes.fromHexString("0x0000000000000001")); + trie.put(Bytes.fromHexString( + "0x02a0f9490505f11ffb8d7e3df9789e63ab8709cf457200000000000f42410000"), + Bytes.fromHexString("0x0000000000000063")); + trie.put(Bytes.fromHexString( + "0x02a0548794500882809695a8a687866e76d4271a1abc00000000000f42410000"), + Bytes.fromHexString("0x0000000000000009")); + trie.put(Bytes.fromHexString( + "0x02a0abd4b9367799eaa3197fecb144eb71de1e049abc00000000000f42410000"), + Bytes.fromHexString("0x0000000005f5e094")); + + long tokenId = Bytes.fromHexString("0x00000000000f4241").toLong(); + + Bytes32 min = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), + Bytes.fromHexString("0xa0548794500882809695a8a687866e76d4271a1abc"), + Bytes.ofUnsignedLong(0))); + + Bytes32 max = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), + Bytes.fromHexString("0xa0548794500882809695a8a687866e76d4271a1abc"), + Bytes.ofUnsignedLong(Long.MAX_VALUE))); + Map assets = new HashMap<>(); + trie.entriesFrom(min, max).forEach((k, v) -> assets.put( + k.slice(Byte.BYTES + ADDRESS_SIZE, Long.BYTES).toLong(), + v.toLong())); + Assert.assertEquals(Bytes.fromHexString("0x0000000000000009").toLong(), + assets.get(tokenId).longValue()); + + min = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), + Bytes.fromHexString("0xa0f9490505f11ffb8d7e3df9789e63ab8709cf4572"), + Bytes.ofUnsignedLong(0))); + + max = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), + Bytes.fromHexString("0xa0f9490505f11ffb8d7e3df9789e63ab8709cf4572"), + Bytes.ofUnsignedLong(Long.MAX_VALUE))); + assets.clear(); + trie.entriesFrom(min, max).forEach((k, v) -> assets.put( + k.slice(Byte.BYTES + ADDRESS_SIZE, Long.BYTES).toLong(), + v.toLong())); + Assert.assertEquals(Bytes.fromHexString("0x0000000000000063").toLong(), + assets.get(tokenId).longValue()); + + min = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), + Bytes.fromHexString("a0abd4b9367799eaa3197fecb144eb71de1e049abc"), + Bytes.ofUnsignedLong(0))); + + max = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), + Bytes.fromHexString("a0abd4b9367799eaa3197fecb144eb71de1e049abc"), + Bytes.ofUnsignedLong(Long.MAX_VALUE))); + assets.clear(); + trie.entriesFrom(min, max).forEach((k, v) -> assets.put( + k.slice(Byte.BYTES + ADDRESS_SIZE, Long.BYTES).toLong(), + v.toLong())); + Assert.assertEquals(Bytes.fromHexString("0x0000000005f5e094").toLong(), + assets.get(tokenId).longValue()); + } + + @Test + public void testEqual() throws IOException { + TrieImpl2 trie = new TrieImpl2(folder.newFolder().toPath().toString()); + TrieImpl2 trie2 = new TrieImpl2(folder.newFolder().toPath().toString()); + Bytes k1 = Bytes.fromHexString("41548794500882809695a8a687866e76d4271a1abc"); + Bytes k2 = Bytes.fromHexString("41548794500882809695a8a687866e76d4271a3456"); + Bytes v1 = Bytes32.random(); + Bytes v2 = Bytes32.random(); + trie.put(k1, v1); + trie.put(k2, v2); + trie2.put(k2, v2); + trie2.put(k1, v1); + Assert.assertEquals(trie2, trie); + Assert.assertEquals(trie.hashCode(), trie2.hashCode()); + Assert.assertEquals(trie.toString(), trie2.toString()); + trie.commit(); + TrieImpl2 trie3 = new TrieImpl2(trie.getMerkleStorage(), trie2.getRootHashByte32()); + Assert.assertEquals(trie3, trie); + } + +} diff --git a/framework/src/test/resources/config-localtest.conf b/framework/src/test/resources/config-localtest.conf index c6ecaf28173..58a45bc33a9 100644 --- a/framework/src/test/resources/config-localtest.conf +++ b/framework/src/test/resources/config-localtest.conf @@ -52,6 +52,8 @@ storage { // }, ] + stateRoot.switch = true + } node.discovery = { diff --git a/framework/src/test/resources/config-test.conf b/framework/src/test/resources/config-test.conf index d506521965f..5ab997277d2 100644 --- a/framework/src/test/resources/config-test.conf +++ b/framework/src/test/resources/config-test.conf @@ -66,6 +66,7 @@ storage { # the estimated number of block transactions (default 1000, min 100, max 10000). # so the total number of cached transactions is 65536 * txCache.estimatedTransactions txCache.estimatedTransactions = 50 + stateRoot.switch = true } diff --git a/protocol/src/main/protos/core/Tron.proto b/protocol/src/main/protos/core/Tron.proto index aa6a96ba1b3..365080b903b 100644 --- a/protocol/src/main/protos/core/Tron.proto +++ b/protocol/src/main/protos/core/Tron.proto @@ -514,6 +514,7 @@ message BlockHeader { } raw raw_data = 1; bytes witness_signature = 2; + bytes archive_root = 3; } // block diff --git a/settings.gradle b/settings.gradle index eb304444378..d91187499c8 100644 --- a/settings.gradle +++ b/settings.gradle @@ -8,4 +8,5 @@ include 'common' include 'example:actuator-example' include 'crypto' include 'plugins' +include 'state-trie-jdk8' diff --git a/state-trie-jdk8/build.gradle b/state-trie-jdk8/build.gradle new file mode 100644 index 00000000000..4022c6c595e --- /dev/null +++ b/state-trie-jdk8/build.gradle @@ -0,0 +1,50 @@ +plugins { + id 'java' + id 'idea' +} +group 'io.github.tronprotocol' +version '1.0.0' + +repositories { + mavenCentral() +} + +repositories { + mavenCentral() + mavenLocal() +} + +sourceCompatibility = JavaVersion.VERSION_1_8 +targetCompatibility = JavaVersion.VERSION_1_8 + +[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' + + +dependencies { + compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.69' + compile group: 'org.connid', name: 'framework', version: '1.3.2' + compile group: 'org.jetbrains', name: 'annotations', version: '23.1.0' + compile group: 'io.netty', name: 'netty-buffer', version: '4.1.27.Final' + compile group: 'io.vertx', name: 'vertx-core', version: '4.3.7' + compile group: 'org.immutables', name: 'value', version: '2.9.3' + compile group: 'org.immutables', name: 'value-annotations', version: '2.9.3' + compile group: 'org.rocksdb', name: 'rocksdbjni', version: '5.15.10' + + + testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.9.1' + testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '5.9.1' + testCompile group: 'org.mockito', name: 'mockito-junit-jupiter', version: '4.11.0' + testCompile group: 'junit', name: 'junit', version: '4.13.1' + testCompile group: 'org.assertj', name: 'assertj-core', version: '3.24.1' +} + +tasks.matching { it instanceof Test }.all { + testLogging.events = ["failed", "passed", "skipped"] +} + + +test { + testLogging { + exceptionFormat = 'full' + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/AbstractBytes.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/AbstractBytes.java new file mode 100644 index 00000000000..9b7cfe5a83e --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/AbstractBytes.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +/** + * An abstract {@link Bytes} value that provides implementations of {@link #equals(Object)}, {@link #hashCode()} and + * {@link #toString()}. + */ +public abstract class AbstractBytes implements Bytes { + + static final String HEX_CODE_AS_STRING = "0123456789abcdef"; + static final char[] HEX_CODE = HEX_CODE_AS_STRING.toCharArray(); + + private Integer hashCode; + + /** + * Compare this value and the provided one for equality. + * + *

+ * Two {@link Bytes} values are equal is they have contain the exact same bytes. + * + * @param obj The object to test for equality with. + * @return {@code true} if this value and {@code obj} are equal. + */ + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof Bytes)) { + return false; + } + + Bytes other = (Bytes) obj; + if (this.size() != other.size()) { + return false; + } + + for (int i = 0; i < size(); i++) { + if (this.get(i) != other.get(i)) { + return false; + } + } + + return true; + } + + protected int computeHashcode() { + int result = 1; + for (int i = 0; i < size(); i++) { + result = 31 * result + get(i); + } + return result; + } + + @Override + public int hashCode() { + if (this.hashCode == null) { + this.hashCode = computeHashcode(); + } + return this.hashCode; + } + + @Override + public String toString() { + return toHexString(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ArrayWrappingBytes.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ArrayWrappingBytes.java new file mode 100644 index 00000000000..fec9addaa4c --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ArrayWrappingBytes.java @@ -0,0 +1,165 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import io.vertx.core.buffer.Buffer; + +import java.nio.ByteBuffer; +import java.security.MessageDigest; +import java.util.Arrays; + +import static org.apache.tuweni.bytes.Checks.checkArgument; +import static org.apache.tuweni.bytes.Checks.checkElementIndex; + +class ArrayWrappingBytes extends AbstractBytes { + + protected final byte[] bytes; + protected final int offset; + protected final int length; + + ArrayWrappingBytes(byte[] bytes) { + this(bytes, 0, bytes.length); + } + + ArrayWrappingBytes(byte[] bytes, int offset, int length) { + checkArgument(length >= 0, "Invalid negative length"); + if (bytes.length > 0) { + checkElementIndex(offset, bytes.length); + } + checkArgument( + offset + length <= bytes.length, + "Provided length %s is too big: the value has only %s bytes from offset %s", + length, + bytes.length - offset, + offset); + + this.bytes = bytes; + this.offset = offset; + this.length = length; + } + + @Override + public int size() { + return length; + } + + @Override + public byte get(int i) { + // Check bounds because while the array access would throw, the error message would be confusing + // for the caller. + checkElementIndex(i, size()); + return bytes[offset + i]; + } + + @Override + public Bytes slice(int i, int length) { + if (i == 0 && length == this.length) { + return this; + } + if (length == 0) { + return Bytes.EMPTY; + } + + checkElementIndex(i, this.length); + checkArgument( + i + length <= this.length, + "Provided length %s is too big: the value has size %s and has only %s bytes from %s", + length, + this.length, + this.length - i, + i); + + return length == Bytes32.SIZE ? new ArrayWrappingBytes32(bytes, offset + i) + : new ArrayWrappingBytes(bytes, offset + i, length); + } + + // MUST be overridden by mutable implementations + @Override + public Bytes copy() { + if (offset == 0 && length == bytes.length) { + return this; + } + return new ArrayWrappingBytes(toArray()); + } + + @Override + public MutableBytes mutableCopy() { + return new MutableArrayWrappingBytes(toArray()); + } + + @Override + public int commonPrefixLength(Bytes other) { + if (!(other instanceof ArrayWrappingBytes)) { + return super.commonPrefixLength(other); + } + ArrayWrappingBytes o = (ArrayWrappingBytes) other; + int i = 0; + while (i < length && i < o.length && bytes[offset + i] == o.bytes[o.offset + i]) { + i++; + } + return i; + } + + @Override + public void update(MessageDigest digest) { + digest.update(bytes, offset, length); + } + + @Override + public void copyTo(MutableBytes destination, int destinationOffset) { + if (!(destination instanceof MutableArrayWrappingBytes)) { + super.copyTo(destination, destinationOffset); + return; + } + + int size = size(); + if (size == 0) { + return; + } + + checkElementIndex(destinationOffset, destination.size()); + checkArgument( + destination.size() - destinationOffset >= size, + "Cannot copy %s bytes, destination has only %s bytes from index %s", + size, + destination.size() - destinationOffset, + destinationOffset); + + MutableArrayWrappingBytes d = (MutableArrayWrappingBytes) destination; + System.arraycopy(bytes, offset, d.bytes, d.offset + destinationOffset, size); + } + + @Override + public void appendTo(ByteBuffer byteBuffer) { + byteBuffer.put(bytes, offset, length); + } + + @Override + public void appendTo(Buffer buffer) { + buffer.appendBytes(bytes, offset, length); + } + + + @Override + public byte[] toArray() { + return Arrays.copyOfRange(bytes, offset, offset + length); + } + + @Override + public byte[] toArrayUnsafe() { + if (offset == 0 && length == bytes.length) { + return bytes; + } + return toArray(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ArrayWrappingBytes32.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ArrayWrappingBytes32.java new file mode 100644 index 00000000000..9c80382aeb6 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ArrayWrappingBytes32.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import static org.apache.tuweni.bytes.Checks.checkArgument; + +final class ArrayWrappingBytes32 extends ArrayWrappingBytes implements Bytes32 { + + ArrayWrappingBytes32(byte[] bytes) { + this(checkLength(bytes), 0); + } + + ArrayWrappingBytes32(byte[] bytes, int offset) { + super(checkLength(bytes, offset), offset, SIZE); + } + + // Ensures a proper error message. + private static byte[] checkLength(byte[] bytes) { + checkArgument(bytes.length == SIZE, "Expected %s bytes but got %s", SIZE, bytes.length); + return bytes; + } + + // Ensures a proper error message. + private static byte[] checkLength(byte[] bytes, int offset) { + checkArgument( + bytes.length - offset >= SIZE, + "Expected at least %s bytes from offset %s but got only %s", + SIZE, + offset, + bytes.length - offset); + return bytes; + } + + @Override + public Bytes32 copy() { + if (offset == 0 && length == bytes.length) { + return this; + } + return new ArrayWrappingBytes32(toArray()); + } + + @Override + public MutableBytes32 mutableCopy() { + return new MutableArrayWrappingBytes32(toArray()); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ArrayWrappingBytes48.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ArrayWrappingBytes48.java new file mode 100644 index 00000000000..d950af5caaa --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ArrayWrappingBytes48.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import static org.apache.tuweni.bytes.Checks.checkArgument; + +final class ArrayWrappingBytes48 extends ArrayWrappingBytes implements Bytes48 { + + ArrayWrappingBytes48(byte[] bytes) { + this(checkLength(bytes), 0); + } + + ArrayWrappingBytes48(byte[] bytes, int offset) { + super(checkLength(bytes, offset), offset, SIZE); + } + + // Ensures a proper error message. + private static byte[] checkLength(byte[] bytes) { + checkArgument(bytes.length == SIZE, "Expected %s bytes but got %s", SIZE, bytes.length); + return bytes; + } + + // Ensures a proper error message. + private static byte[] checkLength(byte[] bytes, int offset) { + checkArgument( + bytes.length - offset >= SIZE, + "Expected at least %s bytes from offset %s but got only %s", + SIZE, + offset, + bytes.length - offset); + return bytes; + } + + @Override + public Bytes48 copy() { + if (offset == 0 && length == bytes.length) { + return this; + } + return new ArrayWrappingBytes48(toArray()); + } + + @Override + public MutableBytes48 mutableCopy() { + return new MutableArrayWrappingBytes48(toArray()); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/BufferWrappingBytes.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/BufferWrappingBytes.java new file mode 100644 index 00000000000..0a8d84b3e5d --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/BufferWrappingBytes.java @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import io.vertx.core.buffer.Buffer; + +import static org.apache.tuweni.bytes.Checks.checkArgument; +import static org.apache.tuweni.bytes.Checks.checkElementIndex; + +class BufferWrappingBytes extends AbstractBytes { + + protected final Buffer buffer; + + BufferWrappingBytes(Buffer buffer) { + this.buffer = buffer; + } + + BufferWrappingBytes(Buffer buffer, int offset, int length) { + checkArgument(length >= 0, "Invalid negative length"); + int bufferLength = buffer.length(); + checkElementIndex(offset, bufferLength + 1); + checkArgument( + offset + length <= bufferLength, + "Provided length %s is too big: the buffer has size %s and has only %s bytes from %s", + length, + bufferLength, + bufferLength - offset, + offset); + + if (offset == 0 && length == bufferLength) { + this.buffer = buffer; + } else { + this.buffer = buffer.slice(offset, offset + length); + } + } + + @Override + public int size() { + return buffer.length(); + } + + @Override + public byte get(int i) { + return buffer.getByte(i); + } + + @Override + public int getInt(int i) { + return buffer.getInt(i); + } + + @Override + public long getLong(int i) { + return buffer.getLong(i); + } + + @Override + public Bytes slice(int i, int length) { + int size = buffer.length(); + if (i == 0 && length == size) { + return this; + } + if (length == 0) { + return Bytes.EMPTY; + } + + checkElementIndex(i, size); + checkArgument( + i + length <= size, + "Provided length %s is too big: the value has size %s and has only %s bytes from %s", + length, + size, + size - i, + i); + + return new BufferWrappingBytes(buffer.slice(i, i + length)); + } + + // MUST be overridden by mutable implementations + @Override + public Bytes copy() { + return Bytes.wrap(toArray()); + } + + @Override + public MutableBytes mutableCopy() { + return MutableBytes.wrap(toArray()); + } + + @Override + public void appendTo(Buffer buffer) { + buffer.appendBuffer(this.buffer); + } + + @Override + public byte[] toArray() { + return buffer.getBytes(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ByteBufWrappingBytes.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ByteBufWrappingBytes.java new file mode 100644 index 00000000000..c63892bf1c8 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ByteBufWrappingBytes.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import io.netty.buffer.ByteBuf; +import io.vertx.core.buffer.Buffer; + +import static org.apache.tuweni.bytes.Checks.checkArgument; +import static org.apache.tuweni.bytes.Checks.checkElementIndex; + +class ByteBufWrappingBytes extends AbstractBytes { + + protected final ByteBuf byteBuf; + + ByteBufWrappingBytes(ByteBuf byteBuf) { + this.byteBuf = byteBuf; + } + + ByteBufWrappingBytes(ByteBuf byteBuf, int offset, int length) { + checkArgument(length >= 0, "Invalid negative length"); + int bufferLength = byteBuf.capacity(); + checkElementIndex(offset, bufferLength + 1); + checkArgument( + offset + length <= bufferLength, + "Provided length %s is too big: the buffer has size %s and has only %s bytes from %s", + length, + bufferLength, + bufferLength - offset, + offset); + + if (offset == 0 && length == bufferLength) { + this.byteBuf = byteBuf; + } else { + this.byteBuf = byteBuf.slice(offset, length); + } + } + + @Override + public int size() { + return byteBuf.capacity(); + } + + @Override + public byte get(int i) { + return byteBuf.getByte(i); + } + + @Override + public int getInt(int i) { + return byteBuf.getInt(i); + } + + @Override + public long getLong(int i) { + return byteBuf.getLong(i); + } + + @Override + public Bytes slice(int i, int length) { + int size = byteBuf.capacity(); + if (i == 0 && length == size) { + return this; + } + if (length == 0) { + return Bytes.EMPTY; + } + + checkElementIndex(i, size); + checkArgument( + i + length <= size, + "Provided length %s is too big: the value has size %s and has only %s bytes from %s", + length, + size, + size - i, + i); + + return new ByteBufWrappingBytes(byteBuf.slice(i, length)); + } + + // MUST be overridden by mutable implementations + @Override + public Bytes copy() { + return Bytes.wrap(toArray()); + } + + @Override + public MutableBytes mutableCopy() { + return MutableBytes.wrap(toArray()); + } + + @Override + public void appendTo(Buffer buffer) { + buffer.appendBuffer(Buffer.buffer(this.byteBuf)); + } + + @Override + public byte[] toArray() { + int size = byteBuf.capacity(); + byte[] array = new byte[size]; + byteBuf.getBytes(0, array); + return array; + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ByteBufferWrappingBytes.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ByteBufferWrappingBytes.java new file mode 100644 index 00000000000..b2517537b15 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ByteBufferWrappingBytes.java @@ -0,0 +1,133 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import java.nio.ByteBuffer; +import java.util.Arrays; + +import static org.apache.tuweni.bytes.Checks.checkArgument; +import static org.apache.tuweni.bytes.Checks.checkElementIndex; + +class ByteBufferWrappingBytes extends AbstractBytes { + + protected final ByteBuffer byteBuffer; + protected final int offset; + protected final int length; + + ByteBufferWrappingBytes(ByteBuffer byteBuffer) { + this(byteBuffer, 0, byteBuffer.limit()); + } + + ByteBufferWrappingBytes(ByteBuffer byteBuffer, int offset, int length) { + checkArgument(length >= 0, "Invalid negative length"); + int bufferLength = byteBuffer.capacity(); + if (bufferLength > 0) { + checkElementIndex(offset, bufferLength); + } + checkArgument( + offset + length <= bufferLength, + "Provided length %s is too big: the value has only %s bytes from offset %s", + length, + bufferLength - offset, + offset); + + this.byteBuffer = byteBuffer; + this.offset = offset; + this.length = length; + } + + @Override + public int size() { + return length; + } + + @Override + public int getInt(int i) { + return byteBuffer.getInt(offset + i); + } + + @Override + public long getLong(int i) { + return byteBuffer.getLong(offset + i); + } + + @Override + public byte get(int i) { + return byteBuffer.get(offset + i); + } + + @Override + public Bytes slice(int i, int length) { + if (i == 0 && length == this.length) { + return this; + } + if (length == 0) { + return Bytes.EMPTY; + } + + checkElementIndex(i, this.length); + checkArgument( + i + length <= this.length, + "Provided length %s is too big: the value has size %s and has only %s bytes from %s", + length, + this.length, + this.length - i, + i); + + if (length == 32) { + return new ByteBufferWrappingBytes32(byteBuffer, offset + i, length); + } + + return new ByteBufferWrappingBytes(byteBuffer, offset + i, length); + } + + // MUST be overridden by mutable implementations + @Override + public Bytes copy() { + if (offset == 0 && length == byteBuffer.limit()) { + return this; + } + return new ArrayWrappingBytes(toArray()); + } + + @Override + public MutableBytes mutableCopy() { + return new MutableArrayWrappingBytes(toArray()); + } + + @Override + public void appendTo(ByteBuffer byteBuffer) { + byteBuffer.put(this.byteBuffer); + } + + @Override + public byte[] toArray() { + if (!byteBuffer.hasArray()) { + return super.toArray(); + } + int arrayOffset = byteBuffer.arrayOffset(); + return Arrays.copyOfRange(byteBuffer.array(), arrayOffset + offset, arrayOffset + offset + length); + } + + @Override + public byte[] toArrayUnsafe() { + if (!byteBuffer.hasArray()) { + return toArray(); + } + byte[] array = byteBuffer.array(); + if (array.length != length || byteBuffer.arrayOffset() != 0) { + return toArray(); + } + return array; + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ByteBufferWrappingBytes32.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ByteBufferWrappingBytes32.java new file mode 100644 index 00000000000..d62b9e29d47 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ByteBufferWrappingBytes32.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import java.nio.ByteBuffer; + +import static org.apache.tuweni.bytes.Checks.checkArgument; + +class ByteBufferWrappingBytes32 extends ByteBufferWrappingBytes implements Bytes32 { + + ByteBufferWrappingBytes32(ByteBuffer byteBuffer) { + this(byteBuffer, 0, byteBuffer.limit()); + } + + ByteBufferWrappingBytes32(ByteBuffer byteBuffer, int offset, int length) { + super(byteBuffer, offset, length); + checkArgument(length == SIZE, "Expected %s bytes but got %s", SIZE, length); + } + + // MUST be overridden by mutable implementations + @Override + public Bytes32 copy() { + if (offset == 0 && length == byteBuffer.limit()) { + return this; + } + return new ArrayWrappingBytes32(toArray()); + } + + @Override + public MutableBytes32 mutableCopy() { + return new MutableArrayWrappingBytes32(toArray()); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/Bytes.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/Bytes.java new file mode 100644 index 00000000000..9493c622673 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/Bytes.java @@ -0,0 +1,1706 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import io.netty.buffer.ByteBuf; +import io.vertx.core.buffer.Buffer; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.math.BigInteger; +import java.nio.BufferOverflowException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.ReadOnlyBufferException; +import java.security.MessageDigest; +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.Base64; +import java.util.List; +import java.util.Random; + +import static java.lang.String.format; +import static java.nio.ByteOrder.BIG_ENDIAN; +import static org.apache.tuweni.bytes.Checks.*; + +/** + * A value made of bytes. + * + *

+ * This interface makes no thread-safety guarantee, and a {@link Bytes} value is generally not thread safe. However, + * specific implementations may be thread-safe. For instance, the value returned by {@link #copy} is guaranteed to be + * thread-safe as it is immutable. + */ +public interface Bytes extends Comparable { + + /** + * The empty value (with 0 bytes). + */ + Bytes EMPTY = wrap(new byte[0]); + + /** + * Wrap the provided byte array as a {@link Bytes} value. + * + *

+ * Note that value is not copied and thus any future update to {@code value} will be reflected in the returned value. + * + * @param value The value to wrap. + * @return A {@link Bytes} value wrapping {@code value}. + */ + static Bytes wrap(byte[] value) { + return wrap(value, 0, value.length); + } + + /** + * Wrap a slice of a byte array as a {@link Bytes} value. + * + *

+ * Note that value is not copied and thus any future update to {@code value} within the slice will be reflected in the + * returned value. + * + * @param value The value to wrap. + * @param offset The index (inclusive) in {@code value} of the first byte exposed by the returned value. In other + * words, you will have {@code wrap(value, o, l).get(0) == value[o]}. + * @param length The length of the resulting value. + * @return A {@link Bytes} value that expose the bytes of {@code value} from {@code offset} (inclusive) to + * {@code offset + length} (exclusive). + * @throws IndexOutOfBoundsException if {@code offset < 0 || (value.length > 0 && offset >= + * value.length)}. + * @throws IllegalArgumentException if {@code length < 0 || offset + length > value.length}. + */ + static Bytes wrap(byte[] value, int offset, int length) { + checkNotNull(value); + if (length == 32) { + return new ArrayWrappingBytes32(value, offset); + } + return new ArrayWrappingBytes(value, offset, length); + } + + /** + * Wrap the provided byte array as a {@link Bytes} value, encrypted in memory. + * + * + * @param value The value to secure. + * @return A {@link Bytes} value securing {@code value}. + */ + static Bytes secure(byte[] value) { + return secure(value, 0, value.length); + } + + /** + * Wrap a slice of a byte array as a {@link Bytes} value, encrypted in memory. + * + * + * @param value The value to secure. + * @param offset The index (inclusive) in {@code value} of the first byte exposed by the returned value. In other + * words, you will have {@code wrap(value, o, l).get(0) == value[o]}. + * @param length The length of the resulting value. + * @return A {@link Bytes} value that holds securely the bytes of {@code value} from {@code offset} (inclusive) to + * {@code offset + length} (exclusive). + * @throws IndexOutOfBoundsException if {@code offset < 0 || (value.length > 0 && offset >= + * value.length)}. + * @throws IllegalArgumentException if {@code length < 0 || offset + length > value.length}. + */ + static Bytes secure(byte[] value, int offset, int length) { + checkNotNull(value); + return new GuardedByteArrayBytes(value, offset, length); + } + + /** + * Wrap a list of other values into a concatenated view. + * + *

+ * Note that the values are not copied and thus any future update to the values will be reflected in the returned + * value. If copying the inputs is desired, use {@link #concatenate(Bytes...)}. + * + * @param values The values to wrap. + * @return A value representing a view over the concatenation of all {@code values}. + * @throws IllegalArgumentException if the result overflows an int. + */ + static Bytes wrap(Bytes... values) { + return ConcatenatedBytes.wrap(values); + } + + /** + * Wrap a list of other values into a concatenated view. + * + *

+ * Note that the values are not copied and thus any future update to the values will be reflected in the returned + * value. If copying the inputs is desired, use {@link #concatenate(Bytes...)}. + * + * @param values The values to wrap. + * @return A value representing a view over the concatenation of all {@code values}. + * @throws IllegalArgumentException if the result overflows an int. + */ + static Bytes wrap(List values) { + return ConcatenatedBytes.wrap(values); + } + + /** + * Create a value containing the concatenation of the values provided. + * + * @param values The values to copy and concatenate. + * @return A value containing the result of concatenating the value from {@code values} in their provided order. + * @throws IllegalArgumentException if the result overflows an int. + */ + static Bytes concatenate(List values) { + if (values.size() == 0) { + return EMPTY; + } + + int size; + try { + size = values.stream().mapToInt(Bytes::size).reduce(0, Math::addExact); + } catch (ArithmeticException e) { + throw new IllegalArgumentException("Combined length of values is too long (> Integer.MAX_VALUE)"); + } + + MutableBytes result = MutableBytes.create(size); + int offset = 0; + for (Bytes value : values) { + value.copyTo(result, offset); + offset += value.size(); + } + return result; + } + + /** + * Create a value containing the concatenation of the values provided. + * + * @param values The values to copy and concatenate. + * @return A value containing the result of concatenating the value from {@code values} in their provided order. + * @throws IllegalArgumentException if the result overflows an int. + */ + static Bytes concatenate(Bytes... values) { + if (values.length == 0) { + return EMPTY; + } + + int size; + try { + size = Arrays.stream(values).mapToInt(Bytes::size).reduce(0, Math::addExact); + } catch (ArithmeticException e) { + throw new IllegalArgumentException("Combined length of values is too long (> Integer.MAX_VALUE)"); + } + + MutableBytes result = MutableBytes.create(size); + int offset = 0; + for (Bytes value : values) { + value.copyTo(result, offset); + offset += value.size(); + } + return result; + } + + /** + * Wrap a full Vert.x {@link Buffer} as a {@link Bytes} value. + * + *

+ * Note that any change to the content of the buffer may be reflected in the returned value. + * + * @param buffer The buffer to wrap. + * @return A {@link Bytes} value. + */ + static Bytes wrapBuffer(Buffer buffer) { + checkNotNull(buffer); + if (buffer.length() == 0) { + return EMPTY; + } + return new BufferWrappingBytes(buffer); + } + + /** + * Wrap a slice of a Vert.x {@link Buffer} as a {@link Bytes} value. + * + *

+ * Note that any change to the content of the buffer may be reflected in the returned value. + * + * @param buffer The buffer to wrap. + * @param offset The offset in {@code buffer} from which to expose the bytes in the returned value. That is, + * {@code wrapBuffer(buffer, i, 1).get(0) == buffer.getByte(i)}. + * @param size The size of the returned value. + * @return A {@link Bytes} value. + * @throws IndexOutOfBoundsException if {@code offset < 0 || (buffer.length() > 0 && offset >= + * buffer.length())}. + * @throws IllegalArgumentException if {@code length < 0 || offset + length > buffer.length()}. + */ + static Bytes wrapBuffer(Buffer buffer, int offset, int size) { + checkNotNull(buffer); + if (size == 0) { + return EMPTY; + } + return new BufferWrappingBytes(buffer, offset, size); + } + + /** + * Wrap a full Netty {@link ByteBuf} as a {@link Bytes} value. + * + *

+ * Note that any change to the content of the byteBuf may be reflected in the returned value. + * + * @param byteBuf The {@link ByteBuf} to wrap. + * @return A {@link Bytes} value. + */ + static Bytes wrapByteBuf(ByteBuf byteBuf) { + checkNotNull(byteBuf); + if (byteBuf.capacity() == 0) { + return EMPTY; + } + return new ByteBufWrappingBytes(byteBuf); + } + + /** + * Wrap a slice of a Netty {@link ByteBuf} as a {@link Bytes} value. + * + *

+ * Note that any change to the content of the buffer may be reflected in the returned value. + * + * @param byteBuf The {@link ByteBuf} to wrap. + * @param offset The offset in {@code byteBuf} from which to expose the bytes in the returned value. That is, + * {@code wrapByteBuf(byteBuf, i, 1).get(0) == byteBuf.getByte(i)}. + * @param size The size of the returned value. + * @return A {@link Bytes} value. + * @throws IndexOutOfBoundsException if {@code offset < 0 || (byteBuf.capacity() > 0 && offset >= + * byteBuf.capacity())}. + * @throws IllegalArgumentException if {@code length < 0 || offset + length > byteBuf.capacity()}. + */ + static Bytes wrapByteBuf(ByteBuf byteBuf, int offset, int size) { + checkNotNull(byteBuf); + if (size == 0) { + return EMPTY; + } + return new ByteBufWrappingBytes(byteBuf, offset, size); + } + + /** + * Wrap a full Java NIO {@link ByteBuffer} as a {@link Bytes} value. + * + *

+ * Note that any change to the content of the byteBuf may be reflected in the returned value. + * + * @param byteBuffer The {@link ByteBuffer} to wrap. + * @return A {@link Bytes} value. + */ + static Bytes wrapByteBuffer(ByteBuffer byteBuffer) { + checkNotNull(byteBuffer); + if (byteBuffer.limit() == 0) { + return EMPTY; + } + return new ByteBufferWrappingBytes(byteBuffer); + } + + /** + * Wrap a slice of a Java NIO {@link ByteBuf} as a {@link Bytes} value. + * + *

+ * Note that any change to the content of the buffer may be reflected in the returned value. + * + * @param byteBuffer The {@link ByteBuffer} to wrap. + * @param offset The offset in {@code byteBuffer} from which to expose the bytes in the returned value. That is, + * {@code wrapByteBuffer(byteBuffer, i, 1).get(0) == byteBuffer.getByte(i)}. + * @param size The size of the returned value. + * @return A {@link Bytes} value. + * @throws IndexOutOfBoundsException if {@code offset < 0 || (byteBuffer.limit() > 0 && offset >= + * byteBuf.limit())}. + * @throws IllegalArgumentException if {@code length < 0 || offset + length > byteBuffer.limit()}. + */ + static Bytes wrapByteBuffer(ByteBuffer byteBuffer, int offset, int size) { + checkNotNull(byteBuffer); + if (size == 0) { + return EMPTY; + } + return new ByteBufferWrappingBytes(byteBuffer, offset, size); + } + + /** + * Create a value that contains the specified bytes in their specified order. + * + * @param bytes The bytes that must compose the returned value. + * @return A value containing the specified bytes. + */ + static Bytes of(byte... bytes) { + return wrap(bytes); + } + + /** + * Create a value that contains the specified bytes in their specified order. + * + * @param bytes The bytes. + * @return A value containing bytes are the one from {@code bytes}. + * @throws IllegalArgumentException if any of the specified would be truncated when storing as a byte. + */ + static Bytes of(int... bytes) { + byte[] result = new byte[bytes.length]; + for (int i = 0; i < bytes.length; i++) { + int b = bytes[i]; + checkArgument(b == (((byte) b) & 0xff), "%sth value %s does not fit a byte", i + 1, b); + result[i] = (byte) b; + } + return Bytes.wrap(result); + } + + /** + * Return a 2-byte value corresponding to the provided value interpreted as an unsigned short. + * + * @param value The value, which must be no larger than an unsigned short. + * @return A 2 bytes value corresponding to {@code value}. + * @throws IllegalArgumentException if {@code value < 0} or {@code value} is too big to fit an unsigned 2-byte short + * (that is, if {@code value >= (1 << 16)}). + */ + static Bytes ofUnsignedShort(int value) { + return ofUnsignedShort(value, BIG_ENDIAN); + } + + /** + * Return a 2-byte value corresponding to the provided value interpreted as an unsigned short. + * + * @param value The value, which must be no larger than an unsigned short. + * @param order The byte-order for the integer encoding. + * @return A 2 bytes value corresponding to {@code value}. + * @throws IllegalArgumentException if {@code value < 0} or {@code value} is too big to fit an unsigned 2-byte short + * (that is, if {@code value >= (1 << 16)}). + */ + static Bytes ofUnsignedShort(int value, ByteOrder order) { + checkArgument( + value >= 0 && value <= BytesValues.MAX_UNSIGNED_SHORT, + "Value %s cannot be represented as an unsigned short (it is negative or too big)", + value); + byte[] res = new byte[2]; + if (order == BIG_ENDIAN) { + res[0] = (byte) ((value >> 8) & 0xFF); + res[1] = (byte) (value & 0xFF); + } else { + res[0] = (byte) (value & 0xFF); + res[1] = (byte) ((value >> 8) & 0xFF); + } + return Bytes.wrap(res); + } + + /** + * Return a 4-byte value corresponding to the provided value interpreted as an unsigned int. + * + * @param value The value, which must be no larger than an unsigned int. + * @return A 4 bytes value corresponding to {@code value}. + * @throws IllegalArgumentException if {@code value < 0} or {@code value} is too big to fit an unsigned 4-byte int + * (that is, if {@code value >= (1L << 32)}). + */ + static Bytes ofUnsignedInt(long value) { + return ofUnsignedInt(value, BIG_ENDIAN); + } + + /** + * Return a 4-byte value corresponding to the provided value interpreted as an unsigned int. + * + * @param value The value, which must be no larger than an unsigned int. + * @param order The byte-order for the integer encoding. + * @return A 4 bytes value corresponding to the encoded {@code value}. + * @throws IllegalArgumentException if {@code value < 0} or {@code value} is too big to fit an unsigned 4-byte int + * (that is, if {@code value >= (1L << 32)}). + */ + static Bytes ofUnsignedInt(long value, ByteOrder order) { + checkArgument( + value >= 0 && value <= BytesValues.MAX_UNSIGNED_INT, + "Value %s cannot be represented as an unsigned int (it is negative or too big)", + value); + byte[] res = new byte[4]; + if (order == BIG_ENDIAN) { + res[0] = (byte) ((value >> 24) & 0xFF); + res[1] = (byte) ((value >> 16) & 0xFF); + res[2] = (byte) ((value >> 8) & 0xFF); + res[3] = (byte) ((value) & 0xFF); + } else { + res[0] = (byte) ((value) & 0xFF); + res[1] = (byte) ((value >> 8) & 0xFF); + res[2] = (byte) ((value >> 16) & 0xFF); + res[3] = (byte) ((value >> 24) & 0xFF); + } + return Bytes.wrap(res); + } + + /** + * Return an 8-byte value corresponding to the provided value interpreted as an unsigned long. + * + * @param value The value, which will be interpreted as an unsigned long. + * @return A 8 bytes value corresponding to {@code value}. + * @throws IllegalArgumentException if {@code value < 0} or {@code value} is too big to fit an unsigned 8-byte int + * (that is, if {@code value >= (1L << 64)}). + */ + static Bytes ofUnsignedLong(long value) { + return ofUnsignedLong(value, BIG_ENDIAN); + } + + /** + * Return an 8-byte value corresponding to the provided value interpreted as an unsigned long. + * + * @param value The value, which will be interpreted as an unsigned long. + * @param order The byte-order for the integer encoding. + * @return A 8 bytes value corresponding to {@code value}. + * @throws IllegalArgumentException if {@code value < 0} or {@code value} is too big to fit an unsigned 8-byte int + * (that is, if {@code value >= (1L << 64)}). + */ + static Bytes ofUnsignedLong(long value, ByteOrder order) { + byte[] res = new byte[8]; + if (order == BIG_ENDIAN) { + res[0] = (byte) ((value >> 56) & 0xFF); + res[1] = (byte) ((value >> 48) & 0xFF); + res[2] = (byte) ((value >> 40) & 0xFF); + res[3] = (byte) ((value >> 32) & 0xFF); + res[4] = (byte) ((value >> 24) & 0xFF); + res[5] = (byte) ((value >> 16) & 0xFF); + res[6] = (byte) ((value >> 8) & 0xFF); + res[7] = (byte) (value & 0xFF); + } else { + res[0] = (byte) ((value) & 0xFF); + res[1] = (byte) ((value >> 8) & 0xFF); + res[2] = (byte) ((value >> 16) & 0xFF); + res[3] = (byte) ((value >> 24) & 0xFF); + res[4] = (byte) ((value >> 32) & 0xFF); + res[5] = (byte) ((value >> 40) & 0xFF); + res[6] = (byte) ((value >> 48) & 0xFF); + res[7] = (byte) ((value >> 56) & 0xFF); + } + return Bytes.wrap(res); + } + + /** + * Return the smallest bytes value whose bytes correspond to the provided long. That is, the returned value may be of + * size less than 8 if the provided long has leading zero bytes. + * + * @param value The long from which to create the bytes value. + * @return The minimal bytes representation corresponding to {@code l}. + */ + static Bytes minimalBytes(long value) { + if (value == 0) { + return Bytes.EMPTY; + } + + int zeros = Long.numberOfLeadingZeros(value); + int resultBytes = 8 - (zeros / 8); + + byte[] result = new byte[resultBytes]; + int shift = 0; + for (int i = 0; i < resultBytes; i++) { + result[resultBytes - i - 1] = (byte) ((value >> shift) & 0xFF); + shift += 8; + } + return Bytes.wrap(result); + } + + /** + * Parse a hexadecimal string into a {@link Bytes} value. + * + *

+ * This method is lenient in that {@code str} may of an odd length, in which case it will behave exactly as if it had + * an additional 0 in front. + * + * @param str The hexadecimal string to parse, which may or may not start with "0x". + * @return The value corresponding to {@code str}. + * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation. + */ + static Bytes fromHexStringLenient(CharSequence str) { + checkNotNull(str); + return BytesValues.fromHexString(str, -1, true); + } + + /** + * Parse a hexadecimal string into a {@link Bytes} value of the provided size. + * + *

+ * This method allows for {@code str} to have an odd length, in which case it will behave exactly as if it had an + * additional 0 in front. + * + * @param str The hexadecimal string to parse, which may or may not start with "0x". + * @param destinationSize The size of the returned value, which must be big enough to hold the bytes represented by + * {@code str}. If it is strictly bigger those bytes from {@code str}, the returned value will be left padded + * with zeros. + * @return A value of size {@code destinationSize} corresponding to {@code str} potentially left-padded. + * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation, + * represents more bytes than {@code destinationSize} or {@code destinationSize < 0}. + */ + static Bytes fromHexStringLenient(CharSequence str, int destinationSize) { + checkNotNull(str); + checkArgument(destinationSize >= 0, "Invalid negative destination size %s", destinationSize); + return BytesValues.fromHexString(str, destinationSize, true); + } + + /** + * Parse a hexadecimal string into a {@link Bytes} value. + * + *

+ * This method requires that {@code str} have an even length. + * + * @param str The hexadecimal string to parse, which may or may not start with "0x". + * @return The value corresponding to {@code str}. + * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation, or is of + * an odd length. + */ + static Bytes fromHexString(CharSequence str) { + checkNotNull(str); + return BytesValues.fromHexString(str, -1, false); + } + + /** + * Parse a hexadecimal string into a {@link Bytes} value. + * + *

+ * This method requires that {@code str} have an even length. + * + * @param str The hexadecimal string to parse, which may or may not start with "0x". + * @param destinationSize The size of the returned value, which must be big enough to hold the bytes represented by + * {@code str}. If it is strictly bigger those bytes from {@code str}, the returned value will be left padded + * with zeros. + * @return A value of size {@code destinationSize} corresponding to {@code str} potentially left-padded. + * @throws IllegalArgumentException if {@code str} does correspond to a valid hexadecimal representation, or is of an + * odd length. + * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation, or is of + * an odd length, or represents more bytes than {@code destinationSize} or {@code destinationSize < 0}. + */ + static Bytes fromHexString(CharSequence str, int destinationSize) { + checkNotNull(str); + checkArgument(destinationSize >= 0, "Invalid negative destination size %s", destinationSize); + return BytesValues.fromHexString(str, destinationSize, false); + } + + /** + * Parse a base 64 string into a {@link Bytes} value. + * + * @param str The base 64 string to parse. + * @return The value corresponding to {@code str}. + */ + static Bytes fromBase64String(CharSequence str) { + return Bytes.wrap(Base64.getDecoder().decode(str.toString())); + } + + /** + * Generate random bytes. + * + * @param size The number of bytes to generate. + * @return A value containing the desired number of random bytes. + */ + static Bytes random(int size) { + return random(size, new SecureRandom()); + } + + /** + * Generate random bytes. + * + * @param size The number of bytes to generate. + * @param generator The generator for random bytes. + * @return A value containing the desired number of random bytes. + */ + static Bytes random(int size, Random generator) { + byte[] array = new byte[size]; + generator.nextBytes(array); + return Bytes.wrap(array); + } + + /** + * Generate a bytes object filled with the same byte. + * + * @param b the byte to fill the Bytes with + * @param size the size of the object + * @return a value filled with a fixed byte + */ + static Bytes repeat(byte b, int size) { + return new ConstantBytesValue(b, size); + } + + /** + * Splits a Bytes object into Bytes32 objects. If the last element is not exactly 32 bytes, it is right padded with + * zeros. + * + * @param bytes the bytes object to segment + * @return an array of Bytes32 objects + */ + static Bytes32[] segment(Bytes bytes) { + int segments = (int) Math.ceil(bytes.size() / 32.0); + Bytes32[] result = new Bytes32[segments]; + for (int i = 0; i < segments; i++) { + result[i] = Bytes32.rightPad(bytes.slice(i * 32, Math.min(32, bytes.size() - i * 32))); + } + return result; + } + + /** + * + * Provides the number of bytes this value represents. + * + * @return The number of bytes this value represents. + */ + int size(); + + /** + * Retrieve a byte in this value. + * + * @param i The index of the byte to fetch within the value (0-indexed). + * @return The byte at index {@code i} in this value. + * @throws IndexOutOfBoundsException if {@code i < 0} or {i >= size()}. + */ + byte get(int i); + + /** + * Retrieve the 4 bytes starting at the provided index in this value as an integer. + * + * @param i The index from which to get the int, which must less than or equal to {@code size() - 4}. + * @return An integer whose value is the 4 bytes from this value starting at index {@code i}. + * @throws IndexOutOfBoundsException if {@code i < 0} or {@code i > size() - 4}. + */ + default int getInt(int i) { + return getInt(i, BIG_ENDIAN); + } + + /** + * Retrieve the 4 bytes starting at the provided index in this value as an integer. + * + * @param i The index from which to get the int, which must less than or equal to {@code size() - 4}. + * @param order The byte-order for decoding the integer. + * @return An integer whose value is the 4 bytes from this value starting at index {@code i}. + * @throws IndexOutOfBoundsException if {@code i < 0} or {@code i > size() - 4}. + */ + default int getInt(int i, ByteOrder order) { + int size = size(); + checkElementIndex(i, size); + if (i > (size - 4)) { + throw new IndexOutOfBoundsException( + format("Value of size %s has not enough bytes to read a 4 bytes int from index %s", size, i)); + } + + int value = 0; + if (order == BIG_ENDIAN) { + value |= ((int) get(i) & 0xFF) << 24; + value |= ((int) get(i + 1) & 0xFF) << 16; + value |= ((int) get(i + 2) & 0xFF) << 8; + value |= ((int) get(i + 3) & 0xFF); + } else { + value |= ((int) get(i + 3) & 0xFF) << 24; + value |= ((int) get(i + 2) & 0xFF) << 16; + value |= ((int) get(i + 1) & 0xFF) << 8; + value |= ((int) get(i) & 0xFF); + } + return value; + } + + /** + * The value corresponding to interpreting these bytes as an integer. + * + * @return An value corresponding to this value interpreted as an integer. + * @throws IllegalArgumentException if {@code size() > 4}. + */ + default int toInt() { + return toInt(BIG_ENDIAN); + } + + /** + * The value corresponding to interpreting these bytes as an integer. + * + * @param order The byte-order for decoding the integer. + * @return An value corresponding to this value interpreted as an integer. + * @throws IllegalArgumentException if {@code size() > 4}. + */ + default int toInt(ByteOrder order) { + int size = size(); + checkArgument(size <= 4, "Value of size %s has more than 4 bytes", size()); + if (size == 0) { + return 0; + } + if (order == BIG_ENDIAN) { + int i = size; + int value = ((int) get(--i) & 0xFF); + if (i == 0) { + return value; + } + value |= ((int) get(--i) & 0xFF) << 8; + if (i == 0) { + return value; + } + value |= ((int) get(--i) & 0xFF) << 16; + if (i == 0) { + return value; + } + return value | ((int) get(--i) & 0xFF) << 24; + } else { + int i = 0; + int value = ((int) get(i) & 0xFF); + if (++i == size) { + return value; + } + value |= ((int) get(i++) & 0xFF) << 8; + if (i == size) { + return value; + } + value |= ((int) get(i++) & 0xFF) << 16; + if (i == size) { + return value; + } + return value | ((int) get(i) & 0xFF) << 24; + } + } + + /** + * Whether this value contains no bytes. + * + * @return true if the value contains no bytes + */ + default boolean isEmpty() { + return size() == 0; + } + + /** + * Retrieves the 8 bytes starting at the provided index in this value as a long. + * + * @param i The index from which to get the long, which must less than or equal to {@code size() - 8}. + * @return A long whose value is the 8 bytes from this value starting at index {@code i}. + * @throws IndexOutOfBoundsException if {@code i < 0} or {@code i > size() - 8}. + */ + default long getLong(int i) { + return getLong(i, BIG_ENDIAN); + } + + /** + * Retrieves the 8 bytes starting at the provided index in this value as a long. + * + * @param i The index from which to get the long, which must less than or equal to {@code size() - 8}. + * @param order The byte-order for decoding the integer. + * @return A long whose value is the 8 bytes from this value starting at index {@code i}. + * @throws IndexOutOfBoundsException if {@code i < 0} or {@code i > size() - 8}. + */ + default long getLong(int i, ByteOrder order) { + int size = size(); + checkElementIndex(i, size); + if (i > (size - 8)) { + throw new IndexOutOfBoundsException( + format("Value of size %s has not enough bytes to read a 8 bytes long from index %s", size, i)); + } + + long value = 0; + if (order == BIG_ENDIAN) { + value |= ((long) get(i) & 0xFF) << 56; + value |= ((long) get(i + 1) & 0xFF) << 48; + value |= ((long) get(i + 2) & 0xFF) << 40; + value |= ((long) get(i + 3) & 0xFF) << 32; + value |= ((long) get(i + 4) & 0xFF) << 24; + value |= ((long) get(i + 5) & 0xFF) << 16; + value |= ((long) get(i + 6) & 0xFF) << 8; + value |= ((long) get(i + 7) & 0xFF); + } else { + value |= ((long) get(i + 7) & 0xFF) << 56; + value |= ((long) get(i + 6) & 0xFF) << 48; + value |= ((long) get(i + 5) & 0xFF) << 40; + value |= ((long) get(i + 4) & 0xFF) << 32; + value |= ((long) get(i + 3) & 0xFF) << 24; + value |= ((long) get(i + 2) & 0xFF) << 16; + value |= ((long) get(i + 1) & 0xFF) << 8; + value |= ((long) get(i) & 0xFF); + } + return value; + } + + /** + * The value corresponding to interpreting these bytes as a long. + * + * @return An value corresponding to this value interpreted as a long. + * @throws IllegalArgumentException if {@code size() > 8}. + */ + default long toLong() { + return toLong(BIG_ENDIAN); + } + + /** + * The value corresponding to interpreting these bytes as a long. + * + * @param order The byte-order for decoding the integer. + * @return An value corresponding to this value interpreted as a long. + * @throws IllegalArgumentException if {@code size() > 8}. + */ + default long toLong(ByteOrder order) { + int size = size(); + checkArgument(size <= 8, "Value of size %s has more than 8 bytes", size()); + if (size == 0) { + return 0; + } + if (order == BIG_ENDIAN) { + int i = size; + long value = ((long) get(--i) & 0xFF); + if (i == 0) { + return value; + } + value |= ((long) get(--i) & 0xFF) << 8; + if (i == 0) { + return value; + } + value |= ((long) get(--i) & 0xFF) << 16; + if (i == 0) { + return value; + } + value |= ((long) get(--i) & 0xFF) << 24; + if (i == 0) { + return value; + } + value |= ((long) get(--i) & 0xFF) << 32; + if (i == 0) { + return value; + } + value |= ((long) get(--i) & 0xFF) << 40; + if (i == 0) { + return value; + } + value |= ((long) get(--i) & 0xFF) << 48; + if (i == 0) { + return value; + } + return value | ((long) get(--i) & 0xFF) << 56; + } else { + int i = 0; + long value = ((long) get(i) & 0xFF); + if (++i == size) { + return value; + } + value |= ((long) get(i) & 0xFF) << 8; + if (++i == size) { + return value; + } + value |= ((long) get(i) & 0xFF) << 16; + if (++i == size) { + return value; + } + value |= ((long) get(i) & 0xFF) << 24; + if (++i == size) { + return value; + } + value |= ((long) get(i) & 0xFF) << 32; + if (++i == size) { + return value; + } + value |= ((long) get(i) & 0xFF) << 40; + if (++i == size) { + return value; + } + value |= ((long) get(i) & 0xFF) << 48; + if (++i == size) { + return value; + } + return value | ((long) get(i) & 0xFF) << 56; + } + } + + /** + * The BigInteger corresponding to interpreting these bytes as a two's-complement signed integer. + * + * @return A {@link BigInteger} corresponding to interpreting these bytes as a two's-complement signed integer. + */ + default BigInteger toBigInteger() { + return toBigInteger(BIG_ENDIAN); + } + + /** + * The BigInteger corresponding to interpreting these bytes as a two's-complement signed integer. + * + * @param order The byte-order for decoding the integer. + * @return A {@link BigInteger} corresponding to interpreting these bytes as a two's-complement signed integer. + */ + default BigInteger toBigInteger(ByteOrder order) { + if (size() == 0) { + return BigInteger.ZERO; + } + return new BigInteger((order == BIG_ENDIAN) ? toArrayUnsafe() : reverse().toArrayUnsafe()); + } + + /** + * The BigInteger corresponding to interpreting these bytes as an unsigned integer. + * + * @return A positive (or zero) {@link BigInteger} corresponding to interpreting these bytes as an unsigned integer. + */ + default BigInteger toUnsignedBigInteger() { + return toUnsignedBigInteger(BIG_ENDIAN); + } + + /** + * The BigInteger corresponding to interpreting these bytes as an unsigned integer. + * + * @param order The byte-order for decoding the integer. + * @return A positive (or zero) {@link BigInteger} corresponding to interpreting these bytes as an unsigned integer. + */ + default BigInteger toUnsignedBigInteger(ByteOrder order) { + return new BigInteger(1, (order == BIG_ENDIAN) ? toArrayUnsafe() : reverse().toArrayUnsafe()); + } + + /** + * Whether this value has only zero bytes. + * + * @return {@code true} if all the bits of this value are zeros. + */ + default boolean isZero() { + for (int i = size() - 1; i >= 0; --i) { + if (get(i) != 0) + return false; + } + return true; + } + + /** + * Whether the bytes start with a zero bit value. + * + * @return true if the first bit equals zero + */ + default boolean hasLeadingZero() { + return size() > 0 && (get(0) & 0x80) == 0; + } + + /** + * Provides the number of zero bits preceding the highest-order ("leftmost") one-bit, or {@code size() * 8} if all + * bits * are zero. + * + * @return The number of zero bits preceding the highest-order ("leftmost") one-bit, or {@code size() * 8} if all bits + * are zero. + */ + default int numberOfLeadingZeros() { + int size = size(); + for (int i = 0; i < size; i++) { + byte b = get(i); + if (b == 0) { + continue; + } + + return (i * 8) + Integer.numberOfLeadingZeros(b & 0xFF) - 3 * 8; + } + return size * 8; + } + + /** + * Whether the bytes start with a zero byte value. + * + * @return true if the first byte equals zero + */ + default boolean hasLeadingZeroByte() { + return size() > 0 && get(0) == 0; + } + + /** + * Provides the number of leading zero bytes of the value + * + * @return The number of leading zero bytes of the value. + */ + default int numberOfLeadingZeroBytes() { + int size = size(); + for (int i = 0; i < size; i++) { + if (get(i) != 0) { + return i; + } + } + return size; + } + + /** + * Provides the number of trailing zero bytes of the value. + * + * @return The number of trailing zero bytes of the value. + */ + default int numberOfTrailingZeroBytes() { + int size = size(); + for (int i = size; i >= 1; i--) { + if (get(i - 1) != 0) { + return size - i; + } + } + return size; + } + + /** + * Provides the number of bits following and including the highest-order ("leftmost") one-bit, or zero if all bits are + * zero. + * + * @return The number of bits following and including the highest-order ("leftmost") one-bit, or zero if all bits are + * zero. + */ + default int bitLength() { + int size = size(); + for (int i = 0; i < size; i++) { + byte b = get(i); + if (b == 0) + continue; + + return (size * 8) - (i * 8) - (Integer.numberOfLeadingZeros(b & 0xFF) - 3 * 8); + } + return 0; + } + + /** + * Return a bit-wise AND of these bytes and the supplied bytes. + * + * If this value and the supplied value are different lengths, then the shorter will be zero-padded to the left. + * + * @param other The bytes to perform the operation with. + * @return The result of a bit-wise AND. + */ + default Bytes and(Bytes other) { + return and(other, MutableBytes.create(Math.max(size(), other.size()))); + } + + /** + * Calculate a bit-wise AND of these bytes and the supplied bytes. + * + *

+ * If this value or the supplied value are shorter in length than the output vector, then they will be zero-padded to + * the left. Likewise, if either this value or the supplied valid is longer in length than the output vector, then + * they will be truncated to the left. + * + * @param other The bytes to perform the operation with. + * @param result The mutable output vector for the result. + * @param The {@link MutableBytes} value type. + * @return The {@code result} output vector. + */ + default T and(Bytes other, T result) { + checkNotNull(other); + checkNotNull(result); + int rSize = result.size(); + int offsetSelf = rSize - size(); + int offsetOther = rSize - other.size(); + for (int i = 0; i < rSize; i++) { + byte b1 = (i < offsetSelf) ? 0x00 : get(i - offsetSelf); + byte b2 = (i < offsetOther) ? 0x00 : other.get(i - offsetOther); + result.set(i, (byte) (b1 & b2)); + } + return result; + } + + /** + * Return a bit-wise OR of these bytes and the supplied bytes. + * + *

+ * If this value and the supplied value are different lengths, then the shorter will be zero-padded to the left. + * + * @param other The bytes to perform the operation with. + * @return The result of a bit-wise OR. + */ + default Bytes or(Bytes other) { + return or(other, MutableBytes.create(Math.max(size(), other.size()))); + } + + /** + * Calculate a bit-wise OR of these bytes and the supplied bytes. + * + *

+ * If this value or the supplied value are shorter in length than the output vector, then they will be zero-padded to + * the left. Likewise, if either this value or the supplied valid is longer in length than the output vector, then + * they will be truncated to the left. + * + * @param other The bytes to perform the operation with. + * @param result The mutable output vector for the result. + * @param The {@link MutableBytes} value type. + * @return The {@code result} output vector. + */ + default T or(Bytes other, T result) { + checkNotNull(other); + checkNotNull(result); + int rSize = result.size(); + int offsetSelf = rSize - size(); + int offsetOther = rSize - other.size(); + for (int i = 0; i < rSize; i++) { + byte b1 = (i < offsetSelf) ? 0x00 : get(i - offsetSelf); + byte b2 = (i < offsetOther) ? 0x00 : other.get(i - offsetOther); + result.set(i, (byte) (b1 | b2)); + } + return result; + } + + /** + * Return a bit-wise XOR of these bytes and the supplied bytes. + * + *

+ * If this value and the supplied value are different lengths, then the shorter will be zero-padded to the left. + * + * @param other The bytes to perform the operation with. + * @return The result of a bit-wise XOR. + */ + default Bytes xor(Bytes other) { + return xor(other, MutableBytes.create(Math.max(size(), other.size()))); + } + + /** + * Calculate a bit-wise XOR of these bytes and the supplied bytes. + * + *

+ * If this value or the supplied value are shorter in length than the output vector, then they will be zero-padded to + * the left. Likewise, if either this value or the supplied valid is longer in length than the output vector, then + * they will be truncated to the left. + * + * @param other The bytes to perform the operation with. + * @param result The mutable output vector for the result. + * @param The {@link MutableBytes} value type. + * @return The {@code result} output vector. + */ + default T xor(Bytes other, T result) { + checkNotNull(other); + checkNotNull(result); + int rSize = result.size(); + int offsetSelf = rSize - size(); + int offsetOther = rSize - other.size(); + for (int i = 0; i < rSize; i++) { + byte b1 = (i < offsetSelf) ? 0x00 : get(i - offsetSelf); + byte b2 = (i < offsetOther) ? 0x00 : other.get(i - offsetOther); + result.set(i, (byte) (b1 ^ b2)); + } + return result; + } + + /** + * Return a bit-wise NOT of these bytes. + * + * @return The result of a bit-wise NOT. + */ + default Bytes not() { + return not(MutableBytes.create(size())); + } + + /** + * Calculate a bit-wise NOT of these bytes. + * + *

+ * If this value is shorter in length than the output vector, then it will be zero-padded to the left. Likewise, if + * this value is longer in length than the output vector, then it will be truncated to the left. + * + * @param result The mutable output vector for the result. + * @param The {@link MutableBytes} value type. + * @return The {@code result} output vector. + */ + default T not(T result) { + checkNotNull(result); + int rSize = result.size(); + int offsetSelf = rSize - size(); + for (int i = 0; i < rSize; i++) { + byte b1 = (i < offsetSelf) ? 0x00 : get(i - offsetSelf); + result.set(i, (byte) ~b1); + } + return result; + } + + /** + * Shift all bits in this value to the right. + * + * @param distance The number of bits to shift by. + * @return A value containing the shifted bits. + */ + default Bytes shiftRight(int distance) { + return shiftRight(distance, MutableBytes.create(size())); + } + + /** + * Shift all bits in this value to the right. + * + *

+ * If this value is shorter in length than the output vector, then it will be zero-padded to the left. Likewise, if + * this value is longer in length than the output vector, then it will be truncated to the left (after shifting). + * + * @param distance The number of bits to shift by. + * @param result The mutable output vector for the result. + * @param The {@link MutableBytes} value type. + * @return The {@code result} output vector. + */ + default T shiftRight(int distance, T result) { + checkNotNull(result); + int rSize = result.size(); + int offsetSelf = rSize - size(); + + int d = distance / 8; + int s = distance % 8; + int resIdx = rSize - 1; + for (int i = rSize - 1 - d; i >= 0; i--) { + byte res; + if (i < offsetSelf) { + res = 0; + } else { + int selfIdx = i - offsetSelf; + int leftSide = (get(selfIdx) & 0xFF) >>> s; + int rightSide = (selfIdx == 0) ? 0 : get(selfIdx - 1) << (8 - s); + res = (byte) (leftSide | rightSide); + } + result.set(resIdx--, res); + } + for (; resIdx >= 0; resIdx--) { + result.set(resIdx, (byte) 0); + } + return result; + } + + /** + * Shift all bits in this value to the left. + * + * @param distance The number of bits to shift by. + * @return A value containing the shifted bits. + */ + default Bytes shiftLeft(int distance) { + return shiftLeft(distance, MutableBytes.create(size())); + } + + /** + * Shift all bits in this value to the left. + * + *

+ * If this value is shorter in length than the output vector, then it will be zero-padded to the left. Likewise, if + * this value is longer in length than the output vector, then it will be truncated to the left. + * + * @param distance The number of bits to shift by. + * @param result The mutable output vector for the result. + * @param The {@link MutableBytes} value type. + * @return The {@code result} output vector. + */ + default T shiftLeft(int distance, T result) { + checkNotNull(result); + int size = size(); + int rSize = result.size(); + int offsetSelf = rSize - size; + + int d = distance / 8; + int s = distance % 8; + int resIdx = 0; + for (int i = d; i < rSize; i++) { + byte res; + if (i < offsetSelf) { + res = 0; + } else { + int selfIdx = i - offsetSelf; + int leftSide = get(selfIdx) << s; + int rightSide = (selfIdx == size - 1) ? 0 : (get(selfIdx + 1) & 0xFF) >>> (8 - s); + res = (byte) (leftSide | rightSide); + } + result.set(resIdx++, res); + } + for (; resIdx < rSize; resIdx++) { + result.set(resIdx, (byte) 0); + } + return result; + } + + /** + * Create a new value representing (a view of) a slice of the bytes of this value. + * + *

+ * Please note that the resulting slice is only a view and as such maintains a link to the underlying full value. So + * holding a reference to the returned slice may hold more memory than the slide represents. Use {@link #copy} on the + * returned slice if that is not what you want. + * + * @param i The start index for the slice. + * @return A new value providing a view over the bytes from index {@code i} (included) to the end. + * @throws IndexOutOfBoundsException if {@code i < 0}. + */ + default Bytes slice(int i) { + if (i == 0) { + return this; + } + int size = size(); + if (i >= size) { + return EMPTY; + } + return slice(i, size - i); + } + + /** + * Create a new value representing (a view of) a slice of the bytes of this value. + * + *

+ * Please note that the resulting slice is only a view and as such maintains a link to the underlying full value. So + * holding a reference to the returned slice may hold more memory than the slide represents. Use {@link #copy} on the + * returned slice if that is not what you want. + * + * @param i The start index for the slice. + * @param length The length of the resulting value. + * @return A new value providing a view over the bytes from index {@code i} (included) to {@code i + length} + * (excluded). + * @throws IllegalArgumentException if {@code length < 0}. + * @throws IndexOutOfBoundsException if {@code i < 0} or {i >= size()} or {i + length > size()} . + */ + Bytes slice(int i, int length); + + /** + * Return a value equivalent to this one but guaranteed to 1) be deeply immutable (i.e. the underlying value will be + * immutable) and 2) to not retain more bytes than exposed by the value. + * + * @return A value, equals to this one, but deeply immutable and that doesn't retain any "unreachable" bytes. For + * performance reasons, this is allowed to return this value however if it already fit those constraints. + */ + Bytes copy(); + + /** + * Return a new mutable value initialized with the content of this value. + * + * @return A mutable copy of this value. This will copy bytes, modifying the returned value will not modify + * this value. + */ + MutableBytes mutableCopy(); + + /** + * Copy the bytes of this value to the provided mutable one, which must have the same size. + * + * @param destination The mutable value to which to copy the bytes to, which must have the same size as this value. If + * you want to copy value where size differs, you should use {@link #slice} and/or + * {@link MutableBytes#mutableSlice} and apply the copy to the result. + * @throws IllegalArgumentException if {@code this.size() != destination.size()}. + */ + default void copyTo(MutableBytes destination) { + checkNotNull(destination); + checkArgument( + destination.size() == size(), + "Cannot copy %s bytes to destination of non-equal size %s", + size(), + destination.size()); + copyTo(destination, 0); + } + + /** + * Copy the bytes of this value to the provided mutable one from a particular offset. + * + *

+ * This is a (potentially slightly more efficient) shortcut for {@code + * copyTo(destination.mutableSlice(destinationOffset, this.size()))}. + * + * @param destination The mutable value to which to copy the bytes to, which must have enough bytes from + * {@code destinationOffset} for the copied value. + * @param destinationOffset The offset in {@code destination} at which the copy starts. + * @throws IllegalArgumentException if the destination doesn't have enough room, that is if {@code + * this.size() > (destination.size() - destinationOffset)}. + */ + default void copyTo(MutableBytes destination, int destinationOffset) { + checkNotNull(destination); + + // Special casing an empty source or the following checks might throw (even though we have + // nothing to copy anyway) and this gets inconvenient for generic methods using copyTo() as + // they may have to special case empty values because of this. As an example, + // concatenate(EMPTY, EMPTY) would need to be special cased without this. + int size = size(); + if (size == 0) { + return; + } + + checkElementIndex(destinationOffset, destination.size()); + checkArgument( + destination.size() - destinationOffset >= size, + "Cannot copy %s bytes, destination has only %s bytes from index %s", + size, + destination.size() - destinationOffset, + destinationOffset); + + destination.set(destinationOffset, this); + } + + /** + * Append the bytes of this value to the {@link ByteBuffer}. + * + * @param byteBuffer The {@link ByteBuffer} to which to append this value. + * @throws BufferOverflowException If the writer attempts to write more than the provided buffer can hold. + * @throws ReadOnlyBufferException If the provided buffer is read-only. + */ + default void appendTo(ByteBuffer byteBuffer) { + checkNotNull(byteBuffer); + for (int i = 0; i < size(); i++) { + byteBuffer.put(get(i)); + } + } + + /** + * Append the bytes of this value to the provided Vert.x {@link Buffer}. + * + *

+ * Note that since a Vert.x {@link Buffer} will grow as necessary, this method never fails. + * + * @param buffer The {@link Buffer} to which to append this value. + */ + default void appendTo(Buffer buffer) { + checkNotNull(buffer); + for (int i = 0; i < size(); i++) { + buffer.appendByte(get(i)); + } + } + + /** + * Append this value as a sequence of hexadecimal characters. + * + * @param appendable The appendable + * @param The appendable type. + * @return The appendable. + */ + default T appendHexTo(T appendable) { + try { + appendable.append(toFastHex(false)); + return appendable; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + default String toFastHex(boolean prefix) { + + int offset = prefix ? 2 : 0; + + int resultSize = (size() * 2) + offset; + + char[] result = new char[resultSize]; + + if (prefix) { + result[0] = '0'; + result[1] = 'x'; + } + + for (int i = 0; i < size(); i++) { + byte b = get(i); + int pos = i * 2; + result[pos + offset] = AbstractBytes.HEX_CODE_AS_STRING.charAt(b >> 4 & 15); + result[pos + offset + 1] = AbstractBytes.HEX_CODE_AS_STRING.charAt(b & 15); + } + + return new String(result); + + } + + /** + * Return the number of bytes in common between this set of bytes and another. + * + * @param other The bytes to compare to. + * @return The number of common bytes. + */ + default int commonPrefixLength(Bytes other) { + checkNotNull(other); + int ourSize = size(); + int otherSize = other.size(); + int i = 0; + while (i < ourSize && i < otherSize && get(i) == other.get(i)) { + i++; + } + return i; + } + + /** + * Return a slice over the common prefix between this set of bytes and another. + * + * @param other The bytes to compare to. + * @return A slice covering the common prefix. + */ + default Bytes commonPrefix(Bytes other) { + return slice(0, commonPrefixLength(other)); + } + + /** + * Return a slice of representing the same value but without any leading zero bytes. + * + * @return {@code value} if its left-most byte is non zero, or a slice that exclude any leading zero bytes. + */ + default Bytes trimLeadingZeros() { + int size = size(); + for (int i = 0; i < size; i++) { + if (get(i) != 0) { + return slice(i); + } + } + return Bytes.EMPTY; + } + + /** + * Return a slice of representing the same value but without any trailing zero bytes. + * + * @return {@code value} if its right-most byte is non zero, or a slice that exclude any trailing zero bytes. + */ + default Bytes trimTrailingZeros() { + int size = size(); + for (int i = size - 1; i >= 0; i--) { + if (get(i) != 0) { + return slice(0, i + 1); + } + } + return Bytes.EMPTY; + } + + /** + * Update the provided message digest with the bytes of this value. + * + * @param digest The digest to update. + */ + default void update(MessageDigest digest) { + checkNotNull(digest); + digest.update(toArrayUnsafe()); + } + + /** + * Computes the reverse array of bytes of the current bytes. + * + * @return a new Bytes value, containing the bytes in reverse order + */ + default Bytes reverse() { + byte[] reverse = new byte[size()]; + for (int i = 0; i < size(); i++) { + reverse[size() - i - 1] = get(i); + } + return Bytes.wrap(reverse); + } + + /** + * Extract the bytes of this value into a byte array. + * + * @return A byte array with the same content than this value. + */ + default byte[] toArray() { + return toArray(BIG_ENDIAN); + } + + /** + * Extract the bytes of this value into a byte array. + * + * @param byteOrder the byte order to apply : big endian or little endian + * @return A byte array with the same content than this value. + */ + default byte[] toArray(ByteOrder byteOrder) { + int size = size(); + byte[] array = new byte[size]; + if (byteOrder == BIG_ENDIAN) { + for (int i = 0; i < size; i++) { + array[i] = get(i); + } + } else { + for (int i = 0; i < size(); i++) { + array[size() - i - 1] = get(i); + } + } + return array; + } + + /** + * Get the bytes represented by this value as byte array. + * + *

+ * Contrarily to {@link #toArray()}, this may avoid allocating a new array and directly return the backing array of + * this value if said value is array backed and doing so is possible. As such, modifications to the returned array may + * or may not impact this value. As such, this method should be used with care and hence the "unsafe" moniker. + * + * @return A byte array with the same content than this value, which may or may not be the direct backing of this + * value. + */ + default byte[] toArrayUnsafe() { + return toArray(); + } + + /** + * Return the hexadecimal string representation of this value. + * + * @return The hexadecimal representation of this value, starting with "0x". + */ + @Override + String toString(); + + /** + * Provides this value represented as hexadecimal, starting with "0x". + * + * @return This value represented as hexadecimal, starting with "0x". + */ + default String toHexString() { + return toFastHex(true); + } + + /** + * Provides this value represented as hexadecimal, with no prefix + * + * @return This value represented as hexadecimal, with no prefix. + */ + default String toUnprefixedHexString() { + return toFastHex(false); + } + + default String toEllipsisHexString() { + int size = size(); + if (size < 6) { + return toHexString(); + } + char[] result = new char[12]; + result[0] = '0'; + result[1] = 'x'; + for (int i = 0; i < 2; i++) { + byte b = get(i); + int pos = (i * 2) + 2; + result[pos] = AbstractBytes.HEX_CODE_AS_STRING.charAt(b >> 4 & 15); + result[pos + 1] = AbstractBytes.HEX_CODE_AS_STRING.charAt(b & 15); + } + result[6] = '.'; + result[7] = '.'; + for (int i = 0; i < 2; i++) { + byte b = get(i + size - 2); + int pos = (i * 2) + 8; + result[pos] = AbstractBytes.HEX_CODE_AS_STRING.charAt(b >> 4 & 15); + result[pos + 1] = AbstractBytes.HEX_CODE_AS_STRING.charAt(b & 15); + } + return new String(result); + } + + /** + * Provides this value represented as a minimal hexadecimal string (without any leading zero) + * + * @return This value represented as a minimal hexadecimal string (without any leading zero). + */ + default String toShortHexString() { + String hex = toFastHex(false); + + int i = 0; + while (i < hex.length() && hex.charAt(i) == '0') { + i++; + } + return "0x" + hex.substring(i); + } + + /** + * Provides this value represented as a minimal hexadecimal string (without any leading zero, except if it's valued + * zero or empty, in which case it returns 0x0). + * + * @return This value represented as a minimal hexadecimal string (without any leading zero, except if it's valued + * zero or empty, in which case it returns 0x0). + */ + default String toQuantityHexString() { + if (Bytes.EMPTY.equals(this)) { + return "0x0"; + } + String hex = toFastHex(false); + + int i = 0; + while (i < hex.length() - 1 && hex.charAt(i) == '0') { + i++; + } + return "0x" + hex.substring(i); + } + + /** + * Provides this value represented as base 64 + * + * @return This value represented as base 64. + */ + default String toBase64String() { + return Base64.getEncoder().encodeToString(toArrayUnsafe()); + } + + @Override + default int compareTo(Bytes b) { + checkNotNull(b); + + int bitLength = bitLength(); + int sizeCmp = Integer.compare(bitLength, b.bitLength()); + if (sizeCmp != 0) { + return sizeCmp; + } + // same bitlength and is zeroes only, return 0. + if (bitLength == 0) { + return 0; + } + + for (int i = 0; i < size(); i++) { + int cmp = Integer.compare(get(i) & 0xff, b.get(i) & 0xff); + if (cmp != 0) { + return cmp; + } + } + return 0; + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/Bytes32.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/Bytes32.java new file mode 100644 index 00000000000..e4380b787e0 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/Bytes32.java @@ -0,0 +1,340 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import java.security.SecureRandom; +import java.util.Random; + +import static org.apache.tuweni.bytes.Checks.checkArgument; +import static org.apache.tuweni.bytes.Checks.checkNotNull; + +/** + * A {@link Bytes} value that is guaranteed to contain exactly 32 bytes. + */ +public interface Bytes32 extends Bytes { + /** The number of bytes in this value - i.e. 32 */ + int SIZE = 32; + + /** A {@code Bytes32} containing all zero bytes */ + Bytes32 ZERO = Bytes32.repeat((byte) 0); + + /** + * Generate a bytes object filled with the same byte. + * + * @param b the byte to fill the Bytes with + * @return a value filled with a fixed byte + */ + static Bytes32 repeat(byte b) { + return new ConstantBytes32Value(b); + } + + /** + * Wrap the provided byte array, which must be of length 32, as a {@link Bytes32}. + * + *

+ * Note that value is not copied, only wrapped, and thus any future update to {@code value} will be reflected in the + * returned value. + * + * @param bytes The bytes to wrap. + * @return A {@link Bytes32} wrapping {@code value}. + * @throws IllegalArgumentException if {@code value.length != 32}. + */ + static Bytes32 wrap(byte[] bytes) { + checkNotNull(bytes); + checkArgument(bytes.length == SIZE, "Expected %s bytes but got %s", SIZE, bytes.length); + return wrap(bytes, 0); + } + + /** + * Wrap a slice/sub-part of the provided array as a {@link Bytes32}. + * + *

+ * Note that value is not copied, only wrapped, and thus any future update to {@code value} within the wrapped parts + * will be reflected in the returned value. + * + * @param bytes The bytes to wrap. + * @param offset The index (inclusive) in {@code value} of the first byte exposed by the returned value. In other + * words, you will have {@code wrap(value, i).get(0) == value[i]}. + * @return A {@link Bytes32} that exposes the bytes of {@code value} from {@code offset} (inclusive) to + * {@code offset + 32} (exclusive). + * @throws IndexOutOfBoundsException if {@code offset < 0 || (value.length > 0 && offset >= + * value.length)}. + * @throws IllegalArgumentException if {@code length < 0 || offset + 32 > value.length}. + */ + static Bytes32 wrap(byte[] bytes, int offset) { + checkNotNull(bytes); + return new ArrayWrappingBytes32(bytes, offset); + } + + /** + * Secures the provided byte array, which must be of length 32, as a {@link Bytes32}. + * + * @param bytes The bytes to secure. + * @return A {@link Bytes32} securing {@code value}. + * @throws IllegalArgumentException if {@code value.length != 32}. + */ + static Bytes32 secure(byte[] bytes) { + checkNotNull(bytes); + checkArgument(bytes.length == SIZE, "Expected %s bytes but got %s", SIZE, bytes.length); + return secure(bytes, 0); + } + + /** + * Secures a slice/sub-part of the provided array as a {@link Bytes32}. + * + * @param bytes The bytes to secure. + * @param offset The index (inclusive) in {@code value} of the first byte exposed by the returned value. In other + * words, you will have {@code wrap(value, i).get(0) == value[i]}. + * @return A {@link Bytes32} that holds securely the bytes of {@code value} from {@code offset} (inclusive) to + * {@code offset + 32} (exclusive). + * @throws IndexOutOfBoundsException if {@code offset < 0 || (value.length > 0 && offset >= + * value.length)}. + * @throws IllegalArgumentException if {@code length < 0 || offset + 32 > value.length}. + */ + static Bytes32 secure(byte[] bytes, int offset) { + checkNotNull(bytes); + return new GuardedByteArrayBytes32(bytes, offset); + } + + /** + * Wrap a the provided value, which must be of size 32, as a {@link Bytes32}. + * + *

+ * Note that value is not copied, only wrapped, and thus any future update to {@code value} will be reflected in the + * returned value. + * + * @param value The bytes to wrap. + * @return A {@link Bytes32} that exposes the bytes of {@code value}. + * @throws IllegalArgumentException if {@code value.size() != 32}. + */ + static Bytes32 wrap(Bytes value) { + checkNotNull(value); + if (value instanceof Bytes32) { + return (Bytes32) value; + } + checkArgument(value.size() == SIZE, "Expected %s bytes but got %s", SIZE, value.size()); + return new DelegatingBytes32(value); + } + + /** + * Wrap a slice/sub-part of the provided value as a {@link Bytes32}. + * + *

+ * Note that value is not copied, only wrapped, and thus any future update to {@code value} within the wrapped parts + * will be reflected in the returned value. + * + * @param value The bytes to wrap. + * @param offset The index (inclusive) in {@code value} of the first byte exposed by the returned value. In other + * words, you will have {@code wrap(value, i).get(0) == value.get(i)}. + * @return A {@link Bytes32} that exposes the bytes of {@code value} from {@code offset} (inclusive) to + * {@code offset + 32} (exclusive). + * @throws IndexOutOfBoundsException if {@code offset < 0 || (value.size() > 0 && offset >= + * value.size())}. + * @throws IllegalArgumentException if {@code length < 0 || offset + 32 > value.size()}. + */ + static Bytes32 wrap(Bytes value, int offset) { + checkNotNull(value); + Bytes slice = value.slice(offset, Bytes32.SIZE); + if (slice instanceof Bytes32) { + return (Bytes32) slice; + } + return new DelegatingBytes32(slice); + } + + /** + * Left pad a {@link Bytes} value with a fill byte to create a {@link Bytes32}. + * + * @param value The bytes value pad. + * @param fill the byte to fill with + * @return A {@link Bytes32} that exposes the left-padded bytes of {@code value}. + * @throws IllegalArgumentException if {@code value.size() > 32}. + */ + static Bytes32 leftPad(Bytes value, byte fill) { + checkNotNull(value); + if (value instanceof Bytes32) { + return (Bytes32) value; + } + checkArgument(value.size() <= SIZE, "Expected at most %s bytes but got %s", SIZE, value.size()); + MutableBytes32 result = MutableBytes32.create(); + result.fill(fill); + value.copyTo(result, SIZE - value.size()); + return result; + } + + /** + * Left pad a {@link Bytes} value with zero bytes to create a {@link Bytes32}. + * + * @param value The bytes value pad. + * @return A {@link Bytes32} that exposes the left-padded bytes of {@code value}. + * @throws IllegalArgumentException if {@code value.size() > 32}. + */ + static Bytes32 leftPad(Bytes value) { + checkNotNull(value); + if (value instanceof Bytes32) { + return (Bytes32) value; + } + checkArgument(value.size() <= SIZE, "Expected at most %s bytes but got %s", SIZE, value.size()); + MutableBytes32 result = MutableBytes32.create(); + value.copyTo(result, SIZE - value.size()); + return result; + } + + /** + * Right pad a {@link Bytes} value with zero bytes to create a {@link Bytes32}. + * + * @param value The bytes value pad. + * @return A {@link Bytes32} that exposes the rightw-padded bytes of {@code value}. + * @throws IllegalArgumentException if {@code value.size() > 32}. + */ + static Bytes32 rightPad(Bytes value) { + checkNotNull(value); + if (value instanceof Bytes32) { + return (Bytes32) value; + } + checkArgument(value.size() <= SIZE, "Expected at most %s bytes but got %s", SIZE, value.size()); + MutableBytes32 result = MutableBytes32.create(); + value.copyTo(result, 0); + return result; + } + + /** + * Parse a hexadecimal string into a {@link Bytes32}. + * + *

+ * This method is lenient in that {@code str} may of an odd length, in which case it will behave exactly as if it had + * an additional 0 in front. + * + * @param str The hexadecimal string to parse, which may or may not start with "0x". That representation may contain + * less than 32 bytes, in which case the result is left padded with zeros (see {@link #fromHexStringStrict} if + * this is not what you want). + * @return The value corresponding to {@code str}. + * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation or + * contains more than 32 bytes. + */ + static Bytes32 fromHexStringLenient(CharSequence str) { + checkNotNull(str); + return wrap(BytesValues.fromRawHexString(str, SIZE, true)); + } + + /** + * Parse a hexadecimal string into a {@link Bytes32}. + * + *

+ * This method is strict in that {@code str} must of an even length. + * + * @param str The hexadecimal string to parse, which may or may not start with "0x". That representation may contain + * less than 32 bytes, in which case the result is left padded with zeros (see {@link #fromHexStringStrict} if + * this is not what you want). + * @return The value corresponding to {@code str}. + * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation, is of an + * odd length, or contains more than 32 bytes. + */ + static Bytes32 fromHexString(CharSequence str) { + checkNotNull(str); + return wrap(BytesValues.fromRawHexString(str, SIZE, false)); + } + + /** + * Generate random bytes. + * + * @return A value containing random bytes. + */ + static Bytes32 random() { + return random(new SecureRandom()); + } + + /** + * Generate random bytes. + * + * @param generator The generator for random bytes. + * @return A value containing random bytes. + */ + static Bytes32 random(Random generator) { + byte[] array = new byte[32]; + generator.nextBytes(array); + return wrap(array); + } + + /** + * Parse a hexadecimal string into a {@link Bytes32}. + * + *

+ * This method is extra strict in that {@code str} must of an even length and the provided representation must have + * exactly 32 bytes. + * + * @param str The hexadecimal string to parse, which may or may not start with "0x". + * @return The value corresponding to {@code str}. + * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation, is of an + * odd length or does not contain exactly 32 bytes. + */ + static Bytes32 fromHexStringStrict(CharSequence str) { + checkNotNull(str); + return wrap(BytesValues.fromRawHexString(str, -1, false)); + } + + @Override + default int size() { + return SIZE; + } + + /** + * Return a bit-wise AND of these bytes and the supplied bytes. + * + * @param other The bytes to perform the operation with. + * @return The result of a bit-wise AND. + */ + default Bytes32 and(Bytes32 other) { + return and(other, MutableBytes32.create()); + } + + /** + * Return a bit-wise OR of these bytes and the supplied bytes. + * + * @param other The bytes to perform the operation with. + * @return The result of a bit-wise OR. + */ + default Bytes32 or(Bytes32 other) { + return or(other, MutableBytes32.create()); + } + + /** + * Return a bit-wise XOR of these bytes and the supplied bytes. + * + * @param other The bytes to perform the operation with. + * @return The result of a bit-wise XOR. + */ + default Bytes32 xor(Bytes32 other) { + return xor(other, MutableBytes32.create()); + } + + @Override + default Bytes32 not() { + return not(MutableBytes32.create()); + } + + @Override + default Bytes32 shiftRight(int distance) { + return shiftRight(distance, MutableBytes32.create()); + } + + @Override + default Bytes32 shiftLeft(int distance) { + return shiftLeft(distance, MutableBytes32.create()); + } + + @Override + Bytes32 copy(); + + @Override + MutableBytes32 mutableCopy(); +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/Bytes48.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/Bytes48.java new file mode 100644 index 00000000000..30d7c5a8e83 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/Bytes48.java @@ -0,0 +1,284 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import java.security.SecureRandom; +import java.util.Random; + +import static org.apache.tuweni.bytes.Checks.checkArgument; +import static org.apache.tuweni.bytes.Checks.checkNotNull; + +/** + * A {@link Bytes} value that is guaranteed to contain exactly 48 bytes. + */ +public interface Bytes48 extends Bytes { + /** The number of bytes in this value - i.e. 48 */ + int SIZE = 48; + + /** A {@code Bytes48} containing all zero bytes */ + Bytes48 ZERO = wrap(new byte[SIZE]); + + /** + * Wrap the provided byte array, which must be of length 48, as a {@link Bytes48}. + * + *

+ * Note that value is not copied, only wrapped, and thus any future update to {@code value} will be reflected in the + * returned value. + * + * @param bytes The bytes to wrap. + * @return A {@link Bytes48} wrapping {@code value}. + * @throws IllegalArgumentException if {@code value.length != 48}. + */ + static Bytes48 wrap(byte[] bytes) { + checkNotNull(bytes); + checkArgument(bytes.length == SIZE, "Expected %s bytes but got %s", SIZE, bytes.length); + return wrap(bytes, 0); + } + + /** + * Wrap a slice/sub-part of the provided array as a {@link Bytes48}. + * + *

+ * Note that value is not copied, only wrapped, and thus any future update to {@code value} within the wrapped parts + * will be reflected in the returned value. + * + * @param bytes The bytes to wrap. + * @param offset The index (inclusive) in {@code value} of the first byte exposed by the returned value. In other + * words, you will have {@code wrap(value, i).get(0) == value[i]}. + * @return A {@link Bytes48} that exposes the bytes of {@code value} from {@code offset} (inclusive) to + * {@code offset + 48} (exclusive). + * @throws IndexOutOfBoundsException if {@code offset < 0 || (value.length > 0 && offset >= + * value.length)}. + * @throws IllegalArgumentException if {@code length < 0 || offset + 48 > value.length}. + */ + static Bytes48 wrap(byte[] bytes, int offset) { + checkNotNull(bytes); + return new ArrayWrappingBytes48(bytes, offset); + } + + /** + * Wrap a the provided value, which must be of size 48, as a {@link Bytes48}. + * + *

+ * Note that value is not copied, only wrapped, and thus any future update to {@code value} will be reflected in the + * returned value. + * + * @param value The bytes to wrap. + * @return A {@link Bytes48} that exposes the bytes of {@code value}. + * @throws IllegalArgumentException if {@code value.size() != 48}. + */ + static Bytes48 wrap(Bytes value) { + checkNotNull(value); + if (value instanceof Bytes48) { + return (Bytes48) value; + } + checkArgument(value.size() == SIZE, "Expected %s bytes but got %s", SIZE, value.size()); + return new DelegatingBytes48(value); + } + + /** + * Wrap a slice/sub-part of the provided value as a {@link Bytes48}. + * + *

+ * Note that value is not copied, only wrapped, and thus any future update to {@code value} within the wrapped parts + * will be reflected in the returned value. + * + * @param value The bytes to wrap. + * @param offset The index (inclusive) in {@code value} of the first byte exposed by the returned value. In other + * words, you will have {@code wrap(value, i).get(0) == value.get(i)}. + * @return A {@link Bytes48} that exposes the bytes of {@code value} from {@code offset} (inclusive) to + * {@code offset + 48} (exclusive). + * @throws IndexOutOfBoundsException if {@code offset < 0 || (value.size() > 0 && offset >= + * value.size())}. + * @throws IllegalArgumentException if {@code length < 0 || offset + 48 > value.size()}. + */ + static Bytes48 wrap(Bytes value, int offset) { + checkNotNull(value); + if (value instanceof Bytes48) { + return (Bytes48) value; + } + Bytes slice = value.slice(offset, Bytes48.SIZE); + if (slice instanceof Bytes48) { + return (Bytes48) slice; + } + return new DelegatingBytes48(Bytes48.wrap(slice)); + } + + /** + * Left pad a {@link Bytes} value with zero bytes to create a {@link Bytes48}. + * + * @param value The bytes value pad. + * @return A {@link Bytes48} that exposes the left-padded bytes of {@code value}. + * @throws IllegalArgumentException if {@code value.size() > 48}. + */ + static Bytes48 leftPad(Bytes value) { + checkNotNull(value); + if (value instanceof Bytes48) { + return (Bytes48) value; + } + checkArgument(value.size() <= SIZE, "Expected at most %s bytes but got %s", SIZE, value.size()); + MutableBytes48 result = MutableBytes48.create(); + value.copyTo(result, SIZE - value.size()); + return result; + } + + + /** + * Right pad a {@link Bytes} value with zero bytes to create a {@link Bytes48}. + * + * @param value The bytes value pad. + * @return A {@link Bytes48} that exposes the rightw-padded bytes of {@code value}. + * @throws IllegalArgumentException if {@code value.size() > 48}. + */ + static Bytes48 rightPad(Bytes value) { + checkNotNull(value); + if (value instanceof Bytes48) { + return (Bytes48) value; + } + checkArgument(value.size() <= SIZE, "Expected at most %s bytes but got %s", SIZE, value.size()); + MutableBytes48 result = MutableBytes48.create(); + value.copyTo(result, 0); + return result; + } + + /** + * Parse a hexadecimal string into a {@link Bytes48}. + * + *

+ * This method is lenient in that {@code str} may of an odd length, in which case it will behave exactly as if it had + * an additional 0 in front. + * + * @param str The hexadecimal string to parse, which may or may not start with "0x". That representation may contain + * less than 48 bytes, in which case the result is left padded with zeros (see {@link #fromHexStringStrict} if + * this is not what you want). + * @return The value corresponding to {@code str}. + * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation or + * contains more than 48 bytes. + */ + static Bytes48 fromHexStringLenient(CharSequence str) { + checkNotNull(str); + return wrap(BytesValues.fromRawHexString(str, SIZE, true)); + } + + /** + * Parse a hexadecimal string into a {@link Bytes48}. + * + *

+ * This method is strict in that {@code str} must of an even length. + * + * @param str The hexadecimal string to parse, which may or may not start with "0x". That representation may contain + * less than 48 bytes, in which case the result is left padded with zeros (see {@link #fromHexStringStrict} if + * this is not what you want). + * @return The value corresponding to {@code str}. + * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation, is of an + * odd length, or contains more than 48 bytes. + */ + static Bytes48 fromHexString(CharSequence str) { + checkNotNull(str); + return wrap(BytesValues.fromRawHexString(str, SIZE, false)); + } + + /** + * Generate random bytes. + * + * @return A value containing random bytes. + */ + static Bytes48 random() { + return random(new SecureRandom()); + } + + /** + * Generate random bytes. + * + * @param generator The generator for random bytes. + * @return A value containing random bytes. + */ + static Bytes48 random(Random generator) { + byte[] array = new byte[48]; + generator.nextBytes(array); + return wrap(array); + } + + /** + * Parse a hexadecimal string into a {@link Bytes48}. + * + *

+ * This method is extra strict in that {@code str} must of an even length and the provided representation must have + * exactly 48 bytes. + * + * @param str The hexadecimal string to parse, which may or may not start with "0x". + * @return The value corresponding to {@code str}. + * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation, is of an + * odd length or does not contain exactly 48 bytes. + */ + static Bytes48 fromHexStringStrict(CharSequence str) { + checkNotNull(str); + return wrap(BytesValues.fromRawHexString(str, -1, false)); + } + + @Override + default int size() { + return SIZE; + } + + /** + * Return a bit-wise AND of these bytes and the supplied bytes. + * + * @param other The bytes to perform the operation with. + * @return The result of a bit-wise AND. + */ + default Bytes48 and(Bytes48 other) { + return and(other, MutableBytes48.create()); + } + + /** + * Return a bit-wise OR of these bytes and the supplied bytes. + * + * @param other The bytes to perform the operation with. + * @return The result of a bit-wise OR. + */ + default Bytes48 or(Bytes48 other) { + return or(other, MutableBytes48.create()); + } + + /** + * Return a bit-wise XOR of these bytes and the supplied bytes. + * + * @param other The bytes to perform the operation with. + * @return The result of a bit-wise XOR. + */ + default Bytes48 xor(Bytes48 other) { + return xor(other, MutableBytes48.create()); + } + + @Override + default Bytes48 not() { + return not(MutableBytes48.create()); + } + + @Override + default Bytes48 shiftRight(int distance) { + return shiftRight(distance, MutableBytes48.create()); + } + + @Override + default Bytes48 shiftLeft(int distance) { + return shiftLeft(distance, MutableBytes48.create()); + } + + @Override + Bytes48 copy(); + + @Override + MutableBytes48 mutableCopy(); +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/BytesValues.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/BytesValues.java new file mode 100644 index 00000000000..5ff0948989b --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/BytesValues.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import static org.apache.tuweni.bytes.Checks.checkArgument; + +final class BytesValues { + private BytesValues() {} + + static final int MAX_UNSIGNED_SHORT = (1 << 16) - 1; + static final long MAX_UNSIGNED_INT = (1L << 32) - 1; + static final long MAX_UNSIGNED_LONG = Long.MAX_VALUE; + + static Bytes fromHexString(CharSequence str, int destSize, boolean lenient) { + return Bytes.wrap(fromRawHexString(str, destSize, lenient)); + } + + static byte[] fromRawHexString(CharSequence str, int destSize, boolean lenient) { + int len = str.length(); + CharSequence hex = str; + if (len >= 2 && str.charAt(0) == '0' && str.charAt(1) == 'x') { + hex = str.subSequence(2, len); + len -= 2; + } + + int idxShift = 0; + if ((len & 0x01) != 0) { + if (!lenient) { + throw new IllegalArgumentException("Invalid odd-length hex binary representation"); + } + + hex = "0" + hex; + len += 1; + idxShift = 1; + } + + int size = len >> 1; + if (destSize < 0) { + destSize = size; + } else { + checkArgument(size <= destSize, "Hex value is too large: expected at most %s bytes but got %s", destSize, size); + } + + byte[] out = new byte[destSize]; + + int destOffset = (destSize - size); + for (int i = destOffset, j = 0; j < len; i++) { + int h = Character.digit(hex.charAt(j), 16); + if (h == -1) { + throw new IllegalArgumentException( + String + .format( + "Illegal character '%c' found at index %d in hex binary representation", + hex.charAt(j), + j - idxShift)); + } + j++; + int l = Character.digit(hex.charAt(j), 16); + if (l == -1) { + throw new IllegalArgumentException( + String + .format( + "Illegal character '%c' found at index %d in hex binary representation", + hex.charAt(j), + j - idxShift)); + } + j++; + out[i] = (byte) ((h << 4) + l); + } + return out; + } + +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/Checks.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/Checks.java new file mode 100644 index 00000000000..ae6306c88ed --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/Checks.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import com.google.errorprone.annotations.FormatMethod; + +import javax.annotation.Nullable; + +public class Checks { + + static void checkNotNull(@Nullable Object object) { + if (object == null) { + throw new NullPointerException("argument cannot be null"); + } + } + + static void checkElementIndex(int index, int size) { + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException("index is out of bounds"); + } + } + + @FormatMethod + static void checkArgument(boolean condition, String message, Object... args) { + if (!condition) { + throw new IllegalArgumentException(String.format(message, args)); + } + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ConcatenatedBytes.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ConcatenatedBytes.java new file mode 100644 index 00000000000..9b91fb2cf30 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ConcatenatedBytes.java @@ -0,0 +1,270 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + + +import java.security.MessageDigest; +import java.util.List; + +import static org.apache.tuweni.bytes.Checks.checkArgument; +import static org.apache.tuweni.bytes.Checks.checkElementIndex; + +final class ConcatenatedBytes extends AbstractBytes { + + private final Bytes[] values; + private final int size; + + private ConcatenatedBytes(Bytes[] values, int totalSize) { + this.values = values; + this.size = totalSize; + } + + static Bytes wrap(Bytes... values) { + if (values.length == 0) { + return EMPTY; + } + if (values.length == 1) { + return values[0]; + } + + int count = 0; + int totalSize = 0; + + for (Bytes value : values) { + int size = value.size(); + try { + totalSize = Math.addExact(totalSize, size); + } catch (ArithmeticException e) { + throw new IllegalArgumentException("Combined length of values is too long (> Integer.MAX_VALUE)"); + } + if (value instanceof ConcatenatedBytes) { + count += ((ConcatenatedBytes) value).values.length; + } else if (size != 0) { + count += 1; + } + } + + if (count == 0) { + return Bytes.EMPTY; + } + if (count == values.length) { + return new ConcatenatedBytes(values, totalSize); + } + + Bytes[] concatenated = new Bytes[count]; + int i = 0; + for (Bytes value : values) { + if (value instanceof ConcatenatedBytes) { + Bytes[] subvalues = ((ConcatenatedBytes) value).values; + System.arraycopy(subvalues, 0, concatenated, i, subvalues.length); + i += subvalues.length; + } else if (value.size() != 0) { + concatenated[i++] = value; + } + } + return new ConcatenatedBytes(concatenated, totalSize); + } + + static Bytes wrap(List values) { + if (values.size() == 0) { + return EMPTY; + } + if (values.size() == 1) { + return values.get(0); + } + + int count = 0; + int totalSize = 0; + + for (Bytes value : values) { + int size = value.size(); + try { + totalSize = Math.addExact(totalSize, size); + } catch (ArithmeticException e) { + throw new IllegalArgumentException("Combined length of values is too long (> Integer.MAX_VALUE)"); + } + if (value instanceof ConcatenatedBytes) { + count += ((ConcatenatedBytes) value).values.length; + } else if (size != 0) { + count += 1; + } + } + + if (count == 0) { + return Bytes.EMPTY; + } + if (count == values.size()) { + return new ConcatenatedBytes(values.toArray(new Bytes[0]), totalSize); + } + + Bytes[] concatenated = new Bytes[count]; + int i = 0; + for (Bytes value : values) { + if (value instanceof ConcatenatedBytes) { + Bytes[] subvalues = ((ConcatenatedBytes) value).values; + System.arraycopy(subvalues, 0, concatenated, i, subvalues.length); + i += subvalues.length; + } else if (value.size() != 0) { + concatenated[i++] = value; + } + } + return new ConcatenatedBytes(concatenated, totalSize); + } + + @Override + public int size() { + return size; + } + + @Override + public byte get(int i) { + checkElementIndex(i, size); + for (Bytes value : values) { + int vSize = value.size(); + if (i < vSize) { + return value.get(i); + } + i -= vSize; + } + throw new IllegalStateException("element sizes do not match total size"); + } + + @Override + public Bytes slice(int i, final int length) { + if (i == 0 && length == size) { + return this; + } + if (length == 0) { + return Bytes.EMPTY; + } + + checkElementIndex(i, size); + checkArgument( + (i + length) <= size, + "Provided length %s is too large: the value has size %s and has only %s bytes from %s", + length, + size, + size - i, + i); + + int j = 0; + int vSize; + while (true) { + vSize = values[j].size(); + if (i < vSize) { + break; + } + i -= vSize; + ++j; + } + + if ((i + length) < vSize) { + return values[j].slice(i, length); + } + + int remaining = length - (vSize - i); + Bytes firstValue = this.values[j].slice(i); + int firstOffset = j; + + while (remaining > 0) { + if (++j >= this.values.length) { + throw new IllegalStateException("element sizes do not match total size"); + } + vSize = this.values[j].size(); + if (length < vSize + firstValue.size()) { + break; + } + remaining -= vSize; + } + + Bytes[] combined = new Bytes[j - firstOffset + 1]; + combined[0] = firstValue; + if (remaining > 0) { + if (combined.length > 2) { + System.arraycopy(this.values, firstOffset + 1, combined, 1, combined.length - 2); + } + combined[combined.length - 1] = this.values[j].slice(0, remaining); + } else if (combined.length > 1) { + System.arraycopy(this.values, firstOffset + 1, combined, 1, combined.length - 1); + } + return new ConcatenatedBytes(combined, length); + } + + @Override + public Bytes copy() { + return mutableCopy(); + } + + @Override + public MutableBytes mutableCopy() { + if (size == 0) { + return MutableBytes.EMPTY; + } + MutableBytes result = MutableBytes.create(size); + copyToUnchecked(result, 0); + return result; + } + + @Override + public void copyTo(MutableBytes destination, int destinationOffset) { + if (size == 0) { + return; + } + + checkElementIndex(destinationOffset, destination.size()); + checkArgument( + destination.size() - destinationOffset >= size, + "Cannot copy %s bytes, destination has only %s bytes from index %s", + size, + destination.size() - destinationOffset, + destinationOffset); + + copyToUnchecked(destination, destinationOffset); + } + + @Override + public void update(MessageDigest digest) { + for (Bytes value : values) { + value.update(digest); + } + } + + @Override + public byte[] toArray() { + if (size == 0) { + return new byte[0]; + } + + MutableBytes result = MutableBytes.create(size); + copyToUnchecked(result, 0); + return result.toArrayUnsafe(); + } + + private void copyToUnchecked(MutableBytes destination, int destinationOffset) { + int offset = 0; + for (Bytes value : values) { + int vSize = value.size(); + if ((offset + vSize) > size) { + throw new IllegalStateException("element sizes do not match total size"); + } + value.copyTo(destination, destinationOffset); + offset += vSize; + destinationOffset += vSize; + } + } + + @Override + public int hashCode() { + return computeHashcode(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ConstantBytes32Value.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ConstantBytes32Value.java new file mode 100644 index 00000000000..7a007e26773 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ConstantBytes32Value.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import java.util.Arrays; + +/** + * A Bytes value with just one constant value throughout. Ideal to avoid allocating large byte arrays filled with the + * same byte. + */ +class ConstantBytes32Value extends AbstractBytes implements Bytes32 { + + private final byte value; + + public ConstantBytes32Value(byte b) { + this.value = b; + } + + @Override + public int size() { + return 32; + } + + @Override + public byte get(int i) { + return this.value; + } + + @Override + public Bytes slice(int i, int length) { + if (length == 32) { + return this; + } + return new ConstantBytesValue(this.value, length); + } + + @Override + public Bytes32 copy() { + return new ConstantBytes32Value(this.value); + } + + @Override + public MutableBytes32 mutableCopy() { + byte[] mutable = new byte[32]; + Arrays.fill(mutable, this.value); + return new MutableArrayWrappingBytes32(mutable); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ConstantBytesValue.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ConstantBytesValue.java new file mode 100644 index 00000000000..5578687e165 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/ConstantBytesValue.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import java.util.Arrays; + +/** + * A Bytes value with just one constant value throughout. Ideal to avoid allocating large byte arrays filled with the + * same byte. + */ +class ConstantBytesValue extends AbstractBytes { + + private final int size; + private final byte value; + + public ConstantBytesValue(byte b, int size) { + this.value = b; + this.size = size; + } + + @Override + public int size() { + return this.size; + } + + @Override + public byte get(int i) { + return this.value; + } + + @Override + public Bytes slice(int i, int length) { + return new ConstantBytesValue(this.value, length); + } + + @Override + public Bytes copy() { + return new ConstantBytesValue(this.value, this.size); + } + + @Override + public MutableBytes mutableCopy() { + byte[] mutable = new byte[this.size]; + Arrays.fill(mutable, this.value); + return new MutableArrayWrappingBytes(mutable); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingBytes.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingBytes.java new file mode 100644 index 00000000000..472cb40cceb --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingBytes.java @@ -0,0 +1,322 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + + +import io.vertx.core.buffer.Buffer; + +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.security.MessageDigest; + +/** + * A class that holds and delegates all operations to its inner bytes field. + * + *

+ * This class may be used to create more types that represent bytes, but need a different name for business logic. + */ +public class DelegatingBytes extends AbstractBytes implements Bytes { + + final Bytes delegate; + + protected DelegatingBytes(Bytes delegate) { + this.delegate = delegate; + } + + @Override + public int size() { + return delegate.size(); + } + + @Override + public byte get(int i) { + return delegate.get(i); + } + + @Override + public Bytes slice(int index, int length) { + return delegate.slice(index, length); + } + + @Override + public Bytes copy() { + return Bytes.wrap(toArray()); + } + + @Override + public MutableBytes mutableCopy() { + return MutableBytes.wrap(toArray()); + } + + @Override + public byte[] toArray() { + return delegate.toArray(); + } + + @Override + public byte[] toArray(ByteOrder byteOrder) { + return delegate.toArray(byteOrder); + } + + @Override + public byte[] toArrayUnsafe() { + return delegate.toArrayUnsafe(); + } + + @Override + public String toString() { + return delegate.toString(); + } + + @Override + public int getInt(int i) { + return delegate.getInt(i); + } + + @Override + public int getInt(int i, ByteOrder order) { + return delegate.getInt(i, order); + } + + @Override + public int toInt() { + return delegate.toInt(); + } + + @Override + public int toInt(ByteOrder order) { + return delegate.toInt(order); + } + + @Override + public boolean isEmpty() { + return delegate.isEmpty(); + } + + @Override + public long getLong(int i) { + return delegate.getLong(i); + } + + @Override + public long getLong(int i, ByteOrder order) { + return delegate.getLong(i, order); + } + + @Override + public long toLong() { + return delegate.toLong(); + } + + @Override + public long toLong(ByteOrder order) { + return delegate.toLong(order); + } + + @Override + public BigInteger toBigInteger() { + return delegate.toBigInteger(); + } + + @Override + public BigInteger toBigInteger(ByteOrder order) { + return delegate.toBigInteger(order); + } + + @Override + public BigInteger toUnsignedBigInteger() { + return delegate.toUnsignedBigInteger(); + } + + @Override + public BigInteger toUnsignedBigInteger(ByteOrder order) { + return delegate.toUnsignedBigInteger(order); + } + + @Override + public boolean isZero() { + return delegate.isZero(); + } + + @Override + public boolean hasLeadingZero() { + return delegate.hasLeadingZero(); + } + + @Override + public int numberOfLeadingZeros() { + return delegate.numberOfLeadingZeros(); + } + + @Override + public boolean hasLeadingZeroByte() { + return delegate.hasLeadingZeroByte(); + } + + @Override + public int numberOfLeadingZeroBytes() { + return delegate.numberOfLeadingZeroBytes(); + } + + @Override + public int numberOfTrailingZeroBytes() { + return delegate.numberOfTrailingZeroBytes(); + } + + @Override + public int bitLength() { + return delegate.bitLength(); + } + + @Override + public Bytes and(Bytes other) { + return delegate.and(other); + } + + @Override + public T and(Bytes other, T result) { + return delegate.and(other, result); + } + + @Override + public Bytes or(Bytes other) { + return delegate.or(other); + } + + @Override + public T or(Bytes other, T result) { + return delegate.or(other, result); + } + + @Override + public Bytes xor(Bytes other) { + return delegate.xor(other); + } + + @Override + public T xor(Bytes other, T result) { + return delegate.xor(other, result); + } + + @Override + public T shiftRight(int distance, T result) { + return delegate.shiftRight(distance, result); + } + + @Override + public T shiftLeft(int distance, T result) { + return delegate.shiftLeft(distance, result); + } + + @Override + public Bytes slice(int i) { + return delegate.slice(i); + } + + @Override + public void copyTo(MutableBytes destination) { + delegate.copyTo(destination); + } + + @Override + public void copyTo(MutableBytes destination, int destinationOffset) { + delegate.copyTo(destination, destinationOffset); + } + + @Override + public void appendTo(ByteBuffer byteBuffer) { + delegate.appendTo(byteBuffer); + } + + @Override + public void appendTo(Buffer buffer) { + delegate.appendTo(buffer); + } + + @Override + public T appendHexTo(T appendable) { + return delegate.appendHexTo(appendable); + } + + @Override + public int commonPrefixLength(Bytes other) { + return delegate.commonPrefixLength(other); + } + + @Override + public Bytes commonPrefix(Bytes other) { + return delegate.commonPrefix(other); + } + + @Override + public Bytes trimLeadingZeros() { + return delegate.trimLeadingZeros(); + } + + @Override + public void update(MessageDigest digest) { + delegate.update(digest); + } + + @Override + public Bytes reverse() { + return delegate.reverse(); + } + + @Override + public String toHexString() { + return delegate.toHexString(); + } + + @Override + public String toUnprefixedHexString() { + return delegate.toUnprefixedHexString(); + } + + @Override + public String toEllipsisHexString() { + return delegate.toEllipsisHexString(); + } + + @Override + public String toShortHexString() { + return delegate.toShortHexString(); + } + + @Override + public String toQuantityHexString() { + return delegate.toQuantityHexString(); + } + + @Override + public String toBase64String() { + return delegate.toBase64String(); + } + + @Override + public int compareTo(Bytes b) { + return delegate.compareTo(b); + } + + @Override + public boolean equals(final Object o) { + return delegate.equals(o); + } + + @Override + public int hashCode() { + return delegate.hashCode(); + } + +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingBytes32.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingBytes32.java new file mode 100644 index 00000000000..14832cb6f78 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingBytes32.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + + + +/** + * A class that holds and delegates all operations to its inner bytes field. + * + *

+ * This class may be used to create more types that represent 32 bytes, but need a different name for business logic. + */ +public class DelegatingBytes32 extends DelegatingBytes implements Bytes32 { + + protected DelegatingBytes32(Bytes delegate) { + super(delegate); + } + + @Override + public int size() { + return Bytes32.SIZE; + } + + @Override + public Bytes32 copy() { + return Bytes32.wrap(toArray()); + } + + @Override + public MutableBytes32 mutableCopy() { + return MutableBytes32.wrap(toArray()); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingBytes48.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingBytes48.java new file mode 100644 index 00000000000..de4b295ae60 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingBytes48.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + + + +/** + * A class that holds and delegates all operations to its inner bytes field. + * + *

+ * This class may be used to create more types that represent 48 bytes, but need a different name for business logic. + */ +public class DelegatingBytes48 extends DelegatingBytes implements Bytes48 { + + protected DelegatingBytes48(Bytes delegate) { + super(delegate); + } + + @Override + public int size() { + return Bytes48.SIZE; + } + + @Override + public Bytes48 copy() { + return Bytes48.wrap(toArray()); + } + + @Override + public MutableBytes48 mutableCopy() { + return MutableBytes48.wrap(toArray()); + } + +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingMutableBytes.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingMutableBytes.java new file mode 100644 index 00000000000..4f5d2786937 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingMutableBytes.java @@ -0,0 +1,286 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + + +import io.vertx.core.buffer.Buffer; + +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.security.MessageDigest; + + +/** + * A class that holds and delegates all operations to its inner bytes field. + * + *

+ * This class may be used to create more types that represent bytes, but need a different name for business logic. + */ +public class DelegatingMutableBytes implements MutableBytes { + + final MutableBytes delegate; + + protected DelegatingMutableBytes(MutableBytes delegate) { + this.delegate = delegate; + } + + @Override + public void set(int i, byte b) { + delegate.set(i, b); + } + + @Override + public void set(int i, Bytes b) { + delegate.set(i, b); + } + + @Override + public void setInt(int i, int value) { + delegate.setInt(i, value); + } + + @Override + public void setLong(int i, long value) { + delegate.setLong(i, value); + } + + @Override + public MutableBytes increment() { + return delegate.increment(); + } + + @Override + public MutableBytes decrement() { + return delegate.decrement(); + } + + @Override + public MutableBytes mutableSlice(int i, int length) { + return delegate.mutableSlice(i, length); + } + + @Override + public void fill(byte b) { + delegate.fill(b); + } + + @Override + public void clear() { + delegate.clear(); + } + + @Override + public int size() { + return delegate.size(); + } + + @Override + public byte get(int i) { + return delegate.get(i); + } + + @Override + public int getInt(int i) { + return delegate.getInt(i); + } + + @Override + public int toInt() { + return delegate.toInt(); + } + + @Override + public long getLong(int i) { + return delegate.getLong(i); + } + + @Override + public long toLong() { + return delegate.toLong(); + } + + @Override + public BigInteger toBigInteger() { + return delegate.toBigInteger(); + } + + @Override + public BigInteger toUnsignedBigInteger() { + return delegate.toUnsignedBigInteger(); + } + + @Override + public boolean isZero() { + return delegate.isZero(); + } + + @Override + public int numberOfLeadingZeros() { + return delegate.numberOfLeadingZeros(); + } + + @Override + public int numberOfLeadingZeroBytes() { + return delegate.numberOfLeadingZeroBytes(); + } + + @Override + public boolean hasLeadingZeroByte() { + return delegate.hasLeadingZeroByte(); + } + + @Override + public boolean hasLeadingZero() { + return delegate.hasLeadingZero(); + } + + @Override + public int bitLength() { + return delegate.bitLength(); + } + + @Override + public Bytes and(Bytes other) { + return delegate.and(other); + } + + @Override + public T and(Bytes other, T result) { + return delegate.and(other, result); + } + + @Override + public Bytes or(Bytes other) { + return delegate.or(other); + } + + @Override + public T or(Bytes other, T result) { + return delegate.or(other, result); + } + + @Override + public Bytes xor(Bytes other) { + return delegate.xor(other); + } + + @Override + public T xor(Bytes other, T result) { + return delegate.xor(other, result); + } + + @Override + public T not(T result) { + return delegate.not(result); + } + + @Override + public T shiftRight(int distance, T result) { + return delegate.shiftRight(distance, result); + } + + @Override + public T shiftLeft(int distance, T result) { + return delegate.shiftLeft(distance, result); + } + + @Override + public Bytes slice(int index) { + return delegate.slice(index); + } + + @Override + public Bytes slice(int index, int length) { + return delegate.slice(index, length); + } + + @Override + public Bytes copy() { + return Bytes.wrap(delegate.toArray()); + } + + @Override + public MutableBytes mutableCopy() { + return MutableBytes.wrap(delegate.toArray()); + } + + @Override + public void copyTo(MutableBytes destination) { + delegate.copyTo(destination); + } + + @Override + public void copyTo(MutableBytes destination, int destinationOffset) { + delegate.copyTo(destination, destinationOffset); + } + + @Override + public void appendTo(ByteBuffer byteBuffer) { + delegate.appendTo(byteBuffer); + } + + @Override + public void appendTo(Buffer buffer) { + delegate.appendTo(buffer); + } + + @Override + public int commonPrefixLength(Bytes other) { + return delegate.commonPrefixLength(other); + } + + @Override + public Bytes commonPrefix(Bytes other) { + return delegate.commonPrefix(other); + } + + @Override + public void update(MessageDigest digest) { + delegate.update(digest); + } + + @Override + public byte[] toArray() { + return delegate.toArray(); + } + + @Override + public byte[] toArrayUnsafe() { + return delegate.toArrayUnsafe(); + } + + @Override + public String toString() { + return delegate.toString(); + } + + @Override + public String toHexString() { + return delegate.toHexString(); + } + + @Override + public String toShortHexString() { + return delegate.toShortHexString(); + } + + @Override + public boolean equals(Object obj) { + return delegate.equals(obj); + } + + @Override + public int hashCode() { + return delegate.hashCode(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingMutableBytes32.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingMutableBytes32.java new file mode 100644 index 00000000000..009b719a2c3 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingMutableBytes32.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import static org.apache.tuweni.bytes.Checks.checkArgument; + + +final class DelegatingMutableBytes32 extends DelegatingMutableBytes implements MutableBytes32 { + + private DelegatingMutableBytes32(MutableBytes delegate) { + super(delegate); + } + + static MutableBytes32 delegateTo(MutableBytes value) { + checkArgument(value.size() == SIZE, "Expected %s bytes but got %s", SIZE, value.size()); + return new DelegatingMutableBytes32(value); + } + + @Override + public Bytes32 copy() { + return Bytes32.wrap(delegate.toArray()); + } + + @Override + public MutableBytes32 mutableCopy() { + return MutableBytes32.wrap(delegate.toArray()); + } + +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingMutableBytes48.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingMutableBytes48.java new file mode 100644 index 00000000000..faf84c16930 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/DelegatingMutableBytes48.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import static org.apache.tuweni.bytes.Checks.checkArgument; + + +final class DelegatingMutableBytes48 extends DelegatingMutableBytes implements MutableBytes48 { + + private DelegatingMutableBytes48(MutableBytes delegate) { + super(delegate); + } + + static MutableBytes48 delegateTo(MutableBytes value) { + checkArgument(value.size() == SIZE, "Expected %s bytes but got %s", SIZE, value.size()); + return new DelegatingMutableBytes48(value); + } + + @Override + public Bytes48 copy() { + return Bytes48.wrap(delegate.toArray()); + } + + @Override + public MutableBytes48 mutableCopy() { + return MutableBytes48.wrap(delegate.toArray()); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/GuardedByteArrayBytes.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/GuardedByteArrayBytes.java new file mode 100644 index 00000000000..8a05703030c --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/GuardedByteArrayBytes.java @@ -0,0 +1,191 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import io.vertx.core.buffer.Buffer; +import org.identityconnectors.common.security.GuardedByteArray; + +import java.nio.ByteBuffer; +import java.security.MessageDigest; +import java.util.concurrent.atomic.AtomicReference; + +import static org.apache.tuweni.bytes.Checks.checkArgument; +import static org.apache.tuweni.bytes.Checks.checkElementIndex; + +class GuardedByteArrayBytes extends AbstractBytes { + + protected final GuardedByteArray bytes; + protected final int offset; + protected final int length; + + GuardedByteArrayBytes(byte[] bytes) { + this(bytes, 0, bytes.length); + } + + GuardedByteArrayBytes(byte[] bytes, int offset, int length) { + checkArgument(length >= 0, "Invalid negative length"); + if (bytes.length > 0) { + checkElementIndex(offset, bytes.length); + } + checkArgument( + offset + length <= bytes.length, + "Provided length %s is too big: the value has only %s bytes from offset %s", + length, + bytes.length - offset, + offset); + + this.bytes = new GuardedByteArray(bytes); + this.bytes.makeReadOnly(); + this.offset = offset; + this.length = length; + } + + @Override + public int size() { + return length; + } + + @Override + public byte get(int i) { + // Check bounds because while the array access would throw, the error message would be confusing + // for the caller. + checkElementIndex(i, size()); + AtomicReference b = new AtomicReference<>(); + bytes.access(bytes -> b.set(bytes[offset + i])); + return b.get(); + } + + @Override + public Bytes slice(int i, int length) { + if (i == 0 && length == this.length) { + return this; + } + if (length == 0) { + return Bytes.EMPTY; + } + + checkElementIndex(i, this.length); + checkArgument( + i + length <= this.length, + "Provided length %s is too big: the value has size %s and has only %s bytes from %s", + length, + this.length, + this.length - i, + i); + AtomicReference clearBytes = new AtomicReference<>(); + bytes.access(data -> { + byte[] result = new byte[length]; + System.arraycopy(data, offset + i, result, 0, length); + clearBytes.set(result); + }); + + return length == Bytes32.SIZE ? new ArrayWrappingBytes32(clearBytes.get()) + : new ArrayWrappingBytes(clearBytes.get(), 0, length); + } + + // MUST be overridden by mutable implementations + @Override + public Bytes copy() { + return new ArrayWrappingBytes(toArray()); + } + + @Override + public MutableBytes mutableCopy() { + return new MutableArrayWrappingBytes(toArray()); + } + + @Override + public void update(MessageDigest digest) { + digest.update(toArray(), offset, length); + } + + @Override + public void copyTo(MutableBytes destination, int destinationOffset) { + if (!(destination instanceof MutableArrayWrappingBytes)) { + super.copyTo(destination, destinationOffset); + return; + } + + int size = size(); + if (size == 0) { + return; + } + + checkElementIndex(destinationOffset, destination.size()); + checkArgument( + destination.size() - destinationOffset >= size, + "Cannot copy %s bytes, destination has only %s bytes from index %s", + size, + destination.size() - destinationOffset, + destinationOffset); + + MutableArrayWrappingBytes d = (MutableArrayWrappingBytes) destination; + System.arraycopy(toArray(), offset, d.bytes, d.offset + destinationOffset, size); + } + + @Override + public void appendTo(ByteBuffer byteBuffer) { + byteBuffer.put(toArray(), offset, length); + } + + @Override + public void appendTo(Buffer buffer) { + buffer.appendBytes(toArray(), offset, length); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof GuardedByteArrayBytes)) { + return super.equals(obj); + } + GuardedByteArrayBytes other = (GuardedByteArrayBytes) obj; + if (length != other.length) { + return false; + } + for (int i = 0; i < length; ++i) { + if (get(offset + i) != other.get(other.offset + i)) { + return false; + } + } + return true; + } + + @Override + public int hashCode() { + int result = 1; + int size = size(); + for (int i = 0; i < size; i++) { + result = 31 * result + get(offset + i); + } + return result; + } + + @Override + public byte[] toArray() { + AtomicReference clearBytes = new AtomicReference<>(); + bytes.access(data -> { + byte[] result = new byte[length]; + System.arraycopy(data, offset, result, 0, length); + clearBytes.set(result); + }); + return clearBytes.get(); + } + + @Override + public byte[] toArrayUnsafe() { + return toArray(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/GuardedByteArrayBytes32.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/GuardedByteArrayBytes32.java new file mode 100644 index 00000000000..8c0aee7b6c5 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/GuardedByteArrayBytes32.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import static org.apache.tuweni.bytes.Checks.checkArgument; + +final class GuardedByteArrayBytes32 extends GuardedByteArrayBytes implements Bytes32 { + + GuardedByteArrayBytes32(byte[] bytes) { + this(checkLength(bytes), 0); + } + + GuardedByteArrayBytes32(byte[] bytes, int offset) { + super(checkLength(bytes, offset), offset, SIZE); + } + + // Ensures a proper error message. + private static byte[] checkLength(byte[] bytes) { + checkArgument(bytes.length == SIZE, "Expected %s bytes but got %s", SIZE, bytes.length); + return bytes; + } + + // Ensures a proper error message. + private static byte[] checkLength(byte[] bytes, int offset) { + checkArgument( + bytes.length - offset >= SIZE, + "Expected at least %s bytes from offset %s but got only %s", + SIZE, + offset, + bytes.length - offset); + return bytes; + } + + @Override + public Bytes32 copy() { + return new ArrayWrappingBytes32(toArray()); + } + + @Override + public MutableBytes32 mutableCopy() { + return new MutableArrayWrappingBytes32(toArray()); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableArrayWrappingBytes.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableArrayWrappingBytes.java new file mode 100644 index 00000000000..48eb1b6a90f --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableArrayWrappingBytes.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import java.util.Arrays; + +import static org.apache.tuweni.bytes.Checks.checkArgument; +import static org.apache.tuweni.bytes.Checks.checkElementIndex; + +class MutableArrayWrappingBytes extends ArrayWrappingBytes implements MutableBytes { + + MutableArrayWrappingBytes(byte[] bytes) { + super(bytes); + } + + MutableArrayWrappingBytes(byte[] bytes, int offset, int length) { + super(bytes, offset, length); + } + + @Override + public void set(int i, byte b) { + // Check bounds because while the array access would throw, the error message would be confusing + // for the caller. + checkElementIndex(i, length); + bytes[offset + i] = b; + } + + @Override + public void set(int i, Bytes b) { + byte[] bytesArray = b.toArrayUnsafe(); + System.arraycopy(bytesArray, 0, bytes, offset + i, bytesArray.length); + } + + @Override + public MutableBytes increment() { + for (int i = length - 1; i >= offset; --i) { + if (bytes[i] == (byte) 0xFF) { + bytes[i] = (byte) 0x00; + } else { + ++bytes[i]; + break; + } + } + return this; + } + + @Override + public MutableBytes decrement() { + for (int i = length - 1; i >= offset; --i) { + if (bytes[i] == (byte) 0x00) { + bytes[i] = (byte) 0xFF; + } else { + --bytes[i]; + break; + } + } + return this; + } + + @Override + public MutableBytes mutableSlice(int i, int length) { + if (i == 0 && length == this.length) + return this; + if (length == 0) + return MutableBytes.EMPTY; + + checkElementIndex(i, this.length); + checkArgument( + i + length <= this.length, + "Specified length %s is too large: the value has size %s and has only %s bytes from %s", + length, + this.length, + this.length - i, + i); + return length == Bytes32.SIZE ? new MutableArrayWrappingBytes32(bytes, offset + i) + : new MutableArrayWrappingBytes(bytes, offset + i, length); + } + + @Override + public void fill(byte b) { + Arrays.fill(bytes, offset, offset + length, b); + } + + @Override + public Bytes copy() { + return new ArrayWrappingBytes(toArray()); + } + + @Override + public int hashCode() { + return computeHashcode(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableArrayWrappingBytes32.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableArrayWrappingBytes32.java new file mode 100644 index 00000000000..0cf5096287a --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableArrayWrappingBytes32.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +final class MutableArrayWrappingBytes32 extends MutableArrayWrappingBytes implements MutableBytes32 { + + MutableArrayWrappingBytes32(byte[] bytes) { + this(bytes, 0); + } + + MutableArrayWrappingBytes32(byte[] bytes, int offset) { + super(bytes, offset, SIZE); + } + + @Override + public Bytes32 copy() { + return new ArrayWrappingBytes32(toArray()); + } + + @Override + public MutableBytes32 mutableCopy() { + return new MutableArrayWrappingBytes32(toArray()); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableArrayWrappingBytes48.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableArrayWrappingBytes48.java new file mode 100644 index 00000000000..25bbaeb9865 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableArrayWrappingBytes48.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +final class MutableArrayWrappingBytes48 extends MutableArrayWrappingBytes implements MutableBytes48 { + + MutableArrayWrappingBytes48(byte[] bytes) { + this(bytes, 0); + } + + MutableArrayWrappingBytes48(byte[] bytes, int offset) { + super(bytes, offset, SIZE); + } + + @Override + public Bytes48 copy() { + return new ArrayWrappingBytes48(toArray()); + } + + @Override + public MutableBytes48 mutableCopy() { + return new MutableArrayWrappingBytes48(toArray()); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableBufferWrappingBytes.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableBufferWrappingBytes.java new file mode 100644 index 00000000000..63d79296496 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableBufferWrappingBytes.java @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import io.vertx.core.buffer.Buffer; + +import static org.apache.tuweni.bytes.Checks.checkArgument; +import static org.apache.tuweni.bytes.Checks.checkElementIndex; + +final class MutableBufferWrappingBytes extends BufferWrappingBytes implements MutableBytes { + + MutableBufferWrappingBytes(Buffer buffer) { + super(buffer); + } + + MutableBufferWrappingBytes(Buffer buffer, int offset, int length) { + super(buffer, offset, length); + } + + @Override + public void set(int i, byte b) { + buffer.setByte(i, b); + } + + @Override + public void set(int i, Bytes b) { + byte[] bytes = b.toArrayUnsafe(); + buffer.setBytes(i, bytes); + } + + @Override + public void setInt(int i, int value) { + buffer.setInt(i, value); + } + + @Override + public void setLong(int i, long value) { + buffer.setLong(i, value); + } + + @Override + public MutableBytes mutableSlice(int i, int length) { + int size = size(); + if (i == 0 && length == size) { + return this; + } + if (length == 0) { + return MutableBytes.EMPTY; + } + + checkElementIndex(i, size); + checkArgument( + i + length <= size, + "Provided length %s is too big: the value has size %s and has only %s bytes from %s", + length, + size, + size - i, + i); + + return new MutableBufferWrappingBytes(buffer.slice(i, i + length)); + } + + @Override + public Bytes copy() { + return Bytes.wrap(toArray()); + } + + @Override + public MutableBytes mutableCopy() { + return MutableBytes.wrap(toArray()); + } + + @Override + public int hashCode() { + return computeHashcode(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableByteBufWrappingBytes.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableByteBufWrappingBytes.java new file mode 100644 index 00000000000..392b8bf8d80 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableByteBufWrappingBytes.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import io.netty.buffer.ByteBuf; + +import static org.apache.tuweni.bytes.Checks.checkArgument; +import static org.apache.tuweni.bytes.Checks.checkElementIndex; + +final class MutableByteBufWrappingBytes extends ByteBufWrappingBytes implements MutableBytes { + + MutableByteBufWrappingBytes(ByteBuf buffer) { + super(buffer); + } + + MutableByteBufWrappingBytes(ByteBuf buffer, int offset, int length) { + super(buffer, offset, length); + } + + @Override + public void clear() { + byteBuf.setZero(0, byteBuf.capacity()); + } + + @Override + public void set(int i, byte b) { + byteBuf.setByte(i, b); + } + + @Override + public void set(int i, Bytes b) { + byte[] bytes = b.toArrayUnsafe(); + byteBuf.setBytes(i, bytes); + } + + @Override + public void setInt(int i, int value) { + byteBuf.setInt(i, value); + } + + @Override + public void setLong(int i, long value) { + byteBuf.setLong(i, value); + } + + @Override + public MutableBytes mutableSlice(int i, int length) { + int size = size(); + if (i == 0 && length == size) { + return this; + } + if (length == 0) { + return MutableBytes.EMPTY; + } + + checkElementIndex(i, size); + checkArgument( + i + length <= size, + "Provided length %s is too big: the value has size %s and has only %s bytes from %s", + length, + size, + size - i, + i); + + return new MutableByteBufWrappingBytes(byteBuf.slice(i, length)); + } + + @Override + public Bytes copy() { + return Bytes.wrap(toArray()); + } + + @Override + public MutableBytes mutableCopy() { + return MutableBytes.wrap(toArray()); + } + + @Override + public int hashCode() { + return computeHashcode(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableByteBufferWrappingBytes.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableByteBufferWrappingBytes.java new file mode 100644 index 00000000000..10c8d05eb9f --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableByteBufferWrappingBytes.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import java.nio.ByteBuffer; + +import static org.apache.tuweni.bytes.Checks.checkArgument; +import static org.apache.tuweni.bytes.Checks.checkElementIndex; + +public class MutableByteBufferWrappingBytes extends ByteBufferWrappingBytes implements MutableBytes { + + MutableByteBufferWrappingBytes(ByteBuffer byteBuffer) { + super(byteBuffer); + } + + MutableByteBufferWrappingBytes(ByteBuffer byteBuffer, int offset, int length) { + super(byteBuffer, offset, length); + } + + @Override + public void setInt(int i, int value) { + byteBuffer.putInt(offset + i, value); + } + + @Override + public void setLong(int i, long value) { + byteBuffer.putLong(offset + i, value); + } + + @Override + public void set(int i, byte b) { + byteBuffer.put(offset + i, b); + } + + @Override + public void set(int i, Bytes b) { + byte[] bytes = b.toArrayUnsafe(); + int byteIndex = 0; + int thisIndex = offset + i; + int end = bytes.length; + while (byteIndex < end) { + byteBuffer.put(thisIndex++, bytes[byteIndex++]); + } + } + + @Override + public MutableBytes mutableSlice(int i, int length) { + if (i == 0 && length == this.length) { + return this; + } + if (length == 0) { + return MutableBytes.EMPTY; + } + + checkElementIndex(i, this.length); + checkArgument( + i + length <= this.length, + "Provided length %s is too big: the value has size %s and has only %s bytes from %s", + length, + this.length, + this.length - i, + i); + + return new MutableByteBufferWrappingBytes(byteBuffer, offset + i, length); + } + + @Override + public Bytes copy() { + return new ArrayWrappingBytes(toArray()); + } + + @Override + public int hashCode() { + return computeHashcode(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableBytes.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableBytes.java new file mode 100644 index 00000000000..9501009a2a7 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableBytes.java @@ -0,0 +1,374 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import io.netty.buffer.ByteBuf; +import io.vertx.core.buffer.Buffer; + +import java.nio.ByteBuffer; + +import static java.lang.String.format; +import static org.apache.tuweni.bytes.Checks.*; + +/** + * A mutable {@link Bytes} value. + */ +public interface MutableBytes extends Bytes { + + /** + * The empty value (with 0 bytes). + */ + MutableBytes EMPTY = wrap(new byte[0]); + + /** + * Create a new mutable byte value. + * + * @param size The size of the returned value. + * @return A {@link MutableBytes} value. + */ + static MutableBytes create(int size) { + if (size == 32) { + return MutableBytes32.create(); + } + return new MutableArrayWrappingBytes(new byte[size]); + } + + /** + * Wrap a byte array in a {@link MutableBytes} value. + * + * @param value The value to wrap. + * @return A {@link MutableBytes} value wrapping {@code value}. + */ + static MutableBytes wrap(byte[] value) { + checkNotNull(value); + return new MutableArrayWrappingBytes(value); + } + + /** + * Wrap a slice of a byte array as a {@link MutableBytes} value. + * + *

+ * Note that value is not copied and thus any future update to {@code value} within the slice will be reflected in the + * returned value. + * + * @param value The value to wrap. + * @param offset The index (inclusive) in {@code value} of the first byte exposed by the returned value. In other + * words, you will have {@code wrap(value, o, l).get(0) == value[o]}. + * @param length The length of the resulting value. + * @return A {@link Bytes} value that expose the bytes of {@code value} from {@code offset} (inclusive) to + * {@code offset + length} (exclusive). + * @throws IndexOutOfBoundsException if {@code offset < 0 || (value.length > 0 && offset >= + * value.length)}. + * @throws IllegalArgumentException if {@code length < 0 || offset + length > value.length}. + */ + static MutableBytes wrap(byte[] value, int offset, int length) { + checkNotNull(value); + if (length == 32) { + return new MutableArrayWrappingBytes32(value, offset); + } + return new MutableArrayWrappingBytes(value, offset, length); + } + + /** + * Wrap a full Vert.x {@link Buffer} as a {@link MutableBytes} value. + * + *

+ * Note that any change to the content of the buffer may be reflected in the returned value. + * + * @param buffer The buffer to wrap. + * @return A {@link MutableBytes} value. + */ + static MutableBytes wrapBuffer(Buffer buffer) { + checkNotNull(buffer); + if (buffer.length() == 0) { + return EMPTY; + } + return new MutableBufferWrappingBytes(buffer); + } + + /** + * Wrap a slice of a Vert.x {@link Buffer} as a {@link MutableBytes} value. + * + *

+ * Note that any change to the content of the buffer may be reflected in the returned value, and any change to the + * returned value will be reflected in the buffer. + * + * @param buffer The buffer to wrap. + * @param offset The offset in {@code buffer} from which to expose the bytes in the returned value. That is, + * {@code wrapBuffer(buffer, i, 1).get(0) == buffer.getByte(i)}. + * @param size The size of the returned value. + * @return A {@link MutableBytes} value. + * @throws IndexOutOfBoundsException if {@code offset < 0 || (buffer.length() > 0 && offset >= + * buffer.length())}. + * @throws IllegalArgumentException if {@code length < 0 || offset + length > buffer.length()}. + */ + static MutableBytes wrapBuffer(Buffer buffer, int offset, int size) { + checkNotNull(buffer); + if (size == 0) { + return EMPTY; + } + return new MutableBufferWrappingBytes(buffer, offset, size); + } + + /** + * Wrap a full Netty {@link ByteBuf} as a {@link MutableBytes} value. + * + *

+ * Note that any change to the content of the buffer may be reflected in the returned value. + * + * @param byteBuf The {@link ByteBuf} to wrap. + * @return A {@link MutableBytes} value. + */ + static MutableBytes wrapByteBuf(ByteBuf byteBuf) { + checkNotNull(byteBuf); + if (byteBuf.capacity() == 0) { + return EMPTY; + } + return new MutableByteBufWrappingBytes(byteBuf); + } + + /** + * Wrap a slice of a Netty {@link ByteBuf} as a {@link MutableBytes} value. + * + *

+ * Note that any change to the content of the buffer may be reflected in the returned value, and any change to the + * returned value will be reflected in the buffer. + * + * @param byteBuf The {@link ByteBuf} to wrap. + * @param offset The offset in {@code byteBuf} from which to expose the bytes in the returned value. That is, + * {@code wrapByteBuf(byteBuf, i, 1).get(0) == byteBuf.getByte(i)}. + * @param size The size of the returned value. + * @return A {@link MutableBytes} value. + * @throws IndexOutOfBoundsException if {@code offset < 0 || (byteBuf.capacity() > 0 && offset >= + * byteBuf.capacity())}. + * @throws IllegalArgumentException if {@code length < 0 || offset + length > byteBuf.capacity()}. + */ + static MutableBytes wrapByteBuf(ByteBuf byteBuf, int offset, int size) { + checkNotNull(byteBuf); + if (size == 0) { + return EMPTY; + } + return new MutableByteBufWrappingBytes(byteBuf, offset, size); + } + + /** + * Wrap a full Java NIO {@link ByteBuffer} as a {@link MutableBytes} value. + * + *

+ * Note that any change to the content of the buffer may be reflected in the returned value. + * + * @param byteBuffer The {@link ByteBuffer} to wrap. + * @return A {@link MutableBytes} value. + */ + static MutableBytes wrapByteBuffer(ByteBuffer byteBuffer) { + checkNotNull(byteBuffer); + if (byteBuffer.limit() == 0) { + return EMPTY; + } + return new MutableByteBufferWrappingBytes(byteBuffer); + } + + /** + * Wrap a slice of a Java NIO {@link ByteBuffer} as a {@link MutableBytes} value. + * + *

+ * Note that any change to the content of the buffer may be reflected in the returned value, and any change to the + * returned value will be reflected in the buffer. + * + * @param byteBuffer The {@link ByteBuffer} to wrap. + * @param offset The offset in {@code byteBuffer} from which to expose the bytes in the returned value. That is, + * {@code wrapByteBuffer(byteBuffer, i, 1).get(0) == byteBuffer.getByte(i)}. + * @param size The size of the returned value. + * @return A {@link MutableBytes} value. + * @throws IndexOutOfBoundsException if {@code offset < 0 || (byteBuffer.limit() > 0 && offset >= + * byteBuffer.limit())}. + * @throws IllegalArgumentException if {@code length < 0 || offset + length > byteBuffer.limit()}. + */ + static MutableBytes wrapByteBuffer(ByteBuffer byteBuffer, int offset, int size) { + checkNotNull(byteBuffer); + if (size == 0) { + return EMPTY; + } + return new MutableByteBufferWrappingBytes(byteBuffer, offset, size); + } + + /** + * Create a value that contains the specified bytes in their specified order. + * + * @param bytes The bytes that must compose the returned value. + * @return A value containing the specified bytes. + */ + static MutableBytes of(byte... bytes) { + return wrap(bytes); + } + + /** + * Create a value that contains the specified bytes in their specified order. + * + * @param bytes The bytes. + * @return A value containing bytes are the one from {@code bytes}. + * @throws IllegalArgumentException if any of the specified would be truncated when storing as a byte. + */ + static MutableBytes of(int... bytes) { + byte[] result = new byte[bytes.length]; + for (int i = 0; i < bytes.length; i++) { + int b = bytes[i]; + checkArgument(b == (((byte) b) & 0xff), "%sth value %s does not fit a byte", i + 1, b); + result[i] = (byte) b; + } + return wrap(result); + } + + /** + * Set a byte in this value. + * + * @param i The index of the byte to set. + * @param b The value to set that byte to. + * @throws IndexOutOfBoundsException if {@code i < 0} or {i >= size()}. + */ + void set(int i, byte b); + + /** + * Set a byte in this value. + * + * @param offset The offset of the bytes to set. + * @param bytes The value to set bytes to. + * @throws IndexOutOfBoundsException if {@code i < 0} or {i >= size()}. + */ + default void set(int offset, Bytes bytes) { + for (int i = 0; i < bytes.size(); i++) { + set(offset + i, bytes.get(i)); + } + } + + /** + * Set the 4 bytes starting at the specified index to the specified integer value. + * + * @param i The index, which must less than or equal to {@code size() - 4}. + * @param value The integer value. + * @throws IndexOutOfBoundsException if {@code i < 0} or {@code i > size() - 4}. + */ + default void setInt(int i, int value) { + int size = size(); + checkElementIndex(i, size); + if (i > (size - 4)) { + throw new IndexOutOfBoundsException( + format("Value of size %s has not enough bytes to write a 4 bytes int from index %s", size, i)); + } + + set(i++, (byte) (value >>> 24)); + set(i++, (byte) ((value >>> 16) & 0xFF)); + set(i++, (byte) ((value >>> 8) & 0xFF)); + set(i, (byte) (value & 0xFF)); + } + + /** + * Set the 8 bytes starting at the specified index to the specified long value. + * + * @param i The index, which must less than or equal to {@code size() - 8}. + * @param value The long value. + * @throws IndexOutOfBoundsException if {@code i < 0} or {@code i > size() - 8}. + */ + default void setLong(int i, long value) { + int size = size(); + checkElementIndex(i, size); + if (i > (size - 8)) { + throw new IndexOutOfBoundsException( + format("Value of size %s has not enough bytes to write a 8 bytes long from index %s", size, i)); + } + + set(i++, (byte) (value >>> 56)); + set(i++, (byte) ((value >>> 48) & 0xFF)); + set(i++, (byte) ((value >>> 40) & 0xFF)); + set(i++, (byte) ((value >>> 32) & 0xFF)); + set(i++, (byte) ((value >>> 24) & 0xFF)); + set(i++, (byte) ((value >>> 16) & 0xFF)); + set(i++, (byte) ((value >>> 8) & 0xFF)); + set(i, (byte) (value & 0xFF)); + } + + /** + * Increments the value of the bytes by 1, treating the value as big endian. + * + * If incrementing overflows the value then all bits flip, i.e. incrementing 0xFFFF will return 0x0000. + * + * @return this value + */ + default MutableBytes increment() { + for (int i = size() - 1; i >= 0; --i) { + if (get(i) == (byte) 0xFF) { + set(i, (byte) 0x00); + } else { + byte currentValue = get(i); + set(i, ++currentValue); + break; + } + } + return this; + } + + /** + * Decrements the value of the bytes by 1, treating the value as big endian. + * + * If decrementing underflows the value then all bits flip, i.e. decrementing 0x0000 will return 0xFFFF. + * + * @return this value + */ + default MutableBytes decrement() { + for (int i = size() - 1; i >= 0; --i) { + if (get(i) == (byte) 0x00) { + set(i, (byte) 0xFF); + } else { + byte currentValue = get(i); + set(i, --currentValue); + break; + } + } + return this; + } + + /** + * Create a mutable slice of the bytes of this value. + * + *

+ * Note: the resulting slice is only a view over the original value. Holding a reference to the returned slice may + * hold more memory than the slide represents. Use {@link #copy} on the returned slice to avoid this. + * + * @param i The start index for the slice. + * @param length The length of the resulting value. + * @return A new mutable view over the bytes of this value from index {@code i} (included) to index {@code i + length} + * (excluded). + * @throws IllegalArgumentException if {@code length < 0}. + * @throws IndexOutOfBoundsException if {@code i < 0} or {i >= size()} or {i + length > size()} . + */ + MutableBytes mutableSlice(int i, int length); + + /** + * Fill all the bytes of this value with the specified byte. + * + * @param b The byte to use to fill the value. + */ + default void fill(byte b) { + int size = size(); + for (int i = 0; i < size; i++) { + set(i, b); + } + } + + /** + * Set all bytes in this value to 0. + */ + default void clear() { + fill((byte) 0); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableBytes32.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableBytes32.java new file mode 100644 index 00000000000..41c221aa808 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableBytes32.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import static org.apache.tuweni.bytes.Checks.checkNotNull; + +/** + * A mutable {@link Bytes32}, that is a mutable {@link Bytes} value of exactly 32 bytes. + */ +public interface MutableBytes32 extends MutableBytes, Bytes32 { + + /** + * Create a new mutable 32 bytes value. + * + * @return A newly allocated {@link MutableBytes} value. + */ + static MutableBytes32 create() { + return new MutableArrayWrappingBytes32(new byte[SIZE]); + } + + /** + * Wrap a 32 bytes array as a mutable 32 bytes value. + * + * @param value The value to wrap. + * @return A {@link MutableBytes32} wrapping {@code value}. + * @throws IllegalArgumentException if {@code value.length != 32}. + */ + static MutableBytes32 wrap(byte[] value) { + checkNotNull(value); + return new MutableArrayWrappingBytes32(value); + } + + /** + * Wrap a the provided array as a {@link MutableBytes32}. + * + *

+ * Note that value is not copied, only wrapped, and thus any future update to {@code value} within the wrapped parts + * will be reflected in the returned value. + * + * @param value The bytes to wrap. + * @param offset The index (inclusive) in {@code value} of the first byte exposed by the returned value. In other + * words, you will have {@code wrap(value, i).get(0) == value[i]}. + * @return A {@link MutableBytes32} that exposes the bytes of {@code value} from {@code offset} (inclusive) to + * {@code offset + 32} (exclusive). + * @throws IndexOutOfBoundsException if {@code offset < 0 || (value.length > 0 && offset >= + * value.length)}. + * @throws IllegalArgumentException if {@code length < 0 || offset + 32 > value.length}. + */ + static MutableBytes32 wrap(byte[] value, int offset) { + checkNotNull(value); + return new MutableArrayWrappingBytes32(value, offset); + } + + /** + * Wrap a the provided value, which must be of size 32, as a {@link MutableBytes32}. + * + *

+ * Note that value is not copied, only wrapped, and thus any future update to {@code value} will be reflected in the + * returned value. + * + * @param value The bytes to wrap. + * @return A {@link MutableBytes32} that exposes the bytes of {@code value}. + * @throws IllegalArgumentException if {@code value.size() != 32}. + */ + static MutableBytes32 wrap(MutableBytes value) { + checkNotNull(value); + if (value instanceof MutableBytes32) { + return (MutableBytes32) value; + } + return DelegatingMutableBytes32.delegateTo(value); + } + + /** + * Wrap a slice/sub-part of the provided value as a {@link MutableBytes32}. + * + *

+ * Note that the value is not copied, and thus any future update to {@code value} within the wrapped parts will be + * reflected in the returned value. + * + * @param value The bytes to wrap. + * @param offset The index (inclusive) in {@code value} of the first byte exposed by the returned value. In other + * words, you will have {@code wrap(value, i).get(0) == value.get(i)}. + * @return A {@link Bytes32} that exposes the bytes of {@code value} from {@code offset} (inclusive) to + * {@code offset + 32} (exclusive). + * @throws IndexOutOfBoundsException if {@code offset < 0 || (value.size() > 0 && offset >= + * value.size())}. + * @throws IllegalArgumentException if {@code length < 0 || offset + 32 > value.size()}. + */ + static MutableBytes32 wrap(MutableBytes value, int offset) { + checkNotNull(value); + if (value instanceof MutableBytes32) { + return (MutableBytes32) value; + } + MutableBytes slice = value.mutableSlice(offset, Bytes32.SIZE); + if (slice instanceof MutableBytes32) { + return (MutableBytes32) slice; + } + return DelegatingMutableBytes32.delegateTo(slice); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableBytes48.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableBytes48.java new file mode 100644 index 00000000000..c8f51ad2c70 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/bytes/MutableBytes48.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + + +import static org.apache.tuweni.bytes.Checks.checkNotNull; + +/** + * A mutable {@link Bytes48}, that is a mutable {@link Bytes} value of exactly 48 bytes. + */ +public interface MutableBytes48 extends MutableBytes, Bytes48 { + + /** + * Create a new mutable 48 bytes value. + * + * @return A newly allocated {@link MutableBytes} value. + */ + static MutableBytes48 create() { + return new MutableArrayWrappingBytes48(new byte[SIZE]); + } + + /** + * Wrap a 48 bytes array as a mutable 48 bytes value. + * + * @param value The value to wrap. + * @return A {@link MutableBytes48} wrapping {@code value}. + * @throws IllegalArgumentException if {@code value.length != 48}. + */ + static MutableBytes48 wrap(byte[] value) { + checkNotNull(value); + return new MutableArrayWrappingBytes48(value); + } + + /** + * Wrap a the provided array as a {@link MutableBytes48}. + * + *

+ * Note that value is not copied, only wrapped, and thus any future update to {@code value} within the wrapped parts + * will be reflected in the returned value. + * + * @param value The bytes to wrap. + * @param offset The index (inclusive) in {@code value} of the first byte exposed by the returned value. In other + * words, you will have {@code wrap(value, i).get(0) == value[i]}. + * @return A {@link MutableBytes48} that exposes the bytes of {@code value} from {@code offset} (inclusive) to + * {@code offset + 48} (exclusive). + * @throws IndexOutOfBoundsException if {@code offset < 0 || (value.length > 0 && offset >= + * value.length)}. + * @throws IllegalArgumentException if {@code length < 0 || offset + 48 > value.length}. + */ + static MutableBytes48 wrap(byte[] value, int offset) { + checkNotNull(value); + return new MutableArrayWrappingBytes48(value, offset); + } + + /** + * Wrap a the provided value, which must be of size 48, as a {@link MutableBytes48}. + * + *

+ * Note that value is not copied, only wrapped, and thus any future update to {@code value} will be reflected in the + * returned value. + * + * @param value The bytes to wrap. + * @return A {@link MutableBytes48} that exposes the bytes of {@code value}. + * @throws IllegalArgumentException if {@code value.size() != 48}. + */ + static MutableBytes48 wrap(MutableBytes value) { + checkNotNull(value); + if (value instanceof MutableBytes48) { + return (MutableBytes48) value; + } + return DelegatingMutableBytes48.delegateTo(value); + } + + /** + * Wrap a slice/sub-part of the provided value as a {@link MutableBytes48}. + * + *

+ * Note that the value is not copied, and thus any future update to {@code value} within the wrapped parts will be + * reflected in the returned value. + * + * @param value The bytes to wrap. + * @param offset The index (inclusive) in {@code value} of the first byte exposed by the returned value. In other + * words, you will have {@code wrap(value, i).get(0) == value.get(i)}. + * @return A {@link Bytes48} that exposes the bytes of {@code value} from {@code offset} (inclusive) to + * {@code offset + 48} (exclusive). + * @throws IndexOutOfBoundsException if {@code offset < 0 || (value.size() > 0 && offset >= + * value.size())}. + * @throws IllegalArgumentException if {@code length < 0 || offset + 48 > value.size()}. + */ + static MutableBytes48 wrap(MutableBytes value, int offset) { + checkNotNull(value); + if (value instanceof MutableBytes48) { + return (MutableBytes48) value; + } + MutableBytes slice = value.mutableSlice(offset, Bytes48.SIZE); + if (slice instanceof MutableBytes48) { + return (MutableBytes48) slice; + } + return DelegatingMutableBytes48.delegateTo(slice); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BaseUInt256Value.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BaseUInt256Value.java new file mode 100644 index 00000000000..cf55c329d9d --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BaseUInt256Value.java @@ -0,0 +1,405 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.apache.tuweni.bytes.MutableBytes32; + +import java.math.BigInteger; +import java.nio.ByteOrder; +import java.util.function.Function; + +import static java.util.Objects.requireNonNull; + +/** + * Base class for {@link UInt256Value}. + * + *

+ * This class is abstract as it is not meant to be used directly, but it has no abstract methods. As mentioned in + * {@link UInt256Value}, this is used to create strongly-typed type aliases of {@link UInt256}. In other words, this + * allow to "tag" numbers with the unit of what they represent for the type-system, which can help clarity, but also + * forbid mixing numbers that are mean to be of different units (the strongly-typed part). + * + *

+ * This class implements {@link UInt256Value}, but also adds a few operations that take a {@link UInt256} directly, for + * instance {@link #multiply(UInt256)}. The rational is that multiplying a given quantity of something by a "raw" number + * is always meaningful, and return a new quantity of the same thing. + * + * @param The concrete type of the value. + */ +public abstract class BaseUInt256Value> implements UInt256Value { + + private final UInt256 value; + private final Function ctor; + + /** + * @param value The value to instantiate this {@code UInt256Value} with. + * @param ctor A constructor for the concrete type. + */ + protected BaseUInt256Value(UInt256 value, Function ctor) { + requireNonNull(value); + requireNonNull(ctor); + this.value = value; + this.ctor = ctor; + } + + /** + * @param value An unsigned value to instantiate this {@code UInt256Value} with. + * @param ctor A constructor for the concrete type. + */ + protected BaseUInt256Value(long value, Function ctor) { + requireNonNull(ctor); + this.value = UInt256.valueOf(value); + this.ctor = ctor; + } + + /** + * @param value An unsigned value to instantiate this {@code UInt256Value} with. + * @param ctor A constructor for the concrete type. + */ + protected BaseUInt256Value(BigInteger value, Function ctor) { + requireNonNull(value); + requireNonNull(ctor); + this.value = UInt256.valueOf(value); + this.ctor = ctor; + } + + /** + * Return a copy of this value, or itself if immutable. + * + *

+ * The default implementation of this method returns a copy using the constructor for the concrete type and the bytes + * returned from {@link #toBytes()}. Most implementations will want to override this method to instead return + * {@code this}. + * + * @return A copy of this value, or itself if immutable. + */ + @Override + public T copy() { + return ctor.apply(value); + } + + /** + * Return the zero value for this type. + * + *

+ * The default implementation of this method returns a value obtained from calling the concrete type constructor with + * an argument of {@link UInt256#ZERO}. Most implementations will want to override this method to instead return a + * static constant. + * + * @return The zero value for this type. + */ + protected T zero() { + return ctor.apply(UInt256.ZERO); + } + + /** + * Return the max value for this type. + * + *

+ * The default implementation of this method returns a value obtained from calling the concrete type constructor with + * an argument of {@link UInt256#MAX_VALUE}. Most implementations will want to override this method to instead return + * a static constant. + * + * @return The max value for this type. + */ + @Override + public T max() { + return ctor.apply(UInt256.MAX_VALUE); + } + + @Override + public T add(T value) { + return add(value.toUInt256()); + } + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value The amount to be added to this value. + * @return {@code this + value} + */ + public T add(UInt256 value) { + if (value.isZero()) { + return copy(); + } + return ctor.apply(this.value.add(value)); + } + + @Override + public T add(long value) { + if (value == 0) { + return copy(); + } + return ctor.apply(this.value.add(value)); + } + + @Override + public T addMod(T value, UInt256 modulus) { + return addMod(value.toUInt256(), modulus); + } + + /** + * Returns a value equivalent to {@code ((this + value) mod modulus)}. + * + * @param value The amount to be added to this value. + * @param modulus The modulus. + * @return {@code (this + value) mod modulus} + * @throws ArithmeticException {@code modulus} == 0. + */ + public T addMod(UInt256 value, UInt256 modulus) { + return ctor.apply(this.value.addMod(value, modulus)); + } + + @Override + public T addMod(long value, UInt256 modulus) { + return ctor.apply(this.value.addMod(value, modulus)); + } + + @Override + public T addMod(long value, long modulus) { + return ctor.apply(this.value.addMod(value, modulus)); + } + + @Override + public T subtract(T value) { + return subtract(value.toUInt256()); + } + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value The amount to be subtracted from this value. + * @return {@code this - value} + */ + public T subtract(UInt256 value) { + if (value.isZero()) { + return copy(); + } + return ctor.apply(this.value.subtract(value)); + } + + @Override + public T subtract(long value) { + if (value == 0) { + return copy(); + } + return ctor.apply(this.value.subtract(value)); + } + + @Override + public T multiply(T value) { + return multiply(value.toUInt256()); + } + + /** + * Returns a value that is {@code (this * value)}. + * + * @param value The amount to multiply this value by. + * @return {@code this * value} + */ + public T multiply(UInt256 value) { + if (isZero() || value.isZero()) { + return zero(); + } + if (value.equals(UInt256.ONE)) { + return copy(); + } + if (this.value.equals(UInt256.ONE)) { + return ctor.apply(value); + } + return ctor.apply(this.value.multiply(value)); + } + + @Override + public T multiply(long value) { + if (value == 0 || isZero()) { + return zero(); + } + if (value == 1) { + return copy(); + } + if (this.value.equals(UInt256.ONE)) { + return ctor.apply(UInt256.valueOf(value)); + } + return ctor.apply(this.value.multiply(value)); + } + + @Override + public T multiplyMod(T value, UInt256 modulus) { + return multiplyMod(value.toUInt256(), modulus); + } + + /** + * Returns a value that is {@code ((this * value) mod modulus)}. + * + * @param value The amount to multiply this value by. + * @param modulus The modulus. + * @return {@code (this * value) mod modulus} + * @throws ArithmeticException {@code value} < 0 or {@code modulus} == 0. + */ + public T multiplyMod(UInt256 value, UInt256 modulus) { + return ctor.apply(this.value.multiplyMod(value, modulus)); + } + + @Override + public T multiplyMod(long value, UInt256 modulus) { + return ctor.apply(this.value.multiplyMod(value, modulus)); + } + + @Override + public T multiplyMod(long value, long modulus) { + return ctor.apply(this.value.multiplyMod(value, modulus)); + } + + @Override + public T divide(T value) { + return divide(value.toUInt256()); + } + + /** + * Returns a value that is {@code (this / value)}. + * + * @param value The amount to divide this value by. + * @return {@code this / value} + * @throws ArithmeticException {@code value} == 0. + */ + public T divide(UInt256 value) { + return ctor.apply(this.value.divide(value)); + } + + @Override + public T divide(long value) { + return ctor.apply(this.value.divide(value)); + } + + @Override + public T divideCeil(T value) { + return divideCeil(value.toUInt256()); + } + + /** + * Returns a value that is {@code (this / value)}. + * + * @param value The amount to divide this value by. + * @return {@code this / value} + * @throws ArithmeticException {@code value} == 0. + */ + public T divideCeil(UInt256 value) { + return ctor.apply(this.value.divideCeil(value)); + } + + @Override + public T divideCeil(long value) { + return ctor.apply(this.value.divideCeil(value)); + } + + @Override + public T pow(UInt256 exponent) { + return ctor.apply(this.value.pow(exponent)); + } + + @Override + public T pow(long exponent) { + return ctor.apply(this.value.pow(exponent)); + } + + @Override + public T mod(UInt256 modulus) { + return ctor.apply(this.value.mod(modulus)); + } + + @Override + public T mod(long modulus) { + return ctor.apply(this.value.mod(modulus)); + } + + @Override + public T mod0(UInt256 modulus) { + return ctor.apply(this.value.mod0(modulus)); + } + + @Override + public T mod0(long modulus) { + return ctor.apply(this.value.mod0(modulus)); + } + + /** + * Compare two {@link UInt256} values. + * + * @param other The value to compare to. + * @return A negative integer, zero, or a positive integer as this value is less than, equal to, or greater than the + * specified value. + */ + public int compareTo(UInt256 other) { + return this.value.compareTo(other); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof UInt256Value)) { + return false; + } + UInt256Value other = (UInt256Value) obj; + return this.value.equals(other.toUInt256()); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + + @Override + public String toString() { + return value.toString(); + } + + @Override + public UInt256 toUInt256() { + return value; + } + + @Override + public Bytes32 toBytes() { + return value; + } + + @Override + public Bytes toMinimalBytes() { + return value.toMinimalBytes(); + } + + @Override + public byte get(int i) { + return value.get(i); + } + + @Override + public Bytes slice(int i, int length) { + return value.slice(i, length); + } + + @Override + public MutableBytes32 mutableCopy() { + return MutableBytes32.wrap(value.toArrayUnsafe()); + } + + @Override + public long toLong(ByteOrder order) { + return value.toLong(order); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BaseUInt32Value.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BaseUInt32Value.java new file mode 100644 index 00000000000..f50b8896292 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BaseUInt32Value.java @@ -0,0 +1,334 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +import org.apache.tuweni.bytes.Bytes; + +import java.math.BigInteger; +import java.util.function.Function; + +import static java.util.Objects.requireNonNull; + +/** + * Base class for {@link UInt32Value}. + * + *

+ * This class is abstract as it is not meant to be used directly, but it has no abstract methods. As mentioned in + * {@link UInt32Value}, this is used to create strongly-typed type aliases of {@link UInt32}. In other words, this allow + * to "tag" numbers with the unit of what they represent for the type-system, which can help clarity, but also forbid + * mixing numbers that are mean to be of different units (the strongly-typed part). + * + *

+ * This class implements {@link UInt32Value}, but also adds a few operations that take a {@link UInt32} directly, for + * instance {@link #multiply(UInt32)}. The rational is that multiplying a given quantity of something by a "raw" number + * is always meaningful, and return a new quantity of the same thing. + * + * @param The concrete type of the value. + */ +public abstract class BaseUInt32Value> implements UInt32Value { + + private final UInt32 value; + private final Function ctor; + + /** + * @param value The value to instantiate this {@code UInt32Value} with. + * @param ctor A constructor for the concrete type. + */ + protected BaseUInt32Value(UInt32 value, Function ctor) { + requireNonNull(value); + requireNonNull(ctor); + this.value = value; + this.ctor = ctor; + } + + /** + * @param value An unsigned value to instantiate this {@code UInt32Value} with. + * @param ctor A constructor for the concrete type. + */ + protected BaseUInt32Value(int value, Function ctor) { + requireNonNull(ctor); + this.value = UInt32.valueOf(value); + this.ctor = ctor; + } + + /** + * @param value An unsigned value to instantiate this {@code UInt32Value} with. + * @param ctor A constructor for the concrete type. + */ + protected BaseUInt32Value(BigInteger value, Function ctor) { + requireNonNull(value); + requireNonNull(ctor); + this.value = UInt32.valueOf(value); + this.ctor = ctor; + } + + /** + * Return a copy of this value, or itself if immutable. + * + *

+ * The default implementation of this method returns a copy using the constructor for the concrete type and the bytes + * returned from {@link #toBytes()}. Most implementations will want to override this method to instead return + * {@code this}. + * + * @return A copy of this value, or itself if immutable. + */ + protected T copy() { + return ctor.apply(value); + } + + /** + * Return the zero value for this type. + * + *

+ * The default implementation of this method returns a value obtained from calling the concrete type constructor with + * an argument of {@link UInt32#ZERO}. Most implementations will want to override this method to instead return a + * static constant. + * + * @return The zero value for this type. + */ + protected T zero() { + return ctor.apply(UInt32.ZERO); + } + + @Override + public T add(T value) { + return add(value.toUInt32()); + } + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value The amount to be added to this value. + * @return {@code this + value} + */ + public T add(UInt32 value) { + if (value.isZero()) { + return copy(); + } + return ctor.apply(this.value.add(value)); + } + + @Override + public T add(int value) { + if (value == 0) { + return copy(); + } + return ctor.apply(this.value.add(value)); + } + + @Override + public T addMod(T value, UInt32 modulus) { + return addMod(value.toUInt32(), modulus); + } + + /** + * Returns a value equivalent to {@code ((this + value) mod modulus)}. + * + * @param value The amount to be added to this value. + * @param modulus The modulus. + * @return {@code (this + value) mod modulus} + * @throws ArithmeticException {@code modulus} == 0. + */ + public T addMod(UInt32 value, UInt32 modulus) { + return ctor.apply(this.value.addMod(value, modulus)); + } + + @Override + public T addMod(long value, UInt32 modulus) { + return ctor.apply(this.value.addMod(value, modulus)); + } + + @Override + public T addMod(long value, long modulus) { + return ctor.apply(this.value.addMod(value, modulus)); + } + + @Override + public T subtract(T value) { + return subtract(value.toUInt32()); + } + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value The amount to be subtracted from this value. + * @return {@code this - value} + */ + public T subtract(UInt32 value) { + if (value.isZero()) { + return copy(); + } + return ctor.apply(this.value.subtract(value)); + } + + @Override + public T subtract(int value) { + if (value == 0) { + return copy(); + } + return ctor.apply(this.value.subtract(value)); + } + + @Override + public T multiply(T value) { + return multiply(value.toUInt32()); + } + + /** + * Returns a value that is {@code (this * value)}. + * + * @param value The amount to multiply this value by. + * @return {@code this * value} + */ + public T multiply(UInt32 value) { + if (isZero() || value.isZero()) { + return zero(); + } + if (value.equals(UInt32.ONE)) { + return copy(); + } + return ctor.apply(this.value.multiply(value)); + } + + @Override + public T multiply(int value) { + if (value == 0 || isZero()) { + return zero(); + } + if (value == 1) { + return copy(); + } + return ctor.apply(this.value.multiply(value)); + } + + @Override + public T multiplyMod(T value, UInt32 modulus) { + return multiplyMod(value.toUInt32(), modulus); + } + + /** + * Returns a value that is {@code ((this * value) mod modulus)}. + * + * @param value The amount to multiply this value by. + * @param modulus The modulus. + * @return {@code (this * value) mod modulus} + * @throws ArithmeticException {@code value} < 0 or {@code modulus} == 0. + */ + public T multiplyMod(UInt32 value, UInt32 modulus) { + return ctor.apply(this.value.multiplyMod(value, modulus)); + } + + @Override + public T multiplyMod(int value, UInt32 modulus) { + return ctor.apply(this.value.multiplyMod(value, modulus)); + } + + @Override + public T multiplyMod(int value, int modulus) { + return ctor.apply(this.value.multiplyMod(value, modulus)); + } + + @Override + public T divide(T value) { + return divide(value.toUInt32()); + } + + /** + * Returns a value that is {@code (this / value)}. + * + * @param value The amount to divide this value by. + * @return {@code this / value} + * @throws ArithmeticException {@code value} == 0. + */ + public T divide(UInt32 value) { + return ctor.apply(this.value.divide(value)); + } + + @Override + public T divide(int value) { + return ctor.apply(this.value.divide(value)); + } + + @Override + public T pow(UInt32 exponent) { + return ctor.apply(this.value.pow(exponent)); + } + + @Override + public T pow(long exponent) { + return ctor.apply(this.value.pow(exponent)); + } + + @Override + public T mod(UInt32 modulus) { + return ctor.apply(this.value.mod(modulus)); + } + + @Override + public T mod(int modulus) { + return ctor.apply(this.value.mod(modulus)); + } + + @Override + public int compareTo(T other) { + return compareTo(other.toUInt32()); + } + + /** + * Compare two {@link UInt32} values. + * + * @param other The value to compare to. + * @return A negative integer, zero, or a positive integer as this value is less than, equal to, or greater than the + * specified value. + */ + public int compareTo(UInt32 other) { + return this.value.compareTo(other); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof UInt32Value)) { + return false; + } + UInt32Value other = (UInt32Value) obj; + return this.value.equals(other.toUInt32()); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + + @Override + public String toString() { + return value.toString(); + } + + @Override + public UInt32 toUInt32() { + return value; + } + + @Override + public Bytes toBytes() { + return value.toBytes(); + } + + @Override + public Bytes toMinimalBytes() { + return value.toMinimalBytes(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BaseUInt384Value.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BaseUInt384Value.java new file mode 100644 index 00000000000..fdc0432e4b9 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BaseUInt384Value.java @@ -0,0 +1,335 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes48; + +import java.math.BigInteger; +import java.util.function.Function; + +import static java.util.Objects.requireNonNull; + +/** + * Base class for {@link UInt384Value}. + * + *

+ * This class is abstract as it is not meant to be used directly, but it has no abstract methods. As mentioned in + * {@link UInt384Value}, this is used to create strongly-typed type aliases of {@link UInt384}. In other words, this + * allow to "tag" numbers with the unit of what they represent for the type-system, which can help clarity, but also + * forbid mixing numbers that are mean to be of different units (the strongly-typed part). + * + *

+ * This class implements {@link UInt384Value}, but also adds a few operations that take a {@link UInt384} directly, for + * instance {@link #multiply(UInt384)}. The rational is that multiplying a given quantity of something by a "raw" number + * is always meaningful, and return a new quantity of the same thing. + * + * @param The concrete type of the value. + */ +public abstract class BaseUInt384Value> implements UInt384Value { + + private final UInt384 value; + private final Function ctor; + + /** + * @param value The value to instantiate this {@code UInt384Value} with. + * @param ctor A constructor for the concrete type. + */ + protected BaseUInt384Value(UInt384 value, Function ctor) { + requireNonNull(value); + requireNonNull(ctor); + this.value = value; + this.ctor = ctor; + } + + /** + * @param value An unsigned value to instantiate this {@code UInt384Value} with. + * @param ctor A constructor for the concrete type. + */ + protected BaseUInt384Value(long value, Function ctor) { + requireNonNull(ctor); + this.value = UInt384.valueOf(value); + this.ctor = ctor; + } + + /** + * @param value An unsigned value to instantiate this {@code UInt384Value} with. + * @param ctor A constructor for the concrete type. + */ + protected BaseUInt384Value(BigInteger value, Function ctor) { + requireNonNull(value); + requireNonNull(ctor); + this.value = UInt384.valueOf(value); + this.ctor = ctor; + } + + /** + * Return a copy of this value, or itself if immutable. + * + *

+ * The default implementation of this method returns a copy using the constructor for the concrete type and the bytes + * returned from {@link #toBytes()}. Most implementations will want to override this method to instead return + * {@code this}. + * + * @return A copy of this value, or itself if immutable. + */ + protected T copy() { + return ctor.apply(value); + } + + /** + * Return the zero value for this type. + * + *

+ * The default implementation of this method returns a value obtained from calling the concrete type constructor with + * an argument of {@link Bytes48#ZERO}. Most implementations will want to override this method to instead return a + * static constant. + * + * @return The zero value for this type. + */ + protected T zero() { + return ctor.apply(UInt384.ZERO); + } + + @Override + public T add(T value) { + return add(value.toUInt384()); + } + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value The amount to be added to this value. + * @return {@code this + value} + */ + public T add(UInt384 value) { + if (value.isZero()) { + return copy(); + } + return ctor.apply(this.value.add(value)); + } + + @Override + public T add(long value) { + if (value == 0) { + return copy(); + } + return ctor.apply(this.value.add(value)); + } + + @Override + public T addMod(T value, UInt384 modulus) { + return addMod(value.toUInt384(), modulus); + } + + /** + * Returns a value equivalent to {@code ((this + value) mod modulus)}. + * + * @param value The amount to be added to this value. + * @param modulus The modulus. + * @return {@code (this + value) mod modulus} + * @throws ArithmeticException {@code modulus} == 0. + */ + public T addMod(UInt384 value, UInt384 modulus) { + return ctor.apply(this.value.addMod(value, modulus)); + } + + @Override + public T addMod(long value, UInt384 modulus) { + return ctor.apply(this.value.addMod(value, modulus)); + } + + @Override + public T addMod(long value, long modulus) { + return ctor.apply(this.value.addMod(value, modulus)); + } + + @Override + public T subtract(T value) { + return subtract(value.toUInt384()); + } + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value The amount to be subtracted from this value. + * @return {@code this - value} + */ + public T subtract(UInt384 value) { + if (value.isZero()) { + return copy(); + } + return ctor.apply(this.value.subtract(value)); + } + + @Override + public T subtract(long value) { + if (value == 0) { + return copy(); + } + return ctor.apply(this.value.subtract(value)); + } + + @Override + public T multiply(T value) { + return multiply(value.toUInt384()); + } + + /** + * Returns a value that is {@code (this * value)}. + * + * @param value The amount to multiply this value by. + * @return {@code this * value} + */ + public T multiply(UInt384 value) { + if (isZero() || value.isZero()) { + return zero(); + } + if (value.equals(UInt384.ONE)) { + return copy(); + } + return ctor.apply(this.value.multiply(value)); + } + + @Override + public T multiply(long value) { + if (value == 0 || isZero()) { + return zero(); + } + if (value == 1) { + return copy(); + } + return ctor.apply(this.value.multiply(value)); + } + + @Override + public T multiplyMod(T value, UInt384 modulus) { + return multiplyMod(value.toUInt384(), modulus); + } + + /** + * Returns a value that is {@code ((this * value) mod modulus)}. + * + * @param value The amount to multiply this value by. + * @param modulus The modulus. + * @return {@code (this * value) mod modulus} + * @throws ArithmeticException {@code value} < 0 or {@code modulus} == 0. + */ + public T multiplyMod(UInt384 value, UInt384 modulus) { + return ctor.apply(this.value.multiplyMod(value, modulus)); + } + + @Override + public T multiplyMod(long value, UInt384 modulus) { + return ctor.apply(this.value.multiplyMod(value, modulus)); + } + + @Override + public T multiplyMod(long value, long modulus) { + return ctor.apply(this.value.multiplyMod(value, modulus)); + } + + @Override + public T divide(T value) { + return divide(value.toUInt384()); + } + + /** + * Returns a value that is {@code (this / value)}. + * + * @param value The amount to divide this value by. + * @return {@code this / value} + * @throws ArithmeticException {@code value} == 0. + */ + public T divide(UInt384 value) { + return ctor.apply(this.value.divide(value)); + } + + @Override + public T divide(long value) { + return ctor.apply(this.value.divide(value)); + } + + @Override + public T pow(UInt384 exponent) { + return ctor.apply(this.value.pow(exponent)); + } + + @Override + public T pow(long exponent) { + return ctor.apply(this.value.pow(exponent)); + } + + @Override + public T mod(UInt384 modulus) { + return ctor.apply(this.value.mod(modulus)); + } + + @Override + public T mod(long modulus) { + return ctor.apply(this.value.mod(modulus)); + } + + @Override + public int compareTo(T other) { + return compareTo(other.toUInt384()); + } + + /** + * Compare two {@link UInt384} values. + * + * @param other The value to compare to. + * @return A negative integer, zero, or a positive integer as this value is less than, equal to, or greater than the + * specified value. + */ + public int compareTo(UInt384 other) { + return this.value.compareTo(other); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof UInt384Value)) { + return false; + } + UInt384Value other = (UInt384Value) obj; + return this.value.equals(other.toUInt384()); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + + @Override + public String toString() { + return value.toString(); + } + + @Override + public UInt384 toUInt384() { + return value; + } + + @Override + public Bytes48 toBytes() { + return value.toBytes(); + } + + @Override + public Bytes toMinimalBytes() { + return value.toMinimalBytes(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BaseUInt64Value.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BaseUInt64Value.java new file mode 100644 index 00000000000..c216791615e --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BaseUInt64Value.java @@ -0,0 +1,334 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +import org.apache.tuweni.bytes.Bytes; + +import java.math.BigInteger; +import java.util.function.Function; + +import static java.util.Objects.requireNonNull; + +/** + * Base class for {@link UInt64Value}. + * + *

+ * This class is abstract as it is not meant to be used directly, but it has no abstract methods. As mentioned in + * {@link UInt64Value}, this is used to create strongly-typed type aliases of {@link UInt64}. In other words, this allow + * to "tag" numbers with the unit of what they represent for the type-system, which can help clarity, but also forbid + * mixing numbers that are mean to be of different units (the strongly-typed part). + * + *

+ * This class implements {@link UInt64Value}, but also adds a few operations that take a {@link UInt64} directly, for + * instance {@link #multiply(UInt64)}. The rational is that multiplying a given quantity of something by a "raw" number + * is always meaningful, and return a new quantity of the same thing. + * + * @param The concrete type of the value. + */ +public abstract class BaseUInt64Value> implements UInt64Value { + + private final UInt64 value; + private final Function ctor; + + /** + * @param value The value to instantiate this {@code UInt64Value} with. + * @param ctor A constructor for the concrete type. + */ + protected BaseUInt64Value(UInt64 value, Function ctor) { + requireNonNull(value); + requireNonNull(ctor); + this.value = value; + this.ctor = ctor; + } + + /** + * @param value An unsigned value to instantiate this {@code UInt64Value} with. + * @param ctor A constructor for the concrete type. + */ + protected BaseUInt64Value(long value, Function ctor) { + requireNonNull(ctor); + this.value = UInt64.valueOf(value); + this.ctor = ctor; + } + + /** + * @param value An unsigned value to instantiate this {@code UInt64Value} with. + * @param ctor A constructor for the concrete type. + */ + protected BaseUInt64Value(BigInteger value, Function ctor) { + requireNonNull(value); + requireNonNull(ctor); + this.value = UInt64.valueOf(value); + this.ctor = ctor; + } + + /** + * Return a copy of this value, or itself if immutable. + * + *

+ * The default implementation of this method returns a copy using the constructor for the concrete type and the bytes + * returned from {@link #toBytes()}. Most implementations will want to override this method to instead return + * {@code this}. + * + * @return A copy of this value, or itself if immutable. + */ + protected T copy() { + return ctor.apply(value); + } + + /** + * Return the zero value for this type. + * + *

+ * The default implementation of this method returns a value obtained from calling the concrete type constructor with + * an argument of {@link UInt64#ZERO}. Most implementations will want to override this method to instead return a + * static constant. + * + * @return The zero value for this type. + */ + protected T zero() { + return ctor.apply(UInt64.ZERO); + } + + @Override + public T add(T value) { + return add(value.toUInt64()); + } + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value The amount to be added to this value. + * @return {@code this + value} + */ + public T add(UInt64 value) { + if (value.isZero()) { + return copy(); + } + return ctor.apply(this.value.add(value)); + } + + @Override + public T add(long value) { + if (value == 0) { + return copy(); + } + return ctor.apply(this.value.add(value)); + } + + @Override + public T addMod(T value, UInt64 modulus) { + return addMod(value.toUInt64(), modulus); + } + + /** + * Returns a value equivalent to {@code ((this + value) mod modulus)}. + * + * @param value The amount to be added to this value. + * @param modulus The modulus. + * @return {@code (this + value) mod modulus} + * @throws ArithmeticException {@code modulus} == 0. + */ + public T addMod(UInt64 value, UInt64 modulus) { + return ctor.apply(this.value.addMod(value, modulus)); + } + + @Override + public T addMod(long value, UInt64 modulus) { + return ctor.apply(this.value.addMod(value, modulus)); + } + + @Override + public T addMod(long value, long modulus) { + return ctor.apply(this.value.addMod(value, modulus)); + } + + @Override + public T subtract(T value) { + return subtract(value.toUInt64()); + } + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value The amount to be subtracted from this value. + * @return {@code this - value} + */ + public T subtract(UInt64 value) { + if (value.isZero()) { + return copy(); + } + return ctor.apply(this.value.subtract(value)); + } + + @Override + public T subtract(long value) { + if (value == 0) { + return copy(); + } + return ctor.apply(this.value.subtract(value)); + } + + @Override + public T multiply(T value) { + return multiply(value.toUInt64()); + } + + /** + * Returns a value that is {@code (this * value)}. + * + * @param value The amount to multiply this value by. + * @return {@code this * value} + */ + public T multiply(UInt64 value) { + if (isZero() || value.isZero()) { + return zero(); + } + if (value.equals(UInt64.ONE)) { + return copy(); + } + return ctor.apply(this.value.multiply(value)); + } + + @Override + public T multiply(long value) { + if (value == 0 || isZero()) { + return zero(); + } + if (value == 1) { + return copy(); + } + return ctor.apply(this.value.multiply(value)); + } + + @Override + public T multiplyMod(T value, UInt64 modulus) { + return multiplyMod(value.toUInt64(), modulus); + } + + /** + * Returns a value that is {@code ((this * value) mod modulus)}. + * + * @param value The amount to multiply this value by. + * @param modulus The modulus. + * @return {@code (this * value) mod modulus} + * @throws ArithmeticException {@code value} < 0 or {@code modulus} == 0. + */ + public T multiplyMod(UInt64 value, UInt64 modulus) { + return ctor.apply(this.value.multiplyMod(value, modulus)); + } + + @Override + public T multiplyMod(long value, UInt64 modulus) { + return ctor.apply(this.value.multiplyMod(value, modulus)); + } + + @Override + public T multiplyMod(long value, long modulus) { + return ctor.apply(this.value.multiplyMod(value, modulus)); + } + + @Override + public T divide(T value) { + return divide(value.toUInt64()); + } + + /** + * Returns a value that is {@code (this / value)}. + * + * @param value The amount to divide this value by. + * @return {@code this / value} + * @throws ArithmeticException {@code value} == 0. + */ + public T divide(UInt64 value) { + return ctor.apply(this.value.divide(value)); + } + + @Override + public T divide(long value) { + return ctor.apply(this.value.divide(value)); + } + + @Override + public T pow(UInt64 exponent) { + return ctor.apply(this.value.pow(exponent)); + } + + @Override + public T pow(long exponent) { + return ctor.apply(this.value.pow(exponent)); + } + + @Override + public T mod(UInt64 modulus) { + return ctor.apply(this.value.mod(modulus)); + } + + @Override + public T mod(long modulus) { + return ctor.apply(this.value.mod(modulus)); + } + + @Override + public int compareTo(T other) { + return compareTo(other.toUInt64()); + } + + /** + * Compare two {@link UInt64} values. + * + * @param other The value to compare to. + * @return A negative integer, zero, or a positive integer as this value is less than, equal to, or greater than the + * specified value. + */ + public int compareTo(UInt64 other) { + return this.value.compareTo(other); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof UInt64Value)) { + return false; + } + UInt64Value other = (UInt64Value) obj; + return this.value.equals(other.toUInt64()); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + + @Override + public String toString() { + return value.toString(); + } + + @Override + public UInt64 toUInt64() { + return value; + } + + @Override + public Bytes toBytes() { + return value.toBytes(); + } + + @Override + public Bytes toMinimalBytes() { + return value.toMinimalBytes(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BytesUInt256Value.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BytesUInt256Value.java new file mode 100644 index 00000000000..cd1ead967e3 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/BytesUInt256Value.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +import java.math.BigInteger; + +public interface BytesUInt256Value> extends Bytes32, UInt256Value { + + @Override + default long toLong() { + return ((Bytes32) this).toLong(); + } + + @Override + default String toHexString() { + return ((Bytes32) this).toHexString(); + } + + @Override + default String toShortHexString() { + return ((Bytes) this).toShortHexString(); + } + + @Override + default BigInteger toBigInteger() { + return ((UInt256Value) this).toBigInteger(); + } + + @Override + default int numberOfLeadingZeros() { + return ((Bytes) this).numberOfLeadingZeros(); + } + + @Override + default boolean isZero() { + return ((Bytes) this).isZero(); + } + + @Override + default int bitLength() { + return ((Bytes) this).bitLength(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt256.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt256.java new file mode 100644 index 00000000000..c6d060e6178 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt256.java @@ -0,0 +1,970 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.apache.tuweni.bytes.MutableBytes; +import org.apache.tuweni.bytes.MutableBytes32; +import org.jetbrains.annotations.Nullable; + +import java.math.BigInteger; +import java.util.Arrays; + +/** + * An unsigned 256-bit precision number. + * + * This is a raw {@link UInt256Value} - a 256-bit precision unsigned number of no particular unit. + */ +public final class UInt256 implements UInt256Value { + private final static int MAX_CONSTANT = 64; + private final static BigInteger BI_MAX_CONSTANT = BigInteger.valueOf(MAX_CONSTANT); + private static UInt256[] CONSTANTS = new UInt256[MAX_CONSTANT + 1]; + static { + CONSTANTS[0] = new UInt256(Bytes32.ZERO); + for (int i = 1; i <= MAX_CONSTANT; ++i) { + CONSTANTS[i] = new UInt256(i); + } + } + + /** The minimum value of a UInt256 */ + public final static UInt256 MIN_VALUE = valueOf(0); + /** The maximum value of a UInt256 */ + public final static UInt256 MAX_VALUE = new UInt256(Bytes32.ZERO.not()); + /** The value 0 */ + public final static UInt256 ZERO = valueOf(0); + /** The value 1 */ + public final static UInt256 ONE = valueOf(1); + + private static final int INTS_SIZE = 32 / 4; + // The mask is used to obtain the value of an int as if it were unsigned. + private static final long LONG_MASK = 0xFFFFFFFFL; + private static final BigInteger P_2_256 = BigInteger.valueOf(2).pow(256); + + // The unsigned int components of the value + private final int[] ints; + private Integer hashCode; + + /** + * Return a {@code UInt256} containing the specified value. + * + * @param value The value to create a {@code UInt256} for. + * @return A {@code UInt256} containing the specified value. + * @throws IllegalArgumentException If the value is negative. + */ + public static UInt256 valueOf(long value) { + if (value < 0) { + throw new IllegalArgumentException("Argument must be positive"); + } + if (value <= MAX_CONSTANT) { + return CONSTANTS[(int) value]; + } + return new UInt256(value); + } + + /** + * Return a {@link UInt256} containing the specified value. + * + * @param value the value to create a {@link UInt256} for + * @return a {@link UInt256} containing the specified value + * @throws IllegalArgumentException if the value is negative or too large to be represented as a UInt256 + */ + public static UInt256 valueOf(BigInteger value) { + if (value.signum() < 0) { + throw new IllegalArgumentException("Argument must be positive"); + } + if (value.bitLength() > 256) { + throw new IllegalArgumentException("Argument is too large to represent a UInt256"); + } + if (value.compareTo(BI_MAX_CONSTANT) <= 0) { + return CONSTANTS[value.intValue()]; + } + int[] ints = new int[INTS_SIZE]; + for (int i = INTS_SIZE - 1; i >= 0; --i) { + ints[i] = value.intValue(); + value = value.shiftRight(32); + } + return new UInt256(ints); + } + + /** + * Return a {@link UInt256} containing the value described by the specified bytes. + * + * @param bytes The bytes containing a {@link UInt256}. + * @return A {@link UInt256} containing the specified value. + * @throws IllegalArgumentException if {@code bytes.size() > 32}. + */ + public static UInt256 fromBytes(final Bytes bytes) { + if (bytes instanceof UInt256) { + return (UInt256) bytes; + } + if (bytes instanceof Bytes32) { + final byte[] array = bytes.toArrayUnsafe(); + return new UInt256( + new int[] { + (Byte.toUnsignedInt(array[0])) << 24 + | (Byte.toUnsignedInt(array[1]) << 16) + | (Byte.toUnsignedInt(array[2]) << 8) + | (Byte.toUnsignedInt(array[3])), + (Byte.toUnsignedInt(array[4]) << 24) + | (Byte.toUnsignedInt(array[5]) << 16) + | (Byte.toUnsignedInt(array[6]) << 8) + | (Byte.toUnsignedInt(array[7])), + (Byte.toUnsignedInt(array[8]) << 24) + | (Byte.toUnsignedInt(array[9]) << 16) + | (Byte.toUnsignedInt(array[10]) << 8) + | (Byte.toUnsignedInt(array[11])), + (Byte.toUnsignedInt(array[12]) << 24) + | (Byte.toUnsignedInt(array[13]) << 16) + | (Byte.toUnsignedInt(array[14]) << 8) + | (Byte.toUnsignedInt(array[15])), + (Byte.toUnsignedInt(array[16]) << 24) + | (Byte.toUnsignedInt(array[17]) << 16) + | (Byte.toUnsignedInt(array[18]) << 8) + | (Byte.toUnsignedInt(array[19])), + (Byte.toUnsignedInt(array[20]) << 24) + | (Byte.toUnsignedInt(array[21]) << 16) + | (Byte.toUnsignedInt(array[22]) << 8) + | (Byte.toUnsignedInt(array[23])), + (Byte.toUnsignedInt(array[24]) << 24) + | (Byte.toUnsignedInt(array[25]) << 16) + | (Byte.toUnsignedInt(array[26]) << 8) + | (Byte.toUnsignedInt(array[27])), + (Byte.toUnsignedInt(array[28]) << 24) + | (Byte.toUnsignedInt(array[29]) << 16) + | (Byte.toUnsignedInt(array[30]) << 8) + | (Byte.toUnsignedInt(array[31]))}); + } else { + return new UInt256(Bytes32.leftPad(bytes)); + } + } + + /** + * Parse a hexadecimal string into a {@link UInt256}. + * + * @param str The hexadecimal string to parse, which may or may not start with "0x". That representation may contain + * less than 32 bytes, in which case the result is left padded with zeros. + * @return The value corresponding to {@code str}. + * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation or + * contains more than 32 bytes. + */ + public static UInt256 fromHexString(String str) { + return new UInt256(Bytes32.fromHexStringLenient(str)); + } + + private UInt256(Bytes32 bytes) { + this.ints = new int[INTS_SIZE]; + for (int i = 0, j = 0; i < INTS_SIZE; ++i, j += 4) { + ints[i] = bytes.getInt(j); + } + } + + private UInt256(long value) { + this.ints = new int[INTS_SIZE]; + this.ints[INTS_SIZE - 2] = (int) ((value >>> 32) & LONG_MASK); + this.ints[INTS_SIZE - 1] = (int) (value & LONG_MASK); + } + + private UInt256(int[] ints) { + this.ints = ints; + } + + @SuppressWarnings("ReferenceEquality") + @Override + public boolean isZero() { + if (this == ZERO) { + return true; + } + for (int i = INTS_SIZE - 1; i >= 0; --i) { + if (this.ints[i] != 0) { + return false; + } + } + return true; + } + + @Override + public UInt256 add(UInt256 value) { + if (value.isZero()) { + return this; + } + if (isZero()) { + return value; + } + int[] result = new int[INTS_SIZE]; + boolean constant = true; + long sum = (this.ints[INTS_SIZE - 1] & LONG_MASK) + (value.ints[INTS_SIZE - 1] & LONG_MASK); + result[INTS_SIZE - 1] = (int) (sum & LONG_MASK); + if (result[INTS_SIZE - 1] < 0 || result[INTS_SIZE - 1] > MAX_CONSTANT) { + constant = false; + } + for (int i = INTS_SIZE - 2; i >= 0; --i) { + sum = (this.ints[i] & LONG_MASK) + (value.ints[i] & LONG_MASK) + (sum >>> 32); + result[i] = (int) (sum & LONG_MASK); + constant &= result[i] == 0; + } + if (constant) { + return CONSTANTS[result[INTS_SIZE - 1]]; + } + return new UInt256(result); + } + + @Override + public UInt256 add(long value) { + if (value == 0) { + return this; + } + if (value > 0 && isZero()) { + return UInt256.valueOf(value); + } + int[] result = new int[INTS_SIZE]; + boolean constant = true; + long sum = (this.ints[INTS_SIZE - 1] & LONG_MASK) + (value & LONG_MASK); + result[INTS_SIZE - 1] = (int) (sum & LONG_MASK); + if (result[INTS_SIZE - 1] < 0 || result[INTS_SIZE - 1] > MAX_CONSTANT) { + constant = false; + } + sum = (this.ints[INTS_SIZE - 2] & LONG_MASK) + (value >>> 32) + (sum >>> 32); + result[INTS_SIZE - 2] = (int) (sum & LONG_MASK); + constant &= result[INTS_SIZE - 2] == 0; + long signExtent = (value >> 63) & LONG_MASK; + for (int i = INTS_SIZE - 3; i >= 0; --i) { + sum = (this.ints[i] & LONG_MASK) + signExtent + (sum >>> 32); + result[i] = (int) (sum & LONG_MASK); + constant &= result[i] == 0; + } + if (constant) { + return CONSTANTS[result[INTS_SIZE - 1]]; + } + return new UInt256(result); + } + + @Override + public UInt256 addMod(UInt256 value, UInt256 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("addMod with zero modulus"); + } + return UInt256 + .valueOf(toUnsignedBigInteger().add(value.toUnsignedBigInteger()).mod(modulus.toUnsignedBigInteger())); + } + + @Override + public UInt256 addMod(long value, UInt256 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("addMod with zero modulus"); + } + return UInt256.valueOf(toUnsignedBigInteger().add(BigInteger.valueOf(value)).mod(modulus.toUnsignedBigInteger())); + } + + @Override + public UInt256 addMod(long value, long modulus) { + if (modulus == 0) { + throw new ArithmeticException("addMod with zero modulus"); + } + if (modulus < 0) { + throw new ArithmeticException("addMod unsigned with negative modulus"); + } + return UInt256.valueOf(toUnsignedBigInteger().add(BigInteger.valueOf(value)).mod(BigInteger.valueOf(modulus))); + } + + @Override + public UInt256 subtract(UInt256 value) { + if (value.isZero()) { + return this; + } + + int[] result = new int[INTS_SIZE]; + boolean constant = true; + long sum = (this.ints[INTS_SIZE - 1] & LONG_MASK) + ((~value.ints[INTS_SIZE - 1]) & LONG_MASK) + 1; + result[INTS_SIZE - 1] = (int) (sum & LONG_MASK); + if (result[INTS_SIZE - 1] < 0 || result[INTS_SIZE - 1] > MAX_CONSTANT) { + constant = false; + } + for (int i = INTS_SIZE - 2; i >= 0; --i) { + sum = (this.ints[i] & LONG_MASK) + ((~value.ints[i]) & LONG_MASK) + (sum >>> 32); + result[i] = (int) (sum & LONG_MASK); + constant &= result[i] == 0; + } + if (constant) { + return CONSTANTS[result[INTS_SIZE - 1]]; + } + return new UInt256(result); + } + + @Override + public UInt256 subtract(long value) { + return add(-value); + } + + @Override + public UInt256 multiply(UInt256 value) { + if (isZero() || value.isZero()) { + return ZERO; + } + if (value.equals(UInt256.ONE)) { + return this; + } + if (this.equals(UInt256.ONE)) { + return value; + } + return multiply(this.ints, value.ints); + } + + private static UInt256 multiply(int[] x, int[] y) { + int[] result = new int[INTS_SIZE + INTS_SIZE]; + + long carry = 0; + for (int j = INTS_SIZE - 1, k = INTS_SIZE + INTS_SIZE - 1; j >= 0; j--, k--) { + long product = (y[j] & LONG_MASK) * (x[INTS_SIZE - 1] & LONG_MASK) + carry; + result[k] = (int) product; + carry = product >>> 32; + } + result[INTS_SIZE - 1] = (int) carry; + + for (int i = INTS_SIZE - 2; i >= 0; i--) { + carry = 0; + for (int j = INTS_SIZE - 1, k = INTS_SIZE + i; j >= 0; j--, k--) { + long product = (y[j] & LONG_MASK) * (x[i] & LONG_MASK) + (result[k] & LONG_MASK) + carry; + + result[k] = (int) product; + carry = product >>> 32; + } + result[i] = (int) carry; + } + + boolean constant = true; + for (int i = INTS_SIZE; i < (INTS_SIZE + INTS_SIZE) - 1; ++i) { + constant &= (result[i] == 0); + } + if (constant && result[INTS_SIZE + INTS_SIZE - 1] >= 0 && result[INTS_SIZE + INTS_SIZE - 1] <= MAX_CONSTANT) { + return CONSTANTS[result[INTS_SIZE + INTS_SIZE - 1]]; + } + return new UInt256(Arrays.copyOfRange(result, INTS_SIZE, INTS_SIZE + INTS_SIZE)); + } + + @Override + public UInt256 multiply(long value) { + if (value == 0 || isZero()) { + return ZERO; + } + if (value == 1) { + return this; + } + if (value < 0) { + throw new ArithmeticException("multiply unsigned by negative"); + } + UInt256 other = new UInt256(value); + if (this.equals(UInt256.ONE)) { + return other; + } + return multiply(this.ints, other.ints); + } + + @Override + public UInt256 multiplyMod(UInt256 value, UInt256 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("multiplyMod with zero modulus"); + } + if (isZero() || value.isZero()) { + return ZERO; + } + if (value.equals(UInt256.ONE)) { + return mod(modulus); + } + return UInt256 + .valueOf(toUnsignedBigInteger().multiply(value.toUnsignedBigInteger()).mod(modulus.toUnsignedBigInteger())); + } + + @Override + public UInt256 multiplyMod(long value, UInt256 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("multiplyMod with zero modulus"); + } + if (value == 0 || isZero()) { + return ZERO; + } + if (value == 1) { + return mod(modulus); + } + if (value < 0) { + throw new ArithmeticException("multiplyMod unsigned by negative"); + } + return UInt256 + .valueOf(toUnsignedBigInteger().multiply(BigInteger.valueOf(value)).mod(modulus.toUnsignedBigInteger())); + } + + @Override + public UInt256 multiplyMod(long value, long modulus) { + if (modulus == 0) { + throw new ArithmeticException("multiplyMod with zero modulus"); + } + if (modulus < 0) { + throw new ArithmeticException("multiplyMod unsigned with negative modulus"); + } + if (value == 0 || isZero()) { + return ZERO; + } + if (value == 1) { + return mod(modulus); + } + if (value < 0) { + throw new ArithmeticException("multiplyMod unsigned by negative"); + } + return UInt256.valueOf(toUnsignedBigInteger().multiply(BigInteger.valueOf(value)).mod(BigInteger.valueOf(modulus))); + } + + @Override + public UInt256 divide(UInt256 value) { + if (value.isZero()) { + throw new ArithmeticException("divide by zero"); + } + if (value.equals(UInt256.ONE)) { + return this; + } + return UInt256.valueOf(toUnsignedBigInteger().divide(value.toUnsignedBigInteger())); + } + + @Override + public UInt256 divide(long value) { + if (value == 0) { + throw new ArithmeticException("divide by zero"); + } + if (value < 0) { + throw new ArithmeticException("divide unsigned by negative"); + } + if (value == 1) { + return this; + } + if (isPowerOf2(value)) { + return shiftRight(log2(value)); + } + return UInt256.valueOf(toUnsignedBigInteger().divide(BigInteger.valueOf(value))); + } + + public UInt256 sdiv0(UInt256 divisor) { + if (divisor.isZero()) { + return UInt256.ZERO; + } else { + BigInteger result = this.toSignedBigInteger().divide(divisor.toSignedBigInteger()); + Bytes resultBytes = Bytes.wrap(result.toByteArray()); + if (resultBytes.size() > 32) { + resultBytes = resultBytes.slice(resultBytes.size() - 32, 32); + } + return UInt256.fromBytes(Bytes32.leftPad(resultBytes, result.signum() < 0 ? (byte) 0xFF : 0x00)); + } + } + + @Override + public UInt256 divideCeil(UInt256 value) { + return this.divide(value).add(this.mod(value).isZero() ? 0 : 1); + } + + @Override + public UInt256 divideCeil(long value) { + return this.divide(value).add(this.mod(value).isZero() ? 0 : 1); + } + + @Override + public UInt256 pow(UInt256 exponent) { + return UInt256.valueOf(toUnsignedBigInteger().modPow(exponent.toUnsignedBigInteger(), P_2_256)); + } + + @Override + public UInt256 pow(long exponent) { + return UInt256.valueOf(toUnsignedBigInteger().modPow(BigInteger.valueOf(exponent), P_2_256)); + } + + @Override + public UInt256 mod(UInt256 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("mod by zero"); + } + return UInt256.valueOf(toUnsignedBigInteger().mod(modulus.toUnsignedBigInteger())); + } + + @Override + public UInt256 mod(long modulus) { + if (modulus == 0) { + throw new ArithmeticException("mod by zero"); + } + if (modulus < 0) { + throw new ArithmeticException("mod by negative"); + } + if (isPowerOf2(modulus)) { + int log2 = log2(modulus); + int d = log2 / 32; + int s = log2 % 32; + assert (d == 0 || d == 1); + + int[] result = new int[INTS_SIZE]; + // Mask the byte at d to only include the s right-most bits + result[INTS_SIZE - 1 - d] = this.ints[INTS_SIZE - 1 - d] & ~(0xFFFFFFFF << s); + if (d != 0) { + result[INTS_SIZE - 1] = this.ints[INTS_SIZE - 1]; + } + return new UInt256(result); + } + return UInt256.valueOf(toUnsignedBigInteger().mod(BigInteger.valueOf(modulus))); + } + + @Override + public UInt256 mod0(UInt256 modulus) { + if (modulus.equals(UInt256.ZERO)) { + return UInt256.ZERO; + } + return mod(modulus); + } + + /** + * Returns a value that is the {@code (this signed mod modulus)}, or 0 if modulus is 0. + * + * @param modulus The modulus. + * @return {@code this signed mod modulus}. + */ + public UInt256 smod0(UInt256 modulus) { + if (modulus.equals(UInt256.ZERO)) { + return UInt256.ZERO; + } + + BigInteger bi = this.toSignedBigInteger(); + BigInteger result = bi.abs().mod(modulus.toSignedBigInteger().abs()); + + if (bi.signum() < 0) { + result = result.negate(); + } + + Bytes resultBytes = Bytes.wrap(result.toByteArray()); + if (resultBytes.size() > 32) { + resultBytes = resultBytes.slice(resultBytes.size() - 32, 32); + } + + return UInt256.fromBytes(Bytes32.leftPad(resultBytes, result.signum() < 0 ? (byte) 0xFF : 0x00)); + } + + @Override + public UInt256 mod0(long modulus) { + if (modulus == 0) { + return UInt256.ZERO; + } + if (modulus < 0) { + throw new ArithmeticException("mod by negative"); + } + return mod(modulus); + } + + /** + * Return a bit-wise AND of this value and the supplied value. + * + * @param value the value to perform the operation with + * @return the result of a bit-wise AND + */ + public UInt256 and(UInt256 value) { + int[] result = new int[INTS_SIZE]; + for (int i = INTS_SIZE - 1; i >= 0; --i) { + result[i] = this.ints[i] & value.ints[i]; + } + return new UInt256(result); + } + + /** + * Return a bit-wise AND of this value and the supplied bytes. + * + * @param bytes the bytes to perform the operation with + * @return the result of a bit-wise AND + */ + @Override + public UInt256 and(Bytes32 bytes) { + int[] result = new int[INTS_SIZE]; + for (int i = INTS_SIZE - 1, j = 28; i >= 0; --i, j -= 4) { + int other = ((int) bytes.get(j) & 0xFF) << 24; + other |= ((int) bytes.get(j + 1) & 0xFF) << 16; + other |= ((int) bytes.get(i + 2) & 0xFF) << 8; + other |= ((int) bytes.get(i + 3) & 0xFF); + result[i] = this.ints[i] & other; + } + return new UInt256(result); + } + + /** + * Return a bit-wise OR of this value and the supplied value. + * + * @param value the value to perform the operation with + * @return the result of a bit-wise OR + */ + public UInt256 or(UInt256 value) { + int[] result = new int[INTS_SIZE]; + for (int i = INTS_SIZE - 1; i >= 0; --i) { + result[i] = this.ints[i] | value.ints[i]; + } + return new UInt256(result); + } + + /** + * Return a bit-wise OR of this value and the supplied bytes. + * + * @param bytes the bytes to perform the operation with + * @return the result of a bit-wise OR + */ + @Override + public UInt256 or(Bytes32 bytes) { + int[] result = new int[INTS_SIZE]; + for (int i = INTS_SIZE - 1, j = 28; i >= 0; --i, j -= 4) { + result[i] = this.ints[i] | (((int) bytes.get(j) & 0xFF) << 24); + result[i] |= ((int) bytes.get(j + 1) & 0xFF) << 16; + result[i] |= ((int) bytes.get(j + 2) & 0xFF) << 8; + result[i] |= ((int) bytes.get(j + 3) & 0xFF); + } + return new UInt256(result); + } + + /** + * Return a bit-wise XOR of this value and the supplied value. + * + * @param value the value to perform the operation with + * @return the result of a bit-wise XOR + */ + public UInt256 xor(UInt256 value) { + int[] result = new int[INTS_SIZE]; + for (int i = INTS_SIZE - 1; i >= 0; --i) { + result[i] = this.ints[i] ^ value.ints[i]; + } + return new UInt256(result); + } + + /** + * Return a bit-wise XOR of this value and the supplied bytes. + * + * @param bytes the bytes to perform the operation with + * @return the result of a bit-wise XOR + */ + @Override + public UInt256 xor(Bytes32 bytes) { + int[] result = new int[INTS_SIZE]; + for (int i = INTS_SIZE - 1, j = 28; i >= 0; --i, j -= 4) { + result[i] = this.ints[i] ^ (((int) bytes.get(j) & 0xFF) << 24); + result[i] ^= ((int) bytes.get(j + 1) & 0xFF) << 16; + result[i] ^= ((int) bytes.get(j + 2) & 0xFF) << 8; + result[i] ^= ((int) bytes.get(j + 3) & 0xFF); + } + return new UInt256(result); + } + + /** + * Return a bit-wise NOT of this value. + * + * @return the result of a bit-wise NOT + */ + @Override + public UInt256 not() { + int[] result = new int[INTS_SIZE]; + for (int i = INTS_SIZE - 1; i >= 0; --i) { + result[i] = ~(this.ints[i]); + } + return new UInt256(result); + } + + /** + * Shift all bits in this value to the right. + * + * @param distance The number of bits to shift by. + * @return A value containing the shifted bits. + */ + @Override + public UInt256 shiftRight(int distance) { + if (distance == 0) { + return this; + } + if (distance >= 256) { + return ZERO; + } + int[] result = new int[INTS_SIZE]; + int d = distance / 32; + int s = distance % 32; + + int resIdx = INTS_SIZE; + if (s == 0) { + for (int i = INTS_SIZE - d; i > 0;) { + result[--resIdx] = this.ints[--i]; + } + } else { + for (int i = INTS_SIZE - 1 - d; i >= 0; i--) { + int leftSide = this.ints[i] >>> s; + int rightSide = (i == 0) ? 0 : this.ints[i - 1] << (32 - s); + result[--resIdx] = (leftSide | rightSide); + } + } + return new UInt256(result); + } + + /** + * Shift all bits in this value to the left. + * + * @param distance The number of bits to shift by. + * @return A value containing the shifted bits. + */ + @Override + public UInt256 shiftLeft(int distance) { + if (distance == 0) { + return this; + } + if (distance >= 256) { + return ZERO; + } + int[] result = new int[INTS_SIZE]; + int d = distance / 32; + int s = distance % 32; + + int resIdx = 0; + if (s == 0) { + for (int i = d; i < INTS_SIZE;) { + result[resIdx++] = this.ints[i++]; + } + } else { + for (int i = d; i < INTS_SIZE; ++i) { + int leftSide = this.ints[i] << s; + int rightSide = (i == INTS_SIZE - 1) ? 0 : (this.ints[i + 1] >>> (32 - s)); + result[resIdx++] = (leftSide | rightSide); + } + } + return new UInt256(result); + } + + @Override + public boolean equals(@Nullable Object object) { + if (object == this) { + return true; + } + if (object instanceof UInt256) { + UInt256 other = (UInt256) object; + for (int i = 0; i < INTS_SIZE; ++i) { + if (this.ints[i] != other.ints[i]) { + return false; + } + } + return true; + } + if (object instanceof Bytes) { + Bytes other = (Bytes) object; + if (this.size() != other.size()) { + return false; + } + + for (int i = 0; i < size(); i++) { + if (this.get(i) != other.get(i)) { + return false; + } + } + + return true; + } + return false; + } + + int computeHashcode() { + int result = 1; + for (int i = 0; i < size(); i++) { + result = 31 * result + get(i); + } + return result; + } + + @Override + public int hashCode() { + if (this.hashCode == null) { + this.hashCode = computeHashcode(); + } + return this.hashCode; + } + + @Override + public boolean fitsInt() { + for (int i = 0; i < INTS_SIZE - 1; i++) { + if (this.ints[i] != 0) { + return false; + } + } + // Lastly, the left-most byte of the int must not start with a 1. + return this.ints[INTS_SIZE - 1] >= 0; + } + + @Override + public int intValue() { + if (!fitsInt()) { + throw new ArithmeticException("Value does not fit a 4 byte int"); + } + return this.ints[INTS_SIZE - 1]; + } + + @Override + public boolean fitsLong() { + for (int i = 0; i < INTS_SIZE - 2; i++) { + if (this.ints[i] != 0) { + return false; + } + } + // Lastly, the left-most byte of the int must not start with a 1. + return this.ints[INTS_SIZE - 2] >= 0; + } + + @Override + public byte get(int i) { + int whichInt = i / 4; + int whichIndex = 3 - i % 4; + return (byte) ((this.ints[whichInt] >> (8 * whichIndex)) & 0xFF); + } + + @Override + public Bytes32 copy() { + return toBytes(); + } + + @Override + public long toLong() { + if (!fitsLong()) { + throw new ArithmeticException("Value does not fit a 8 byte long"); + } + return (((long) this.ints[INTS_SIZE - 2]) << 32) | (((long) (this.ints[INTS_SIZE - 1])) & LONG_MASK); + } + + @Override + public String toString() { + return toHexString(); + } + + @Override + public UInt256 toUInt256() { + return this; + } + + private byte[] toByteArray() { + return new byte[] { + (byte) (ints[0] >> 24), + (byte) (ints[0] >> 16), + (byte) (ints[0] >> 8), + (byte) (ints[0]), + (byte) (ints[1] >> 24), + (byte) (ints[1] >> 16), + (byte) (ints[1] >> 8), + (byte) (ints[1]), + (byte) (ints[2] >> 24), + (byte) (ints[2] >> 16), + (byte) (ints[2] >> 8), + (byte) (ints[2]), + (byte) (ints[3] >> 24), + (byte) (ints[3] >> 16), + (byte) (ints[3] >> 8), + (byte) (ints[3]), + (byte) (ints[4] >> 24), + (byte) (ints[4] >> 16), + (byte) (ints[4] >> 8), + (byte) (ints[4]), + (byte) (ints[5] >> 24), + (byte) (ints[5] >> 16), + (byte) (ints[5] >> 8), + (byte) (ints[5]), + (byte) (ints[6] >> 24), + (byte) (ints[6] >> 16), + (byte) (ints[6] >> 8), + (byte) (ints[6]), + (byte) (ints[7] >> 24), + (byte) (ints[7] >> 16), + (byte) (ints[7] >> 8), + (byte) (ints[7])}; + } + + @Override + public Bytes slice(int i, int length) { + return toBytes().slice(i, length); + } + + @Override + public MutableBytes32 mutableCopy() { + return MutableBytes32.wrap(toByteArray()); + } + + @Override + public Bytes32 toBytes() { + return Bytes32.wrap(toByteArray()); + } + + @Override + public Bytes toMinimalBytes() { + int i = 0; + while (i < INTS_SIZE && this.ints[i] == 0) { + ++i; + } + if (i == INTS_SIZE) { + return Bytes.EMPTY; + } + int firstIntBytes = 4 - (Integer.numberOfLeadingZeros(this.ints[i]) / 8); + int totalBytes = firstIntBytes + ((INTS_SIZE - (i + 1)) * 4); + MutableBytes bytes = MutableBytes.create(totalBytes); + int j = 0; + switch (firstIntBytes) { + case 4: + bytes.set(j++, (byte) (this.ints[i] >>> 24)); + // fall through + case 3: + bytes.set(j++, (byte) ((this.ints[i] >>> 16) & 0xFF)); + // fall through + case 2: + bytes.set(j++, (byte) ((this.ints[i] >>> 8) & 0xFF)); + // fall through + case 1: + bytes.set(j++, (byte) (this.ints[i] & 0xFF)); + } + ++i; + for (; i < INTS_SIZE; ++i, j += 4) { + bytes.setInt(j, this.ints[i]); + } + return bytes; + } + + @Override + public int numberOfLeadingZeros() { + for (int i = 0; i < INTS_SIZE; i++) { + if (this.ints[i] == 0) { + continue; + } + return (i * 32) + Integer.numberOfLeadingZeros(this.ints[i]); + } + return 256; + } + + @Override + public int bitLength() { + for (int i = 0; i < INTS_SIZE; i++) { + if (this.ints[i] == 0) { + continue; + } + return (INTS_SIZE * 32) - (i * 32) - Integer.numberOfLeadingZeros(this.ints[i]); + } + return 0; + } + + @Override + public UInt256 max() { + return UInt256.MAX_VALUE; + } + + private static boolean isPowerOf2(long n) { + assert n > 0; + return (n & (n - 1)) == 0; + } + + private static int log2(long v) { + assert v > 0; + return 63 - Long.numberOfLeadingZeros(v); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt256Value.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt256Value.java new file mode 100644 index 00000000000..c31e2f3b22a --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt256Value.java @@ -0,0 +1,597 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +import java.math.BigInteger; +import java.nio.ByteOrder; + +import static java.nio.ByteOrder.BIG_ENDIAN; + + +/** + * Represents a 256-bit (32 bytes) unsigned integer value. + * + *

+ * A {@link UInt256Value} is an unsigned integer value stored with 32 bytes, so whose value can range between 0 and + * 2^256-1. + * + *

+ * This interface defines operations for value types with a 256-bit precision range. The methods provided by this + * interface take parameters of the same type (and also {@code long}. This provides type safety by ensuring calculations + * cannot mix different {@code UInt256Value} types. + * + *

+ * Where only a pure numerical 256-bit value is required, {@link UInt256} should be used. + * + *

+ * It is strongly advised to extend {@link BaseUInt256Value} rather than implementing this interface directly. Doing so + * provides type safety in that quantities of different units cannot be mixed accidentally. + * + * @param The concrete type of the value. + */ +public interface UInt256Value> extends Bytes32 { + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value The amount to be added to this value. + * @return {@code this + value} + */ + T add(T value); + + /** + * Returns a value that is {@code (this + value)}. + * + *

+ * This notation can be used in Kotlin with the {@code +} operator. + * + * @param value The amount to be added to this value. + * @return {@code this + value} + */ + default T plus(T value) { + return add(value); + } + + /** + * Returns a value that is {@code (this + value)}. + * + *

+ * This notation can be used in Kotlin with the {@code +} operator. + * + * @param value The amount to be added to this value. + * @return {@code this + value} + */ + default T plus(long value) { + return add(value); + } + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value the amount to be added to this value + * @return {@code this + value} + * @throws ArithmeticException if the result of the addition overflows + */ + default T addExact(T value) { + T result = add(value); + if (compareTo(result) > 0) { + throw new ArithmeticException("UInt256 overflow"); + } + return result; + } + + /** + * Returns a value that is {@code (this + value)}, or MAX_VALUE if it overflows. + * + * @param value the amount to be added to this value + * @return {@code this + value} or UInt256.MAX + */ + default T addSafe(T value) { + T result = add(value); + if (compareTo(result) > 0) { + return max(); + } + return result; + } + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value The amount to be added to this value. + * @return {@code this + value} + */ + T add(long value); + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value the amount to be added to this value + * @return {@code this + value} + * @throws ArithmeticException if the result of the addition overflows + */ + default T addExact(long value) { + T result = add(value); + if ((value > 0 && compareTo(result) > 0) || (value < 0 && compareTo(result) < 0)) { + throw new ArithmeticException("UInt256 overflow"); + } + return result; + } + + /** + * Returns a value that is {@code (this + value)}, or MAX_VALUE if it overflows. + * + * @param value the amount to be added to this value + * @return {@code this + value} or UInt256.MAX + */ + default T addSafe(long value) { + T result = add(value); + if ((value > 0 && compareTo(result) > 0) || (value < 0 && compareTo(result) < 0)) { + return max(); + } + return result; + } + + /** + * Returns a value equivalent to {@code ((this + value) mod modulus)}. + * + * @param value The amount to be added to this value. + * @param modulus The modulus. + * @return {@code (this + value) mod modulus} + * @throws ArithmeticException {@code modulus} == 0. + */ + T addMod(T value, UInt256 modulus); + + /** + * Returns a value equivalent to {@code ((this + value) mod modulus)}. + * + * @param value The amount to be added to this value. + * @param modulus The modulus. + * @return {@code (this + value) mod modulus} + * @throws ArithmeticException {@code modulus} == 0. + */ + T addMod(long value, UInt256 modulus); + + /** + * Returns a value equivalent to {@code ((this + value) mod modulus)}. + * + * @param value The amount to be added to this value. + * @param modulus The modulus. + * @return {@code (this + value) mod modulus} + * @throws ArithmeticException {@code modulus} ≤ 0. + */ + T addMod(long value, long modulus); + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value The amount to be subtracted from this value. + * @return {@code this - value} + */ + T subtract(T value); + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value the amount to be subtracted to this value + * @return {@code this - value} + * @throws ArithmeticException if the result of the addition overflows + */ + default T subtractExact(T value) { + T result = subtract(value); + if (compareTo(result) < 0) { + throw new ArithmeticException("UInt256 overflow"); + } + return result; + } + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value The amount to be subtracted from this value. + * @return {@code this - value} + */ + T subtract(long value); + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value the amount to be subtracted to this value + * @return {@code this - value} + * @throws ArithmeticException if the result of the addition overflows + */ + default T subtractExact(long value) { + T result = subtract(value); + if ((value > 0 && compareTo(result) < 0) || (value < 0 && compareTo(result) > 0)) { + throw new ArithmeticException("UInt256 overflow"); + } + return result; + } + + /** + * Return the max value for this type. + * + *

+ * The default implementation of this method returns a value obtained from calling the concrete type constructor with + * an argument of {@link UInt256#MAX_VALUE}. Most implementations will want to override this method to instead return + * a static constant. + * + * @return The max value for this type. + */ + public T max(); + + /** + * Returns a value that is {@code (this * value)}. + * + * @param value The amount to multiply this value by. + * @return {@code this * value} + */ + T multiply(T value); + + /** + * Returns a value that is {@code (this * value)}. + * + * @param value The amount to multiply this value by. + * @return {@code this * value} + * @throws ArithmeticException {@code value} < 0. + */ + T multiply(long value); + + /** + * Returns a value that is {@code ((this * value) mod modulus)}. + * + * @param value The amount to multiply this value by. + * @param modulus The modulus. + * @return {@code (this * value) mod modulus} + * @throws ArithmeticException {@code value} < 0 or {@code modulus} == 0. + */ + T multiplyMod(T value, UInt256 modulus); + + /** + * Returns a value that is {@code ((this * value) mod modulus)}. + * + * @param value The amount to multiply this value by. + * @param modulus The modulus. + * @return {@code (this * value) mod modulus} + * @throws ArithmeticException {@code value} < 0 or {@code modulus} == 0. + */ + T multiplyMod(long value, UInt256 modulus); + + /** + * Returns a value that is {@code ((this * value) mod modulus)}. + * + * @param value The amount to multiply this value by. + * @param modulus The modulus. + * @return {@code (this * value) mod modulus} + * @throws ArithmeticException {@code value} < 0 or {@code modulus} ≤ 0. + */ + T multiplyMod(long value, long modulus); + + /** + * Returns a value that is {@code (this / value)}. + * + * @param value The amount to divide this value by. + * @return {@code this / value} + * @throws ArithmeticException {@code value} == 0. + */ + T divide(T value); + + /** + * Returns a value that is {@code (this / value)}. + * + * @param value The amount to divide this value by. + * @return {@code this / value} + * @throws ArithmeticException {@code value} ≤ 0. + */ + T divide(long value); + + /** + * Returns a value that is {@code ceiling(this / value)}. + * + * @param value The amount to divide this value by. + * @return {@code this / value + ( this % value == 0 ? 0 : 1)} + * @throws ArithmeticException {@code value} == 0. + */ + T divideCeil(T value); + + /** + * Returns a value that is {@code ceiling(this / value)}. + * + * @param value The amount to divide this value by. + * @return {@code this / value + ( this % value == 0 ? 0 : 1)} + * @throws ArithmeticException {@code value} == 0. + */ + T divideCeil(long value); + + /** + * Returns a value that is {@code (thisexponent mod 2256)} + * + *

+ * This calculates an exponentiation over the modulus of {@code 2^256}. + * + *

+ * Note that {@code exponent} is an {@link UInt256} rather than of the type {@code T}. + * + * @param exponent The exponent to which this value is to be raised. + * @return {@code thisexponent mod 2256} + */ + T pow(UInt256 exponent); + + /** + * Returns a value that is {@code (thisexponent mod 2256)} + * + *

+ * This calculates an exponentiation over the modulus of {@code 2^256}. + * + * @param exponent The exponent to which this value is to be raised. + * @return {@code thisexponent mod 2256} + */ + T pow(long exponent); + + /** + * Returns a value that is {@code (this mod modulus)}. + * + * @param modulus The modulus. + * @return {@code this mod modulus}. + * @throws ArithmeticException {@code modulus} == 0. + */ + T mod(UInt256 modulus); + + /** + * Returns a value that is {@code (this mod modulus)}. + * + * @param modulus The modulus. + * @return {@code this mod modulus}. + * @throws ArithmeticException {@code modulus} ≤ 0. + */ + T mod(long modulus); + + /** + * Returns a value that is {@code (this mod modulus)}, or 0 if modulus is 0. + * + * @param modulus The modulus. + * @return {@code this mod modulus}. + */ + T mod0(UInt256 modulus); + + /** + * Returns a value that is {@code (this mod modulus)}, or 0 if modulus is 0. + * + * @param modulus The modulus. + * @return {@code this mod modulus}. + */ + T mod0(long modulus); + + /** + * Returns true if the value can fit in an int. + * + * @return True if this value fits a java {@code int} (i.e. is less or equal to {@code Integer.MAX_VALUE}). + */ + default boolean fitsInt() { + return fitsInt(ByteOrder.BIG_ENDIAN); + } + + /** + * Returns true if the value can fit in an int according to the byte order. + * + * @param order the byte order, little or big endian + * @return True if this value fits a java {@code int} (i.e. is less or equal to {@code Integer.MAX_VALUE}). + */ + default boolean fitsInt(ByteOrder order) { + if (order == ByteOrder.BIG_ENDIAN) { + // Ints are 4 bytes, so anything but the 4 last bytes must be zeroes + for (int i = 0; i < Bytes32.SIZE - 4; i++) { + if (get(i) != 0) + return false; + } + // Lastly, the left-most byte of the int must not start with a 1. + return get(Bytes32.SIZE - 4) >= 0; + } else { + // Ints are 4 bytes, so only the 4 first bytes must not be zeroes + for (int i = 4; i < Bytes32.SIZE - 4; i++) { + if (get(i) != 0) + return false; + } + // Lastly, the right-most byte of the int must not start with a 1. + return get(3) >= 0; + } + } + + /** + * Provides this value as an int. + * + * @return This value as a java {@code int} assuming it is small enough to fit an {@code int}. + * @throws ArithmeticException If the value does not fit an {@code int}, that is if {@code !fitsInt()}. + */ + default int intValue() { + if (!fitsInt()) { + throw new ArithmeticException("Value does not fit a 4 byte int"); + } + return getInt(Bytes32.SIZE - 4); + } + + @Override + default int toInt(ByteOrder order) { + if (!fitsInt(order)) { + throw new ArithmeticException("Value does not fit a 4 byte int"); + } + if (order == ByteOrder.BIG_ENDIAN) { + return getInt(Bytes32.SIZE - 4, order); + } else { + return getInt(0, order); + } + } + + @Override + default long toLong(ByteOrder order) { + if (!fitsLong(order)) { + throw new ArithmeticException("Value does not fit a 8 byte long"); + } + if (order == ByteOrder.BIG_ENDIAN) { + return getLong(Bytes32.SIZE - 8, order); + } else { + return getLong(0, order); + } + } + + /** + * Returns true if the value can fit in a long. + * + * @return True if this value fits a java {@code long} (i.e. is less or equal to {@code Long.MAX_VALUE}). + */ + default boolean fitsLong() { + return fitsLong(ByteOrder.BIG_ENDIAN); + } + + /** + * Returns true if the value can fit in a long. + * + * @param order byte order, little or big endian + * @return True if this value fits a java {@code long} (i.e. is less or equal to {@code Long.MAX_VALUE}). + */ + default boolean fitsLong(ByteOrder order) { + if (order == ByteOrder.BIG_ENDIAN) { + // Longs are 8 bytes, so anything but the 8 last bytes must be zeroes + for (int i = 0; i < Bytes32.SIZE - 8; i++) { + if (get(i) != 0) + return false; + } + // Lastly, the left-most byte of the long must not start with a 1. + return get(Bytes32.SIZE - 8) >= 0; + } else { + // Longs are 8 bytes, so only the 8 first bytes may not be zeroes + for (int i = 8; i < Bytes32.SIZE; i++) { + if (get(i) != 0) + return false; + } + // Lastly, the left-most byte of the long must not start with a 1. + return get(7) >= 0; + } + } + + /** + * Convert this value to a {@link UInt256}. + * + * @return This value as a {@link UInt256}. + */ + UInt256 toUInt256(); + + /** + * Provides the value as bytes. + * + * @return The value as bytes. + */ + Bytes32 toBytes(); + + /** + * Provides the value as bytes without any leading zero bytes. + * + * @return The value as bytes without any leading zero bytes. + */ + Bytes toMinimalBytes(); + + /** + * Returns true if this value is greater than the other one + * + * @param other the other value being compared + * @return true if this value is greater than the other one, false otherwise + */ + default boolean greaterThan(UInt256Value other) { + return compareTo(other) > 0; + } + + /** + * Returns true if this value is greater or equal than the other one + * + * @param other the other value being compared + * @return true if this value is greater or equal than the other one, false otherwise + */ + default boolean greaterOrEqualThan(UInt256Value other) { + return compareTo(other) >= 0; + } + + /** + * Returns true if this value is less than the other one + * + * @param other the other value being compared + * @return true if this value is less than the other one, false otherwise + */ + default boolean lessThan(UInt256Value other) { + return compareTo(other) < 0; + } + + /** + * Returns true if this value is less or equal than the other one + * + * @param other the other value being compared + * @return true if this value is less or equal than the other one, false otherwise + */ + default boolean lessOrEqualThan(UInt256Value other) { + return compareTo(other) <= 0; + } + + /** + * Returns the decimal representation of this value as a String. + * + * @return the decimal representation of this value as a String. + */ + default String toDecimalString() { + return toBigInteger().toString(10); + } + + /** + * The BigInteger corresponding to interpreting these bytes as a two's-complement signed integer. + * + * @return A {@link BigInteger} corresponding to interpreting these bytes as a two's-complement signed integer. + */ + default BigInteger toSignedBigInteger() { + return toSignedBigInteger(BIG_ENDIAN); + } + + /** + * The BigInteger corresponding to interpreting these bytes as a two's-complement signed integer. + * + * @param order The byte-order for decoding the integer. + * @return A {@link BigInteger} corresponding to interpreting these bytes as a two's-complement signed integer. + */ + default BigInteger toSignedBigInteger(ByteOrder order) { + if (size() == 0) { + return BigInteger.ZERO; + } + return new BigInteger((order == BIG_ENDIAN) ? toArrayUnsafe() : reverse().toArrayUnsafe()); + } + + /** + * The BigInteger corresponding to interpreting these bytes as an unsigned integer. + * + * @return A positive (or zero) {@link BigInteger} corresponding to interpreting these bytes as an unsigned integer. + */ + @Override + default BigInteger toBigInteger() { + return toUnsignedBigInteger(); + } + + /** + * The BigInteger corresponding to interpreting these bytes as an unsigned integer. + * + * @param order The byte-order for decoding the integer. + * @return A positive (or zero) {@link BigInteger} corresponding to interpreting these bytes as an unsigned integer. + */ + @Override + default BigInteger toBigInteger(ByteOrder order) { + return toUnsignedBigInteger(order); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt256s.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt256s.java new file mode 100644 index 00000000000..53a26ad5210 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt256s.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +/** Static utility methods on UInt256 values. */ +public final class UInt256s { + private UInt256s() {} + + /** + * Returns the maximum of two UInt256 values. + * + * @param v1 The first value. + * @param v2 The second value. + * @return The maximum of {@code v1} and {@code v2}. + * @param The concrete type of the two values. + */ + public static > T max(T v1, T v2) { + return (v1.compareTo(v2)) >= 0 ? v1 : v2; + } + + /** + * Returns the minimum of two UInt256 values. + * + * @param v1 The first value. + * @param v2 The second value. + * @return The minimum of {@code v1} and {@code v2}. + * @param The concrete type of the two values. + */ + public static > T min(T v1, T v2) { + return (v1.compareTo(v2)) < 0 ? v1 : v2; + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt32.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt32.java new file mode 100644 index 00000000000..c93f70c361a --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt32.java @@ -0,0 +1,583 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +import org.apache.tuweni.bytes.Bytes; + +import java.math.BigInteger; +import java.nio.ByteOrder; + +/** + * An unsigned 32-bit precision number. + *

+ * This is a raw {@link UInt32Value} - a 32-bit precision unsigned number of no particular unit. + */ +public final class UInt32 implements UInt32Value { + private final static int MAX_CONSTANT = 0xff; + private static UInt32[] CONSTANTS = new UInt32[MAX_CONSTANT + 1]; + + static { + CONSTANTS[0] = new UInt32(new byte[4]); + for (int i = 1; i <= MAX_CONSTANT; ++i) { + CONSTANTS[i] = new UInt32( + new byte[] { + (byte) ((i >> 24) & 0xff), + (byte) ((i >> 16) & 0xff), + (byte) ((i >> 8) & 0xff), + (byte) ((i >> 0) & 0xff)}); + } + } + + /** + * The minimum value of a UInt32 + */ + public final static UInt32 MIN_VALUE = valueOf(0); + /** + * The maximum value of a UInt32 + */ + public final static UInt32 MAX_VALUE = create(new byte[] {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}); + /** + * The value 0 + */ + public final static UInt32 ZERO = valueOf(0); + /** + * The value 1 + */ + public final static UInt32 ONE = valueOf(1); + + private static final BigInteger P_2_32 = BigInteger.valueOf(2).pow(32); + + private final Bytes value; + + /** + * Return a {@code UInt32} containing the specified value. + * + * @param value The value to create a {@code UInt32} for. + * @return A {@code UInt32} containing the specified value. + * @throws IllegalArgumentException If the value is negative. + */ + public static UInt32 valueOf(int value) { + if (value < 0) { + throw new IllegalArgumentException("Argument must be positive"); + } + return create(value); + } + + /** + * Return a {@link UInt32} containing the specified value. + * + * @param value the value to create a {@link UInt32} for + * @return a {@link UInt32} containing the specified value + * @throws IllegalArgumentException if the value is negative or too large to be represented as a UInt32 + */ + public static UInt32 valueOf(BigInteger value) { + if (value.bitLength() > 32) { + throw new IllegalArgumentException("Argument is too large to represent a UInt32"); + } + if (value.signum() < 0) { + throw new IllegalArgumentException("Argument must be positive"); + } + return create(value.toByteArray()); + } + + /** + * Return a {@link UInt32} containing the value described by the specified bytes. + * + * @param bytes The bytes containing a {@link UInt32}. \ * @return A {@link UInt32} containing the specified value. + * @throws IllegalArgumentException if {@code bytes.size() > 4}. + */ + public static UInt32 fromBytes(Bytes bytes) { + return fromBytes(bytes, ByteOrder.BIG_ENDIAN); + } + + /** + * Return a {@link UInt32} containing the value described by the specified bytes. + * + * @param bytes The bytes containing a {@link UInt32}. + * @param byteOrder the byte order of the value + * @return A {@link UInt32} containing the specified value. + * @throws IllegalArgumentException if {@code bytes.size() > 4}. + */ + public static UInt32 fromBytes(Bytes bytes, ByteOrder byteOrder) { + if (bytes.size() > 4) { + throw new IllegalArgumentException("Argument is greater than 4 bytes"); + } + return create(byteOrder == ByteOrder.LITTLE_ENDIAN ? bytes.reverse() : bytes); + } + + /** + * Parse a hexadecimal string into a {@link UInt32}. + * + * @param str The hexadecimal string to parse, which may or may not start with "0x". That representation may contain + * less than 8 bytes, in which case the result is left padded with zeros. + * @return The value corresponding to {@code str}. + * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation or + * contains more than 8 bytes. + */ + public static UInt32 fromHexString(String str) { + return fromBytes(Bytes.fromHexStringLenient(str)); + } + + private static UInt32 create(Bytes value) { + return create(value.toArrayUnsafe()); + } + + private static UInt32 create(byte[] value) { + if (value.length == 4 && value[0] == 0 && value[1] == 0 && value[2] == 0) { + return CONSTANTS[value[3] & 0xff]; + } + if (value.length == 3) { + value = new byte[] {0, value[0], value[1], value[2]}; + } else if (value.length == 2) { + value = new byte[] {0, 0, value[0], value[1]}; + } else if (value.length == 1) { + value = new byte[] {0, 0, 0, value[0]}; + } else if (value.length == 0) { + value = new byte[4]; + } + return new UInt32(value); + } + + private static UInt32 create(int value) { + if (value >= 0 && value <= MAX_CONSTANT) { + return CONSTANTS[value]; + } + return new UInt32( + new byte[] { + (byte) ((value >> 24) & 0xff), + (byte) ((value >> 16) & 0xff), + (byte) ((value >> 8) & 0xff), + (byte) ((value >> 0) & 0xff)}); + } + + private UInt32(byte[] bytes) { + this.value = Bytes.wrap(bytes); + } + + @Override + public boolean isZero() { + return ZERO.equals(this); + } + + @Override + public UInt32 add(UInt32 value) { + if (value.isZero()) { + return this; + } + if (this.isZero()) { + return value; + } + byte[] result = new byte[4]; + int carry = 0; + for (int i = 3; i >= 0; i--) { + int sum = (this.value.get(i) & 0xff) + (value.value.get(i) & 0xff) + carry; + result[i] = (byte) sum; + carry = sum >>> 8; + } + return create(result); + } + + @Override + public UInt32 add(int value) { + if (value == 0) { + return this; + } + return create(this.value.toInt() + value); + } + + @Override + public UInt32 addMod(UInt32 value, UInt32 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("addMod with zero modulus"); + } + return create(toBigInteger().add(value.toBigInteger()).mod(modulus.toBigInteger()).intValue()); + } + + @Override + public UInt32 addMod(long value, UInt32 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("addMod with zero modulus"); + } + return create(toBigInteger().add(BigInteger.valueOf(value)).mod(modulus.toBigInteger()).intValue()); + } + + @Override + public UInt32 addMod(long value, long modulus) { + if (modulus == 0) { + throw new ArithmeticException("addMod with zero modulus"); + } + if (modulus < 0) { + throw new ArithmeticException("addMod unsigned with negative modulus"); + } + return create(toBigInteger().add(BigInteger.valueOf(value)).mod(BigInteger.valueOf(modulus)).intValue()); + } + + @Override + public UInt32 subtract(UInt32 value) { + if (value.isZero()) { + return this; + } + + byte[] result = new byte[4]; + int borrow = 0; + for (int i = 3; 0 <= i; i--) { + int i1 = this.value.get(i) & 0xff; + int i2 = value.value.get(i) & 0xff; + int col = i1 - i2 + borrow; + borrow = (col >> 8); + result[i] = (byte) (col & 0xff); + } + return create(result); + } + + @Override + public UInt32 subtract(int value) { + return subtract(UInt32.create(value)); + } + + @Override + public UInt32 multiply(UInt32 value) { + return create(this.value.toInt() * value.value.toInt()); + } + + @Override + public UInt32 multiply(int value) { + if (value < 0) { + throw new ArithmeticException("multiply unsigned by negative"); + } + if (value == 0 || isZero()) { + return ZERO; + } + if (value == 1) { + return this; + } + return multiply(UInt32.valueOf(value)); + } + + @Override + public UInt32 multiplyMod(UInt32 value, UInt32 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("multiplyMod with zero modulus"); + } + if (isZero() || value.isZero()) { + return ZERO; + } + if (ONE.equals(value)) { + return mod(modulus); + } + return create(toBigInteger().multiply(value.toBigInteger()).mod(modulus.toBigInteger()).intValue()); + } + + @Override + public UInt32 multiplyMod(int value, UInt32 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("multiplyMod with zero modulus"); + } + if (value == 0 || this.isZero()) { + return ZERO; + } + if (value == 1) { + return mod(modulus); + } + if (value < 0) { + throw new ArithmeticException("multiplyMod unsigned by negative"); + } + return create(toBigInteger().multiply(BigInteger.valueOf(value)).mod(modulus.toBigInteger()).intValue()); + } + + @Override + public UInt32 multiplyMod(int value, int modulus) { + if (modulus == 0) { + throw new ArithmeticException("multiplyMod with zero modulus"); + } + if (modulus < 0) { + throw new ArithmeticException("multiplyMod unsigned with negative modulus"); + } + if (value == 0 || this.isZero()) { + return ZERO; + } + if (value == 1) { + return mod(modulus); + } + if (value < 0) { + throw new ArithmeticException("multiplyMod unsigned by negative"); + } + return create(toBigInteger().multiply(BigInteger.valueOf(value)).mod(BigInteger.valueOf(modulus)).intValue()); + } + + @Override + public UInt32 divide(UInt32 value) { + if (value.isZero()) { + throw new ArithmeticException("divide by zero"); + } + + if (value.equals(ONE)) { + return this; + } + return create(toBigInteger().divide(value.toBigInteger()).intValue()); + } + + @Override + public UInt32 divide(int value) { + if (value == 0) { + throw new ArithmeticException("divide by zero"); + } + if (value < 0) { + throw new ArithmeticException("divide unsigned by negative"); + } + if (value == 1) { + return this; + } + if (isPowerOf2(value)) { + return shiftRight(log2(value)); + } + return create(toBigInteger().divide(BigInteger.valueOf(value)).intValue()); + } + + @Override + public UInt32 pow(UInt32 exponent) { + return create(toBigInteger().modPow(exponent.toBigInteger(), P_2_32).intValue()); + } + + @Override + public UInt32 pow(long exponent) { + return create(toBigInteger().modPow(BigInteger.valueOf(exponent), P_2_32).intValue()); + } + + @Override + public UInt32 mod(UInt32 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("mod by zero"); + } + return create(Integer.remainderUnsigned(this.value.toInt(), modulus.value.toInt())); + } + + @Override + public UInt32 mod(int modulus) { + if (modulus == 0) { + throw new ArithmeticException("mod by zero"); + } + if (modulus < 0) { + throw new ArithmeticException("mod by negative"); + } + return create(Integer.remainderUnsigned(this.value.toInt(), modulus)); + } + + /** + * Return a bit-wise AND of this value and the supplied value. + * + * @param value the value to perform the operation with + * @return the result of a bit-wise AND + */ + public UInt32 and(UInt32 value) { + if (this.isZero() || value.isZero()) { + return ZERO; + } + return create(this.value.toInt() & value.value.toInt()); + } + + /** + * Return a bit-wise AND of this value and the supplied bytes. + * + * @param bytes the bytes to perform the operation with + * @return the result of a bit-wise AND + * @throws IllegalArgumentException if more than 8 bytes are supplied + */ + public UInt32 and(Bytes bytes) { + if (bytes.size() > 4) { + throw new IllegalArgumentException("and with more than 4 bytes"); + } + if (this.isZero()) { + return ZERO; + } + int value = bytes.toInt(); + if (value == 0) { + return ZERO; + } + return create(this.value.toInt() & value); + } + + /** + * Return a bit-wise OR of this value and the supplied value. + * + * @param value the value to perform the operation with + * @return the result of a bit-wise OR + */ + public UInt32 or(UInt32 value) { + return create(this.value.or(value.value)); + } + + /** + * Return a bit-wise OR of this value and the supplied bytes. + * + * @param bytes the bytes to perform the operation with + * @return the result of a bit-wise OR + * @throws IllegalArgumentException if more than 8 bytes are supplied + */ + public UInt32 or(Bytes bytes) { + if (bytes.size() > 4) { + throw new IllegalArgumentException("or with more than 4 bytes"); + } + return create(this.value.or(bytes)); + } + + /** + * Return a bit-wise XOR of this value and the supplied value. + *

+ * If this value and the supplied value are different lengths, then the shorter will be zero-padded to the left. + * + * @param value the value to perform the operation with + * @return the result of a bit-wise XOR + * @throws IllegalArgumentException if more than 8 bytes are supplied + */ + public UInt32 xor(UInt32 value) { + return create(this.value.xor(value.value)); + } + + + /** + * Return a bit-wise XOR of this value and the supplied value. + *

+ * If this value and the supplied value are different lengths, then the shorter will be zero-padded to the left. + * + * @param value the value to perform the operation with + * @return the result of a bit-wise XOR + * @throws IllegalArgumentException if more than 8 bytes are supplied + */ + public UInt32 xor(int value) { + return create(this.value.toInt() ^ value); + } + + /** + * Return a bit-wise XOR of this value and the supplied bytes. + * + * @param bytes the bytes to perform the operation with + * @return the result of a bit-wise XOR + * @throws IllegalArgumentException if more than 8 bytes are supplied + */ + public UInt32 xor(Bytes bytes) { + if (bytes.size() > 4) { + throw new IllegalArgumentException("xor with more than 4 bytes"); + } + return create(this.value.xor(bytes).toArrayUnsafe()); + } + + /** + * Return a bit-wise NOT of this value. + * + * @return the result of a bit-wise NOT + */ + public UInt32 not() { + return create(this.value.not()); + } + + /** + * Shift all bits in this value to the right. + * + * @param distance The number of bits to shift by. + * @return A value containing the shifted bits. + */ + public UInt32 shiftRight(int distance) { + if (distance == 0) { + return this; + } + if (distance >= 32) { + return ZERO; + } + return create(this.value.shiftRight(distance)); + } + + /** + * Shift all bits in this value to the left. + * + * @param distance The number of bits to shift by. + * @return A value containing the shifted bits. + */ + public UInt32 shiftLeft(int distance) { + if (distance == 0) { + return this; + } + if (distance >= 32) { + return ZERO; + } + return create(this.value.shiftLeft(distance)); + } + + @Override + public boolean equals(Object object) { + if (object == this) { + return true; + } + if (!(object instanceof UInt32)) { + return false; + } + UInt32 other = (UInt32) object; + return this.value.equals(other.value); + } + + @Override + public int hashCode() { + return Long.hashCode(this.value.toInt()); + } + + @Override + public int compareTo(UInt32 other) { + return Long.compareUnsigned(this.value.toInt(), other.value.toInt()); + } + + @Override + public String toString() { + return toHexString(); + } + + @Override + public BigInteger toBigInteger() { + return value.toUnsignedBigInteger(); + } + + @Override + public UInt32 toUInt32() { + return this; + } + + @Override + public Bytes toBytes() { + return value; + } + + @Override + public Bytes toMinimalBytes() { + return value.slice(value.numberOfLeadingZeroBytes()); + } + + @Override + public int numberOfLeadingZeros() { + return value.numberOfLeadingZeros(); + } + + @Override + public int bitLength() { + return 32 - value.numberOfLeadingZeros(); + } + + private static boolean isPowerOf2(long n) { + assert n > 0; + return (n & (n - 1)) == 0; + } + + private static int log2(int v) { + assert v > 0; + return 63 - Long.numberOfLeadingZeros(v); + } + +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt32Value.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt32Value.java new file mode 100644 index 00000000000..c45b2a9bcae --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt32Value.java @@ -0,0 +1,402 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + + +import org.apache.tuweni.bytes.Bytes; + +import java.math.BigInteger; + +/** + * Represents a 32-bit (8 bytes) unsigned integer value. + * + *

+ * A {@link UInt32Value} is an unsigned integer value whose value can range between 0 and 2^32-1. + * + *

+ * This interface defines operations for value types with a 32-bit precision range. The methods provided by this + * interface take parameters of the same type (and also {@code long}. This provides type safety by ensuring calculations + * cannot mix different {@code UInt32Value} types. + * + *

+ * Where only a pure numerical 32-bit value is required, {@link UInt32} should be used. + * + *

+ * It is strongly advised to extend {@link BaseUInt32Value} rather than implementing this interface directly. Doing so + * provides type safety in that quantities of different units cannot be mixed accidentally. + * + * @param The concrete type of the value. + */ +public interface UInt32Value> extends Comparable { + + /** + * Returns true is this is 0. + * + * @return True if this is the value 0. + */ + default boolean isZero() { + return toBytes().isZero(); + } + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value The amount to be added to this value. + * @return {@code this + value} + */ + T add(T value); + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value the amount to be added to this value + * @return {@code this + value} + * @throws ArithmeticException if the result of the addition overflows + */ + default T addExact(T value) { + T result = add(value); + if (compareTo(result) > 0) { + throw new ArithmeticException("UInt32 overflow"); + } + return result; + } + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value The amount to be added to this value. + * @return {@code this + value} + */ + T add(int value); + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value the amount to be added to this value + * @return {@code this + value} + * @throws ArithmeticException if the result of the addition overflows + */ + default T addExact(int value) { + T result = add(value); + if ((value > 0 && compareTo(result) > 0) || (value < 0 && compareTo(result) < 0)) { + throw new ArithmeticException("UInt32 overflow"); + } + return result; + } + + /** + * Returns a value equivalent to {@code ((this + value) mod modulus)}. + * + * @param value The amount to be added to this value. + * @param modulus The modulus. + * @return {@code (this + value) mod modulus} + * @throws ArithmeticException {@code modulus} == 0. + */ + T addMod(T value, UInt32 modulus); + + /** + * Returns a value equivalent to {@code ((this + value) mod modulus)}. + * + * @param value The amount to be added to this value. + * @param modulus The modulus. + * @return {@code (this + value) mod modulus} + * @throws ArithmeticException {@code modulus} == 0. + */ + T addMod(long value, UInt32 modulus); + + /** + * Returns a value equivalent to {@code ((this + value) mod modulus)}. + * + * @param value The amount to be added to this value. + * @param modulus The modulus. + * @return {@code (this + value) mod modulus} + * @throws ArithmeticException {@code modulus} ≤ 0. + */ + T addMod(long value, long modulus); + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value The amount to be subtracted from this value. + * @return {@code this - value} + */ + T subtract(T value); + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value the amount to be subtracted to this value + * @return {@code this - value} + * @throws ArithmeticException if the result of the subtraction overflows + */ + default T subtractExact(T value) { + T result = subtract(value); + if (compareTo(result) < 0) { + throw new ArithmeticException("UInt32 overflow"); + } + return result; + } + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value The amount to be subtracted from this value. + * @return {@code this - value} + */ + T subtract(int value); + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value the amount to be subtracted to this value + * @return {@code this - value} + * @throws ArithmeticException if the result of the subtraction overflows + */ + default T subtractExact(int value) { + T result = subtract(value); + if ((value > 0 && compareTo(result) < 0) || (value < 0 && compareTo(result) > 0)) { + throw new ArithmeticException("UInt32 overflow"); + } + return result; + } + + /** + * Returns a value that is {@code (this * value)}. + * + * @param value The amount to multiply this value by. + * @return {@code this * value} + */ + T multiply(T value); + + /** + * Returns a value that is {@code (this * value)}. + * + * @param value The amount to multiply this value by. + * @return {@code this * value} + * @throws ArithmeticException {@code value} < 0. + */ + T multiply(int value); + + /** + * Returns a value that is {@code ((this * value) mod modulus)}. + * + * @param value The amount to multiply this value by. + * @param modulus The modulus. + * @return {@code (this * value) mod modulus} + * @throws ArithmeticException {@code value} < 0 or {@code modulus} == 0. + */ + T multiplyMod(T value, UInt32 modulus); + + /** + * Returns a value that is {@code ((this * value) mod modulus)}. + * + * @param value The amount to multiply this value by. + * @param modulus The modulus. + * @return {@code (this * value) mod modulus} + * @throws ArithmeticException {@code value} < 0 or {@code modulus} == 0. + */ + T multiplyMod(int value, UInt32 modulus); + + /** + * Returns a value that is {@code ((this * value) mod modulus)}. + * + * @param value The amount to multiply this value by. + * @param modulus The modulus. + * @return {@code (this * value) mod modulus} + * @throws ArithmeticException {@code value} < 0 or {@code modulus} ≤ 0. + */ + T multiplyMod(int value, int modulus); + + /** + * Returns a value that is {@code (this / value)}. + * + * @param value The amount to divide this value by. + * @return {@code this / value} + * @throws ArithmeticException {@code value} == 0. + */ + T divide(T value); + + /** + * Returns a value that is {@code (this / value)}. + * + * @param value The amount to divide this value by. + * @return {@code this / value} + * @throws ArithmeticException {@code value} ≤ 0. + */ + T divide(int value); + + /** + * Returns a value that is {@code (thisexponent mod 232)} + * + *

+ * This calculates an exponentiation over the modulus of {@code 2^32}. + * + *

+ * Note that {@code exponent} is an {@link UInt32} rather than of the type {@code T}. + * + * @param exponent The exponent to which this value is to be raised. + * @return {@code thisexponent mod 232} + */ + T pow(UInt32 exponent); + + /** + * Returns a value that is {@code (thisexponent mod 232)} + * + *

+ * This calculates an exponentiation over the modulus of {@code 2^32}. + * + * @param exponent The exponent to which this value is to be raised. + * @return {@code thisexponent mod 232} + */ + T pow(long exponent); + + /** + * Returns a value that is {@code (this mod modulus)}. + * + * @param modulus The modulus. + * @return {@code this mod modulus}. + * @throws ArithmeticException {@code modulus} == 0. + */ + T mod(UInt32 modulus); + + /** + * Returns a value that is {@code (this mod modulus)}. + * + * @param modulus The modulus. + * @return {@code this mod modulus}. + * @throws ArithmeticException {@code modulus} ≤ 0. + */ + T mod(int modulus); + + /** + * Returns true if this value fits an int. + * + * @return True if this value fits a java {@code int} (i.e. is less or equal to {@code Integer.MAX_VALUE}). + */ + default boolean fitsInt() { + return !UInt32.MAX_VALUE.equals(this); + } + + /** + * Returns this value as an int. + * + * @return This value as a java {@code int} assuming it is small enough to fit an {@code int}. + * @throws ArithmeticException If the value does not fit an {@code int}, that is if {@code + * !fitsInt()}. + */ + default int intValue() { + return toBigInteger().intValueExact(); + } + + /** + * Returns true if this value fits a long. + * + * @return True if this value fits a java {@code long} (i.e. is less or equal to {@code Long.MAX_VALUE}). + */ + default boolean fitsLong() { + return true; + } + + /** + * Returns this value as a long. + * + * @return This value as a java {@code long} assuming it is small enough to fit a {@code long}. + * @throws ArithmeticException If the value does not fit a {@code long}, that is if {@code + * !fitsLong()}. + */ + default long toLong() { + return toBigInteger().longValueExact(); + } + + /** + * Provides this value as a BigInteger. + * + * @return This value as a {@link BigInteger}. + */ + default BigInteger toBigInteger() { + return toBytes().toUnsignedBigInteger(); + } + + /** + * This value represented as an hexadecimal string. + * + *

+ * Note that this representation includes all the 8 underlying bytes, no matter what the integer actually represents + * (in other words, it can have many leading zeros). For a shorter representation that don't include leading zeros, + * use {@link #toShortHexString}. + * + * @return This value represented as an hexadecimal string. + */ + default String toHexString() { + return toBytes().toHexString(); + } + + /** + * Returns this value represented as a minimal hexadecimal string (without any leading zero). + * + * @return This value represented as a minimal hexadecimal string (without any leading zero). + */ + default String toShortHexString() { + return toBytes().toShortHexString(); + } + + /** + * Convert this value to a {@link UInt32}. + * + * @return This value as a {@link UInt32}. + */ + UInt32 toUInt32(); + + /** + * Provides the value as bytes. + * + * @return The value as bytes. + */ + Bytes toBytes(); + + /** + * Provides the value as bytes without any leading zero bytes + * + * @return The value as bytes without any leading zero bytes. + */ + Bytes toMinimalBytes(); + + /** + * Provides the number of zero bits preceding the highest-order ("leftmost") one-bit + * + * @return the number of zero bits preceding the highest-order ("leftmost") one-bit in the binary representation of + * this value, or 32 if the value is equal to zero. + */ + default int numberOfLeadingZeros() { + return toBytes().numberOfLeadingZeros(); + } + + /** + * Provides the number of bits following and including the highest-order ("leftmost") one-bit + * + * @return The number of bits following and including the highest-order ("leftmost") one-bit in the binary + * representation of this value, or zero if all bits are zero. + */ + default int bitLength() { + return toBytes().bitLength(); + } + + /** + * Returns the decimal representation of this value as a String. + * + * @return the decimal representation of this value as a String. + */ + default String toDecimalString() { + return toBigInteger().toString(10); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt32s.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt32s.java new file mode 100644 index 00000000000..b4f33248d9e --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt32s.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +/** Static utility methods on UInt32 values. */ +public final class UInt32s { + private UInt32s() {} + + /** + * Returns the maximum of two UInt32 values. + * + * @param v1 The first value. + * @param v2 The second value. + * @return The maximum of {@code v1} and {@code v2}. + * @param The concrete type of the two values. + */ + public static > T max(T v1, T v2) { + return (v1.compareTo(v2)) >= 0 ? v1 : v2; + } + + /** + * Returns the minimum of two UInt32 values. + * + * @param v1 The first value. + * @param v2 The second value. + * @return The minimum of {@code v1} and {@code v2}. + * @param The concrete type of the two values. + */ + public static > T min(T v1, T v2) { + return (v1.compareTo(v2)) < 0 ? v1 : v2; + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt384.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt384.java new file mode 100644 index 00000000000..3e2872de4ca --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt384.java @@ -0,0 +1,786 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes48; +import org.apache.tuweni.bytes.MutableBytes; +import org.apache.tuweni.bytes.MutableBytes48; + +import java.math.BigInteger; +import java.util.Arrays; + +/** + * An unsigned 384-bit precision number. + * + * This is a raw {@link UInt384Value} - a 384-bit precision unsigned number of no particular unit. + */ +public final class UInt384 implements UInt384Value { + private final static int MAX_CONSTANT = 64; + private final static BigInteger BI_MAX_CONSTANT = BigInteger.valueOf(MAX_CONSTANT); + private static UInt384[] CONSTANTS = new UInt384[MAX_CONSTANT + 1]; + static { + CONSTANTS[0] = new UInt384(Bytes48.ZERO); + for (int i = 1; i <= MAX_CONSTANT; ++i) { + CONSTANTS[i] = new UInt384(i); + } + } + + /** The minimum value of a UInt384 */ + public final static UInt384 MIN_VALUE = valueOf(0); + /** The maximum value of a UInt384 */ + public final static UInt384 MAX_VALUE = new UInt384(Bytes48.ZERO.not()); + /** The value 0 */ + public final static UInt384 ZERO = valueOf(0); + /** The value 1 */ + public final static UInt384 ONE = valueOf(1); + + private static final int INTS_SIZE = 48 / 4; + // The mask is used to obtain the value of an int as if it were unsigned. + private static final long LONG_MASK = 0xFFFFFFFFL; + private static final BigInteger P_2_384 = BigInteger.valueOf(2).pow(384); + + // The unsigned int components of the value + private final int[] ints; + + /** + * Return a {@code UInt384} containing the specified value. + * + * @param value The value to create a {@code UInt384} for. + * @return A {@code UInt384} containing the specified value. + * @throws IllegalArgumentException If the value is negative. + */ + public static UInt384 valueOf(long value) { + if (value < 0) { + throw new IllegalArgumentException("Argument must be positive"); + } + if (value <= MAX_CONSTANT) { + return CONSTANTS[(int) value]; + } + return new UInt384(value); + } + + /** + * Return a {@link UInt384} containing the specified value. + * + * @param value the value to create a {@link UInt384} for + * @return a {@link UInt384} containing the specified value + * @throws IllegalArgumentException if the value is negative or too large to be represented as a UInt384 + */ + public static UInt384 valueOf(BigInteger value) { + if (value.signum() < 0) { + throw new IllegalArgumentException("Argument must be positive"); + } + if (value.bitLength() > 384) { + throw new IllegalArgumentException("Argument is too large to represent a UInt384"); + } + if (value.compareTo(BI_MAX_CONSTANT) <= 0) { + return CONSTANTS[value.intValue()]; + } + int[] ints = new int[INTS_SIZE]; + for (int i = INTS_SIZE - 1; i >= 0; --i) { + ints[i] = value.intValue(); + value = value.shiftRight(32); + } + return new UInt384(ints); + } + + /** + * Return a {@link UInt384} containing the value described by the specified bytes. + * + * @param bytes The bytes containing a {@link UInt384}. + * @return A {@link UInt384} containing the specified value. + * @throws IllegalArgumentException if {@code bytes.size() > 48}. + */ + public static UInt384 fromBytes(Bytes bytes) { + return new UInt384(Bytes48.leftPad(bytes)); + } + + /** + * Parse a hexadecimal string into a {@link UInt384}. + * + * @param str The hexadecimal string to parse, which may or may not start with "0x". That representation may contain + * less than 48 bytes, in which case the result is left padded with zeros. + * @return The value corresponding to {@code str}. + * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation or + * contains more than 48 bytes. + */ + public static UInt384 fromHexString(String str) { + return new UInt384(Bytes48.fromHexStringLenient(str)); + } + + private UInt384(Bytes48 bytes) { + this.ints = new int[INTS_SIZE]; + for (int i = 0, j = 0; i < INTS_SIZE; ++i, j += 4) { + ints[i] = bytes.getInt(j); + } + } + + private UInt384(long value) { + this.ints = new int[INTS_SIZE]; + this.ints[INTS_SIZE - 2] = (int) ((value >>> 32) & LONG_MASK); + this.ints[INTS_SIZE - 1] = (int) (value & LONG_MASK); + } + + private UInt384(int[] ints) { + this.ints = ints; + } + + @SuppressWarnings("ReferenceEquality") + @Override + public boolean isZero() { + if (this == ZERO) { + return true; + } + for (int i = INTS_SIZE - 1; i >= 0; --i) { + if (this.ints[i] != 0) { + return false; + } + } + return true; + } + + @Override + public UInt384 add(UInt384 value) { + if (value.isZero()) { + return this; + } + if (isZero()) { + return value; + } + int[] result = new int[INTS_SIZE]; + boolean constant = true; + long sum = (this.ints[INTS_SIZE - 1] & LONG_MASK) + (value.ints[INTS_SIZE - 1] & LONG_MASK); + result[INTS_SIZE - 1] = (int) (sum & LONG_MASK); + if (result[INTS_SIZE - 1] < 0 || result[INTS_SIZE - 1] > MAX_CONSTANT) { + constant = false; + } + for (int i = INTS_SIZE - 2; i >= 0; --i) { + sum = (this.ints[i] & LONG_MASK) + (value.ints[i] & LONG_MASK) + (sum >>> 32); + result[i] = (int) (sum & LONG_MASK); + constant &= result[i] == 0; + } + if (constant) { + return CONSTANTS[result[INTS_SIZE - 1]]; + } + return new UInt384(result); + } + + @Override + public UInt384 add(long value) { + if (value == 0) { + return this; + } + if (value > 0 && isZero()) { + return UInt384.valueOf(value); + } + int[] result = new int[INTS_SIZE]; + boolean constant = true; + long sum = (this.ints[INTS_SIZE - 1] & LONG_MASK) + (value & LONG_MASK); + result[INTS_SIZE - 1] = (int) (sum & LONG_MASK); + if (result[INTS_SIZE - 1] < 0 || result[INTS_SIZE - 1] > MAX_CONSTANT) { + constant = false; + } + sum = (this.ints[INTS_SIZE - 2] & LONG_MASK) + (value >>> 32) + (sum >>> 32); + result[INTS_SIZE - 2] = (int) (sum & LONG_MASK); + constant &= result[INTS_SIZE - 2] == 0; + long signExtent = (value >> 63) & LONG_MASK; + for (int i = INTS_SIZE - 3; i >= 0; --i) { + sum = (this.ints[i] & LONG_MASK) + signExtent + (sum >>> 32); + result[i] = (int) (sum & LONG_MASK); + constant &= result[i] == 0; + } + if (constant) { + return CONSTANTS[result[INTS_SIZE - 1]]; + } + return new UInt384(result); + } + + @Override + public UInt384 addMod(UInt384 value, UInt384 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("addMod with zero modulus"); + } + return UInt384.valueOf(toBigInteger().add(value.toBigInteger()).mod(modulus.toBigInteger())); + } + + @Override + public UInt384 addMod(long value, UInt384 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("addMod with zero modulus"); + } + return UInt384.valueOf(toBigInteger().add(BigInteger.valueOf(value)).mod(modulus.toBigInteger())); + } + + @Override + public UInt384 addMod(long value, long modulus) { + if (modulus == 0) { + throw new ArithmeticException("addMod with zero modulus"); + } + if (modulus < 0) { + throw new ArithmeticException("addMod unsigned with negative modulus"); + } + return UInt384.valueOf(toBigInteger().add(BigInteger.valueOf(value)).mod(BigInteger.valueOf(modulus))); + } + + @Override + public UInt384 subtract(UInt384 value) { + if (value.isZero()) { + return this; + } + + int[] result = new int[INTS_SIZE]; + boolean constant = true; + long sum = (this.ints[INTS_SIZE - 1] & LONG_MASK) + ((~value.ints[INTS_SIZE - 1]) & LONG_MASK) + 1; + result[INTS_SIZE - 1] = (int) (sum & LONG_MASK); + if (result[INTS_SIZE - 1] < 0 || result[INTS_SIZE - 1] > MAX_CONSTANT) { + constant = false; + } + for (int i = INTS_SIZE - 2; i >= 0; --i) { + sum = (this.ints[i] & LONG_MASK) + ((~value.ints[i]) & LONG_MASK) + (sum >>> 32); + result[i] = (int) (sum & LONG_MASK); + constant &= result[i] == 0; + } + if (constant) { + return CONSTANTS[result[INTS_SIZE - 1]]; + } + return new UInt384(result); + } + + @Override + public UInt384 subtract(long value) { + return add(-value); + } + + @Override + public UInt384 multiply(UInt384 value) { + if (isZero() || value.isZero()) { + return ZERO; + } + if (value.equals(UInt384.ONE)) { + return this; + } + return multiply(this.ints, value.ints); + } + + private static UInt384 multiply(int[] x, int[] y) { + int[] result = new int[INTS_SIZE + INTS_SIZE]; + + long carry = 0; + for (int j = INTS_SIZE - 1, k = INTS_SIZE + INTS_SIZE - 1; j >= 0; j--, k--) { + long product = (y[j] & LONG_MASK) * (x[INTS_SIZE - 1] & LONG_MASK) + carry; + result[k] = (int) product; + carry = product >>> 32; + } + result[INTS_SIZE - 1] = (int) carry; + + for (int i = INTS_SIZE - 2; i >= 0; i--) { + carry = 0; + for (int j = INTS_SIZE - 1, k = INTS_SIZE + i; j >= 0; j--, k--) { + long product = (y[j] & LONG_MASK) * (x[i] & LONG_MASK) + (result[k] & LONG_MASK) + carry; + + result[k] = (int) product; + carry = product >>> 32; + } + result[i] = (int) carry; + } + + boolean constant = true; + for (int i = INTS_SIZE; i < (INTS_SIZE + INTS_SIZE) - 2; ++i) { + constant &= (result[i] == 0); + } + if (constant && result[INTS_SIZE + INTS_SIZE - 1] >= 0 && result[INTS_SIZE + INTS_SIZE - 1] <= MAX_CONSTANT) { + return CONSTANTS[result[INTS_SIZE + INTS_SIZE - 1]]; + } + return new UInt384(Arrays.copyOfRange(result, INTS_SIZE, INTS_SIZE + INTS_SIZE)); + } + + @Override + public UInt384 multiply(long value) { + if (value == 0 || isZero()) { + return ZERO; + } + if (value == 1) { + return this; + } + if (value < 0) { + throw new ArithmeticException("multiply unsigned by negative"); + } + UInt384 other = new UInt384(value); + return multiply(this.ints, other.ints); + } + + @Override + public UInt384 multiplyMod(UInt384 value, UInt384 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("multiplyMod with zero modulus"); + } + if (isZero() || value.isZero()) { + return ZERO; + } + if (value.equals(UInt384.ONE)) { + return mod(modulus); + } + return UInt384.valueOf(toBigInteger().multiply(value.toBigInteger()).mod(modulus.toBigInteger())); + } + + @Override + public UInt384 multiplyMod(long value, UInt384 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("multiplyMod with zero modulus"); + } + if (value == 0 || isZero()) { + return ZERO; + } + if (value == 1) { + return mod(modulus); + } + if (value < 0) { + throw new ArithmeticException("multiplyMod unsigned by negative"); + } + return UInt384.valueOf(toBigInteger().multiply(BigInteger.valueOf(value)).mod(modulus.toBigInteger())); + } + + @Override + public UInt384 multiplyMod(long value, long modulus) { + if (modulus == 0) { + throw new ArithmeticException("multiplyMod with zero modulus"); + } + if (modulus < 0) { + throw new ArithmeticException("multiplyMod unsigned with negative modulus"); + } + if (value == 0 || isZero()) { + return ZERO; + } + if (value == 1) { + return mod(modulus); + } + if (value < 0) { + throw new ArithmeticException("multiplyMod unsigned by negative"); + } + return UInt384.valueOf(toBigInteger().multiply(BigInteger.valueOf(value)).mod(BigInteger.valueOf(modulus))); + } + + @Override + public UInt384 divide(UInt384 value) { + if (value.isZero()) { + throw new ArithmeticException("divide by zero"); + } + if (value.equals(UInt384.ONE)) { + return this; + } + return UInt384.valueOf(toBigInteger().divide(value.toBigInteger())); + } + + @Override + public UInt384 divide(long value) { + if (value == 0) { + throw new ArithmeticException("divide by zero"); + } + if (value < 0) { + throw new ArithmeticException("divide unsigned by negative"); + } + if (value == 1) { + return this; + } + if (isPowerOf2(value)) { + return shiftRight(log2(value)); + } + return UInt384.valueOf(toBigInteger().divide(BigInteger.valueOf(value))); + } + + @Override + public UInt384 pow(UInt384 exponent) { + return UInt384.valueOf(toBigInteger().modPow(exponent.toBigInteger(), P_2_384)); + } + + @Override + public UInt384 pow(long exponent) { + return UInt384.valueOf(toBigInteger().modPow(BigInteger.valueOf(exponent), P_2_384)); + } + + @Override + public UInt384 mod(UInt384 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("mod by zero"); + } + return UInt384.valueOf(toBigInteger().mod(modulus.toBigInteger())); + } + + @Override + public UInt384 mod(long modulus) { + if (modulus == 0) { + throw new ArithmeticException("mod by zero"); + } + if (modulus < 0) { + throw new ArithmeticException("mod by negative"); + } + if (isPowerOf2(modulus)) { + int log2 = log2(modulus); + int d = log2 / 32; + int s = log2 % 32; + assert (d == 0 || d == 1); + + int[] result = new int[INTS_SIZE]; + // Mask the byte at d to only include the s right-most bits + result[INTS_SIZE - 1 - d] = this.ints[INTS_SIZE - 1 - d] & ~(0xFFFFFFFF << s); + if (d != 0) { + result[INTS_SIZE - 1] = this.ints[INTS_SIZE - 1]; + } + return new UInt384(result); + } + return UInt384.valueOf(toBigInteger().mod(BigInteger.valueOf(modulus))); + } + + /** + * Return a bit-wise AND of this value and the supplied value. + * + * @param value the value to perform the operation with + * @return the result of a bit-wise AND + */ + public UInt384 and(UInt384 value) { + int[] result = new int[INTS_SIZE]; + for (int i = INTS_SIZE - 1; i >= 0; --i) { + result[i] = this.ints[i] & value.ints[i]; + } + return new UInt384(result); + } + + /** + * Return a bit-wise AND of this value and the supplied bytes. + * + * @param bytes the bytes to perform the operation with + * @return the result of a bit-wise AND + */ + public UInt384 and(Bytes48 bytes) { + int[] result = new int[INTS_SIZE]; + for (int i = INTS_SIZE - 1, j = 28; i >= 0; --i, j -= 4) { + int other = ((int) bytes.get(j) & 0xFF) << 24; + other |= ((int) bytes.get(j + 1) & 0xFF) << 16; + other |= ((int) bytes.get(i + 2) & 0xFF) << 8; + other |= ((int) bytes.get(i + 3) & 0xFF); + result[i] = this.ints[i] & other; + } + return new UInt384(result); + } + + /** + * Return a bit-wise OR of this value and the supplied value. + * + * @param value the value to perform the operation with + * @return the result of a bit-wise OR + */ + public UInt384 or(UInt384 value) { + int[] result = new int[INTS_SIZE]; + for (int i = INTS_SIZE - 1; i >= 0; --i) { + result[i] = this.ints[i] | value.ints[i]; + } + return new UInt384(result); + } + + /** + * Return a bit-wise OR of this value and the supplied bytes. + * + * @param bytes the bytes to perform the operation with + * @return the result of a bit-wise OR + */ + public UInt384 or(Bytes48 bytes) { + int[] result = new int[INTS_SIZE]; + for (int i = INTS_SIZE - 1, j = 28; i >= 0; --i, j -= 4) { + result[i] = this.ints[i] | (((int) bytes.get(j) & 0xFF) << 24); + result[i] |= ((int) bytes.get(j + 1) & 0xFF) << 16; + result[i] |= ((int) bytes.get(j + 2) & 0xFF) << 8; + result[i] |= ((int) bytes.get(j + 3) & 0xFF); + } + return new UInt384(result); + } + + /** + * Return a bit-wise XOR of this value and the supplied value. + * + * @param value the value to perform the operation with + * @return the result of a bit-wise XOR + */ + public UInt384 xor(UInt384 value) { + int[] result = new int[INTS_SIZE]; + for (int i = INTS_SIZE - 1; i >= 0; --i) { + result[i] = this.ints[i] ^ value.ints[i]; + } + return new UInt384(result); + } + + /** + * Return a bit-wise XOR of this value and the supplied bytes. + * + * @param bytes the bytes to perform the operation with + * @return the result of a bit-wise XOR + */ + public UInt384 xor(Bytes48 bytes) { + int[] result = new int[INTS_SIZE]; + for (int i = INTS_SIZE - 1, j = 28; i >= 0; --i, j -= 4) { + result[i] = this.ints[i] ^ (((int) bytes.get(j) & 0xFF) << 24); + result[i] ^= ((int) bytes.get(j + 1) & 0xFF) << 16; + result[i] ^= ((int) bytes.get(j + 2) & 0xFF) << 8; + result[i] ^= ((int) bytes.get(j + 3) & 0xFF); + } + return new UInt384(result); + } + + /** + * Return a bit-wise NOT of this value. + * + * @return the result of a bit-wise NOT + */ + public UInt384 not() { + int[] result = new int[INTS_SIZE]; + for (int i = INTS_SIZE - 1; i >= 0; --i) { + result[i] = ~(this.ints[i]); + } + return new UInt384(result); + } + + /** + * Shift all bits in this value to the right. + * + * @param distance The number of bits to shift by. + * @return A value containing the shifted bits. + */ + public UInt384 shiftRight(int distance) { + if (distance == 0) { + return this; + } + if (distance >= 384) { + return ZERO; + } + int[] result = new int[INTS_SIZE]; + int d = distance / 32; + int s = distance % 32; + + int resIdx = INTS_SIZE; + if (s == 0) { + for (int i = INTS_SIZE - d; i > 0;) { + result[--resIdx] = this.ints[--i]; + } + } else { + for (int i = INTS_SIZE - 1 - d; i >= 0; i--) { + int leftSide = this.ints[i] >>> s; + int rightSide = (i == 0) ? 0 : this.ints[i - 1] << (32 - s); + result[--resIdx] = (leftSide | rightSide); + } + } + return new UInt384(result); + } + + /** + * Shift all bits in this value to the left. + * + * @param distance The number of bits to shift by. + * @return A value containing the shifted bits. + */ + public UInt384 shiftLeft(int distance) { + if (distance == 0) { + return this; + } + if (distance >= 384) { + return ZERO; + } + int[] result = new int[INTS_SIZE]; + int d = distance / 32; + int s = distance % 32; + + int resIdx = 0; + if (s == 0) { + for (int i = d; i < INTS_SIZE;) { + result[resIdx++] = this.ints[i++]; + } + } else { + for (int i = d; i < INTS_SIZE; ++i) { + int leftSide = this.ints[i] << s; + int rightSide = (i == INTS_SIZE - 1) ? 0 : (this.ints[i + 1] >>> (32 - s)); + result[resIdx++] = (leftSide | rightSide); + } + } + return new UInt384(result); + } + + @Override + public boolean equals(Object object) { + if (object == this) { + return true; + } + if (!(object instanceof UInt384)) { + return false; + } + UInt384 other = (UInt384) object; + for (int i = 0; i < INTS_SIZE; ++i) { + if (this.ints[i] != other.ints[i]) { + return false; + } + } + return true; + } + + @Override + public int hashCode() { + int result = 1; + for (int i = 0; i < INTS_SIZE; ++i) { + result = 31 * result + this.ints[i]; + } + return result; + } + + @Override + public int compareTo(UInt384 other) { + for (int i = 0; i < INTS_SIZE; ++i) { + int cmp = Long.compare(((long) this.ints[i]) & LONG_MASK, ((long) other.ints[i]) & LONG_MASK); + if (cmp != 0) { + return cmp; + } + } + return 0; + } + + @Override + public boolean fitsInt() { + for (int i = 0; i < INTS_SIZE - 1; i++) { + if (this.ints[i] != 0) { + return false; + } + } + // Lastly, the left-most byte of the int must not start with a 1. + return this.ints[INTS_SIZE - 1] >= 0; + } + + @Override + public int intValue() { + if (!fitsInt()) { + throw new ArithmeticException("Value does not fit a 4 byte int"); + } + return this.ints[INTS_SIZE - 1]; + } + + @Override + public boolean fitsLong() { + for (int i = 0; i < INTS_SIZE - 2; i++) { + if (this.ints[i] != 0) { + return false; + } + } + // Lastly, the left-most byte of the int must not start with a 1. + return this.ints[INTS_SIZE - 2] >= 0; + } + + @Override + public long toLong() { + if (!fitsLong()) { + throw new ArithmeticException("Value does not fit a 8 byte long"); + } + return (((long) this.ints[INTS_SIZE - 2]) << 32) | (((long) (this.ints[INTS_SIZE - 1])) & LONG_MASK); + } + + @Override + public String toString() { + return toBigInteger().toString(); + } + + @Override + public BigInteger toBigInteger() { + byte[] mag = new byte[48]; + for (int i = 0, j = 0; i < INTS_SIZE; ++i) { + mag[j++] = (byte) (this.ints[i] >>> 24); + mag[j++] = (byte) ((this.ints[i] >>> 16) & 0xFF); + mag[j++] = (byte) ((this.ints[i] >>> 8) & 0xFF); + mag[j++] = (byte) (this.ints[i] & 0xFF); + } + return new BigInteger(1, mag); + } + + @Override + public UInt384 toUInt384() { + return this; + } + + @Override + public Bytes48 toBytes() { + MutableBytes48 bytes = MutableBytes48.create(); + for (int i = 0, j = 0; i < INTS_SIZE; ++i, j += 4) { + bytes.setInt(j, this.ints[i]); + } + return bytes; + } + + @Override + public Bytes toMinimalBytes() { + int i = 0; + while (i < INTS_SIZE && this.ints[i] == 0) { + ++i; + } + if (i == INTS_SIZE) { + return Bytes.EMPTY; + } + int firstIntBytes = 4 - (Integer.numberOfLeadingZeros(this.ints[i]) / 8); + int totalBytes = firstIntBytes + ((INTS_SIZE - (i + 1)) * 4); + MutableBytes bytes = MutableBytes.create(totalBytes); + int j = 0; + switch (firstIntBytes) { + case 4: + bytes.set(j++, (byte) (this.ints[i] >>> 24)); + // fall through + case 3: + bytes.set(j++, (byte) ((this.ints[i] >>> 16) & 0xFF)); + // fall through + case 2: + bytes.set(j++, (byte) ((this.ints[i] >>> 8) & 0xFF)); + // fall through + case 1: + bytes.set(j++, (byte) (this.ints[i] & 0xFF)); + } + ++i; + for (; i < INTS_SIZE; ++i, j += 4) { + bytes.setInt(j, this.ints[i]); + } + return bytes; + } + + @Override + public int numberOfLeadingZeros() { + for (int i = 0; i < INTS_SIZE; i++) { + if (this.ints[i] == 0) { + continue; + } + return (i * 32) + Integer.numberOfLeadingZeros(this.ints[i]); + } + return 384; + } + + @Override + public int bitLength() { + for (int i = 0; i < INTS_SIZE; i++) { + if (this.ints[i] == 0) { + continue; + } + return (INTS_SIZE * 32) - (i * 32) - Integer.numberOfLeadingZeros(this.ints[i]); + } + return 0; + } + + private static boolean isPowerOf2(long n) { + assert n > 0; + return (n & (n - 1)) == 0; + } + + private static int log2(long v) { + assert v > 0; + return 63 - Long.numberOfLeadingZeros(v); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt384Value.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt384Value.java new file mode 100644 index 00000000000..62859b6a855 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt384Value.java @@ -0,0 +1,421 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes48; + +import java.math.BigInteger; + +/** + * Represents a 384-bit (48 bytes) unsigned integer value. + * + *

+ * A {@link UInt384Value} is an unsigned integer value stored with 48 bytes, so whose value can range between 0 and + * 2^384-1. + * + *

+ * This interface defines operations for value types with a 384-bit precision range. The methods provided by this + * interface take parameters of the same type (and also {@code long}. This provides type safety by ensuring calculations + * cannot mix different {@code UInt384Value} types. + * + *

+ * Where only a pure numerical 384-bit value is required, {@link UInt384} should be used. + * + *

+ * It is strongly advised to extend {@link BaseUInt384Value} rather than implementing this interface directly. Doing so + * provides type safety in that quantities of different units cannot be mixed accidentally. + * + * @param The concrete type of the value. + */ +public interface UInt384Value> extends Comparable { + + /** + * Returns true is this is 0. + * + * @return True if this is the value 0. + */ + default boolean isZero() { + return toBytes().isZero(); + } + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value The amount to be added to this value. + * @return {@code this + value} + */ + T add(T value); + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value the amount to be added to this value + * @return {@code this + value} + * @throws ArithmeticException if the result of the addition overflows + */ + default T addExact(T value) { + T result = add(value); + if (compareTo(result) > 0) { + throw new ArithmeticException("UInt384 overflow"); + } + return result; + } + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value The amount to be added to this value. + * @return {@code this + value} + */ + T add(long value); + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value the amount to be added to this value + * @return {@code this + value} + * @throws ArithmeticException if the result of the addition overflows + */ + default T addExact(long value) { + T result = add(value); + if ((value > 0 && compareTo(result) > 0) || (value < 0 && compareTo(result) < 0)) { + throw new ArithmeticException("UInt384 overflow"); + } + return result; + } + + /** + * Returns a value equivalent to {@code ((this + value) mod modulus)}. + * + * @param value The amount to be added to this value. + * @param modulus The modulus. + * @return {@code (this + value) mod modulus} + * @throws ArithmeticException {@code modulus} == 0. + */ + T addMod(T value, UInt384 modulus); + + /** + * Returns a value equivalent to {@code ((this + value) mod modulus)}. + * + * @param value The amount to be added to this value. + * @param modulus The modulus. + * @return {@code (this + value) mod modulus} + * @throws ArithmeticException {@code modulus} == 0. + */ + T addMod(long value, UInt384 modulus); + + /** + * Returns a value equivalent to {@code ((this + value) mod modulus)}. + * + * @param value The amount to be added to this value. + * @param modulus The modulus. + * @return {@code (this + value) mod modulus} + * @throws ArithmeticException {@code modulus} ≤ 0. + */ + T addMod(long value, long modulus); + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value The amount to be subtracted from this value. + * @return {@code this - value} + */ + T subtract(T value); + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value the amount to be subtracted to this value + * @return {@code this - value} + * @throws ArithmeticException if the result of the addition overflows + */ + default T subtractExact(T value) { + T result = subtract(value); + if (compareTo(result) < 0) { + throw new ArithmeticException("UInt384 overflow"); + } + return result; + } + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value The amount to be subtracted from this value. + * @return {@code this - value} + */ + T subtract(long value); + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value the amount to be subtracted to this value + * @return {@code this - value} + * @throws ArithmeticException if the result of the addition overflows + */ + default T subtractExact(long value) { + T result = subtract(value); + if ((value > 0 && compareTo(result) < 0) || (value < 0 && compareTo(result) > 0)) { + throw new ArithmeticException("UInt384 overflow"); + } + return result; + } + + /** + * Returns a value that is {@code (this * value)}. + * + * @param value The amount to multiply this value by. + * @return {@code this * value} + */ + T multiply(T value); + + /** + * Returns a value that is {@code (this * value)}. + * + * @param value The amount to multiply this value by. + * @return {@code this * value} + * @throws ArithmeticException {@code value} < 0. + */ + T multiply(long value); + + /** + * Returns a value that is {@code ((this * value) mod modulus)}. + * + * @param value The amount to multiply this value by. + * @param modulus The modulus. + * @return {@code (this * value) mod modulus} + * @throws ArithmeticException {@code value} < 0 or {@code modulus} == 0. + */ + T multiplyMod(T value, UInt384 modulus); + + /** + * Returns a value that is {@code ((this * value) mod modulus)}. + * + * @param value The amount to multiply this value by. + * @param modulus The modulus. + * @return {@code (this * value) mod modulus} + * @throws ArithmeticException {@code value} < 0 or {@code modulus} == 0. + */ + T multiplyMod(long value, UInt384 modulus); + + /** + * Returns a value that is {@code ((this * value) mod modulus)}. + * + * @param value The amount to multiply this value by. + * @param modulus The modulus. + * @return {@code (this * value) mod modulus} + * @throws ArithmeticException {@code value} < 0 or {@code modulus} ≤ 0. + */ + T multiplyMod(long value, long modulus); + + /** + * Returns a value that is {@code (this / value)}. + * + * @param value The amount to divide this value by. + * @return {@code this / value} + * @throws ArithmeticException {@code value} == 0. + */ + T divide(T value); + + /** + * Returns a value that is {@code (this / value)}. + * + * @param value The amount to divide this value by. + * @return {@code this / value} + * @throws ArithmeticException {@code value} ≤ 0. + */ + T divide(long value); + + /** + * Returns a value that is {@code (thisexponent mod 2384)} + * + *

+ * This calculates an exponentiation over the modulus of {@code 2^384}. + * + *

+ * Note that {@code exponent} is an {@link UInt384} rather than of the type {@code T}. + * + * @param exponent The exponent to which this value is to be raised. + * @return {@code thisexponent mod 2384} + */ + T pow(UInt384 exponent); + + /** + * Returns a value that is {@code (thisexponent mod 2384)} + * + *

+ * This calculates an exponentiation over the modulus of {@code 2^384}. + * + * @param exponent The exponent to which this value is to be raised. + * @return {@code thisexponent mod 2384} + */ + T pow(long exponent); + + /** + * Returns a value that is {@code (this mod modulus)}. + * + * @param modulus The modulus. + * @return {@code this mod modulus}. + * @throws ArithmeticException {@code modulus} == 0. + */ + T mod(UInt384 modulus); + + /** + * Returns a value that is {@code (this mod modulus)}. + * + * @param modulus The modulus. + * @return {@code this mod modulus}. + * @throws ArithmeticException {@code modulus} ≤ 0. + */ + T mod(long modulus); + + /** + * Returns true if this value fits an int + * + * @return True if this value fits a java {@code int} (i.e. is less or equal to {@code Integer.MAX_VALUE}). + */ + default boolean fitsInt() { + // Ints are 4 bytes, so anything but the 4 last bytes must be zeroes + Bytes48 bytes = toBytes(); + for (int i = 0; i < Bytes48.SIZE - 4; i++) { + if (bytes.get(i) != 0) + return false; + } + // Lastly, the left-most byte of the int must not start with a 1. + return bytes.get(Bytes48.SIZE - 4) >= 0; + } + + /** + * Returns the value as an int. + * + * @return This value as a java {@code int} assuming it is small enough to fit an {@code int}. + * @throws ArithmeticException If the value does not fit an {@code int}, that is if {@code !fitsInt()}. + */ + default int intValue() { + if (!fitsInt()) { + throw new ArithmeticException("Value does not fit a 4 byte int"); + } + return toBytes().getInt(Bytes48.SIZE - 4); + } + + /** + * Returns true if this value fits in a long. + * + * @return True if this value fits a java {@code long} (i.e. is less or equal to {@code Long.MAX_VALUE}). + */ + default boolean fitsLong() { + // Longs are 8 bytes, so anything but the 8 last bytes must be zeroes + for (int i = 0; i < Bytes48.SIZE - 8; i++) { + if (toBytes().get(i) != 0) + return false; + } + // Lastly, the left-most byte of the long must not start with a 1. + return toBytes().get(Bytes48.SIZE - 8) >= 0; + } + + /** + * Returns this value as a long. + * + * @return This value as a java {@code long} assuming it is small enough to fit a {@code long}. + * @throws ArithmeticException If the value does not fit a {@code long}, that is if {@code !fitsLong()}. + */ + default long toLong() { + if (!fitsLong()) { + throw new ArithmeticException("Value does not fit a 8 byte long"); + } + return toBytes().getLong(Bytes48.SIZE - 8); + } + + /** + * Returns this value as a {@link BigInteger}. + * + * @return This value as a {@link BigInteger}. + */ + default BigInteger toBigInteger() { + return toBytes().toUnsignedBigInteger(); + } + + /** + * This value represented as an hexadecimal string. + * + *

+ * Note that this representation includes all the 48 underlying bytes, no matter what the integer actually represents + * (in other words, it can have many leading zeros). For a shorter representation that don't include leading zeros, + * use {@link #toShortHexString}. + * + * @return This value represented as an hexadecimal string. + */ + default String toHexString() { + return toBytes().toHexString(); + } + + /** + * Returns this value represented as a minimal hexadecimal string (without any leading zero). + * + * @return This value represented as a minimal hexadecimal string (without any leading zero). + */ + default String toShortHexString() { + return toBytes().toShortHexString(); + } + + /** + * Convert this value to a {@link UInt384}. + * + * @return This value as a {@link UInt384}. + */ + UInt384 toUInt384(); + + /** + * Returns the value as bytes + * + * @return The value as bytes. + */ + Bytes48 toBytes(); + + /** + * Retuns the value as bytes without any leading zero bytes. + * + * @return The value as bytes without any leading zero bytes. + */ + Bytes toMinimalBytes(); + + /** + * Returns the number of zero bits preceding the highest-order ("leftmost") one-bit + * + * @return the number of zero bits preceding the highest-order ("leftmost") one-bit in the binary representation of + * this value, or 384 if the value is equal to zero. + */ + default int numberOfLeadingZeros() { + return toBytes().numberOfLeadingZeros(); + } + + /** + * Returns the number of bits following and including the highest-order ("leftmost") one-bit + * + * @return The number of bits following and including the highest-order ("leftmost") one-bit in the binary + * representation of this value, or zero if all bits are zero. + */ + default int bitLength() { + return toBytes().bitLength(); + } + + /** + * Returns the decimal representation of this value as a String. + * + * @return the decimal representation of this value as a String. + */ + default String toDecimalString() { + return toBigInteger().toString(10); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt384s.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt384s.java new file mode 100644 index 00000000000..c5e8d3ea119 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt384s.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +/** Static utility methods on UInt384 values. */ +public final class UInt384s { + private UInt384s() {} + + /** + * Returns the maximum of two UInt384 values. + * + * @param v1 The first value. + * @param v2 The second value. + * @return The maximum of {@code v1} and {@code v2}. + * @param The concrete type of the two values. + */ + public static > T max(T v1, T v2) { + return (v1.compareTo(v2)) >= 0 ? v1 : v2; + } + + /** + * Returns the minimum of two UInt384 values. + * + * @param v1 The first value. + * @param v2 The second value. + * @return The minimum of {@code v1} and {@code v2}. + * @param The concrete type of the two values. + */ + public static > T min(T v1, T v2) { + return (v1.compareTo(v2)) < 0 ? v1 : v2; + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt64.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt64.java new file mode 100644 index 00000000000..40a14b2cba6 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt64.java @@ -0,0 +1,581 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.MutableBytes; + +import java.math.BigInteger; + +/** + * An unsigned 64-bit precision number. + * + * This is a raw {@link UInt64Value} - a 64-bit precision unsigned number of no particular unit. + */ +public final class UInt64 implements UInt64Value { + private final static int MAX_CONSTANT = 64; + private static UInt64[] CONSTANTS = new UInt64[MAX_CONSTANT + 1]; + static { + CONSTANTS[0] = new UInt64(0); + for (int i = 1; i <= MAX_CONSTANT; ++i) { + CONSTANTS[i] = new UInt64(i); + } + } + + /** The minimum value of a UInt64 */ + public final static UInt64 MIN_VALUE = valueOf(0); + /** The maximum value of a UInt64 */ + public final static UInt64 MAX_VALUE = new UInt64(~0L); + /** The value 0 */ + public final static UInt64 ZERO = valueOf(0); + /** The value 1 */ + public final static UInt64 ONE = valueOf(1); + + private static final BigInteger P_2_64 = BigInteger.valueOf(2).pow(64); + + private final long value; + + /** + * Return a {@code UInt64} containing the specified value. + * + * @param value The value to create a {@code UInt64} for. + * @return A {@code UInt64} containing the specified value. + * @throws IllegalArgumentException If the value is negative. + */ + public static UInt64 valueOf(long value) { + if (value < 0) { + throw new IllegalArgumentException("Argument must be positive"); + } + return create(value); + } + + /** + * Return a {@link UInt64} containing a random value. + * + * @return a {@link UInt64} containing a random value + */ + public static UInt64 random() { + return UInt64.fromBytes(Bytes.random(8)); + } + + /** + * Return a {@link UInt64} containing the specified value. + * + * @param value the value to create a {@link UInt64} for + * @return a {@link UInt64} containing the specified value + * @throws IllegalArgumentException if the value is negative or too large to be represented as a UInt64 + */ + public static UInt64 valueOf(BigInteger value) { + if (value.signum() < 0) { + throw new IllegalArgumentException("Argument must be positive"); + } + if (value.bitLength() > 64) { + throw new IllegalArgumentException("Argument is too large to represent a UInt64"); + } + return create(value.longValue()); + } + + /** + * Return a {@link UInt64} containing the value described by the specified bytes. + * + * @param bytes The bytes containing a {@link UInt64}. + * @return A {@link UInt64} containing the specified value. + * @throws IllegalArgumentException if {@code bytes.size() > 8}. + */ + public static UInt64 fromBytes(Bytes bytes) { + if (bytes.size() > 8) { + throw new IllegalArgumentException("Argument is greater than 8 bytes"); + } + return create(bytes.toLong()); + } + + /** + * Parse a hexadecimal string into a {@link UInt64}. + * + * @param str The hexadecimal string to parse, which may or may not start with "0x". That representation may contain + * less than 8 bytes, in which case the result is left padded with zeros. + * @return The value corresponding to {@code str}. + * @throws IllegalArgumentException if {@code str} does not correspond to a valid hexadecimal representation or + * contains more than 8 bytes. + */ + public static UInt64 fromHexString(String str) { + return fromBytes(Bytes.fromHexStringLenient(str)); + } + + private static UInt64 create(long value) { + if (value >= 0 && value <= MAX_CONSTANT) { + return CONSTANTS[(int) value]; + } + return new UInt64(value); + } + + private UInt64(long value) { + this.value = value; + } + + @Override + public boolean isZero() { + return this.value == 0; + } + + @Override + public UInt64 add(UInt64 value) { + if (value.value == 0) { + return this; + } + if (this.value == 0) { + return value; + } + return create(this.value + value.value); + } + + @Override + public UInt64 add(long value) { + if (value == 0) { + return this; + } + return create(this.value + value); + } + + @Override + public UInt64 addMod(UInt64 value, UInt64 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("addMod with zero modulus"); + } + return create(toBigInteger().add(value.toBigInteger()).mod(modulus.toBigInteger()).longValue()); + } + + @Override + public UInt64 addMod(long value, UInt64 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("addMod with zero modulus"); + } + return create(toBigInteger().add(BigInteger.valueOf(value)).mod(modulus.toBigInteger()).longValue()); + } + + @Override + public UInt64 addMod(long value, long modulus) { + if (modulus == 0) { + throw new ArithmeticException("addMod with zero modulus"); + } + if (modulus < 0) { + throw new ArithmeticException("addMod unsigned with negative modulus"); + } + return create(toBigInteger().add(BigInteger.valueOf(value)).mod(BigInteger.valueOf(modulus)).longValue()); + } + + @Override + public UInt64 subtract(UInt64 value) { + if (value.isZero()) { + return this; + } + return create(this.value - value.value); + } + + @Override + public UInt64 subtract(long value) { + return add(-value); + } + + @Override + public UInt64 multiply(UInt64 value) { + if (this.value == 0 || value.value == 0) { + return ZERO; + } + if (value.value == 1) { + return this; + } + return create(this.value * value.value); + } + + @Override + public UInt64 multiply(long value) { + if (value < 0) { + throw new ArithmeticException("multiply unsigned by negative"); + } + if (value == 0 || this.value == 0) { + return ZERO; + } + if (value == 1) { + return this; + } + return create(this.value * value); + } + + @Override + public UInt64 multiplyMod(UInt64 value, UInt64 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("multiplyMod with zero modulus"); + } + if (this.value == 0 || value.value == 0) { + return ZERO; + } + if (value.value == 1) { + return mod(modulus); + } + return create(toBigInteger().multiply(value.toBigInteger()).mod(modulus.toBigInteger()).longValue()); + } + + @Override + public UInt64 multiplyMod(long value, UInt64 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("multiplyMod with zero modulus"); + } + if (value == 0 || this.value == 0) { + return ZERO; + } + if (value == 1) { + return mod(modulus); + } + if (value < 0) { + throw new ArithmeticException("multiplyMod unsigned by negative"); + } + return create(toBigInteger().multiply(BigInteger.valueOf(value)).mod(modulus.toBigInteger()).longValue()); + } + + @Override + public UInt64 multiplyMod(long value, long modulus) { + if (modulus == 0) { + throw new ArithmeticException("multiplyMod with zero modulus"); + } + if (modulus < 0) { + throw new ArithmeticException("multiplyMod unsigned with negative modulus"); + } + if (value == 0 || this.value == 0) { + return ZERO; + } + if (value == 1) { + return mod(modulus); + } + if (value < 0) { + throw new ArithmeticException("multiplyMod unsigned by negative"); + } + return create(toBigInteger().multiply(BigInteger.valueOf(value)).mod(BigInteger.valueOf(modulus)).longValue()); + } + + @Override + public UInt64 divide(UInt64 value) { + if (value.value == 0) { + throw new ArithmeticException("divide by zero"); + } + if (value.value == 1) { + return this; + } + return create(toBigInteger().divide(value.toBigInteger()).longValue()); + } + + @Override + public UInt64 divide(long value) { + if (value == 0) { + throw new ArithmeticException("divide by zero"); + } + if (value < 0) { + throw new ArithmeticException("divide unsigned by negative"); + } + if (value == 1) { + return this; + } + if (isPowerOf2(value)) { + return shiftRight(log2(value)); + } + return create(toBigInteger().divide(BigInteger.valueOf(value)).longValue()); + } + + @Override + public UInt64 pow(UInt64 exponent) { + return create(toBigInteger().modPow(exponent.toBigInteger(), P_2_64).longValue()); + } + + @Override + public UInt64 pow(long exponent) { + return create(toBigInteger().modPow(BigInteger.valueOf(exponent), P_2_64).longValue()); + } + + @Override + public UInt64 mod(UInt64 modulus) { + if (modulus.isZero()) { + throw new ArithmeticException("mod by zero"); + } + return create(toBigInteger().mod(modulus.toBigInteger()).longValue()); + } + + @Override + public UInt64 mod(long modulus) { + if (modulus == 0) { + throw new ArithmeticException("mod by zero"); + } + if (modulus < 0) { + throw new ArithmeticException("mod by negative"); + } + return create(this.value % modulus); + } + + /** + * Return a bit-wise AND of this value and the supplied value. + * + * @param value the value to perform the operation with + * @return the result of a bit-wise AND + */ + public UInt64 and(UInt64 value) { + if (this.value == 0 || value.value == 0) { + return ZERO; + } + return create(this.value & value.value); + } + + /** + * Return a bit-wise AND of this value and the supplied bytes. + * + * @param bytes the bytes to perform the operation with + * @return the result of a bit-wise AND + * @throws IllegalArgumentException if more than 8 bytes are supplied + */ + public UInt64 and(Bytes bytes) { + if (bytes.size() > 8) { + throw new IllegalArgumentException("and with more than 8 bytes"); + } + if (this.value == 0) { + return ZERO; + } + long value = bytes.toLong(); + if (value == 0) { + return ZERO; + } + return create(this.value & value); + } + + /** + * Return a bit-wise OR of this value and the supplied value. + * + * @param value the value to perform the operation with + * @return the result of a bit-wise OR + */ + public UInt64 or(UInt64 value) { + return create(this.value | value.value); + } + + /** + * Return a bit-wise OR of this value and the supplied bytes. + * + * @param bytes the bytes to perform the operation with + * @return the result of a bit-wise OR + * @throws IllegalArgumentException if more than 8 bytes are supplied + */ + public UInt64 or(Bytes bytes) { + if (bytes.size() > 8) { + throw new IllegalArgumentException("or with more than 8 bytes"); + } + return create(this.value | bytes.toLong()); + } + + /** + * Return a bit-wise XOR of this value and the supplied value. + * + * If this value and the supplied value are different lengths, then the shorter will be zero-padded to the left. + * + * @param value the value to perform the operation with + * @return the result of a bit-wise XOR + * @throws IllegalArgumentException if more than 8 bytes are supplied + */ + public UInt64 xor(UInt64 value) { + return create(this.value ^ value.value); + } + + /** + * Return a bit-wise XOR of this value and the supplied bytes. + * + * @param bytes the bytes to perform the operation with + * @return the result of a bit-wise XOR + * @throws IllegalArgumentException if more than 8 bytes are supplied + */ + public UInt64 xor(Bytes bytes) { + if (bytes.size() > 8) { + throw new IllegalArgumentException("xor with more than 8 bytes"); + } + return create(this.value ^ bytes.toLong()); + } + + /** + * Return a bit-wise NOT of this value. + * + * @return the result of a bit-wise NOT + */ + public UInt64 not() { + return create(~this.value); + } + + /** + * Shift all bits in this value to the right. + * + * @param distance The number of bits to shift by. + * @return A value containing the shifted bits. + */ + public UInt64 shiftRight(int distance) { + if (distance == 0) { + return this; + } + if (distance >= 64) { + return ZERO; + } + return create(this.value >>> distance); + } + + /** + * Shift all bits in this value to the left. + * + * @param distance The number of bits to shift by. + * @return A value containing the shifted bits. + */ + public UInt64 shiftLeft(int distance) { + if (distance == 0) { + return this; + } + if (distance >= 64) { + return ZERO; + } + return create(this.value << distance); + } + + @Override + public boolean equals(Object object) { + if (object == this) { + return true; + } + if (!(object instanceof UInt64)) { + return false; + } + UInt64 other = (UInt64) object; + return this.value == other.value; + } + + @Override + public int hashCode() { + return Long.hashCode(this.value); + } + + @Override + public int compareTo(UInt64 other) { + return Long.compareUnsigned(this.value, other.value); + } + + @Override + public boolean fitsInt() { + return this.value >= 0 && this.value <= Integer.MAX_VALUE; + } + + @Override + public int intValue() { + if (!fitsInt()) { + throw new ArithmeticException("Value does not fit a 4 byte int"); + } + return (int) this.value; + } + + @Override + public boolean fitsLong() { + return this.value >= 0; + } + + @Override + public long toLong() { + if (!fitsLong()) { + throw new ArithmeticException("Value does not fit a 8 byte long"); + } + return this.value; + } + + @Override + public String toString() { + return toBigInteger().toString(); + } + + @Override + public BigInteger toBigInteger() { + byte[] mag = new byte[8]; + mag[0] = (byte) ((this.value >>> 56) & 0xFF); + mag[1] = (byte) ((this.value >>> 48) & 0xFF); + mag[2] = (byte) ((this.value >>> 40) & 0xFF); + mag[3] = (byte) ((this.value >>> 32) & 0xFF); + mag[4] = (byte) ((this.value >>> 24) & 0xFF); + mag[5] = (byte) ((this.value >>> 16) & 0xFF); + mag[6] = (byte) ((this.value >>> 8) & 0xFF); + mag[7] = (byte) (this.value & 0xFF); + return new BigInteger(1, mag); + } + + @Override + public UInt64 toUInt64() { + return this; + } + + @Override + public Bytes toBytes() { + MutableBytes bytes = MutableBytes.create(8); + bytes.setLong(0, this.value); + return bytes; + } + + @Override + public Bytes toMinimalBytes() { + int requiredBytes = 8 - (Long.numberOfLeadingZeros(this.value) / 8); + MutableBytes bytes = MutableBytes.create(requiredBytes); + int j = 0; + switch (requiredBytes) { + case 8: + bytes.set(j++, (byte) (this.value >>> 56)); + // fall through + case 7: + bytes.set(j++, (byte) ((this.value >>> 48) & 0xFF)); + // fall through + case 6: + bytes.set(j++, (byte) ((this.value >>> 40) & 0xFF)); + // fall through + case 5: + bytes.set(j++, (byte) ((this.value >>> 32) & 0xFF)); + // fall through + case 4: + bytes.set(j++, (byte) ((this.value >>> 24) & 0xFF)); + // fall through + case 3: + bytes.set(j++, (byte) ((this.value >>> 16) & 0xFF)); + // fall through + case 2: + bytes.set(j++, (byte) ((this.value >>> 8) & 0xFF)); + // fall through + case 1: + bytes.set(j, (byte) (this.value & 0xFF)); + } + return bytes; + } + + @Override + public int numberOfLeadingZeros() { + return Long.numberOfLeadingZeros(this.value); + } + + @Override + public int bitLength() { + return 64 - Long.numberOfLeadingZeros(this.value); + } + + private static boolean isPowerOf2(long n) { + assert n > 0; + return (n & (n - 1)) == 0; + } + + private static int log2(long v) { + assert v > 0; + return 63 - Long.numberOfLeadingZeros(v); + } + +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt64Value.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt64Value.java new file mode 100644 index 00000000000..6def37a2365 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt64Value.java @@ -0,0 +1,415 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + + +import org.apache.tuweni.bytes.Bytes; + +import java.math.BigInteger; + +/** + * Represents a 64-bit (8 bytes) unsigned integer value. + * + *

+ * A {@link UInt64Value} is an unsigned integer value whose value can range between 0 and 2^64-1. + * + *

+ * This interface defines operations for value types with a 64-bit precision range. The methods provided by this + * interface take parameters of the same type (and also {@code long}. This provides type safety by ensuring calculations + * cannot mix different {@code UInt64Value} types. + * + *

+ * Where only a pure numerical 64-bit value is required, {@link UInt64} should be used. + * + *

+ * It is strongly advised to extend {@link BaseUInt64Value} rather than implementing this interface directly. Doing so + * provides type safety in that quantities of different units cannot be mixed accidentally. + * + * @param The concrete type of the value. + */ +public interface UInt64Value> extends Comparable { + + /** + * Returns true if this is 0. + * + * @return True if this is the value 0. + */ + default boolean isZero() { + return toBytes().isZero(); + } + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value The amount to be added to this value. + * @return {@code this + value} + */ + T add(T value); + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value the amount to be added to this value + * @return {@code this + value} + * @throws ArithmeticException if the result of the addition overflows + */ + default T addExact(T value) { + T result = add(value); + if (compareTo(result) > 0) { + throw new ArithmeticException("UInt64 overflow"); + } + return result; + } + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value The amount to be added to this value. + * @return {@code this + value} + */ + T add(long value); + + /** + * Returns a value that is {@code (this + value)}. + * + * @param value the amount to be added to this value + * @return {@code this + value} + * @throws ArithmeticException if the result of the addition overflows + */ + default T addExact(long value) { + T result = add(value); + if ((value > 0 && compareTo(result) > 0) || (value < 0 && compareTo(result) < 0)) { + throw new ArithmeticException("UInt64 overflow"); + } + return result; + } + + /** + * Returns a value equivalent to {@code ((this + value) mod modulus)}. + * + * @param value The amount to be added to this value. + * @param modulus The modulus. + * @return {@code (this + value) mod modulus} + * @throws ArithmeticException {@code modulus} == 0. + */ + T addMod(T value, UInt64 modulus); + + /** + * Returns a value equivalent to {@code ((this + value) mod modulus)}. + * + * @param value The amount to be added to this value. + * @param modulus The modulus. + * @return {@code (this + value) mod modulus} + * @throws ArithmeticException {@code modulus} == 0. + */ + T addMod(long value, UInt64 modulus); + + /** + * Returns a value equivalent to {@code ((this + value) mod modulus)}. + * + * @param value The amount to be added to this value. + * @param modulus The modulus. + * @return {@code (this + value) mod modulus} + * @throws ArithmeticException {@code modulus} ≤ 0. + */ + T addMod(long value, long modulus); + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value The amount to be subtracted from this value. + * @return {@code this - value} + */ + T subtract(T value); + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value the amount to be subtracted to this value + * @return {@code this - value} + * @throws ArithmeticException if the result of the subtraction overflows + */ + default T subtractExact(T value) { + T result = subtract(value); + if (compareTo(result) < 0) { + throw new ArithmeticException("UInt64 overflow"); + } + return result; + } + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value The amount to be subtracted from this value. + * @return {@code this - value} + */ + T subtract(long value); + + /** + * Returns a value that is {@code (this - value)}. + * + * @param value the amount to be subtracted to this value + * @return {@code this - value} + * @throws ArithmeticException if the result of the subtraction overflows + */ + default T subtractExact(long value) { + T result = subtract(value); + if ((value > 0 && compareTo(result) < 0) || (value < 0 && compareTo(result) > 0)) { + throw new ArithmeticException("UInt64 overflow"); + } + return result; + } + + /** + * Returns a value that is {@code (this * value)}. + * + * @param value The amount to multiply this value by. + * @return {@code this * value} + */ + T multiply(T value); + + /** + * Returns a value that is {@code (this * value)}. + * + * @param value The amount to multiply this value by. + * @return {@code this * value} + * @throws ArithmeticException {@code value} < 0. + */ + T multiply(long value); + + /** + * Returns a value that is {@code ((this * value) mod modulus)}. + * + * @param value The amount to multiply this value by. + * @param modulus The modulus. + * @return {@code (this * value) mod modulus} + * @throws ArithmeticException {@code value} < 0 or {@code modulus} == 0. + */ + T multiplyMod(T value, UInt64 modulus); + + /** + * Returns a value that is {@code ((this * value) mod modulus)}. + * + * @param value The amount to multiply this value by. + * @param modulus The modulus. + * @return {@code (this * value) mod modulus} + * @throws ArithmeticException {@code value} < 0 or {@code modulus} == 0. + */ + T multiplyMod(long value, UInt64 modulus); + + /** + * Returns a value that is {@code ((this * value) mod modulus)}. + * + * @param value The amount to multiply this value by. + * @param modulus The modulus. + * @return {@code (this * value) mod modulus} + * @throws ArithmeticException {@code value} < 0 or {@code modulus} ≤ 0. + */ + T multiplyMod(long value, long modulus); + + /** + * Returns a value that is {@code (this / value)}. + * + * @param value The amount to divide this value by. + * @return {@code this / value} + * @throws ArithmeticException {@code value} == 0. + */ + T divide(T value); + + /** + * Returns a value that is {@code (this / value)}. + * + * @param value The amount to divide this value by. + * @return {@code this / value} + * @throws ArithmeticException {@code value} ≤ 0. + */ + T divide(long value); + + /** + * Returns a value that is {@code (thisexponent mod 264)} + * + *

+ * This calculates an exponentiation over the modulus of {@code 2^64}. + * + *

+ * Note that {@code exponent} is an {@link UInt64} rather than of the type {@code T}. + * + * @param exponent The exponent to which this value is to be raised. + * @return {@code thisexponent mod 264} + */ + T pow(UInt64 exponent); + + /** + * Returns a value that is {@code (thisexponent mod 264)} + * + *

+ * This calculates an exponentiation over the modulus of {@code 2^64}. + * + * @param exponent The exponent to which this value is to be raised. + * @return {@code thisexponent mod 264} + */ + T pow(long exponent); + + /** + * Returns a value that is {@code (this mod modulus)}. + * + * @param modulus The modulus. + * @return {@code this mod modulus}. + * @throws ArithmeticException {@code modulus} == 0. + */ + T mod(UInt64 modulus); + + /** + * Returns a value that is {@code (this mod modulus)}. + * + * @param modulus The modulus. + * @return {@code this mod modulus}. + * @throws ArithmeticException {@code modulus} ≤ 0. + */ + T mod(long modulus); + + /** + * Returns true if this value fits an int. + * + * @return True if this value fits a java {@code int} (i.e. is less or equal to {@code Integer.MAX_VALUE}). + */ + default boolean fitsInt() { + // Ints are 4 bytes, so anything but the 4 last bytes must be zeroes + Bytes bytes = toBytes(); + for (int i = 0; i < 8 - 4; i++) { + if (bytes.get(i) != 0) + return false; + } + // Lastly, the left-most byte of the int must not start with a 1. + return bytes.get(4) >= 0; + } + + /** + * Returns this value as an int. + * + * @return This value as a java {@code int} assuming it is small enough to fit an {@code int}. + * @throws ArithmeticException If the value does not fit an {@code int}, that is if {@code + * !fitsInt()}. + */ + default int intValue() { + if (!fitsInt()) { + throw new ArithmeticException("Value does not fit a 4 byte int"); + } + return toBytes().getInt(4); + } + + /** + * Returns true if this value fits a long. + * + * @return True if this value fits a java {@code long} (i.e. is less or equal to {@code Long.MAX_VALUE}). + */ + default boolean fitsLong() { + return true; + } + + /** + * Returns this value as a long. + * + * @return This value as a java {@code long} assuming it is small enough to fit a {@code long}. + * @throws ArithmeticException If the value does not fit a {@code long}, that is if {@code + * !fitsLong()}. + */ + default long toLong() { + if (!fitsLong()) { + throw new ArithmeticException("Value does not fit a 8 byte long"); + } + return toBytes().getLong(0); + } + + /** + * Returns this value as a BigInteger + * + * @return This value as a {@link BigInteger}. + */ + default BigInteger toBigInteger() { + return toBytes().toUnsignedBigInteger(); + } + + /** + * This value represented as an hexadecimal string. + * + *

+ * Note that this representation includes all the 8 underlying bytes, no matter what the integer actually represents + * (in other words, it can have many leading zeros). For a shorter representation that don't include leading zeros, + * use {@link #toShortHexString}. + * + * @return This value represented as an hexadecimal string. + */ + default String toHexString() { + return toBytes().toHexString(); + } + + /** + * Returns this value represented as a minimal hexadecimal string (without any leading zero) + * + * @return This value represented as a minimal hexadecimal string (without any leading zero). + */ + default String toShortHexString() { + return toBytes().toShortHexString(); + } + + /** + * Convert this value to a {@link UInt64}. + * + * @return This value as a {@link UInt64}. + */ + UInt64 toUInt64(); + + /** + * Returns the value as bytes. + * + * @return The value as bytes. + */ + Bytes toBytes(); + + /** + * Returns the value as bytes without any leading zero bytes. + * + * @return The value as bytes without any leading zero bytes. + */ + Bytes toMinimalBytes(); + + /** + * Returns the number of zero bits preceding the highest-order ("leftmost") one-bit + * + * @return the number of zero bits preceding the highest-order ("leftmost") one-bit in the binary representation of + * this value, or 64 if the value is equal to zero. + */ + default int numberOfLeadingZeros() { + return toBytes().numberOfLeadingZeros(); + } + + /** + * Returns the number of bits following and including the highest-order ("leftmost") one-bit + * + * @return The number of bits following and including the highest-order ("leftmost") one-bit in the binary + * representation of this value, or zero if all bits are zero. + */ + default int bitLength() { + return toBytes().bitLength(); + } + + /** + * Returns the decimal representation of this value as a String. + * + * @return the decimal representation of this value as a String. + */ + default String toDecimalString() { + return toBigInteger().toString(10); + } +} diff --git a/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt64s.java b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt64s.java new file mode 100644 index 00000000000..692e1a12a95 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/apache/tuweni/units/bigints/UInt64s.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +/** Static utility methods on UInt64 values. */ +public final class UInt64s { + private UInt64s() {} + + /** + * Returns the maximum of two UInt64 values. + * + * @param v1 The first value. + * @param v2 The second value. + * @return The maximum of {@code v1} and {@code v2}. + * @param The concrete type of the two values. + */ + public static > T max(T v1, T v2) { + return (v1.compareTo(v2)) >= 0 ? v1 : v2; + } + + /** + * Returns the minimum of two UInt64 values. + * + * @param v1 The first value. + * @param v2 The second value. + * @return The minimum of {@code v1} and {@code v2}. + * @param The concrete type of the two values. + */ + public static > T min(T v1, T v2) { + return (v1.compareTo(v2)) < 0 ? v1 : v2; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/crypto/BesuProvider.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/crypto/BesuProvider.java new file mode 100644 index 00000000000..65dbb72d466 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/crypto/BesuProvider.java @@ -0,0 +1,29 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.crypto; + +import java.security.Provider; + +public final class BesuProvider extends Provider { + + private static final String info = "Besu Security Provider v1.0"; + + public static final String PROVIDER_NAME = "Besu"; + + @SuppressWarnings({"unchecked", "removal"}) + public BesuProvider() { + super(PROVIDER_NAME, 1.0, info); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/crypto/Hash.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/crypto/Hash.java new file mode 100644 index 00000000000..261504c1f28 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/crypto/Hash.java @@ -0,0 +1,68 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.crypto; + +import com.google.common.base.Suppliers; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.function.Supplier; + +/** Various utilities for providing hashes (digests) of arbitrary data. */ +public abstract class Hash { + private Hash() {} + + public static final String KECCAK256_ALG = "KECCAK-256"; + + private static final Supplier KECCAK256_SUPPLIER = + Suppliers.memoize(() -> messageDigest(KECCAK256_ALG)); + + private static MessageDigest messageDigest(final String algorithm) { + try { + return MessageDigestFactory.create(algorithm); + } catch (final NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } + + /** + * Helper method to generate a digest using the provided algorithm. + * + * @param input The input bytes to produce the digest for. + * @param digestSupplier the digest supplier to use + * @return A digest. + */ + private static byte[] digestUsingAlgorithm( + final Bytes input, final Supplier digestSupplier) { + try { + final MessageDigest digest = (MessageDigest) digestSupplier.get().clone(); + input.update(digest); + return digest.digest(); + } catch (final CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + /** + * Digest using keccak-256. + * + * @param input The input bytes to produce the digest for. + * @return A digest. + */ + public static Bytes32 keccak256(final Bytes input) { + return Bytes32.wrap(digestUsingAlgorithm(input, KECCAK256_SUPPLIER)); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/crypto/MessageDigestFactory.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/crypto/MessageDigestFactory.java new file mode 100644 index 00000000000..85deeec97d5 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/crypto/MessageDigestFactory.java @@ -0,0 +1,34 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.crypto; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.Security; + +public class MessageDigestFactory { + + static { + Security.addProvider(new BesuProvider()); + Security.addProvider(new BouncyCastleProvider()); + } + + @SuppressWarnings("DoNotInvokeMessageDigestDirectly") + public static MessageDigest create(final String algorithm) throws NoSuchAlgorithmException { + return MessageDigest.getInstance(algorithm); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java new file mode 100644 index 00000000000..b1b8c1ec051 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPInput.java @@ -0,0 +1,556 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.rlp; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.apache.tuweni.bytes.MutableBytes; +import org.apache.tuweni.bytes.MutableBytes32; +import org.apache.tuweni.units.bigints.UInt256; + +import java.math.BigInteger; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.function.Function; + +import static com.google.common.base.Preconditions.checkState; + +abstract class AbstractRLPInput implements RLPInput { + + private final boolean lenient; + + protected long size; // The number of bytes in this rlp-encoded byte string + + // Information on the item the input currently is at (next thing to read). + protected long + currentItem; // Offset in value to the beginning of the item (or value.size() if done) + private RLPDecodingHelpers.Kind currentKind; // Kind of the item. + private long currentPayloadOffset; // Offset to the beginning of the current item payload. + private int currentPayloadSize; // Size of the current item payload. + + // Information regarding opened list. The depth is how many list deep we are, and endOfListOffset + // holds the offset in value at which each list ends (indexed by depth). Allows to know if we're + // at the end of our current list, and if there is any unfinished one. + private int depth; + private long[] endOfListOffset = new long[4]; + + AbstractRLPInput(final boolean lenient) { + this.lenient = lenient; + } + + protected void init(final long inputSize, final boolean shouldFitInputSizeExactly) { + if (inputSize == 0) { + return; + } + + currentItem = 0; + // Initially set the size to the input as prepareCurrentItem() needs it. Once we've prepared the + // top level item, we know where that item ends exactly and can update the size to that more + // precise value (which basically mean we'll throw errors on malformed inputs potentially + // sooner). + size = inputSize; + prepareCurrentItem(); + if (currentKind.isList()) { + size = nextItem(); + } + + // No matter what, if the first item advertise a payload ending after the end of the input, that + // input is corrupted. + if (size > inputSize) { + // Our error message include a snippet of the input and that code assume size is not set + // outside of the input, and that's exactly the case we're testing, so resetting the size + // simply for the sake of the error being properly generated. + final long itemEnd = size; + size = inputSize; + throw corrupted( + "Input doesn't have enough data for RLP encoding: encoding advertise a " + + "payload ending at byte %d but input has size %d", + itemEnd, inputSize); + } + + if (shouldFitInputSizeExactly && inputSize > size) { + throwMalformed( + "Input has extra data after RLP encoding: encoding ends at byte %d but " + + "input has size %d", + size, inputSize); + } + + validateCurrentItem(); + } + + protected abstract byte inputByte(long offset); + + protected abstract Bytes inputSlice(long offset, int length); + + protected abstract Bytes32 inputSlice32(long offset); + + protected abstract String inputHex(long offset, int length); + + protected abstract BigInteger getUnsignedBigInteger(long offset, int length); + + protected abstract int getInt(long offset); + + protected abstract long getLong(long offset); + + /** + * Sets the input to the item provided (an offset to the beginning of an item) and check this is + * valid. + * + * @param item the value to which the current item is to be set. + */ + protected void setTo(final long item) { + currentItem = item; + if (currentItem >= size) { + // Setting somewhat safe values so that multiple calls to setTo(nextItem()) don't do anything + // even when at the end. + currentKind = null; + currentPayloadOffset = item; + currentPayloadSize = 0; + return; + } + prepareCurrentItem(); + validateCurrentItem(); + } + + private void prepareCurrentItem() { + // Sets the kind of the item, the offset at which his payload starts and the size of this + // payload. + try { + final RLPDecodingHelpers.RLPElementMetadata elementMetadata = + RLPDecodingHelpers.rlpElementMetadata(this::inputByte, size, currentItem); + currentKind = elementMetadata.kind; + currentPayloadOffset = elementMetadata.payloadStart; + currentPayloadSize = elementMetadata.payloadSize; + } catch (final RLPException exception) { + final String message = + String.format( + exception.getMessage() + getErrorMessageSuffix(), getErrorMessageSuffixParams()); + throw new RLPException(message, exception); + } + } + + private void validateCurrentItem() { + if (currentKind == RLPDecodingHelpers.Kind.SHORT_ELEMENT) { + // Validate that a single byte SHORT_ELEMENT payload is not <= 0x7F. If it is, is should have + // been written as a BYTE_ELEMENT. + if (currentPayloadSize == 1 + && currentPayloadOffset < size + && (payloadByte(0) & 0xFF) <= 0x7F) { + throwMalformed( + "Malformed RLP item: single byte value 0x%s should have been " + + "written without a prefix", + hex(currentPayloadOffset, currentPayloadOffset + 1)); + } + } + + if (currentPayloadSize > 0 && currentPayloadOffset >= size) { + throw corrupted( + "Invalid RLP item: payload should start at offset %d but input has only " + "%d bytes", + currentPayloadOffset, size); + } + if (size - currentPayloadOffset < currentPayloadSize) { + throw corrupted( + "Invalid RLP item: payload starting at byte %d should be %d bytes long, but input " + + "has only %d bytes from that offset", + currentPayloadOffset, currentPayloadSize, size - currentPayloadOffset); + } + } + + private long nextItem() { + return currentPayloadOffset + currentPayloadSize; + } + + @Override + public boolean isDone() { + // The input is done if we're out of input, but also if we've called leaveList() an appropriate + // amount of times. + return currentItem >= size && depth == 0; + } + + private String hex(final long start, final long taintedEnd) { + final long end = Math.min(taintedEnd, size); + final long size = end - start; + if (size < 10) { + return inputHex(start, Math.toIntExact(size)); + } else { + return String.format("%s...%s", inputHex(start, 4), inputHex(end - 4, 4)); + } + } + + private void throwMalformed(final String msg, final Object... params) { + if (!lenient) throw new MalformedRLPInputException(errorMsg(msg, params)); + } + + private CorruptedRLPInputException corrupted(final String msg, final Object... params) { + throw new CorruptedRLPInputException(errorMsg(msg, params)); + } + + private RLPException error(final String msg, final Object... params) { + throw new RLPException(errorMsg(msg, params)); + } + + private RLPException error(final Throwable cause, final String msg, final Object... params) { + throw new RLPException(errorMsg(msg, params), cause); + } + + private String errorMsg(final String message, final Object... params) { + return String.format( + message + getErrorMessageSuffix(), concatParams(params, getErrorMessageSuffixParams())); + } + + private String getErrorMessageSuffix() { + return " (at bytes %d-%d: %s%s[%s]%s%s)"; + } + + private Object[] getErrorMessageSuffixParams() { + final long start = currentItem; + final long end = Math.min(size, nextItem()); + final long realStart = Math.max(0, start - 4); + final long realEnd = Math.min(size, end + 4); + return new Object[] { + start, + end, + realStart == 0 ? "" : "...", + hex(realStart, start), + hex(start, end), + hex(end, realEnd), + realEnd == size ? "" : "..." + }; + } + + private static Object[] concatParams(final Object[] initial, final Object... others) { + final Object[] params = Arrays.copyOf(initial, initial.length + others.length); + System.arraycopy(others, 0, params, initial.length, others.length); + return params; + } + + private void checkElt(final String what) { + if (currentItem >= size) { + throw error("Cannot read a %s, input is fully consumed", what); + } + if (isEndOfCurrentList()) { + throw error("Cannot read a %s, reached end of current list", what); + } + if (currentKind.isList()) { + throw error("Cannot read a %s, current item is a list", what); + } + } + + private void checkElt(final String what, final int expectedSize) { + checkElt(what); + if (currentPayloadSize != expectedSize) + throw error( + "Cannot read a %s, expecting %d bytes but current element is %d bytes long", + what, expectedSize, currentPayloadSize); + } + + private void checkScalar(final String what) { + checkElt(what); + if (currentPayloadSize > 0 && payloadByte(0) == 0) { + throwMalformed("Invalid scalar, has leading zeros bytes"); + } + } + + private void checkScalar(final String what, final int maxExpectedSize) { + checkScalar(what); + if (currentPayloadSize > maxExpectedSize) + throw error( + "Cannot read a %s, expecting a maximum of %d bytes but current element is %d bytes long", + what, maxExpectedSize, currentPayloadSize); + } + + private byte payloadByte(final int offsetInPayload) { + return inputByte(currentPayloadOffset + offsetInPayload); + } + + private Bytes payloadSlice() { + return inputSlice(currentPayloadOffset, currentPayloadSize); + } + + @Override + public void skipNext() { + setTo(nextItem()); + } + + @Override + public long readLongScalar() { + checkScalar("long scalar", 8); + long res = readGenericLongScalar(); + setTo(nextItem()); + return res; + } + + private long readGenericLongScalar() { + long res = 0; + int shift = 0; + for (int i = 0; i < currentPayloadSize; i++) { + res |= ((long) payloadByte(currentPayloadSize - i - 1) & 0xFF) << shift; + shift += 8; + } + return res; + } + + @Override + public int readIntScalar() { + checkScalar("int scalar", 4); + int res = 0; + int shift = 0; + for (int i = 0; i < currentPayloadSize; i++) { + res |= (payloadByte(currentPayloadSize - i - 1) & 0xFF) << shift; + shift += 8; + } + setTo(nextItem()); + return res; + } + + @Override + public BigInteger readBigIntegerScalar() { + checkScalar("arbitrary precision scalar"); + final BigInteger res = getUnsignedBigInteger(currentPayloadOffset, currentPayloadSize); + setTo(nextItem()); + return res; + } + + private Bytes32 readBytes32Scalar() { + checkScalar("32-bytes scalar", 32); + final MutableBytes32 res = MutableBytes32.create(); + payloadSlice().copyTo(res, res.size() - currentPayloadSize); + setTo(nextItem()); + return res; + } + + @Override + public UInt256 readUInt256Scalar() { + return UInt256.fromBytes(readBytes32Scalar()); + } + + @Override + public byte readByte() { + checkElt("byte", 1); + final byte b = payloadByte(0); + setTo(nextItem()); + return b; + } + + @Override + public short readShort() { + checkElt("2-byte short", 2); + final short s = (short) ((payloadByte(0) << 8) | (payloadByte(1) & 0xFF)); + setTo(nextItem()); + return s; + } + + @Override + public int readInt() { + checkElt("4-byte int", 4); + final int res = getInt(currentPayloadOffset); + setTo(nextItem()); + return res; + } + + @Override + public long readLong() { + checkElt("8-byte long", 8); + final long res = getLong(currentPayloadOffset); + setTo(nextItem()); + return res; + } + + @Override + public InetAddress readInetAddress() { + checkElt("inet address"); + if (currentPayloadSize != 4 && currentPayloadSize != 16) { + throw error( + "Cannot read an inet address, current element is %d bytes long", currentPayloadSize); + } + final byte[] address = new byte[currentPayloadSize]; + for (int i = 0; i < currentPayloadSize; i++) { + address[i] = payloadByte(i); + } + setTo(nextItem()); + try { + return InetAddress.getByAddress(address); + } catch (final UnknownHostException e) { + // InetAddress.getByAddress() only throws for an address of illegal length, and we have + // validated that length already, this this genuinely shouldn't throw. + throw new AssertionError(e); + } + } + + @Override + public Bytes readBytes() { + checkElt("arbitrary bytes value"); + final Bytes res = payloadSlice(); + setTo(nextItem()); + return res; + } + + @Override + public Bytes32 readBytes32() { + checkElt("32 bytes value", 32); + final Bytes32 res = inputSlice32(currentPayloadOffset); + setTo(nextItem()); + return res; + } + + @Override + public T readBytes(final Function mapper) { + final Bytes res = readBytes(); + try { + return mapper.apply(res); + } catch (final Exception e) { + throw error(e, "Problem decoding bytes value"); + } + } + + @Override + public RLPInput readAsRlp() { + if (currentItem >= size) { + throw error("Cannot read current element as RLP, input is fully consumed"); + } + final long next = nextItem(); + final RLPInput res = RLP.input(inputSlice(currentItem, Math.toIntExact(next - currentItem))); + setTo(next); + return res; + } + + @Override + public int enterList() { + return enterList(false); + } + + /** + * Enters the list, but does not return the number of item of the entered list. This prevents + * bouncing all around the file to read values that are probably not even used. + * + * @see #enterList() + * @param skipCount true if the element count is not required. + * @return -1 if skipCount==true, otherwise, the number of item of the entered list. + */ + public int enterList(final boolean skipCount) { + if (currentItem >= size) { + throw error("Cannot enter a lists, input is fully consumed"); + } + if (!currentKind.isList()) { + throw error("Expected current item to be a list, but it is: " + currentKind); + } + + ++depth; + if (depth > endOfListOffset.length) { + endOfListOffset = Arrays.copyOf(endOfListOffset, (endOfListOffset.length * 3) / 2); + } + // The first list element is the beginning of the payload. It's end is the end of this item. + final long listStart = currentPayloadOffset; + final long listEnd = nextItem(); + + if (listEnd > size) { + throw corrupted( + "Invalid RLP item: list payload should end at offset %d but input has only %d bytes", + listEnd, size); + } + + endOfListOffset[depth - 1] = listEnd; + int count = -1; + + if (!skipCount) { + // Count list elements from first one. + count = 0; + setTo(listStart); + while (currentItem < listEnd) { + ++count; + setTo(nextItem()); + } + } + + // And lastly reset on the list first element before returning + setTo(listStart); + return count; + } + + @Override + public void leaveList() { + leaveList(false); + } + + @Override + public void leaveListLenient() { + leaveList(true); + } + + private void leaveList(final boolean ignoreRest) { + checkState(depth > 0, "Not within an RLP list"); + + if (!ignoreRest) { + final long listEndOffset = endOfListOffset[depth - 1]; + if (currentItem < listEndOffset) throw error("Not at the end of the current list"); + } + + --depth; + } + + @Override + public boolean nextIsList() { + return currentKind != null && currentKind.isList(); + } + + @Override + public boolean nextIsNull() { + return currentKind == RLPDecodingHelpers.Kind.SHORT_ELEMENT && currentPayloadSize == 0; + } + + @Override + public int nextSize() { + return currentPayloadSize; + } + + @Override + public int nextOffset() { + return Math.toIntExact(currentPayloadOffset); + } + + @Override + public boolean isEndOfCurrentList() { + return depth > 0 && currentItem >= endOfListOffset[depth - 1]; + } + + @Override + public boolean isZeroLengthString() { + return currentKind == RLPDecodingHelpers.Kind.SHORT_ELEMENT && currentPayloadSize == 0; + } + + @Override + public void reset() { + setTo(0); + } + + @Override + public Bytes currentListAsBytes() { + if (currentItem >= size) { + throw error("Cannot read list, input is fully consumed"); + } + if (!currentKind.isList()) { + throw error("Cannot read list, current item is not a list list"); + } + + final MutableBytes scratch = MutableBytes.create(currentPayloadSize + 10); + final int headerSize = RLPEncodingHelpers.writeListHeader(currentPayloadSize, scratch, 0); + payloadSlice().copyTo(scratch, headerSize); + final Bytes res = scratch.slice(0, currentPayloadSize + headerSize); + + setTo(nextItem()); + return res; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPOutput.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPOutput.java new file mode 100644 index 00000000000..882a4e08eb8 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/AbstractRLPOutput.java @@ -0,0 +1,208 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.rlp; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.MutableBytes; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.List; +import java.util.function.Consumer; + +import static com.google.common.base.Preconditions.checkState; + +abstract class AbstractRLPOutput implements RLPOutput { + /* + * The algorithm implemented works as follows: + * + * Values written to the output are accumulated in the 'values' list. When a list is started, it + * is indicated by adding a specific marker in that list (LIST_MARKER). + * While this is gathered, we also incrementally compute the size of the payload of every list of + * that output. Those sizes are stored in 'payloadSizes': when all the output has been added, + * payloadSizes[i] will contain the size of the (encoded) payload of the ith list in 'values' + * (that is, the list that starts at the ith LIST_MARKER in 'values'). + * + * With that information gathered, encoded() can write its output in a single walk of 'values': + * values can be encoded directly, and every time we read a list marker, we use the corresponding + * payload size to write the proper prefix and continue. + * + * The main remaining aspect is how the values of 'payloadSizes' are computed. Computing the size + * of a list without nesting inside is easy: simply add the encoded size of any newly added value + * to the running size. The difficulty is with nesting: when we start a new list, we need to + * track both the sizes of the previous list and the new one. To deal with that, we use the small + * stack 'parentListStack': it stores the index in 'payloadSizes' of every currently "open" lists. + * In other words, payloadSizes[parentListStack[stackSize - 1]] corresponds to the size of the + * current list, the one to which newly added value are currently written (until the next call + * to 'endList()' that is, while payloadSizes[parentListStack[stackSize - 2]] would be the size + * of the parent list, .... + * + * Note that when a new value is added, we add its size only the currently running list. We should + * add that size to that of any parent list as well, but we do so indirectly when a list is + * finished: when 'endList()' is called, we add the size of the full list we just finished (and + * whose size we have now completed) to its parent size. + * + * Side-note: this class internally and informally use "element" to refer to a non list items. + */ + + private static final Bytes LIST_MARKER = Bytes.wrap(new byte[0]); + + private final List values = new ArrayList<>(); + // For every value i in values, rlpEncoded.get(i) will be true only if the value stored is an + // already encoded item. + private final BitSet rlpEncoded = new BitSet(); + + // First element is the total size of everything (the encoding may be a single non-list item, so + // this handles that case more easily; we need that value to size out final output). Following + // elements holds the size of the payload of the ith list in 'values'. + private int[] payloadSizes = new int[8]; + private int listsCount = 1; // number of lists current in 'values' + 1. + + private int[] parentListStack = new int[4]; + private int stackSize = 1; + + private int currentList() { + return parentListStack[stackSize - 1]; + } + + @Override + public void writeBytes(final Bytes v) { + checkState( + stackSize > 1 || values.isEmpty(), "Terminated RLP output, cannot add more elements"); + values.add(v); + payloadSizes[currentList()] += RLPEncodingHelpers.elementSize(v); + } + + @Override + public void writeRaw(final Bytes v) { + checkState( + stackSize > 1 || values.isEmpty(), "Terminated RLP output, cannot add more elements"); + values.add(v); + // Mark that last value added as already encoded. + rlpEncoded.set(values.size() - 1); + payloadSizes[currentList()] += v.size(); + } + + @Override + public void startList() { + values.add(LIST_MARKER); + ++listsCount; // we'll add a new element to payloadSizes + ++stackSize; // and to the list stack. + + // Resize our lists if necessary. + if (listsCount > payloadSizes.length) { + payloadSizes = Arrays.copyOf(payloadSizes, (payloadSizes.length * 3) / 2); + } + if (stackSize > parentListStack.length) { + parentListStack = Arrays.copyOf(parentListStack, (parentListStack.length * 3) / 2); + } + + // The new current list size is store in the slot we just made room for by incrementing + // listsCount + parentListStack[stackSize - 1] = listsCount - 1; + } + + @Override + public void endList() { + checkState(stackSize > 1, "LeaveList() called with no prior matching startList()"); + + final int current = currentList(); + final int finishedListSize = RLPEncodingHelpers.listSize(payloadSizes[current]); + --stackSize; + + // We just finished an item of our parent list, add it to that parent list size now. + final int newCurrent = currentList(); + payloadSizes[newCurrent] += finishedListSize; + } + + /** + * Computes the final encoded data size. + * + * @return The size of the RLP-encoded data written to this output. + * @throws IllegalStateException if some opened list haven't been closed (the output is not valid + * as is). + */ + public int encodedSize() { + checkState(stackSize == 1, "A list has been entered (startList()) but not left (endList())"); + return payloadSizes[0]; + } + + /** + * Write the rlp encoded value to the provided {@link MutableBytes} + * + * @param mutableBytes the value to which the rlp-data will be written + */ + public void writeEncoded(final MutableBytes mutableBytes) { + // Special case where we encode only a single non-list item (note that listsCount is initially + // set to 1, so listsCount == 1 really mean no list explicitly added to the output). + if (listsCount == 1) { + // writeBytes make sure we cannot have more than 1 value without a list + assert values.size() == 1; + final Bytes value = values.get(0); + + final int finalOffset; + // Single non-list value. + if (rlpEncoded.get(0)) { + value.copyTo(mutableBytes, 0); + finalOffset = value.size(); + } else { + finalOffset = RLPEncodingHelpers.writeElement(value, mutableBytes, 0); + } + checkState( + finalOffset == mutableBytes.size(), + "Expected single element RLP encode to be of size %s but was of size %s.", + mutableBytes.size(), + finalOffset); + return; + } + + int offset = 0; + int listIdx = 0; + for (int i = 0; i < values.size(); i++) { + final Bytes value = values.get(i); + if (value == LIST_MARKER) { + final int payloadSize = payloadSizes[++listIdx]; + offset = RLPEncodingHelpers.writeListHeader(payloadSize, mutableBytes, offset); + } else if (rlpEncoded.get(i)) { + value.copyTo(mutableBytes, offset); + offset += value.size(); + } else { + offset = RLPEncodingHelpers.writeElement(value, mutableBytes, offset); + } + } + + checkState( + offset == mutableBytes.size(), + "Expected RLP encoding to be of size %s but was of size %s.", + mutableBytes.size(), + offset); + } + + /** + * Check if the incoming value is 0 and writes it as 0x80, per the spec. + * + * @param input The value to check + * @param writer The consumer to write the non-zero output + */ + public void processZeroByte(final Long input, final Consumer writer) { + // If input == 0, encode 0 value as 0x80 + if (input == 0) { + writeRaw(Bytes.of(0x80)); + } else { + writer.accept(input); + } + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/BytesValueRLPInput.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/BytesValueRLPInput.java new file mode 100644 index 00000000000..c7c113027ef --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/BytesValueRLPInput.java @@ -0,0 +1,78 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.rlp; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +import java.math.BigInteger; + +/** An {@link RLPInput} that reads RLP encoded data from a {@link Bytes}. */ +public class BytesValueRLPInput extends AbstractRLPInput { + + // The RLP encoded data. + private final Bytes value; + + public BytesValueRLPInput(final Bytes value, final boolean lenient) { + this(value, lenient, true); + } + + public BytesValueRLPInput( + final Bytes value, final boolean lenient, final boolean shouldFitExactly) { + super(lenient); + this.value = value; + init(value.size(), shouldFitExactly); + } + + @Override + protected byte inputByte(final long offset) { + return value.get((int) offset); + } + + @Override + protected Bytes inputSlice(final long offset, final int length) { + return value.slice(Math.toIntExact(offset), length); + } + + @Override + protected Bytes32 inputSlice32(final long offset) { + return Bytes32.wrap(inputSlice(offset, 32)); + } + + @Override + protected String inputHex(final long offset, final int length) { + return value.slice(Math.toIntExact(offset), length).toString().substring(2); + } + + @Override + protected BigInteger getUnsignedBigInteger(final long offset, final int length) { + return value.slice(Math.toIntExact(offset), length).toUnsignedBigInteger(); + } + + @Override + protected int getInt(final long offset) { + return value.getInt(Math.toIntExact(offset)); + } + + @Override + protected long getLong(final long offset) { + return value.getLong(Math.toIntExact(offset)); + } + + @Override + public Bytes raw() { + return value; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/BytesValueRLPOutput.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/BytesValueRLPOutput.java new file mode 100644 index 00000000000..295fb1d34e8 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/BytesValueRLPOutput.java @@ -0,0 +1,37 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.rlp; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.MutableBytes; + +/** An {@link RLPOutput} that writes RLP encoded data to a {@link Bytes}. */ +public class BytesValueRLPOutput extends AbstractRLPOutput { + /** + * Computes the final encoded data. + * + * @return A value containing the data written to this output RLP-encoded. + */ + public Bytes encoded() { + final int size = encodedSize(); + if (size == 0) { + return Bytes.EMPTY; + } + + final MutableBytes output = MutableBytes.create(size); + writeEncoded(output); + return output; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/CorruptedRLPInputException.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/CorruptedRLPInputException.java new file mode 100644 index 00000000000..317dc279381 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/CorruptedRLPInputException.java @@ -0,0 +1,22 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.rlp; + +/** Exception thrown if an RLP input is corrupted and cannot be decoded properly. */ +public class CorruptedRLPInputException extends RLPException { + CorruptedRLPInputException(final String message) { + super(message); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/MalformedRLPInputException.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/MalformedRLPInputException.java new file mode 100644 index 00000000000..1cd4073918c --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/MalformedRLPInputException.java @@ -0,0 +1,25 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.rlp; + +/** + * Exception thrown if an RLP input is strictly malformed, but in such a way that can be processed + * by a lenient RLP decoder. + */ +public class MalformedRLPInputException extends RLPException { + MalformedRLPInputException(final String message) { + super(message); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLP.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLP.java new file mode 100644 index 00000000000..680c57a8160 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLP.java @@ -0,0 +1,212 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.rlp; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.MutableBytes; + +import java.util.function.Consumer; + +import static java.lang.String.format; + +/** Static methods to work with RLP encoding/decoding. */ +public abstract class RLP { + private RLP() {} + + /** The RLP encoding of a single empty value, also known as RLP null. */ + public static final Bytes NULL = encodeOne(Bytes.EMPTY); + + public static final Bytes EMPTY_LIST; + + // RLP encoding requires payloads to be less thatn 2^64 bytes in length + // As a result, the longest RLP strings will have a prefix composed of 1 byte encoding the type + // of string followed by at most 8 bytes describing the length of the string + public static final int MAX_PREFIX_SIZE = 9; + + static { + final BytesValueRLPOutput out = new BytesValueRLPOutput(); + out.startList(); + out.endList(); + EMPTY_LIST = out.encoded(); + } + + /** + * Creates a new {@link RLPInput} suitable for decoding the provided RLP encoded value. + * + *

The created input is strict, in that exceptions will be thrown for any malformed input, + * either by this method or by future reads from the returned input. + * + * @param encoded The RLP encoded data for which to create a {@link RLPInput}. + * @return A newly created {@link RLPInput} to decode {@code encoded}. + * @throws MalformedRLPInputException if {@code encoded} doesn't contain a single RLP encoded item + * (item that can be a list itself). Note that more deeply nested corruption/malformation of + * the input will not be detected by this method call, but will be later when the input is + * read. + */ + public static RLPInput input(final Bytes encoded) { + return input(encoded, false); + } + + public static RLPInput input(final Bytes encoded, final boolean lenient) { + return new BytesValueRLPInput(encoded, lenient); + } + + /** + * Creates a {@link RLPOutput}, pass it to the provided consumer for writing, and then return the + * RLP encoded result of that writing. + * + *

This method is a convenience method that is mostly meant for use with class that have a + * method to write to an {@link RLPOutput}. For instance: + * + *

{@code
+   * class Foo {
+   *   public void writeTo(RLPOutput out) {
+   *     //... write some data to out ...
+   *   }
+   * }
+   *
+   * Foo f = ...;
+   * // RLP encode f
+   * Bytes encoded = RLPs.encode(f::writeTo);
+   * }
+ * + * @param writer A method that given an {@link RLPOutput}, writes some data to it. + * @return The RLP encoding of the data written by {@code writer}. + */ + public static Bytes encode(final Consumer writer) { + final BytesValueRLPOutput out = new BytesValueRLPOutput(); + writer.accept(out); + return out.encoded(); + } + + /** + * Encodes a single binary value into RLP. + * + *

This is equivalent (but possibly more efficient) to: + * + *

+   * {
+   *   @code
+   *   BytesValueRLPOutput out = new BytesValueRLPOutput();
+   *   out.writeBytes(value);
+   *   return out.encoded();
+   * }
+   * 
+ * + *

So note in particular that the value is encoded as is (and so not as a scalar in + * particular). + * + * @param value The value to encode. + * @return The RLP encoding containing only {@code value}. + */ + public static Bytes encodeOne(final Bytes value) { + if (RLPEncodingHelpers.isSingleRLPByte(value)) return value; + + final MutableBytes res = MutableBytes.create(RLPEncodingHelpers.elementSize(value)); + RLPEncodingHelpers.writeElement(value, res, 0); + return res; + } + + /** + * Decodes an RLP-encoded value assuming it contains a single non-list item. + * + *

This is equivalent (but possibly more efficient) to: + * + *

{@code
+   * return input(value).readBytes();
+   * }
+ * + *

So note in particular that the value is decoded as is (and so not as a scalar in + * particular). + * + * @param encodedValue The encoded RLP value. + * @return The single value encoded in {@code encodedValue}. + * @throws RLPException if {@code encodedValue} is not a valid RLP encoding or if it does not + * contains a single non-list item. + */ + public static Bytes decodeOne(final Bytes encodedValue) { + if (encodedValue.size() == 0) { + throw new RLPException("Invalid empty input for RLP decoding"); + } + + final int prefix = encodedValue.get(0) & 0xFF; + final RLPDecodingHelpers.Kind kind = RLPDecodingHelpers.Kind.of(prefix); + if (kind.isList()) { + throw new RLPException(format("Invalid input: value %s is an RLP list", encodedValue)); + } + + if (kind == RLPDecodingHelpers.Kind.BYTE_ELEMENT) { + return encodedValue; + } + + final int offset; + final int size; + if (kind == RLPDecodingHelpers.Kind.SHORT_ELEMENT) { + offset = 1; + size = prefix - 0x80; + } else { + final int sizeLength = prefix - 0xb7; + if (1 + sizeLength > encodedValue.size()) { + throw new RLPException( + format( + "Malformed RLP input: not enough bytes to read size of " + + "long item in %s: expected %d bytes but only %d", + encodedValue, sizeLength + 1, encodedValue.size())); + } + offset = 1 + sizeLength; + size = RLPDecodingHelpers.extractSize((index) -> encodedValue.get(index), 1, sizeLength); + } + if (offset + size != encodedValue.size()) { + throw new RLPException( + format( + "Malformed RLP input: %s should be of size %d according to " + + "prefix byte but of size %d", + encodedValue, offset + size, encodedValue.size())); + } + return encodedValue.slice(offset, size); + } + + /** + * Validates that the provided value is a valid RLP encoding. + * + * @param encodedValue The value to check. + * @throws RLPException if {@code encodedValue} is not a valid RLP encoding. + */ + public static void validate(final Bytes encodedValue) { + final RLPInput in = input(encodedValue); + while (!in.isDone()) { + if (in.nextIsList()) { + in.enterList(); + } else if (in.isEndOfCurrentList()) { + in.leaveList(); + } else { + // Skip does as much validation as can be done in general, without allocating anything. + in.skipNext(); + } + } + } + + /** + * Given a {@link Bytes} containing rlp-encoded data, determines the full length of the encoded + * value (including the prefix) by inspecting the prefixed metadata. + * + * @param value the rlp-encoded byte string + * @return the length of the encoded data, according to the prefixed metadata + */ + public static int calculateSize(final Bytes value) { + return RLPDecodingHelpers.rlpElementMetadata((index) -> value.get((int) index), value.size(), 0) + .getEncodedSize(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPDecodingHelpers.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPDecodingHelpers.java new file mode 100644 index 00000000000..670a6b83fb6 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPDecodingHelpers.java @@ -0,0 +1,208 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.rlp; + +import java.util.function.IntUnaryOperator; +import java.util.function.LongUnaryOperator; + +/** + * Helper static methods to facilitate RLP decoding within this package. Neither this class + * nor any of its method are meant to be exposed publicly, they are too low level. + */ +class RLPDecodingHelpers { + + /** The kind of items an RLP item can be. */ + enum Kind { + BYTE_ELEMENT, + SHORT_ELEMENT, + LONG_ELEMENT, + SHORT_LIST, + LONG_LIST; + + static Kind of(final int prefix) { + if (prefix <= 0x7F) { + return Kind.BYTE_ELEMENT; + } else if (prefix <= 0xb7) { + return Kind.SHORT_ELEMENT; + } else if (prefix <= 0xbf) { + return Kind.LONG_ELEMENT; + } else if (prefix <= 0xf7) { + return Kind.SHORT_LIST; + } else { + return Kind.LONG_LIST; + } + } + + boolean isList() { + switch (this) { + case SHORT_LIST: + case LONG_LIST: + return true; + default: + return false; + } + } + } + + /** Read from the provided offset a size of the provided length, assuming this is enough bytes. */ + static int extractSize(final IntUnaryOperator getter, final int offset, final int sizeLength) { + int res = 0; + int shift = 0; + for (int i = 0; i < sizeLength; i++) { + res |= (getter.applyAsInt(offset + (sizeLength - 1) - i) & 0xFF) << shift; + shift += 8; + } + return res; + } + + /** Read from the provided offset a size of the provided length, assuming this is enough bytes. */ + private static int extractSizeFromLongItem( + final LongUnaryOperator getter, final long offset, final int sizeLength) { + if (sizeLength > 4) { + throw new RLPException( + "RLP item at offset " + + offset + + " with size value consuming " + + sizeLength + + " bytes exceeds max supported size of " + + Integer.MAX_VALUE); + } + + long res = 0; + int shift = 0; + for (int i = 0; i < sizeLength; i++) { + res |= (getter.applyAsLong(offset + (sizeLength - 1) - i) & 0xFF) << shift; + shift += 8; + } + try { + return Math.toIntExact(res); + } catch (final ArithmeticException e) { + throw new RLPException( + "RLP item at offset " + + offset + + " with size value consuming " + + sizeLength + + " bytes exceeds max supported size of " + + Integer.MAX_VALUE, + e); + } + } + + static RLPElementMetadata rlpElementMetadata( + final LongUnaryOperator byteGetter, final long size, final long elementStart) { + final int prefix = Math.toIntExact(byteGetter.applyAsLong(elementStart)) & 0xFF; + final Kind kind = Kind.of(prefix); + long payloadStart = 0; + int payloadSize = 0; + + switch (kind) { + case BYTE_ELEMENT: + payloadStart = elementStart; + payloadSize = 1; + break; + case SHORT_ELEMENT: + payloadStart = elementStart + 1; + payloadSize = prefix - 0x80; + break; + case LONG_ELEMENT: + final int sizeLengthElt = prefix - 0xb7; + payloadStart = elementStart + 1 + sizeLengthElt; + payloadSize = readLongSize(byteGetter, size, elementStart, sizeLengthElt); + break; + case SHORT_LIST: + payloadStart = elementStart + 1; + payloadSize = prefix - 0xc0; + break; + case LONG_LIST: + final int sizeLengthList = prefix - 0xf7; + payloadStart = elementStart + 1 + sizeLengthList; + payloadSize = readLongSize(byteGetter, size, elementStart, sizeLengthList); + break; + } + + return new RLPElementMetadata(kind, elementStart, payloadStart, payloadSize); + } + + /** The size of the item payload for a "long" item, given the length in bytes of the said size. */ + private static int readLongSize( + final LongUnaryOperator byteGetter, + final long sizeOfRlpEncodedByteString, + final long item, + final int sizeLength) { + // We will read sizeLength bytes from item + 1. There must be enough bytes for this or the input + // is corrupted. + if (sizeOfRlpEncodedByteString - (item + 1) < sizeLength) { + throw new CorruptedRLPInputException( + String.format( + "Invalid RLP item: value of size %d has not enough bytes to read the %d " + + "bytes payload size", + sizeOfRlpEncodedByteString, sizeLength)); + } + + // That size (which is at least 1 byte by construction) shouldn't have leading zeros. + if (byteGetter.applyAsLong(item + 1) == 0) { + throw new MalformedRLPInputException("Malformed RLP item: size of payload has leading zeros"); + } + + final int res = RLPDecodingHelpers.extractSizeFromLongItem(byteGetter, item + 1, sizeLength); + + // We should not have had the size written separately if it was less than 56 bytes long. + if (res < 56) { + throw new MalformedRLPInputException( + String.format("Malformed RLP item: written as a long item, but size %d < 56 bytes", res)); + } + + return res; + } + + static class RLPElementMetadata { + final Kind kind; // The type of rlp element + final long elementStart; // The index at which this element starts + final long payloadStart; // The index at which the payload of this element starts + final int payloadSize; // The size of the paylod + + RLPElementMetadata( + final Kind kind, final long elementStart, final long payloadStart, final int payloadSize) { + this.kind = kind; + this.elementStart = elementStart; + this.payloadStart = payloadStart; + this.payloadSize = payloadSize; + } + + /** + * @return the size of the byte string holding the rlp-encoded value and metadata + */ + int getEncodedSize() { + final long encodedSize = elementEnd() - elementStart + 1; + try { + return Math.toIntExact(encodedSize); + } catch (final ArithmeticException e) { + throw new RLPException( + String.format( + "RLP item exceeds max supported size of %d: %d", Integer.MAX_VALUE, encodedSize), + e); + } + } + + /** + * The index of the last byte of the rlp encoded element at startIndex + * + * @return the index of the last byte of the rlp encoded element at startIndex + */ + long elementEnd() { + return payloadStart + payloadSize - 1; + } + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPEncodingHelpers.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPEncodingHelpers.java new file mode 100644 index 00000000000..10558778268 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPEncodingHelpers.java @@ -0,0 +1,106 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.rlp; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.MutableBytes; + +/** + * Helper static methods to facilitate RLP encoding within this package. Neither this class + * nor any of its method are meant to be exposed publicly, they are too low level. + */ +class RLPEncodingHelpers { + private RLPEncodingHelpers() {} + + static boolean isSingleRLPByte(final Bytes value) { + return value.size() == 1 && value.get(0) >= 0; + } + + static boolean isShortElement(final Bytes value) { + return value.size() <= 55; + } + + static boolean isShortList(final int payloadSize) { + return payloadSize <= 55; + } + + /** The encoded size of the provided value. */ + static int elementSize(final Bytes value) { + if (isSingleRLPByte(value)) return 1; + + if (isShortElement(value)) return 1 + value.size(); + + return 1 + sizeLength(value.size()) + value.size(); + } + + /** The encoded size of a list given the encoded size of its payload. */ + static int listSize(final int payloadSize) { + int size = 1 + payloadSize; + if (!isShortList(payloadSize)) size += sizeLength(payloadSize); + return size; + } + + /** + * Writes the result of encoding the provided value to the provided destination (which must be big + * enough). + */ + static int writeElement(final Bytes value, final MutableBytes dest, final int destOffset) { + final int size = value.size(); + if (isSingleRLPByte(value)) { + dest.set(destOffset, value.get(0)); + return destOffset + 1; + } + + if (isShortElement(value)) { + dest.set(destOffset, (byte) (0x80 + size)); + value.copyTo(dest, destOffset + 1); + return destOffset + 1 + size; + } + + final int offset = writeLongMetadata(0xb7, size, dest, destOffset); + value.copyTo(dest, offset); + return offset + size; + } + + /** + * Writes the encoded header of a list provided its encoded payload size to the provided + * destination (which must be big enough). + */ + static int writeListHeader(final int payloadSize, final MutableBytes dest, final int destOffset) { + if (isShortList(payloadSize)) { + dest.set(destOffset, (byte) (0xc0 + payloadSize)); + return destOffset + 1; + } + + return writeLongMetadata(0xf7, payloadSize, dest, destOffset); + } + + private static int writeLongMetadata( + final int baseCode, final int size, final MutableBytes dest, final int destOffset) { + final int sizeLength = sizeLength(size); + dest.set(destOffset, (byte) (baseCode + sizeLength)); + int shift = 0; + for (int i = 0; i < sizeLength; i++) { + dest.set(destOffset + sizeLength - i, (byte) (size >> shift)); + shift += 8; + } + return destOffset + 1 + sizeLength; + } + + private static int sizeLength(final int size) { + final int zeros = Integer.numberOfLeadingZeros(size); + return 4 - (zeros / 8); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPException.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPException.java new file mode 100644 index 00000000000..a00767053cd --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPException.java @@ -0,0 +1,25 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.rlp; + +public class RLPException extends RuntimeException { + public RLPException(final String message) { + this(message, null); + } + + RLPException(final String message, final Throwable throwable) { + super(message, throwable); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPInput.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPInput.java new file mode 100644 index 00000000000..3419dd4ac9b --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPInput.java @@ -0,0 +1,356 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.rlp; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.apache.tuweni.units.bigints.UInt256; + +import java.math.BigInteger; +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + +/** + * An input used to decode data in RLP encoding. + * + *

An RLP "value" is fundamentally an {@code Item} defined the following way: + * + *

+ *   Item ::= List | Bytes
+ *   List ::= [ Item, ... , Item ]
+ *   Bytes ::= a binary value (comprised of an arbitrary number of bytes).
+ * 
+ * + *

In other words, RLP encodes binary data organized in arbitrary nested lists. + * + *

A {@link RLPInput} thus provides methods to decode both lists and binary values. A list in the + * input is "entered" by calling {@link #enterList()} and left by calling {@link #leaveList()}. + * Binary values can be read directly with {@link #readBytes()} ()}, but the {@link RLPInput} + * interface provides a wealth of convenience methods to read specific types of data that are in + * specific encoding. + * + *

Amongst the methods to read binary data, some methods are provided to read "scalar". A scalar + * should simply be understood as a positive integer that is encoded with no leading zeros. In other + * word, a method like {@link #readLongScalar()} does not expect an encoded value of exactly 8 bytes + * (by opposition to {@link #readLong}), but rather one that is "up to" 8 bytes. + * + * @see BytesValueRLPInput for a {@link RLPInput} that decode an RLP encoded value stored in a + * {@link Bytes}. + */ +public interface RLPInput { + + /** + * Whether the input has been already fully decoded (has no more data to read). + * + * @return {@code false} if the input has more data to read, {@code true} otherwise. + */ + boolean isDone(); + + /** + * Whether the next element to read from this input is a list. + * + * @return {@code true} if the input is not done and the next item to read is a list. + */ + boolean nextIsList(); + + /** + * Whether the next element to read from this input is an RLP "null" (that is, {@link + * Bytes#EMPTY}). + * + * @return {@code true} if the input is not done and the next item to read is an empty value. + */ + boolean nextIsNull(); + + /** + * Returns the payload size of the next item + * + * @return the payload size of the next item + */ + int nextSize(); + + /** + * Returns the offset of the next item, counting from the start of the RLP Input as a whole. + * + * @return offset from buffer start + */ + int nextOffset(); + + /** + * Whether the input is at the end of a currently entered list, that is if {@link #leaveList()} + * should be the next method called. + * + * @return Whether all elements of the current list have been read but said list haven't been + * "left" yet. + */ + boolean isEndOfCurrentList(); + + /** + * Skips the next item to read in the input. + * + *

Note that if the next item is a list, the whole list is skipped. + */ + void skipNext(); + + /** + * If the next item to read is a list, enter that list, placing the input on the first item of + * that list. + * + * @return The number of item of the entered list. + * @throws RLPException if the next item to read from this input is not a list, or the input is + * corrupted. + */ + int enterList(); + + /** + * Exits the current list after all its items have been consumed. + * + *

Note that this method technically doesn't consume any input but must be called after having + * read the last element of a list. This allow to ensure the structure of the input is indeed the + * one expected. + * + * @throws RLPException if the current list is not finished (it has more items). + */ + void leaveList(); + + /** + * Exits the current list, ignoring any remaining unconsumed elements. + * + *

Note that this method technically doesn't consume any input but must be called after having + * read the last element of a list. This allow to ensure the structure of the input is indeed the + * one expected. + */ + void leaveListLenient(); + + /** + * Reads a non-negative scalar from the input and return it as a long value which is interpreted + * as an unsigned long. + * + * @return The next scalar item of this input as a long value. + * @throws RLPException if the next item to read is a list, the input is at the end of its current + * list (and {@link #leaveList()} hasn't been called) or if the next item is either too big to + * fit a long or has leading zeros. + */ + long readLongScalar(); + + /** + * Reads a scalar from the input and return is as an int value. + * + * @return The next scalar item of this input as an int value. + * @throws RLPException if the next item to read is a list, the input is at the end of its current + * list (and {@link #leaveList()} hasn't been called) or if the next item is either too big to + * fit a long or has leading zeros. + */ + int readIntScalar(); + + /** + * Reads a scalar from the input and return is as a {@link BigInteger}. + * + * @return The next scalar item of this input as a {@link BigInteger}. + * @throws RLPException if the next item to read is a list, the input is at the end of its current + * list (and {@link #leaveList()} hasn't been called) or if the next item has leading zeros. + */ + BigInteger readBigIntegerScalar(); + + /** + * Reads a scalar from the input and return is as a {@link UInt256}. + * + * @return The next scalar item of this input as a {@link UInt256}. + * @throws RLPException if the next item to read is a list, the input is at the end of its current + * list (and {@link #leaveList()} hasn't been called) or if the next item is either too big to + * fit a {@link UInt256} or has leading zeros. + */ + UInt256 readUInt256Scalar(); + + /** + * Reads the next item of this input (which must be exactly 1 byte) as a byte. + * + * @return The byte corresponding to the next item of this input. + * @throws RLPException if the next item to read is a list, the input is at the end of its current + * list (and {@link #leaveList()} hasn't been called) or if the next item is not a single byte + * long. + */ + byte readByte(); + + /** + * Reads the next item of this input (which must be exactly 2-bytes) as a (signed) short. + * + * @return The short corresponding to the next item of this input. + * @throws RLPException if the next item to read is a list, the input is at the end of its current + * list (and {@link #leaveList()} hasn't been called) or if the next item is not 2-bytes. + */ + short readShort(); + + /** + * Reads the next item of this input (which must be exactly 4-bytes) as a (signed) int. + * + * @return The int corresponding to the next item of this input. + * @throws RLPException if the next item to read is a list, the input is at the end of its current + * list (and {@link #leaveList()} hasn't been called) or if the next item is not 4-bytes. + */ + int readInt(); + + /** + * Reads the next item of this input (which must be exactly 8-bytes) as a (signed) long. + * + * @return The long corresponding to the next item of this input. + * @throws RLPException if the next item to read is a list, the input is at the end of its current + * list (and {@link #leaveList()} hasn't been called) or if the next item is not 8-bytes. + */ + long readLong(); + + /** + * Reads the next item of this input (which must be exactly 1 byte) as an unsigned byte. + * + * @return The value of the next item interpreted as an unsigned byte. + * @throws RLPException if the next item to read is a list, the input is at the end of its current + * list (and {@link #leaveList()} hasn't been called) or if the next item is not a single byte + * long. + */ + default int readUnsignedByte() { + if (isZeroLengthString()) { + // Decode an empty string (0x80) as an unsigned byte with value 0 + readBytes(); + return 0; + } + return readByte() & 0xFF; + } + + /** + * Reads the next item of this input (which must be exactly 2-bytes) as an unsigned short. + * + * @return The value of the next item interpreted as an unsigned short. + * @throws RLPException if the next item to read is a list, the input is at the end of its current + * list (and {@link #leaveList()} hasn't been called) or if the next item is not 2-bytes. + */ + default int readUnsignedShort() { + return readShort() & 0xFFFF; + } + + /** + * Reads the next item of this input (which must be exactly 4-bytes) as an unsigned int. + * + * @return The value of the next item interpreted as an unsigned int. + * @throws RLPException if the next item to read is a list, the input is at the end of its current + * list (and {@link #leaveList()} hasn't been called) or if the next item is not 4-bytes. + */ + default long readUnsignedInt() { + return (readInt()) & 0xFFFFFFFFL; + } + + /** + * Reads an inet address from this input. + * + * @return The inet address corresponding to the next item of this input. + * @throws RLPException if the next item to read is a list, the input is at the end of its current + * list (and {@link #leaveList()} hasn't been called) or if the next item is neither 4 nor 16 + * bytes. + */ + InetAddress readInetAddress(); + + /** + * Reads the next item of this input (assuming it is not a list). + * + * @return The next item read of this input. + * @throws RLPException if the next item to read is a list or the input is at the end of its + * current list (and {@link #leaveList()} hasn't been called). + */ + Bytes readBytes(); + + /** + * Reads the next item of this input (assuming it is not a list) that must be exact 32 bytes. + * + * @return The next item read of this input. + * @throws RLPException if the next item to read is a list, the input is at the end of its current + * list (and {@link #leaveList()} hasn't been called) or the next element is not exactly 32 + * bytes. + */ + Bytes32 readBytes32(); + + /** + * Reads the next item of this input (assuming it is not a list) and transforms it with the + * provided mapping function. + * + *

Note that the only benefit of this method over calling the mapper function on the result of + * {@link #readBytes()} is that any error thrown by the mapper will be wrapped by a {@link + * RLPException}, which can make error handling more convenient (having a particular decoded value + * not match what is expected is not fundamentally different from trying to read an unsigned short + * from an item with strictly more or less than 2 bytes). + * + * @param mapper The mapper to apply to the read value. + * @param The type of the result. + * @return The next item read from this input, mapped through {@code mapper}. + * @throws RLPException if the next item to read is a list, the input is at the end of its current + * list (and {@link #leaveList()} hasn't been called) or {@code mapper} throws an exception + * when applied. + */ + T readBytes(Function mapper); + + /** + * Returns the current element as a standalone RLP element. + * + *

This method is useful to extract self-contained RLP elements from a list, so they can be + * processed individually later. + * + * @return The current element as a standalone RLP input element. + */ + RLPInput readAsRlp(); + + /** + * Returns a raw {@link Bytes} representation of this RLP. + * + * @return The raw RLP. + */ + Bytes raw(); + + boolean isZeroLengthString(); + + /** Resets this RLP input to the start. */ + void reset(); + + /** + * Returns a raw {@link Bytes} representation of this RLP list. + * + * @return The raw RLP list. + */ + Bytes currentListAsBytes(); + + /** + * Reads a full list from the input given a method that knows how to read its elements. + * + * @param valueReader A method that can decode a single list element. + * @param The type of the elements of the decoded list. + * @return The next list of this input, where elements are decoded using {@code valueReader}. + * @throws RLPException is the next item to read is not a list, of if any error happens when + * applying {@code valueReader} to read elements of the list. + */ + default List readList(final Function valueReader) { + final int size = enterList(); + final List res = new ArrayList<>(size); + for (int i = 0; i < size; i++) { + try { + res.add(valueReader.apply(this)); + } catch (final Exception e) { + throw new RLPException( + String.format( + "Error applying element decoding function on " + "element %d of the list", i), + e); + } + } + leaveList(); + return res; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPOutput.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPOutput.java new file mode 100644 index 00000000000..4c72656c78e --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/rlp/RLPOutput.java @@ -0,0 +1,302 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.rlp; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.MutableBytes; +import org.apache.tuweni.units.bigints.UInt256Value; + +import java.math.BigInteger; +import java.net.InetAddress; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +/** + * An output used to encode data in RLP encoding. + * + *

An RLP "value" is fundamentally an {@code Item} defined the following way: + * + *

+ *   Item ::= List | Bytes
+ *   List ::= [ Item, ... , Item ]
+ *   Bytes ::= a binary value (comprised of an arbitrary number of bytes).
+ * 
+ * + * In other words, RLP encodes binary data organized in arbitrary nested lists. + * + *

A {@link RLPOutput} thus provides methods to write both lists and binary values. A list is + * started by calling {@link #startList()} and ended by {@link #endList()}. Lists can be nested in + * other lists in arbitrary ways. Binary values can be written directly with {@link + * #writeBytes(Bytes)}, but the {@link RLPOutput} interface provides a wealth of convenience methods + * to write specific types of data with a specific encoding. + * + *

Amongst the methods to write binary data, some methods are provided to write "scalar". A + * scalar should simply be understood as a positive integer that is encoded with no leading zeros. + * In other word, if an integer is written with a "Scalar" method variant, that number will be + * encoded with the minimum number of bytes necessary to represent it. + * + *

The {@link RLPOutput} only defines the interface for writing data meant to be RLP encoded. + * Getting the finally encoded output will depend on the concrete implementation, see {@link + * BytesValueRLPOutput} for instance. + */ +public interface RLPOutput { + + /** Starts a new list. */ + void startList(); + + /** + * Ends the current list. + * + * @throws IllegalStateException if no list has been previously started with {@link #startList()} + * (or any started had already be ended). + */ + void endList(); + + /** + * Writes a new value. + * + * @param v The value to write. + */ + void writeBytes(Bytes v); + + /** + * Writes a scalar (encoded with no leading zeroes). + * + * @param v The scalar to write. + */ + default void writeUInt256Scalar(final UInt256Value v) { + writeBytes(v.trimLeadingZeros()); + } + + /** + * Writes a RLP "null", that is an empty value. + * + *

This is a shortcut for {@code writeBytes(Bytes.EMPTY)}. + */ + default void writeNull() { + writeBytes(Bytes.EMPTY); + } + + /** + * Writes a scalar (encoded with no leading zeroes). + * + * @param v The scalar to write. + * @throws IllegalArgumentException if {@code v < 0}. + */ + default void writeIntScalar(final int v) { + writeLongScalar(v); + } + + /** + * Writes a scalar (encoded with no leading zeroes). + * + * @param v The scalar to write. + */ + default void writeLongScalar(final long v) { + writeBytes(Bytes.minimalBytes(v)); + } + + /** + * Writes a scalar (encoded with no leading zeroes). + * + * @param v The scalar to write. + */ + default void writeBigIntegerScalar(final BigInteger v) { + if (v.equals(BigInteger.ZERO)) { + writeBytes(Bytes.EMPTY); + return; + } + + final byte[] bytes = v.toByteArray(); + // BigInteger will not include leading zeros by contract, but it always includes at least one + // bit of sign (a zero here since it's positive). What that mean is that if the first 1 of the + // resulting number is exactly on a byte boundary, then the sign bit constraint will make the + // value include one extra byte, which will be zero. In other words, they can be one zero bytes + // in practice we should ignore, but there should never be more than one. + writeBytes( + bytes.length > 1 && bytes[0] == 0 + ? Bytes.wrap(bytes, 1, bytes.length - 1) + : Bytes.wrap(bytes)); + } + + /** + * Writes a single byte value. + * + * @param b The byte to write. + */ + default void writeByte(final byte b) { + writeBytes(Bytes.of(b)); + } + + /** + * Writes a 2-bytes value. + * + *

Note that this is not a "scalar" write: the value will be encoded with exactly 2 bytes. + * + * @param s The 2-bytes short to write. + */ + default void writeShort(final short s) { + final byte[] res = new byte[2]; + res[0] = (byte) (s >> 8); + res[1] = (byte) s; + writeBytes(Bytes.wrap(res)); + } + + /** + * Writes a 4-bytes value. + * + *

Note that this is not a "scalar" write: the value will be encoded with exactly 4 bytes. + * + * @param i The 4-bytes int to write. + */ + default void writeInt(final int i) { + final MutableBytes v = MutableBytes.create(4); + v.setInt(0, i); + writeBytes(v); + } + + /** + * Writes a 8-bytes value. + * + *

Note that this is not a "scalar" write: the value will be encoded with exactly 8 bytes. + * + * @param l The 8-bytes long to write. + */ + default void writeLong(final long l) { + final MutableBytes v = MutableBytes.create(8); + v.setLong(0, l); + writeBytes(v); + } + + /** + * Writes a single byte value. + * + * @param b A value that must fit an unsigned byte. + * @throws IllegalArgumentException if {@code b} does not fit an unsigned byte, that is if either + * {@code b < 0} or {@code b > 0xFF}. + */ + default void writeUnsignedByte(final int b) { + processZeroByte(Long.valueOf(b), a -> writeBytes(Bytes.of(b))); + } + + /** + * Writes a 2-bytes value. + * + * @param s A value that must fit an unsigned 2-bytes short. + * @throws IllegalArgumentException if {@code s} does not fit an unsigned 2-bytes short, that is + * if either {@code s < 0} or {@code s > 0xFFFF}. + */ + default void writeUnsignedShort(final int s) { + processZeroByte(Long.valueOf(s), a -> writeBytes(Bytes.ofUnsignedShort(s).trimLeadingZeros())); + } + + /** + * Writes a 4-bytes value. + * + * @param i A value that must fit an unsigned 4-bytes integer. + * @throws IllegalArgumentException if {@code i} does not fit an unsigned 4-bytes int, that is if + * either {@code i < 0} or {@code i > 0xFFFFFFFFL}. + */ + default void writeUnsignedInt(final long i) { + processZeroByte(i, a -> writeBytes(Bytes.ofUnsignedInt(i).trimLeadingZeros())); + } + + /** + * Writes the byte representation of an inet address (so either 4 or 16 bytes long). + * + * @param address The address to write. + */ + default void writeInetAddress(final InetAddress address) { + writeBytes(Bytes.wrap(address.getAddress())); + } + + /** + * Writes a list of values of a specific class provided a function to write values of that class + * to an {@link RLPOutput}. + * + *

This is a convenience method whose result is equivalent to doing: + * + *

{@code
+   * startList();
+   * for (T v : values) {
+   *   valueWriter.accept(v, this);
+   * }
+   * endList();
+   * }
+ * + * @param values A list of value of type {@code T}. + * @param valueWriter A method that given a value of type {@code T} and an {@link RLPOutput}, + * writes this value to the output. + * @param The type of values to write. + */ + default void writeList(final Iterable values, final BiConsumer valueWriter) { + startList(); + for (final T v : values) { + valueWriter.accept(v, this); + } + endList(); + } + + /** + * Writes an empty list to the output. + * + *

This is a shortcut for doing: + * + *

{@code
+   * startList();
+   * endList();
+   * }
+ */ + default void writeEmptyList() { + startList(); + endList(); + } + + /** + * Writes an already RLP encoded item to the output. + * + *

This method is the functional equivalent of decoding the provided value entirely (to an + * fully formed Java object) and then re-encoding that result to this output. It is however a lot + * more efficient in that it saves most of that decoding/re-encoding work. Please note however + * that this method does validate that the input is a valid RLP encoding. If you can + * guaranteed that the input is valid and do not want this validation step, please have a look at + * {@link #writeRaw(Bytes)}. + * + * @param rlpEncodedValue An already RLP encoded value to write as next item of this output. + */ + default void writeRLPBytes(final Bytes rlpEncodedValue) { + RLP.validate(rlpEncodedValue); + writeRaw(rlpEncodedValue); + } + + /** + * Writes an already RLP encoded item to the output. + * + *

This method is equivalent to {@link #writeRLPBytes(Bytes)}, but is unsafe in that it does + * not do any validation of the its input. As such, it is faster but can silently yield invalid + * RLP output if misused. + * + * @param bytes An already RLP encoded value to write as next item of this output. + */ + void writeRaw(Bytes bytes); + + /** + * Check if the incoming value is 0 and writes it as 0x80, per the spec. + * + * @param input The value to check + * @param writer The consumer to write the non-zero output + */ + void processZeroByte(final Long input, final Consumer writer); +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/AllNodesVisitor.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/AllNodesVisitor.java new file mode 100644 index 00000000000..3c4d4f6b4b2 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/AllNodesVisitor.java @@ -0,0 +1,51 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import java.util.function.Consumer; + +public class AllNodesVisitor implements NodeVisitor { + + private final Consumer> handler; + + AllNodesVisitor(final Consumer> handler) { + this.handler = handler; + } + + @Override + public void visit(final ExtensionNode extensionNode) { + handler.accept(extensionNode); + acceptAndUnload(extensionNode.getChild()); + } + + @Override + public void visit(final BranchNode branchNode) { + handler.accept(branchNode); + branchNode.getChildren().forEach(this::acceptAndUnload); + } + + @Override + public void visit(final LeafNode leafNode) { + handler.accept(leafNode); + } + + @Override + public void visit(final NullNode nullNode) {} + + private void acceptAndUnload(final Node storedNode) { + storedNode.accept(this); + storedNode.unload(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/BranchNode.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/BranchNode.java new file mode 100644 index 00000000000..af688a02a5c --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/BranchNode.java @@ -0,0 +1,267 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.apache.tuweni.bytes.MutableBytes; +import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; +import org.hyperledger.besu.ethereum.rlp.RLP; + +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; +import java.util.*; +import java.util.function.Function; + +import static org.hyperledger.besu.crypto.Hash.keccak256; + +public class BranchNode implements Node { + public static final byte RADIX = CompactEncoding.LEAF_TERMINATOR; + + @SuppressWarnings("rawtypes") + private static final Node NULL_NODE = NullNode.instance(); + + private final Optional location; + private final ArrayList> children; + private final Optional value; + private final NodeFactory nodeFactory; + private final Function valueSerializer; + private WeakReference rlp; + private SoftReference hash; + private boolean dirty = false; + private boolean needHeal = false; + + BranchNode( + final Bytes location, + final ArrayList> children, + final Optional value, + final NodeFactory nodeFactory, + final Function valueSerializer) { + assert (children.size() == RADIX); + this.location = Optional.ofNullable(location); + this.children = children; + this.value = value; + this.nodeFactory = nodeFactory; + this.valueSerializer = valueSerializer; + } + + BranchNode( + final ArrayList> children, + final Optional value, + final NodeFactory nodeFactory, + final Function valueSerializer) { + assert (children.size() == RADIX); + this.location = Optional.empty(); + this.children = children; + this.value = value; + this.nodeFactory = nodeFactory; + this.valueSerializer = valueSerializer; + } + + @Override + public Node accept(final PathNodeVisitor visitor, final Bytes path) { + return visitor.visit(this, path); + } + + @Override + public void accept(final NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + public void accept(final Bytes location, final LocationNodeVisitor visitor) { + visitor.visit(location, this); + } + + @Override + public Optional getLocation() { + return location; + } + + @Override + public Bytes getPath() { + return Bytes.EMPTY; + } + + @Override + public Optional getValue() { + return value; + } + + @Override + public List> getChildren() { + return Collections.unmodifiableList(children); + } + + public Node child(final byte index) { + return children.get(index); + } + + @Override + public Bytes getRlp() { + if (rlp != null) { + final Bytes encoded = rlp.get(); + if (encoded != null) { + return encoded; + } + } + final BytesValueRLPOutput out = new BytesValueRLPOutput(); + out.startList(); + for (int i = 0; i < RADIX; ++i) { + out.writeRaw(children.get(i).getRlpRef()); + } + if (value.isPresent()) { + out.writeBytes(valueSerializer.apply(value.get())); + } else { + out.writeNull(); + } + out.endList(); + final Bytes encoded = out.encoded(); + rlp = new WeakReference<>(encoded); + return encoded; + } + + @Override + public Bytes getRlpRef() { + if (isReferencedByHash()) { + return RLP.encodeOne(getHash()); + } else { + return getRlp(); + } + } + + @Override + public Bytes32 getHash() { + if (hash != null) { + final Bytes32 hashed = hash.get(); + if (hashed != null) { + return hashed; + } + } + final Bytes32 hashed = keccak256(getRlp()); + hash = new SoftReference<>(hashed); + return hashed; + } + + @Override + public Node replacePath(final Bytes newPath) { + return nodeFactory.createExtension(newPath, this); + } + + public Node replaceChild(final byte index, final Node updatedChild) { + return replaceChild(index, updatedChild, true); + } + + public Node replaceChild( + final byte index, final Node updatedChild, final boolean allowFlatten) { + final ArrayList> newChildren = new ArrayList<>(children); + newChildren.set(index, updatedChild); + + if (updatedChild == NULL_NODE) { + if (value.isPresent() && !hasChildren()) { + return nodeFactory.createLeaf(Bytes.of(index), value.get()); + } else if (!value.isPresent() && allowFlatten) { + final Optional> flattened = maybeFlatten(newChildren); + if (flattened.isPresent()) { + return flattened.get(); + } + } + } + + return nodeFactory.createBranch(newChildren, value); + } + + public Node replaceValue(final V value) { + return nodeFactory.createBranch(children, Optional.of(value)); + } + + public Node removeValue() { + return maybeFlatten(children).orElse(nodeFactory.createBranch(children, Optional.empty())); + } + + private boolean hasChildren() { + for (final Node child : children) { + if (child != NULL_NODE) { + return true; + } + } + return false; + } + + private static Optional> maybeFlatten(final ArrayList> children) { + final int onlyChildIndex = findOnlyChild(children); + if (onlyChildIndex >= 0) { + // replace the path of the only child and return it + final Node onlyChild = children.get(onlyChildIndex); + final Bytes onlyChildPath = onlyChild.getPath(); + final MutableBytes completePath = MutableBytes.create(1 + onlyChildPath.size()); + completePath.set(0, (byte) onlyChildIndex); + onlyChildPath.copyTo(completePath, 1); + return Optional.of(onlyChild.replacePath(completePath)); + } + return Optional.empty(); + } + + private static int findOnlyChild(final ArrayList> children) { + int onlyChildIndex = -1; + assert (children.size() == RADIX); + for (int i = 0; i < RADIX; ++i) { + if (children.get(i) != NULL_NODE) { + if (onlyChildIndex >= 0) { + return -1; + } + onlyChildIndex = i; + } + } + return onlyChildIndex; + } + + @Override + public String print() { + final StringBuilder builder = new StringBuilder(); + builder.append("Branch:"); + builder.append("\n\tRef: ").append(getRlpRef()); + for (int i = 0; i < RADIX; i++) { + final Node child = child((byte) i); + if (!Objects.equals(child, NullNode.instance())) { + final String branchLabel = "[" + Integer.toHexString(i) + "] "; + final String childRep = child.print().replaceAll("\n\t", "\n\t\t"); + builder.append("\n\t").append(branchLabel).append(childRep); + } + } + builder.append("\n\tValue: ").append(getValue().map(Object::toString).orElse("empty")); + return builder.toString(); + } + + @Override + public boolean isDirty() { + return dirty; + } + + @Override + public void markDirty() { + dirty = true; + } + + @Override + public boolean isHealNeeded() { + return needHeal; + } + + @Override + public void markHealNeeded() { + this.needHeal = true; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/CommitVisitor.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/CommitVisitor.java new file mode 100644 index 00000000000..4e3335e3119 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/CommitVisitor.java @@ -0,0 +1,75 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; + +public class CommitVisitor implements LocationNodeVisitor { + + private final NodeUpdater nodeUpdater; + + public CommitVisitor(final NodeUpdater nodeUpdater) { + this.nodeUpdater = nodeUpdater; + } + + @Override + public void visit(final Bytes location, final ExtensionNode extensionNode) { + if (!extensionNode.isDirty()) { + return; + } + + final Node child = extensionNode.getChild(); + if (child.isDirty()) { + child.accept(Bytes.concatenate(location, extensionNode.getPath()), this); + } + + maybeStoreNode(location, extensionNode); + } + + @Override + public void visit(final Bytes location, final BranchNode branchNode) { + if (!branchNode.isDirty()) { + return; + } + + for (byte i = 0; i < BranchNode.RADIX; ++i) { + final Node child = branchNode.child(i); + if (child.isDirty()) { + child.accept(Bytes.concatenate(location, Bytes.of(i)), this); + } + } + + maybeStoreNode(location, branchNode); + } + + @Override + public void visit(final Bytes location, final LeafNode leafNode) { + if (!leafNode.isDirty()) { + return; + } + + maybeStoreNode(location, leafNode); + } + + @Override + public void visit(final Bytes location, final NullNode nullNode) {} + + public void maybeStoreNode(final Bytes location, final Node node) { + final Bytes nodeRLP = node.getRlp(); + if (nodeRLP.size() >= 32) { + this.nodeUpdater.store(location, node.getHash(), nodeRLP); + } + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/CompactEncoding.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/CompactEncoding.java new file mode 100644 index 00000000000..2622e8a45a8 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/CompactEncoding.java @@ -0,0 +1,123 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.MutableBytes; + +import static com.google.common.base.Preconditions.checkArgument; + +public abstract class CompactEncoding { + private CompactEncoding() {} + + public static final byte LEAF_TERMINATOR = 0x10; + + public static Bytes bytesToPath(final Bytes bytes) { + final MutableBytes path = MutableBytes.create(bytes.size() * 2 + 1); + int j = 0; + for (int i = 0; i < bytes.size(); i += 1, j += 2) { + final byte b = bytes.get(i); + path.set(j, (byte) ((b >>> 4) & 0x0f)); + path.set(j + 1, (byte) (b & 0x0f)); + } + path.set(j, LEAF_TERMINATOR); + return path; + } + + public static Bytes pathToBytes(final Bytes path) { + checkArgument(!path.isEmpty(), "Path must not be empty"); + checkArgument(path.get(path.size() - 1) == LEAF_TERMINATOR, "Path must be a leaf path"); + final MutableBytes bytes = MutableBytes.create((path.size() - 1) / 2); + int bytesPos = 0; + for (int pathPos = 0; pathPos < path.size() - 1; pathPos += 2, bytesPos += 1) { + final byte high = path.get(pathPos); + final byte low = path.get(pathPos + 1); + if ((high & 0xf0) != 0 || (low & 0xf0) != 0) { + throw new IllegalArgumentException("Invalid path: contains elements larger than a nibble"); + } + bytes.set(bytesPos, (byte) (high << 4 | low)); + } + return bytes; + } + + public static Bytes encode(final Bytes path) { + int size = path.size(); + final boolean isLeaf = size > 0 && path.get(size - 1) == LEAF_TERMINATOR; + if (isLeaf) { + size = size - 1; + } + + final MutableBytes encoded = MutableBytes.create((size + 2) / 2); + int i = 0; + int j = 0; + + if (size % 2 == 1) { + // add first nibble to magic + final byte high = (byte) (isLeaf ? 0x03 : 0x01); + final byte low = path.get(i++); + if ((low & 0xf0) != 0) { + throw new IllegalArgumentException("Invalid path: contains elements larger than a nibble"); + } + encoded.set(j++, (byte) (high << 4 | low)); + } else { + final byte high = (byte) (isLeaf ? 0x02 : 0x00); + encoded.set(j++, (byte) (high << 4)); + } + + while (i < size) { + final byte high = path.get(i++); + final byte low = path.get(i++); + if ((high & 0xf0) != 0 || (low & 0xf0) != 0) { + throw new IllegalArgumentException("Invalid path: contains elements larger than a nibble"); + } + encoded.set(j++, (byte) (high << 4 | low)); + } + + return encoded; + } + + public static Bytes decode(final Bytes encoded) { + final int size = encoded.size(); + checkArgument(size > 0); + final byte metadata = encoded.get(0); + checkArgument((metadata & 0xc0) == 0, "Invalid compact encoding"); + + final boolean isLeaf = (metadata & 0x20) != 0; + + final int pathLength = ((size - 1) * 2) + (isLeaf ? 1 : 0); + final MutableBytes path; + int i = 0; + + if ((metadata & 0x10) != 0) { + // need to use lower nibble of metadata + path = MutableBytes.create(pathLength + 1); + path.set(i++, (byte) (metadata & 0x0f)); + } else { + path = MutableBytes.create(pathLength); + } + + for (int j = 1; j < size; j++) { + final byte b = encoded.get(j); + path.set(i++, (byte) ((b >>> 4) & 0x0f)); + path.set(i++, (byte) (b & 0x0f)); + } + + if (isLeaf) { + path.set(i, LEAF_TERMINATOR); + } + + return path; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/DefaultNodeFactory.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/DefaultNodeFactory.java new file mode 100644 index 00000000000..e8e01b99258 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/DefaultNodeFactory.java @@ -0,0 +1,71 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Optional; +import java.util.function.Function; + +public class DefaultNodeFactory implements NodeFactory { + @SuppressWarnings("rawtypes") + private static final Node NULL_NODE = NullNode.instance(); + + private final Function valueSerializer; + + public DefaultNodeFactory(final Function valueSerializer) { + this.valueSerializer = valueSerializer; + } + + @Override + public Node createExtension(final Bytes path, final Node child) { + return new ExtensionNode<>(path, child, this); + } + + @SuppressWarnings("unchecked") + @Override + public Node createBranch( + final byte leftIndex, final Node left, final byte rightIndex, final Node right) { + assert (leftIndex <= BranchNode.RADIX); + assert (rightIndex <= BranchNode.RADIX); + assert (leftIndex != rightIndex); + + final ArrayList> children = + new ArrayList<>(Collections.nCopies(BranchNode.RADIX, (Node) NULL_NODE)); + if (leftIndex == BranchNode.RADIX) { + children.set(rightIndex, right); + return createBranch(children, left.getValue()); + } else if (rightIndex == BranchNode.RADIX) { + children.set(leftIndex, left); + return createBranch(children, right.getValue()); + } else { + children.set(leftIndex, left); + children.set(rightIndex, right); + return createBranch(children, Optional.empty()); + } + } + + @Override + public Node createBranch(final ArrayList> children, final Optional value) { + return new BranchNode<>(children, value, this, valueSerializer); + } + + @Override + public Node createLeaf(final Bytes path, final V value) { + return new LeafNode<>(path, value, this, valueSerializer); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/ExtensionNode.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/ExtensionNode.java new file mode 100644 index 00000000000..4677a4004cf --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/ExtensionNode.java @@ -0,0 +1,192 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; +import org.hyperledger.besu.ethereum.rlp.RLP; + +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import static org.hyperledger.besu.crypto.Hash.keccak256; + +public class ExtensionNode implements Node { + + private final Optional location; + private final Bytes path; + private final Node child; + private final NodeFactory nodeFactory; + private WeakReference rlp; + private SoftReference hash; + private boolean dirty = false; + private boolean needHeal = false; + + ExtensionNode( + final Bytes location, + final Bytes path, + final Node child, + final NodeFactory nodeFactory) { + assert (path.size() > 0); + assert (path.get(path.size() - 1) != CompactEncoding.LEAF_TERMINATOR) + : "Extension path ends in a leaf terminator"; + this.location = Optional.ofNullable(location); + this.path = path; + this.child = child; + this.nodeFactory = nodeFactory; + } + + ExtensionNode(final Bytes path, final Node child, final NodeFactory nodeFactory) { + assert (path.size() > 0); + assert (path.get(path.size() - 1) != CompactEncoding.LEAF_TERMINATOR) + : "Extension path ends in a leaf terminator"; + this.location = Optional.empty(); + this.path = path; + this.child = child; + this.nodeFactory = nodeFactory; + } + + @Override + public Node accept(final PathNodeVisitor visitor, final Bytes path) { + return visitor.visit(this, path); + } + + @Override + public void accept(final NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + public void accept(final Bytes location, final LocationNodeVisitor visitor) { + visitor.visit(location, this); + } + + @Override + public Optional getLocation() { + return location; + } + + @Override + public Bytes getPath() { + return path; + } + + @Override + public Optional getValue() { + return Optional.empty(); + } + + @Override + public List> getChildren() { + return Collections.singletonList(child); + } + + public Node getChild() { + return child; + } + + @Override + public Bytes getRlp() { + if (rlp != null) { + final Bytes encoded = rlp.get(); + if (encoded != null) { + return encoded; + } + } + final BytesValueRLPOutput out = new BytesValueRLPOutput(); + out.startList(); + out.writeBytes(CompactEncoding.encode(path)); + out.writeRaw(child.getRlpRef()); + out.endList(); + final Bytes encoded = out.encoded(); + rlp = new WeakReference<>(encoded); + return encoded; + } + + @Override + public Bytes getRlpRef() { + if (isReferencedByHash()) { + return RLP.encodeOne(getHash()); + } else { + return getRlp(); + } + } + + @Override + public Bytes32 getHash() { + if (hash != null) { + final Bytes32 hashed = hash.get(); + if (hashed != null) { + return hashed; + } + } + final Bytes rlp = getRlp(); + final Bytes32 hashed = keccak256(rlp); + hash = new SoftReference<>(hashed); + return hashed; + } + + public Node replaceChild(final Node updatedChild) { + // collapse this extension - if the child is a branch, it will create a new extension + return updatedChild.replacePath(Bytes.concatenate(path, updatedChild.getPath())); + } + + @Override + public Node replacePath(final Bytes path) { + if (path.size() == 0) { + return child; + } + return nodeFactory.createExtension(path, child); + } + + @Override + public String print() { + final StringBuilder builder = new StringBuilder(); + final String childRep = getChild().print().replaceAll("\n\t", "\n\t\t"); + builder + .append("Extension:") + .append("\n\tRef: ") + .append(getRlpRef()) + .append("\n\tPath: ") + .append(CompactEncoding.encode(path)) + .append("\n\t") + .append(childRep); + return builder.toString(); + } + + @Override + public boolean isDirty() { + return dirty; + } + + @Override + public void markDirty() { + dirty = true; + } + + @Override + public boolean isHealNeeded() { + return needHeal; + } + + @Override + public void markHealNeeded() { + this.needHeal = true; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/GetVisitor.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/GetVisitor.java new file mode 100644 index 00000000000..20397701a46 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/GetVisitor.java @@ -0,0 +1,62 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; + +class GetVisitor implements PathNodeVisitor { + private final Node NULL_NODE_RESULT = NullNode.instance(); + + @Override + public Node visit(final ExtensionNode extensionNode, final Bytes path) { + final Bytes extensionPath = extensionNode.getPath(); + final int commonPathLength = extensionPath.commonPrefixLength(path); + assert commonPathLength < path.size() + : "Visiting path doesn't end with a non-matching terminator"; + + if (commonPathLength < extensionPath.size()) { + // path diverges before the end of the extension, so it cannot match + return NULL_NODE_RESULT; + } + + return extensionNode.getChild().accept(this, path.slice(commonPathLength)); + } + + @Override + public Node visit(final BranchNode branchNode, final Bytes path) { + assert path.size() > 0 : "Visiting path doesn't end with a non-matching terminator"; + + final byte childIndex = path.get(0); + if (childIndex == CompactEncoding.LEAF_TERMINATOR) { + return branchNode; + } + + return branchNode.child(childIndex).accept(this, path.slice(1)); + } + + @Override + public Node visit(final LeafNode leafNode, final Bytes path) { + final Bytes leafPath = leafNode.getPath(); + if (leafPath.commonPrefixLength(path) != leafPath.size()) { + return NULL_NODE_RESULT; + } + return leafNode; + } + + @Override + public Node visit(final NullNode nullNode, final Bytes path) { + return NULL_NODE_RESULT; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/KeyValueMerkleStorage.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/KeyValueMerkleStorage.java new file mode 100644 index 00000000000..7c04f18cc0c --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/KeyValueMerkleStorage.java @@ -0,0 +1,66 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.hyperledger.besu.storage.KeyValueStorage; +import org.hyperledger.besu.storage.KeyValueStorageTransaction; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public class KeyValueMerkleStorage implements MerkleStorage { + + private final KeyValueStorage keyValueStorage; + private final Map pendingUpdates = new HashMap<>(); + + public KeyValueMerkleStorage(final KeyValueStorage keyValueStorage) { + this.keyValueStorage = keyValueStorage; + } + + @Override + public Optional get(final Bytes location, final Bytes32 hash) { + return pendingUpdates.containsKey(hash) + ? Optional.of(pendingUpdates.get(hash)) + : keyValueStorage.get(hash.toArrayUnsafe()).map(Bytes::wrap); + } + + @Override + public void put(final Bytes location, final Bytes32 hash, final Bytes value) { + pendingUpdates.put(hash, value); + } + + @Override + public void commit() { + if (pendingUpdates.size() == 0) { + // Nothing to do + return; + } + final KeyValueStorageTransaction kvTx = keyValueStorage.startTransaction(); + for (final Map.Entry entry : pendingUpdates.entrySet()) { + kvTx.put(entry.getKey().toArrayUnsafe(), entry.getValue().toArrayUnsafe()); + } + kvTx.commit(); + + pendingUpdates.clear(); + } + + @Override + public void rollback() { + pendingUpdates.clear(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/LeafNode.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/LeafNode.java new file mode 100644 index 00000000000..a3cc33ebfe8 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/LeafNode.java @@ -0,0 +1,177 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; +import org.hyperledger.besu.ethereum.rlp.RLP; + +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; + +import static org.hyperledger.besu.crypto.Hash.keccak256; + +public class LeafNode implements Node { + private final Optional location; + private final Bytes path; + private final V value; + private final NodeFactory nodeFactory; + private final Function valueSerializer; + private WeakReference rlp; + private SoftReference hash; + private boolean dirty = false; + + LeafNode( + final Bytes location, + final Bytes path, + final V value, + final NodeFactory nodeFactory, + final Function valueSerializer) { + this.location = Optional.ofNullable(location); + this.path = path; + this.value = value; + this.nodeFactory = nodeFactory; + this.valueSerializer = valueSerializer; + } + + LeafNode( + final Bytes path, + final V value, + final NodeFactory nodeFactory, + final Function valueSerializer) { + this.location = Optional.empty(); + this.path = path; + this.value = value; + this.nodeFactory = nodeFactory; + this.valueSerializer = valueSerializer; + } + + @Override + public Node accept(final PathNodeVisitor visitor, final Bytes path) { + return visitor.visit(this, path); + } + + @Override + public void accept(final NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + public void accept(final Bytes location, final LocationNodeVisitor visitor) { + visitor.visit(location, this); + } + + @Override + public Optional getLocation() { + return location; + } + + @Override + public Bytes getPath() { + return path; + } + + @Override + public Optional getValue() { + return Optional.of(value); + } + + @Override + public List> getChildren() { + return Collections.emptyList(); + } + + @Override + public Bytes getRlp() { + if (rlp != null) { + final Bytes encoded = rlp.get(); + if (encoded != null) { + return encoded; + } + } + + final BytesValueRLPOutput out = new BytesValueRLPOutput(); + out.startList(); + out.writeBytes(CompactEncoding.encode(path)); + out.writeBytes(valueSerializer.apply(value)); + out.endList(); + final Bytes encoded = out.encoded(); + rlp = new WeakReference<>(encoded); + return encoded; + } + + @Override + public Bytes getRlpRef() { + if (isReferencedByHash()) { + return RLP.encodeOne(getHash()); + } else { + return getRlp(); + } + } + + @Override + public Bytes32 getHash() { + if (hash != null) { + final Bytes32 hashed = hash.get(); + if (hashed != null) { + return hashed; + } + } + final Bytes32 hashed = keccak256(getRlp()); + hash = new SoftReference<>(hashed); + return hashed; + } + + @Override + public Node replacePath(final Bytes path) { + return nodeFactory.createLeaf(path, value); + } + + @Override + public String print() { + return "Leaf:" + + "\n\tRef: " + + getRlpRef() + + "\n\tPath: " + + CompactEncoding.encode(path) + + "\n\tValue: " + + getValue().map(Object::toString).orElse("empty"); + } + + @Override + public boolean isDirty() { + return dirty; + } + + @Override + public void markDirty() { + dirty = true; + } + + @Override + public boolean isHealNeeded() { + return false; + } + + @Override + public void markHealNeeded() { + // nothing to do a leaf don't have child + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/LocationNodeVisitor.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/LocationNodeVisitor.java new file mode 100644 index 00000000000..2e1f934ea98 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/LocationNodeVisitor.java @@ -0,0 +1,28 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; + +interface LocationNodeVisitor { + + void visit(Bytes location, ExtensionNode extensionNode); + + void visit(Bytes location, BranchNode branchNode); + + void visit(Bytes location, LeafNode leafNode); + + void visit(Bytes location, NullNode nullNode); +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/MerklePatriciaTrie.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/MerklePatriciaTrie.java new file mode 100644 index 00000000000..17e593562bf --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/MerklePatriciaTrie.java @@ -0,0 +1,138 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.hyperledger.besu.ethereum.rlp.RLP; + +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.function.Consumer; +import java.util.function.Function; + +import static org.hyperledger.besu.crypto.Hash.keccak256; + +/** An Merkle Patricial Trie. */ +public interface MerklePatriciaTrie { + + Bytes EMPTY_TRIE_NODE = RLP.NULL; + Bytes32 EMPTY_TRIE_NODE_HASH = keccak256(EMPTY_TRIE_NODE); + + /** + * Returns an {@code Optional} of value mapped to the hash if it exists; otherwise empty. + * + * @param key The key for the value. + * @return an {@code Optional} of value mapped to the hash if it exists; otherwise empty + */ + Optional get(K key); + + /** + * Returns an {@code Optional} of value mapped to the given path if it exists; otherwise empty. + * + * @param path The path for the value. + * @return an {@code Optional} of value mapped to the given path if it exists; otherwise empty + */ + Optional getPath(final K path); + + /** + * Returns value and ordered proof-related nodes mapped to the hash if it exists; otherwise empty. + * + * @param key The key for the value. + * @return value and ordered proof-related nodes + */ + Proof getValueWithProof(K key); + + /** + * Updates the value mapped to the specified key, creating the mapping if one does not already + * exist. + * + * @param key The key that corresponds to the value to be updated. + * @param value The value to associate the key with. + */ + void put(K key, V value); + + /** + * Updates the value mapped to the specified key, creating the mapping if one does not already + * exist. + * + * @param key The key that corresponds to the value to be updated. + * @param putVisitor custom visitor for the update + */ + void put(K key, PutVisitor putVisitor); + + /** + * Deletes the value mapped to the specified key, if such a value exists (Optional operation). + * + * @param key The key of the value to be deleted. + */ + void remove(K key); + + /** + * Deletes the node mapped to the specified path, if such a node exists (Optional operation). + * + * @param path of the node to be deleted. + * @param removeVisitor custom visitor for the deletion + */ + void removePath(K path, RemoveVisitor removeVisitor); + + /** + * Returns the KECCAK256 hash of the root node of the trie. + * + * @return The KECCAK256 hash of the root node of the trie. + */ + Bytes32 getRootHash(); + + /** + * Commits any pending changes to the underlying storage. + * + * @param nodeUpdater used to store the node values + */ + void commit(NodeUpdater nodeUpdater); + + /** + * Commits any pending changes to the underlying storage. + * + * @param nodeUpdater used to store the node values + * @param commitVisitor custom visitor for the commit + */ + void commit(NodeUpdater nodeUpdater, CommitVisitor commitVisitor); + + /** + * Retrieve up to {@code limit} storage entries beginning from the first entry with hash equal to + * or greater than {@code startKeyHash}. + * + * @param startKeyHash the first key hash to return. + * @param limit the maximum number of entries to return. + * @return the requested storage entries as a map of key hash to value. + */ + Map entriesFrom(Bytes32 startKeyHash, int limit); + + /** + * Retrieve entries using a custom collector + * + * @param handler a custom trie collector. + * @return the requested storage entries as a map of key hash to value. + */ + Map entriesFrom(final Function, Map> handler); + + void visitAll(Consumer> nodeConsumer); + + CompletableFuture visitAll(Consumer> nodeConsumer, ExecutorService executorService); + + void visitLeafs(final TrieIterator.LeafHandler handler); +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/MerkleStorage.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/MerkleStorage.java new file mode 100644 index 00000000000..594f2802f55 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/MerkleStorage.java @@ -0,0 +1,52 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +import java.util.Optional; + +/** Storage for use in a {@link StoredMerklePatriciaTrie}. */ +public interface MerkleStorage { + + /** + * Returns an {@code Optional} of the content mapped to the hash if it exists; otherwise empty. + * + * @param location The location in the trie. + * @param hash The hash for the content. + * @return an {@code Optional} of the content mapped to the hash if it exists; otherwise empty + */ + Optional get(Bytes location, Bytes32 hash); + + /** + * Updates the content mapped to the specified hash, creating the mapping if one does not already + * exist. + * + *

Note: if the storage implementation already contains content for the given hash, it will + * replace the existing content. + * + * @param location The location in the trie. + * @param hash The hash for the content. + * @param content The content to store. + */ + void put(Bytes location, Bytes32 hash, Bytes content); + + /** Persist accumulated changes to underlying storage. */ + void commit(); + + /** Throws away any changes accumulated by this store. */ + void rollback(); +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/MerkleTrieException.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/MerkleTrieException.java new file mode 100644 index 00000000000..3ad6d766e2a --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/MerkleTrieException.java @@ -0,0 +1,50 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +/** + * This exception is thrown when there is an issue retrieving or decoding values from {@link + * MerkleStorage}. + */ +public class MerkleTrieException extends RuntimeException { + + private Bytes32 hash; + private Bytes location; + + public MerkleTrieException(final String message) { + super(message); + } + + public MerkleTrieException(final String message, final Bytes32 hash, final Bytes location) { + super(message); + this.hash = hash; + this.location = location; + } + + public MerkleTrieException(final String message, final Exception cause) { + super(message, cause); + } + + public Bytes32 getHash() { + return hash; + } + + public Bytes getLocation() { + return location; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/MissingNode.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/MissingNode.java new file mode 100644 index 00000000000..14c3cf2ff52 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/MissingNode.java @@ -0,0 +1,53 @@ +/* + * Copyright contributors to Hyperledger Besu + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +import java.util.Optional; + +public class MissingNode extends NullNode { + + private final Bytes32 hash; + private final Bytes location; + private final Bytes path; + + public MissingNode(final Bytes32 hash, final Bytes location) { + this.hash = hash; + this.location = location; + this.path = location.isEmpty() ? Bytes.EMPTY : location.slice(0, location.size() - 1); + } + + @Override + public Bytes32 getHash() { + return hash; + } + + @Override + public Bytes getPath() { + return path; + } + + @Override + public boolean isHealNeeded() { + return true; + } + + @Override + public Optional getLocation() { + return Optional.ofNullable(location); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/Node.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/Node.java new file mode 100644 index 00000000000..eba5e67b2b5 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/Node.java @@ -0,0 +1,86 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +import java.util.List; +import java.util.Optional; + +public interface Node { + + Node accept(PathNodeVisitor visitor, Bytes path); + + void accept(NodeVisitor visitor); + + void accept(Bytes location, LocationNodeVisitor visitor); + + Bytes getPath(); + + default Optional getLocation() { + return Optional.empty(); + } + + Optional getValue(); + + List> getChildren(); + + Bytes getRlp(); + + Bytes getRlpRef(); + + /** + * Whether a reference to this node should be represented as a hash of the rlp, or the node rlp + * itself should be inlined (the rlp stored directly in the parent node). If true, the node is + * referenced by hash. If false, the node is referenced by its rlp-encoded value. + * + * @return true if this node should be referenced by hash + */ + default boolean isReferencedByHash() { + return getRlp().size() >= 32; + } + + Bytes32 getHash(); + + Node replacePath(Bytes path); + + /** Marks the node as needing to be persisted */ + void markDirty(); + + /** + * Is this node not persisted and needs to be? + * + * @return True if the node needs to be persisted. + */ + boolean isDirty(); + + String print(); + + /** Unloads the node if it is, for example, a StoredNode. */ + default void unload() {} + + /** + * Return if a node needs heal. If one of its children missing in the storage + * + * @return true if the node need heal + */ + boolean isHealNeeded(); + + /** + * Marking a node as need heal means that one of its children is not yet present in the storage + */ + void markHealNeeded(); +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NodeFactory.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NodeFactory.java new file mode 100644 index 00000000000..dec2adc253d --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NodeFactory.java @@ -0,0 +1,31 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; + +import java.util.ArrayList; +import java.util.Optional; + +public interface NodeFactory { + + Node createExtension(Bytes path, Node child); + + Node createBranch(byte leftIndex, Node left, byte rightIndex, Node right); + + Node createBranch(ArrayList> newChildren, Optional value); + + Node createLeaf(Bytes path, V value); +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NodeLoader.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NodeLoader.java new file mode 100644 index 00000000000..57499dba74b --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NodeLoader.java @@ -0,0 +1,24 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +import java.util.Optional; + +public interface NodeLoader { + Optional getNode(Bytes location, Bytes32 hash); +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NodeUpdater.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NodeUpdater.java new file mode 100644 index 00000000000..1668645fd87 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NodeUpdater.java @@ -0,0 +1,22 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +public interface NodeUpdater { + void store(Bytes location, Bytes32 hash, Bytes value); +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NodeVisitor.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NodeVisitor.java new file mode 100644 index 00000000000..e8a771763c3 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NodeVisitor.java @@ -0,0 +1,26 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +interface NodeVisitor { + + void visit(ExtensionNode extensionNode); + + void visit(BranchNode branchNode); + + void visit(LeafNode leafNode); + + void visit(NullNode nullNode); +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NullNode.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NullNode.java new file mode 100644 index 00000000000..37933c67ac0 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/NullNode.java @@ -0,0 +1,109 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +public class NullNode implements Node { + @SuppressWarnings("rawtypes") + private static final NullNode instance = new NullNode(); + + protected NullNode() {} + + @SuppressWarnings("unchecked") + public static NullNode instance() { + return instance; + } + + @Override + public Node accept(final PathNodeVisitor visitor, final Bytes path) { + return visitor.visit(this, path); + } + + @Override + public void accept(final NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + public void accept(final Bytes location, final LocationNodeVisitor visitor) { + visitor.visit(location, this); + } + + @Override + public Bytes getPath() { + return Bytes.EMPTY; + } + + @Override + public Optional getValue() { + return Optional.empty(); + } + + @Override + public List> getChildren() { + return Collections.emptyList(); + } + + @Override + public Bytes getRlp() { + return MerklePatriciaTrie.EMPTY_TRIE_NODE; + } + + @Override + public Bytes getRlpRef() { + return MerklePatriciaTrie.EMPTY_TRIE_NODE; + } + + @Override + public Bytes32 getHash() { + return MerklePatriciaTrie.EMPTY_TRIE_NODE_HASH; + } + + @Override + public Node replacePath(final Bytes path) { + return this; + } + + @Override + public String print() { + return "[NULL]"; + } + + @Override + public boolean isDirty() { + return false; + } + + @Override + public void markDirty() { + // do nothing + } + + @Override + public boolean isHealNeeded() { + return false; + } + + @Override + public void markHealNeeded() { + // do nothing + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/PathNodeVisitor.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/PathNodeVisitor.java new file mode 100644 index 00000000000..424fca44799 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/PathNodeVisitor.java @@ -0,0 +1,28 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; + +interface PathNodeVisitor { + + Node visit(ExtensionNode extensionNode, Bytes path); + + Node visit(BranchNode branchNode, Bytes path); + + Node visit(LeafNode leafNode, Bytes path); + + Node visit(NullNode nullNode, Bytes path); +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/PersistVisitor.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/PersistVisitor.java new file mode 100644 index 00000000000..2d2f9d9b9aa --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/PersistVisitor.java @@ -0,0 +1,86 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +import java.util.function.BiConsumer; + +public class PersistVisitor implements NodeVisitor { + + private int branchNodeCount = 0; + private int extensionNodeCount = 0; + private int leafNodeCount = 0; + + private final BiConsumer writer; + + public PersistVisitor(final BiConsumer writer) { + this.writer = writer; + } + + public Node initialRoot() { + return NullNode.instance(); + } + + public void persist(final Node root) { + if (root instanceof BranchNode) { + visit((BranchNode) root); + } else if (root instanceof ExtensionNode) { + visit((ExtensionNode) root); + } else if (root instanceof LeafNode) { + visit((LeafNode) root); + } else if (root instanceof NullNode) { + visit((NullNode) root); + } + } + + @Override + public void visit(final BranchNode branchNode) { + writer.accept(branchNode.getHash(), branchNode.getRlp()); + branchNodeCount++; + branchNode.getChildren().forEach(node -> node.accept(this)); + } + + @Override + public void visit(final ExtensionNode extensionNode) { + writer.accept(extensionNode.getHash(), extensionNode.getRlp()); + extensionNodeCount++; + extensionNode.getChild().accept(this); + } + + @Override + public void visit(final LeafNode leafNode) { + writer.accept(leafNode.getHash(), leafNode.getRlp()); + leafNodeCount++; + } + + @Override + public void visit(final NullNode nullNode) {} + + public int getBranchNodeCount() { + return branchNodeCount; + } + + public int getExtensionNodeCount() { + return extensionNodeCount; + } + + public int getLeafNodeCount() { + return leafNodeCount; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/Proof.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/Proof.java new file mode 100644 index 00000000000..a891d536cc3 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/Proof.java @@ -0,0 +1,40 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; + +import java.util.List; +import java.util.Optional; + +public class Proof { + + private final Optional value; + + private final List proofRelatedNodes; + + public Proof(final Optional value, final List proofRelatedNodes) { + this.value = value; + this.proofRelatedNodes = proofRelatedNodes; + } + + public Optional getValue() { + return value; + } + + public List getProofRelatedNodes() { + return proofRelatedNodes; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/ProofVisitor.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/ProofVisitor.java new file mode 100644 index 00000000000..e0f24dcd0b9 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/ProofVisitor.java @@ -0,0 +1,63 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; + +import java.util.ArrayList; +import java.util.List; + +class ProofVisitor extends GetVisitor implements PathNodeVisitor { + + private final Node rootNode; + private final List> proof = new ArrayList<>(); + + ProofVisitor(final Node rootNode) { + this.rootNode = rootNode; + } + + @Override + public Node visit(final ExtensionNode extensionNode, final Bytes path) { + maybeTrackNode(extensionNode); + return super.visit(extensionNode, path); + } + + @Override + public Node visit(final BranchNode branchNode, final Bytes path) { + maybeTrackNode(branchNode); + return super.visit(branchNode, path); + } + + @Override + public Node visit(final LeafNode leafNode, final Bytes path) { + maybeTrackNode(leafNode); + return super.visit(leafNode, path); + } + + @Override + public Node visit(final NullNode nullNode, final Bytes path) { + return super.visit(nullNode, path); + } + + public List> getProof() { + return proof; + } + + private void maybeTrackNode(final Node node) { + if (node.equals(rootNode) || node.isReferencedByHash()) { + proof.add(node); + } + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/PutVisitor.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/PutVisitor.java new file mode 100644 index 00000000000..f157f5187a1 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/PutVisitor.java @@ -0,0 +1,107 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; + +public class PutVisitor implements PathNodeVisitor { + private final NodeFactory nodeFactory; + private final V value; + + public PutVisitor(final NodeFactory nodeFactory, final V value) { + this.nodeFactory = nodeFactory; + this.value = value; + } + + @Override + public Node visit(final ExtensionNode extensionNode, final Bytes path) { + final Bytes extensionPath = extensionNode.getPath(); + final int commonPathLength = extensionPath.commonPrefixLength(path); + assert commonPathLength < path.size() + : "Visiting path doesn't end with a non-matching terminator"; + + if (commonPathLength == extensionPath.size()) { + final Node newChild = extensionNode.getChild().accept(this, path.slice(commonPathLength)); + return extensionNode.replaceChild(newChild); + } + + // path diverges before the end of the extension - create a new branch + + final byte leafIndex = path.get(commonPathLength); + final Bytes leafPath = path.slice(commonPathLength + 1); + + final byte extensionIndex = extensionPath.get(commonPathLength); + final Node updatedExtension = + extensionNode.replacePath(extensionPath.slice(commonPathLength + 1)); + final Node leaf = nodeFactory.createLeaf(leafPath, value); + final Node branch = + nodeFactory.createBranch(leafIndex, leaf, extensionIndex, updatedExtension); + + if (commonPathLength > 0) { + return nodeFactory.createExtension(extensionPath.slice(0, commonPathLength), branch); + } else { + return branch; + } + } + + @Override + public Node visit(final BranchNode branchNode, final Bytes path) { + assert path.size() > 0 : "Visiting path doesn't end with a non-matching terminator"; + + final byte childIndex = path.get(0); + if (childIndex == CompactEncoding.LEAF_TERMINATOR) { + return branchNode.replaceValue(value); + } + + final Node updatedChild = branchNode.child(childIndex).accept(this, path.slice(1)); + return branchNode.replaceChild(childIndex, updatedChild); + } + + @Override + public Node visit(final LeafNode leafNode, final Bytes path) { + final Bytes leafPath = leafNode.getPath(); + final int commonPathLength = leafPath.commonPrefixLength(path); + + // Check if the current leaf node should be replaced + if (commonPathLength == leafPath.size() && commonPathLength == path.size()) { + return nodeFactory.createLeaf(leafPath, value); + } + + assert commonPathLength < leafPath.size() && commonPathLength < path.size() + : "Should not have consumed non-matching terminator"; + + // The current leaf path must be split to accommodate the new value. + + final byte newLeafIndex = path.get(commonPathLength); + final Bytes newLeafPath = path.slice(commonPathLength + 1); + + final byte updatedLeafIndex = leafPath.get(commonPathLength); + + final Node updatedLeaf = leafNode.replacePath(leafPath.slice(commonPathLength + 1)); + final Node leaf = nodeFactory.createLeaf(newLeafPath, value); + final Node branch = + nodeFactory.createBranch(updatedLeafIndex, updatedLeaf, newLeafIndex, leaf); + if (commonPathLength > 0) { + return nodeFactory.createExtension(leafPath.slice(0, commonPathLength), branch); + } else { + return branch; + } + } + + @Override + public Node visit(final NullNode nullNode, final Bytes path) { + return nodeFactory.createLeaf(path, value); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/RangeStorageEntriesCollector.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/RangeStorageEntriesCollector.java new file mode 100644 index 00000000000..7879decd848 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/RangeStorageEntriesCollector.java @@ -0,0 +1,87 @@ +/* + * Copyright contributors to Hyperledger Besu + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +import java.util.Map; +import java.util.Optional; + +public class RangeStorageEntriesCollector extends StorageEntriesCollector { + + private int currentSize = 0; + private final Optional endKeyHash; + private final Integer maxResponseBytes; + + public RangeStorageEntriesCollector( + final Bytes32 startKeyHash, + final Optional endKeyHash, + final int limit, + final int maxResponseBytes) { + super(startKeyHash, limit); + this.endKeyHash = endKeyHash; + this.maxResponseBytes = maxResponseBytes; + } + + public static RangeStorageEntriesCollector createCollector( + final Bytes32 startKeyHash, + final Bytes32 endKeyHash, + final int limit, + final int maxResponseBytes) { + return new RangeStorageEntriesCollector( + startKeyHash, Optional.ofNullable(endKeyHash), limit, maxResponseBytes); + } + + public static RangeStorageEntriesCollector createCollector( + final Bytes32 startKeyHash, final int limit, final int maxResponseBytes) { + return new RangeStorageEntriesCollector( + startKeyHash, Optional.empty(), limit, maxResponseBytes); + } + + public static TrieIterator createVisitor(final RangeStorageEntriesCollector collector) { + return new TrieIterator<>(collector, false); + } + + public static Map collectEntries( + final RangeStorageEntriesCollector collector, + final TrieIterator visitor, + final Node root, + final Bytes32 startKeyHash) { + root.accept(visitor, CompactEncoding.bytesToPath(startKeyHash)); + return collector.getValues(); + } + + @Override + public TrieIterator.State onLeaf(final Bytes32 keyHash, final Node node) { + if (keyHash.compareTo(startKeyHash) >= 0) { + if (node.getValue().isPresent()) { + final Bytes value = node.getValue().get(); + currentSize += Bytes32.SIZE + value.size(); + if (currentSize > maxResponseBytes) { + return TrieIterator.State.STOP; + } + if (endKeyHash.isPresent() + && !values.isEmpty() + && keyHash.compareTo(endKeyHash.get()) > 0) { + return TrieIterator.State.STOP; + } + + values.put(keyHash, value); + } + } + return limitReached() ? TrieIterator.State.STOP : TrieIterator.State.CONTINUE; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/RemoveVisitor.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/RemoveVisitor.java new file mode 100644 index 00000000000..1e55056767b --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/RemoveVisitor.java @@ -0,0 +1,73 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; + +public class RemoveVisitor implements PathNodeVisitor { + private final Node NULL_NODE_RESULT = NullNode.instance(); + + private final boolean allowFlatten; + + public RemoveVisitor() { + allowFlatten = true; + } + + public RemoveVisitor(final boolean allowFlatten) { + this.allowFlatten = allowFlatten; + } + + @Override + public Node visit(final ExtensionNode extensionNode, final Bytes path) { + final Bytes extensionPath = extensionNode.getPath(); + final int commonPathLength = extensionPath.commonPrefixLength(path); + assert commonPathLength < path.size() + : "Visiting path doesn't end with a non-matching terminator"; + + if (commonPathLength == extensionPath.size()) { + final Node newChild = extensionNode.getChild().accept(this, path.slice(commonPathLength)); + return extensionNode.replaceChild(newChild); + } + + // path diverges before the end of the extension, so it cannot match + + return extensionNode; + } + + @Override + public Node visit(final BranchNode branchNode, final Bytes path) { + assert path.size() > 0 : "Visiting path doesn't end with a non-matching terminator"; + + final byte childIndex = path.get(0); + if (childIndex == CompactEncoding.LEAF_TERMINATOR) { + return branchNode.removeValue(); + } + + final Node updatedChild = branchNode.child(childIndex).accept(this, path.slice(1)); + return branchNode.replaceChild(childIndex, updatedChild, allowFlatten); + } + + @Override + public Node visit(final LeafNode leafNode, final Bytes path) { + final Bytes leafPath = leafNode.getPath(); + final int commonPathLength = leafPath.commonPrefixLength(path); + return (commonPathLength == leafPath.size()) ? NULL_NODE_RESULT : leafNode; + } + + @Override + public Node visit(final NullNode nullNode, final Bytes path) { + return NULL_NODE_RESULT; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/RestoreVisitor.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/RestoreVisitor.java new file mode 100644 index 00000000000..7ffef43261a --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/RestoreVisitor.java @@ -0,0 +1,246 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; + +public class RestoreVisitor implements PathNodeVisitor { + + private final NodeFactory nodeFactory; + private final V value; + private final NodeVisitor persistVisitor; + + public RestoreVisitor( + final Function valueSerializer, + final V value, + final NodeVisitor persistVisitor) { + this.nodeFactory = new DefaultNodeFactory<>(valueSerializer); + this.value = value; + this.persistVisitor = persistVisitor; + } + + @Override + public Node visit(final ExtensionNode extensionNode, final Bytes path) { + final Bytes extensionPath = extensionNode.getPath(); + + final int commonPathLength = extensionPath.commonPrefixLength(path); + assert commonPathLength < path.size() + : "Visiting path doesn't end with a non-matching terminator"; + + if (commonPathLength == extensionPath.size()) { + final Node newChild = extensionNode.getChild().accept(this, path.slice(commonPathLength)); + return extensionNode.replaceChild(newChild); + } + + // path diverges before the end of the extension - create a new branch + + final byte leafIndex = path.get(commonPathLength); + final Bytes leafPath = path.slice(commonPathLength + 1); + + final byte extensionIndex = extensionPath.get(commonPathLength); + final Node updatedExtension = + extensionNode.replacePath(extensionPath.slice(commonPathLength + 1)); + final Node leaf = nodeFactory.createLeaf(leafPath, value); + final Node branch = + nodeFactory.createBranch(leafIndex, leaf, extensionIndex, updatedExtension); + + if (commonPathLength > 0) { + return nodeFactory.createExtension(extensionPath.slice(0, commonPathLength), branch); + } else { + return branch; + } + } + + @Override + public Node visit(final BranchNode branchNode, final Bytes path) { + assert path.size() > 0 : "Visiting path doesn't end with a non-matching terminator"; + BranchNode workingNode = branchNode; + + final byte childIndex = path.get(0); + if (childIndex == CompactEncoding.LEAF_TERMINATOR) { + return workingNode.replaceValue(value); + } + + for (byte i = 0; i < childIndex; i++) { + workingNode = persistNode(workingNode, i); + } + + final Node updatedChild = workingNode.child(childIndex).accept(this, path.slice(1)); + return workingNode.replaceChild(childIndex, updatedChild); + } + + private BranchNode persistNode(final BranchNode parent, final byte index) { + final Node child = parent.getChildren().get(index); + if (!(child instanceof StoredNode)) { + child.accept(persistVisitor); + final PersistedNode persistedNode = + new PersistedNode<>(null, child.getHash(), child.getRlpRef()); + return (BranchNode) parent.replaceChild(index, persistedNode); + } else { + return parent; + } + } + + @Override + public Node visit(final LeafNode leafNode, final Bytes path) { + final Bytes leafPath = leafNode.getPath(); + final int commonPathLength = leafPath.commonPrefixLength(path); + + // Check if the current leaf node should be replaced + if (commonPathLength == leafPath.size() && commonPathLength == path.size()) { + return nodeFactory.createLeaf(leafPath, value); + } + + assert commonPathLength < leafPath.size() && commonPathLength < path.size() + : "Should not have consumed non-matching terminator"; + + // The current leaf path must be split to accommodate the new value. + + final byte newLeafIndex = path.get(commonPathLength); + final Bytes newLeafPath = path.slice(commonPathLength + 1); + + final byte updatedLeafIndex = leafPath.get(commonPathLength); + + final Node updatedLeaf = leafNode.replacePath(leafPath.slice(commonPathLength + 1)); + final Node leaf = nodeFactory.createLeaf(newLeafPath, value); + final Node branch = + nodeFactory.createBranch(updatedLeafIndex, updatedLeaf, newLeafIndex, leaf); + if (commonPathLength > 0) { + return nodeFactory.createExtension(leafPath.slice(0, commonPathLength), branch); + } else { + return branch; + } + } + + @Override + public Node visit(final NullNode nullNode, final Bytes path) { + return nodeFactory.createLeaf(path, value); + } + + static class PersistedNode implements Node { + private final Bytes path; + private final Bytes32 hash; + private final Bytes refRlp; + + PersistedNode(final Bytes path, final Bytes32 hash, final Bytes refRlp) { + this.path = path; + this.hash = hash; + this.refRlp = refRlp; + } + + /** + * @return True if the node needs to be persisted. + */ + @Override + public boolean isDirty() { + return false; + } + + /** Marks the node as being modified (needs to be persisted); */ + @Override + public void markDirty() { + throw new UnsupportedOperationException( + "A persisted node cannot ever be dirty since it's loaded from storage"); + } + + @Override + public boolean isHealNeeded() { + return false; + } + + @Override + public void markHealNeeded() { + throw new UnsupportedOperationException( + "A persisted node cannot be healed since it's loaded from storage"); + } + + @Override + public Node accept(final PathNodeVisitor visitor, final Bytes path) { + // do nothing + return this; + } + + @Override + public void accept(final NodeVisitor visitor) { + // do nothing + } + + @Override + public void accept(final Bytes location, final LocationNodeVisitor visitor) { + // do nothing + } + + @Override + public Bytes getPath() { + return path; + } + + @Override + public Optional getValue() { + throw new UnsupportedOperationException( + "A persisted node cannot have a value, as it's already been restored."); + } + + @Override + public List> getChildren() { + return Collections.emptyList(); + } + + @Override + public Bytes getRlp() { + throw new UnsupportedOperationException( + "A persisted node cannot have rlp, as it's already been restored."); + } + + @Override + public Bytes getRlpRef() { + return refRlp; + } + + @Override + public boolean isReferencedByHash() { + // Persisted nodes represent only nodes that are referenced by hash + return true; + } + + @Override + public Bytes32 getHash() { + return hash; + } + + @Override + public Node replacePath(final Bytes path) { + throw new UnsupportedOperationException( + "A persisted node cannot be replaced, as it's already been restored."); + } + + @Override + public void unload() { + throw new UnsupportedOperationException( + "A persisted node cannot be unloaded, as it's already been restored."); + } + + @Override + public String print() { + return "PersistedNode:" + "\n\tPath: " + getPath() + "\n\tHash: " + getHash(); + } + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/SimpleMerklePatriciaTrie.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/SimpleMerklePatriciaTrie.java new file mode 100644 index 00000000000..75d6bb9bc80 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/SimpleMerklePatriciaTrie.java @@ -0,0 +1,162 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.hyperledger.besu.ethereum.trie.CompactEncoding.bytesToPath; + +/** + * An in-memory {@link MerklePatriciaTrie}. + * + * @param The type of values stored by this trie. + */ +public class SimpleMerklePatriciaTrie implements MerklePatriciaTrie { + private final PathNodeVisitor getVisitor = new GetVisitor<>(); + private final PathNodeVisitor removeVisitor = new RemoveVisitor<>(); + private final DefaultNodeFactory nodeFactory; + + private Node root; + + /** + * Create a trie. + * + * @param valueSerializer A function for serializing values to bytes. + */ + public SimpleMerklePatriciaTrie(final Function valueSerializer) { + this.nodeFactory = new DefaultNodeFactory<>(valueSerializer); + this.root = NullNode.instance(); + } + + @Override + public Optional get(final K key) { + checkNotNull(key); + return root.accept(getVisitor, bytesToPath(key)).getValue(); + } + + @Override + public Optional getPath(final K path) { + checkNotNull(path); + return root.accept(getVisitor, path).getValue(); + } + + @Override + public Proof getValueWithProof(final K key) { + checkNotNull(key); + final ProofVisitor proofVisitor = new ProofVisitor<>(root); + final Optional value = root.accept(proofVisitor, bytesToPath(key)).getValue(); + final List proof = + proofVisitor.getProof().stream().map(Node::getRlp).collect(Collectors.toList()); + return new Proof<>(value, proof); + } + + @Override + public void put(final K key, final V value) { + checkNotNull(key); + checkNotNull(value); + this.root = root.accept(new PutVisitor<>(nodeFactory, value), bytesToPath(key)); + } + + @Override + public void put(final K key, final PutVisitor putVisitor) { + checkNotNull(key); + this.root = root.accept(putVisitor, bytesToPath(key)); + } + + @Override + public void remove(final K key) { + checkNotNull(key); + this.root = root.accept(removeVisitor, bytesToPath(key)); + } + + @Override + public void removePath(final K path, final RemoveVisitor removeVisitor) { + checkNotNull(path); + this.root = root.accept(removeVisitor, path); + } + + @Override + public Bytes32 getRootHash() { + return root.getHash(); + } + + @Override + public String toString() { + return getClass().getSimpleName() + "[" + getRootHash() + "]"; + } + + @Override + public void commit(final NodeUpdater nodeUpdater) { + // Nothing to do here + } + + @Override + public void commit(final NodeUpdater nodeUpdater, final CommitVisitor commitVisitor) { + // Nothing to do here + } + + @Override + public Map entriesFrom(final Bytes32 startKeyHash, final int limit) { + return StorageEntriesCollector.collectEntries(root, startKeyHash, limit); + } + + @Override + public Map entriesFrom(final Function, Map> handler) { + return handler.apply(root); + } + + @Override + public void visitAll(final Consumer> nodeConsumer) { + root.accept(new AllNodesVisitor<>(nodeConsumer)); + } + + @Override + public CompletableFuture visitAll( + final Consumer> nodeConsumer, final ExecutorService executorService) { + return CompletableFuture.allOf( + Stream.concat( + Stream.of( + CompletableFuture.runAsync(() -> nodeConsumer.accept(root), executorService)), + root.getChildren().stream() + .map( + rootChild -> + CompletableFuture.runAsync( + () -> rootChild.accept(new AllNodesVisitor<>(nodeConsumer)), + executorService))) + .collect(Collectors.collectingAndThen( + Collectors.toSet(), + Collections::unmodifiableSet + )).toArray(new CompletableFuture[0])); + } + + @Override + public void visitLeafs(final TrieIterator.LeafHandler handler) { + final TrieIterator visitor = new TrieIterator<>(handler, true); + root.accept(visitor, CompactEncoding.bytesToPath(Bytes32.ZERO)); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/SnapPutVisitor.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/SnapPutVisitor.java new file mode 100644 index 00000000000..72dc7430154 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/SnapPutVisitor.java @@ -0,0 +1,48 @@ +/* + * Copyright contributors to Hyperledger Besu + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; + +public class SnapPutVisitor extends PutVisitor { + + public SnapPutVisitor(final NodeFactory nodeFactory, final V value) { + super(nodeFactory, value); + } + + @Override + public Node visit(final BranchNode branchNode, final Bytes path) { + final Node visit = super.visit(branchNode, path); + for (Node child : visit.getChildren()) { + if (child.isHealNeeded() || (child instanceof StoredNode && !child.getValue().isPresent())) { + visit.markHealNeeded(); // not save an incomplete node + return visit; + } + } + return visit; + } + + @Override + public Node visit(final ExtensionNode extensionNode, final Bytes path) { + final Node visit = super.visit(extensionNode, path); + for (Node child : visit.getChildren()) { + if (child.isHealNeeded() || (child instanceof StoredNode && !child.getValue().isPresent())) { + visit.markHealNeeded(); // not save an incomplete node + return visit; + } + } + return visit; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StorageEntriesCollector.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StorageEntriesCollector.java new file mode 100644 index 00000000000..bb0e9aadfae --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StorageEntriesCollector.java @@ -0,0 +1,57 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes32; + +import java.util.Map; +import java.util.TreeMap; + +public class StorageEntriesCollector implements TrieIterator.LeafHandler { + + protected final Bytes32 startKeyHash; + protected final int limit; + protected final Map values = new TreeMap<>(); + + public StorageEntriesCollector(final Bytes32 startKeyHash, final int limit) { + this.startKeyHash = startKeyHash; + this.limit = limit; + } + + public static Map collectEntries( + final Node root, final Bytes32 startKeyHash, final int limit) { + final StorageEntriesCollector entriesCollector = + new StorageEntriesCollector<>(startKeyHash, limit); + final TrieIterator visitor = new TrieIterator<>(entriesCollector, false); + root.accept(visitor, CompactEncoding.bytesToPath(startKeyHash)); + return entriesCollector.getValues(); + } + + protected boolean limitReached() { + return limit <= values.size(); + } + + @Override + public TrieIterator.State onLeaf(final Bytes32 keyHash, final Node node) { + if (keyHash.compareTo(startKeyHash) >= 0) { + node.getValue().ifPresent(value -> values.put(keyHash, value)); + } + return limitReached() ? TrieIterator.State.STOP : TrieIterator.State.CONTINUE; + } + + public Map getValues() { + return values; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StoredMerklePatriciaTrie.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StoredMerklePatriciaTrie.java new file mode 100644 index 00000000000..25d150e13b1 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StoredMerklePatriciaTrie.java @@ -0,0 +1,240 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.hyperledger.besu.ethereum.trie.CompactEncoding.bytesToPath; + +/** + * A {@link MerklePatriciaTrie} that persists trie nodes to a {@link MerkleStorage} key/value store. + * + * @param The type of values stored by this trie. + */ +public class StoredMerklePatriciaTrie implements MerklePatriciaTrie { + + private final GetVisitor getVisitor = new GetVisitor<>(); + private final RemoveVisitor removeVisitor = new RemoveVisitor<>(); + private final StoredNodeFactory nodeFactory; + + private Node root; + + /** + * Create a trie. + * + * @param nodeLoader The {@link NodeLoader} to retrieve node data from. + * @param valueSerializer A function for serializing values to bytes. + * @param valueDeserializer A function for deserializing values from bytes. + */ + public StoredMerklePatriciaTrie( + final NodeLoader nodeLoader, + final Function valueSerializer, + final Function valueDeserializer) { + this(nodeLoader, EMPTY_TRIE_NODE_HASH, valueSerializer, valueDeserializer); + } + + /** + * Create a trie. + * + * @param nodeLoader The {@link NodeLoader} to retrieve node data from. + * @param rootHash The initial root has for the trie, which should be already present in {@code + * storage}. + * @param rootLocation The initial root location for the trie + * @param valueSerializer A function for serializing values to bytes. + * @param valueDeserializer A function for deserializing values from bytes. + */ + public StoredMerklePatriciaTrie( + final NodeLoader nodeLoader, + final Bytes32 rootHash, + final Bytes rootLocation, + final Function valueSerializer, + final Function valueDeserializer) { + this.nodeFactory = new StoredNodeFactory<>(nodeLoader, valueSerializer, valueDeserializer); + this.root = + rootHash.equals(EMPTY_TRIE_NODE_HASH) + ? NullNode.instance() + : new StoredNode<>(nodeFactory, rootLocation, rootHash); + } + + /** + * Create a trie. + * + * @param nodeLoader The {@link NodeLoader} to retrieve node data from. + * @param rootHash The initial root has for the trie, which should be already present in {@code + * storage}. + * @param valueSerializer A function for serializing values to bytes. + * @param valueDeserializer A function for deserializing values from bytes. + */ + public StoredMerklePatriciaTrie( + final NodeLoader nodeLoader, + final Bytes32 rootHash, + final Function valueSerializer, + final Function valueDeserializer) { + this(nodeLoader, rootHash, Bytes.EMPTY, valueSerializer, valueDeserializer); + } + + /** + * Create a trie. + * + * @param nodeFactory The {@link StoredNodeFactory} to retrieve node. + * @param rootHash The initial root hash for the trie, which should be already present in {@code + * storage}. + */ + public StoredMerklePatriciaTrie(final StoredNodeFactory nodeFactory, final Bytes32 rootHash) { + this.nodeFactory = nodeFactory; + this.root = + rootHash.equals(EMPTY_TRIE_NODE_HASH) + ? NullNode.instance() + : new StoredNode<>(nodeFactory, Bytes.EMPTY, rootHash); + } + + @Override + public Optional get(final K key) { + checkNotNull(key); + return root.accept(getVisitor, bytesToPath(key)).getValue(); + } + + @Override + public Optional getPath(final K path) { + checkNotNull(path); + return root.accept(getVisitor, path).getValue(); + } + + @Override + public Proof getValueWithProof(final K key) { + checkNotNull(key); + final ProofVisitor proofVisitor = new ProofVisitor<>(root); + final Optional value = root.accept(proofVisitor, bytesToPath(key)).getValue(); + final List proof = + proofVisitor.getProof().stream().map(Node::getRlp).collect(Collectors.toList()); + return new Proof<>(value, proof); + } + + @Override + public void put(final K key, final V value) { + checkNotNull(key); + checkNotNull(value); + this.root = root.accept(new PutVisitor<>(nodeFactory, value), bytesToPath(key)); + } + + @Override + public void put(final K key, final PutVisitor putVisitor) { + checkNotNull(key); + this.root = root.accept(putVisitor, bytesToPath(key)); + } + + @Override + public void remove(final K key) { + checkNotNull(key); + this.root = root.accept(removeVisitor, bytesToPath(key)); + } + + @Override + public void removePath(final K path, final RemoveVisitor removeVisitor) { + checkNotNull(path); + this.root = root.accept(removeVisitor, path); + } + + @Override + public void commit(final NodeUpdater nodeUpdater) { + commit(nodeUpdater, new CommitVisitor<>(nodeUpdater)); + } + + @Override + public void commit(final NodeUpdater nodeUpdater, final CommitVisitor commitVisitor) { + root.accept(Bytes.EMPTY, commitVisitor); + // Make sure root node was stored + if (root.isDirty() && root.getRlpRef().size() < 32) { + nodeUpdater.store(Bytes.EMPTY, root.getHash(), root.getRlpRef()); + } + // Reset root so dirty nodes can be garbage collected + final Bytes32 rootHash = root.getHash(); + this.root = + rootHash.equals(EMPTY_TRIE_NODE_HASH) + ? NullNode.instance() + : new StoredNode<>(nodeFactory, Bytes.EMPTY, rootHash); + } + + public void acceptAtRoot(final NodeVisitor visitor) { + root.accept(visitor); + } + + public void acceptAtRoot(final PathNodeVisitor visitor, final Bytes path) { + root.accept(visitor, path); + } + + @Override + public Map entriesFrom(final Bytes32 startKeyHash, final int limit) { + return StorageEntriesCollector.collectEntries(root, startKeyHash, limit); + } + + @Override + public Map entriesFrom(final Function, Map> handler) { + return handler.apply(root); + } + + @Override + public void visitAll(final Consumer> nodeConsumer) { + root.accept(new AllNodesVisitor<>(nodeConsumer)); + } + + @Override + public CompletableFuture visitAll( + final Consumer> nodeConsumer, final ExecutorService executorService) { + return CompletableFuture.allOf( + Stream.concat( + Stream.of( + CompletableFuture.runAsync(() -> nodeConsumer.accept(root), executorService)), + root.getChildren().stream() + .map( + rootChild -> + CompletableFuture.runAsync( + () -> rootChild.accept(new AllNodesVisitor<>(nodeConsumer)), + executorService))) + .collect(Collectors.collectingAndThen( + Collectors.toSet(), + Collections::unmodifiableSet + )).toArray(new CompletableFuture[0])); + } + + @Override + public void visitLeafs(final TrieIterator.LeafHandler handler) { + final TrieIterator visitor = new TrieIterator<>(handler, true); + root.accept(visitor, CompactEncoding.bytesToPath(Bytes32.ZERO)); + } + + @Override + public Bytes32 getRootHash() { + return root.getHash(); + } + + @Override + public String toString() { + return getClass().getSimpleName() + "[" + getRootHash() + "]"; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StoredNode.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StoredNode.java new file mode 100644 index 00000000000..c80239ce1cc --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StoredNode.java @@ -0,0 +1,159 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.hyperledger.besu.ethereum.rlp.RLP; + +import java.util.List; +import java.util.Optional; + +public class StoredNode implements Node { + private final StoredNodeFactory nodeFactory; + private final Bytes location; + private final Bytes32 hash; + private Node loaded; + + StoredNode(final StoredNodeFactory nodeFactory, final Bytes location, final Bytes32 hash) { + this.nodeFactory = nodeFactory; + this.location = location; + this.hash = hash; + } + + /** + * @return True if the node needs to be persisted. + */ + @Override + public boolean isDirty() { + return false; + } + + /** Marks the node as being modified (needs to be persisted); */ + @Override + public void markDirty() { + throw new IllegalStateException( + "A stored node cannot ever be dirty since it's loaded from storage"); + } + + @Override + public boolean isHealNeeded() { + return false; + } + + @Override + public void markHealNeeded() { + throw new IllegalStateException( + "A stored node cannot be healed since it's loaded from storage"); + } + + @Override + public Node accept(final PathNodeVisitor visitor, final Bytes path) { + final Node node = load(); + return node.accept(visitor, path); + } + + @Override + public void accept(final NodeVisitor visitor) { + final Node node = load(); + node.accept(visitor); + } + + @Override + public void accept(final Bytes location, final LocationNodeVisitor visitor) { + final Node node = load(); + node.accept(location, visitor); + } + + @Override + public Bytes getPath() { + return load().getPath(); + } + + @Override + public Optional getLocation() { + return Optional.ofNullable(location); + } + + @Override + public Optional getValue() { + return load().getValue(); + } + + @Override + public List> getChildren() { + return load().getChildren(); + } + + @Override + public Bytes getRlp() { + return load().getRlp(); + } + + @Override + public Bytes getRlpRef() { + // If this node was stored, then it must have a rlp larger than a hash + return RLP.encodeOne(hash); + } + + @Override + public boolean isReferencedByHash() { + // Stored nodes represent only nodes that are referenced by hash + return true; + } + + @Override + public Bytes32 getHash() { + return hash; + } + + @Override + public Node replacePath(final Bytes path) { + return load().replacePath(path); + } + + private Node load() { + if (loaded == null) { + loaded = + nodeFactory + .retrieve(location, hash) + .orElseThrow( + () -> + new MerkleTrieException( + "Unable to load trie node value for hash " + + hash + + " location " + + location, + hash, + location)); + } + + return loaded; + } + + @Override + public void unload() { + loaded = null; + } + + @Override + public String print() { + if (loaded == null) { + return "StoredNode:" + "\n\tRef: " + getRlpRef(); + } else { + return load().print(); + } + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StoredNodeFactory.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StoredNodeFactory.java new file mode 100644 index 00000000000..a440498fd7b --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StoredNodeFactory.java @@ -0,0 +1,256 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.hyperledger.besu.ethereum.rlp.RLP; +import org.hyperledger.besu.ethereum.rlp.RLPException; +import org.hyperledger.besu.ethereum.rlp.RLPInput; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Supplier; + +import static java.lang.String.format; + +public class StoredNodeFactory implements NodeFactory { + @SuppressWarnings("rawtypes") + private static final NullNode NULL_NODE = NullNode.instance(); + + private final NodeLoader nodeLoader; + private final Function valueSerializer; + private final Function valueDeserializer; + + public StoredNodeFactory( + final NodeLoader nodeLoader, + final Function valueSerializer, + final Function valueDeserializer) { + this.nodeLoader = nodeLoader; + this.valueSerializer = valueSerializer; + this.valueDeserializer = valueDeserializer; + } + + @Override + public Node createExtension(final Bytes path, final Node child) { + return handleNewNode(new ExtensionNode<>(path, child, this)); + } + + @SuppressWarnings("unchecked") + @Override + public Node createBranch( + final byte leftIndex, final Node left, final byte rightIndex, final Node right) { + assert (leftIndex <= BranchNode.RADIX); + assert (rightIndex <= BranchNode.RADIX); + assert (leftIndex != rightIndex); + + final ArrayList> children = + new ArrayList<>(Collections.nCopies(BranchNode.RADIX, (Node) NULL_NODE)); + + if (leftIndex == BranchNode.RADIX) { + children.set(rightIndex, right); + return createBranch(children, left.getValue()); + } else if (rightIndex == BranchNode.RADIX) { + children.set(leftIndex, left); + return createBranch(children, right.getValue()); + } else { + children.set(leftIndex, left); + children.set(rightIndex, right); + return createBranch(children, Optional.empty()); + } + } + + @Override + public Node createBranch(final ArrayList> children, final Optional value) { + return handleNewNode(new BranchNode<>(children, value, this, valueSerializer)); + } + + @Override + public Node createLeaf(final Bytes path, final V value) { + return handleNewNode(new LeafNode<>(path, value, this, valueSerializer)); + } + + private Node handleNewNode(final Node node) { + node.markDirty(); + return node; + } + + public Optional> retrieve(final Bytes location, final Bytes32 hash) + throws MerkleTrieException { + return nodeLoader + .getNode(location, hash) + .map( + rlp -> { + final Node node = + decode(location, rlp, () -> format("Invalid RLP value for hash %s", hash)); + // recalculating the node.hash() is expensive, so we only do this as an assertion + assert (hash.equals(node.getHash())) + : "Node hash " + node.getHash() + " not equal to expected " + hash; + return node; + }); + } + + public Node decode(final Bytes location, final Bytes rlp) { + return decode(location, rlp, () -> String.format("Failed to decode value %s", rlp.toString())); + } + + private Node decode(final Bytes location, final Bytes rlp, final Supplier errMessage) + throws MerkleTrieException { + try { + return decode(location, RLP.input(rlp), errMessage); + } catch (final RLPException ex) { + throw new MerkleTrieException(errMessage.get(), ex); + } + } + + private Node decode( + final Bytes location, final RLPInput nodeRLPs, final Supplier errMessage) { + final int nodesCount = nodeRLPs.enterList(); + switch (nodesCount) { + case 1: + final NullNode nullNode = decodeNull(nodeRLPs, errMessage); + nodeRLPs.leaveList(); + return nullNode; + + case 2: + final Bytes encodedPath = nodeRLPs.readBytes(); + final Bytes path; + try { + path = CompactEncoding.decode(encodedPath); + } catch (final IllegalArgumentException ex) { + throw new MerkleTrieException(errMessage.get() + ": invalid path " + encodedPath, ex); + } + + final int size = path.size(); + if (size > 0 && path.get(size - 1) == CompactEncoding.LEAF_TERMINATOR) { + final LeafNode leafNode = decodeLeaf(location, path, nodeRLPs, errMessage); + nodeRLPs.leaveList(); + return leafNode; + } else { + final Node extensionNode = decodeExtension(location, path, nodeRLPs, errMessage); + nodeRLPs.leaveList(); + return extensionNode; + } + + case (BranchNode.RADIX + 1): + final BranchNode branchNode = decodeBranch(location, nodeRLPs, errMessage); + nodeRLPs.leaveList(); + return branchNode; + + default: + throw new MerkleTrieException( + errMessage.get() + format(": invalid list size %s", nodesCount)); + } + } + + protected Node decodeExtension( + final Bytes location, + final Bytes path, + final RLPInput valueRlp, + final Supplier errMessage) { + final RLPInput childRlp = valueRlp.readAsRlp(); + if (childRlp.nextIsList()) { + final Node childNode = + decode(location == null ? null : Bytes.concatenate(location, path), childRlp, errMessage); + return new ExtensionNode<>(location, path, childNode, this); + } else { + final Bytes32 childHash = childRlp.readBytes32(); + final StoredNode childNode = + new StoredNode<>( + this, location == null ? null : Bytes.concatenate(location, path), childHash); + return new ExtensionNode<>(location, path, childNode, this); + } + } + + @SuppressWarnings("unchecked") + protected BranchNode decodeBranch( + final Bytes location, final RLPInput nodeRLPs, final Supplier errMessage) { + final ArrayList> children = new ArrayList<>(BranchNode.RADIX); + for (int i = 0; i < BranchNode.RADIX; ++i) { + if (nodeRLPs.nextIsNull()) { + nodeRLPs.skipNext(); + children.add(NULL_NODE); + } else if (nodeRLPs.nextIsList()) { + final Node child = + decode( + location == null ? null : Bytes.concatenate(location, Bytes.of((byte) i)), + nodeRLPs, + errMessage); + children.add(child); + } else { + final Bytes32 childHash = nodeRLPs.readBytes32(); + children.add( + new StoredNode<>( + this, + location == null ? null : Bytes.concatenate(location, Bytes.of((byte) i)), + childHash)); + } + } + + final Optional value; + if (nodeRLPs.nextIsNull()) { + nodeRLPs.skipNext(); + value = Optional.empty(); + } else { + value = Optional.of(decodeValue(nodeRLPs, errMessage)); + } + + return new BranchNode<>(location, children, value, this, valueSerializer); + } + + protected LeafNode decodeLeaf( + final Bytes location, + final Bytes path, + final RLPInput valueRlp, + final Supplier errMessage) { + if (valueRlp.nextIsNull()) { + throw new MerkleTrieException(errMessage.get() + ": leaf has null value"); + } + final V value = decodeValue(valueRlp, errMessage); + return new LeafNode<>(location, path, value, this, valueSerializer); + } + + @SuppressWarnings("unchecked") + private NullNode decodeNull(final RLPInput nodeRLPs, final Supplier errMessage) { + if (!nodeRLPs.nextIsNull()) { + throw new MerkleTrieException(errMessage.get() + ": list size 1 but not null"); + } + nodeRLPs.skipNext(); + return NULL_NODE; + } + + private V decodeValue(final RLPInput valueRlp, final Supplier errMessage) { + final Bytes bytes; + try { + bytes = valueRlp.readBytes(); + } catch (final RLPException ex) { + throw new MerkleTrieException( + errMessage.get() + ": failed decoding value rlp " + valueRlp, ex); + } + return deserializeValue(errMessage, bytes); + } + + private V deserializeValue(final Supplier errMessage, final Bytes bytes) { + final V value; + try { + value = valueDeserializer.apply(bytes); + } catch (final IllegalArgumentException ex) { + throw new MerkleTrieException(errMessage.get() + ": failed deserializing value " + bytes, ex); + } + return value; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/TrieIterator.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/TrieIterator.java new file mode 100644 index 00000000000..6782075ad58 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/TrieIterator.java @@ -0,0 +1,125 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.Iterator; + +public class TrieIterator implements PathNodeVisitor { + + private final Deque paths = new ArrayDeque<>(); + private final LeafHandler leafHandler; + private State state = State.SEARCHING; + private final boolean unload; + + public TrieIterator(final LeafHandler leafHandler, final boolean unload) { + this.leafHandler = leafHandler; + this.unload = unload; + } + + @Override + public Node visit(final ExtensionNode node, final Bytes searchPath) { + Bytes remainingPath = searchPath; + if (state == State.SEARCHING) { + final Bytes extensionPath = node.getPath(); + final int commonPathLength = extensionPath.commonPrefixLength(searchPath); + remainingPath = searchPath.slice(commonPathLength); + } + + paths.push(node.getPath()); + node.getChild().accept(this, remainingPath); + if (unload) { + node.getChild().unload(); + } + paths.pop(); + return node; + } + + @Override + public Node visit(final BranchNode node, final Bytes searchPath) { + byte iterateFrom = 0; + Bytes remainingPath = searchPath; + if (state == State.SEARCHING) { + iterateFrom = searchPath.get(0); + if (iterateFrom == CompactEncoding.LEAF_TERMINATOR) { + return node; + } + remainingPath = searchPath.slice(1); + } + paths.push(node.getPath()); + for (byte i = iterateFrom; i < BranchNode.RADIX && state.continueIterating(); i++) { + paths.push(Bytes.of(i)); + final Node child = node.child(i); + child.accept(this, remainingPath); + if (unload) { + child.unload(); + } + paths.pop(); + } + paths.pop(); + return node; + } + + @Override + public Node visit(final LeafNode node, final Bytes path) { + paths.push(node.getPath()); + state = State.CONTINUE; + try { + state = leafHandler.onLeaf(keyHash(), node); + } catch (IllegalArgumentException e) { + state = State.STOP; + return null; + } finally { + paths.pop(); + } + return node; + } + + @Override + public Node visit(final NullNode node, final Bytes path) { + state = State.CONTINUE; + return node; + } + + private Bytes32 keyHash() { + final Iterator iterator = paths.descendingIterator(); + Bytes fullPath = iterator.next(); + while (iterator.hasNext()) { + fullPath = Bytes.wrap(fullPath, iterator.next()); + } + return fullPath.isZero() + ? Bytes32.ZERO + : Bytes32.wrap(CompactEncoding.pathToBytes(fullPath), 0); + } + + public interface LeafHandler { + + State onLeaf(Bytes32 keyHash, Node node); + } + + public enum State { + SEARCHING, + CONTINUE, + STOP; + + public boolean continueIterating() { + return this != STOP; + } + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/TrieNodeDecoder.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/TrieNodeDecoder.java new file mode 100644 index 00000000000..4cdff3e2ea2 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/TrieNodeDecoder.java @@ -0,0 +1,165 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import com.google.common.collect.Streams; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Stream; + +import static com.google.common.base.Preconditions.checkArgument; + +public class TrieNodeDecoder { + private static final StoredNodeFactory emptyNodeFactory = + new StoredNodeFactory<>((l, h) -> Optional.empty(), Function.identity(), Function.identity()); + + // Hide constructor for static utility class + private TrieNodeDecoder() {} + + /** + * Decode an rlp-encoded trie node + * + * @param location The location in the trie. + * @param rlp The rlp-encoded node + * @return A {@code Node} representation of the rlp data + */ + public static Node decode(final Bytes location, final Bytes rlp) { + return emptyNodeFactory.decode(location, rlp); + } + + /** + * Flattens this node and all of its inlined nodes and node references into a list. + * + * @param location The location in the trie. + * @param nodeRlp The bytes of the trie node to be decoded. + * @return A list of nodes and node references embedded in the given rlp. + */ + public static List> decodeNodes(final Bytes location, final Bytes nodeRlp) { + final Node node = decode(location, nodeRlp); + final List> nodes = new ArrayList<>(); + nodes.add(node); + + final List> toProcess = new ArrayList<>(node.getChildren()); + while (!toProcess.isEmpty()) { + final Node currentNode = toProcess.remove(0); + if (Objects.equals(NullNode.instance(), currentNode)) { + // Skip null nodes + continue; + } + nodes.add(currentNode); + + if (!currentNode.isReferencedByHash()) { + // If current node is inlined, that means we can process its children + toProcess.addAll(currentNode.getChildren()); + } + } + + return nodes; + } + + /** + * Walks the trie in a bread-first manner, returning the list of nodes encountered in order. If + * any nodes are missing from the nodeLoader, those nodes are just skipped. + * + * @param nodeLoader The NodeLoader for looking up nodes by hash + * @param rootHash The hash of the root node + * @param maxDepth The maximum depth to traverse to. A value of zero will traverse the root node + * only. + * @return A stream non-null nodes in the breadth-first traversal order. + */ + public static Stream> breadthFirstDecoder( + final NodeLoader nodeLoader, final Bytes32 rootHash, final int maxDepth) { + checkArgument(maxDepth >= 0); + return Streams.stream(new BreadthFirstIterator(nodeLoader, rootHash, maxDepth)); + } + + /** + * Walks the trie in a bread-first manner, returning the list of nodes encountered in order. If + * any nodes are missing from the nodeLoader, those nodes are just skipped. + * + * @param nodeLoader The NodeLoader for looking up nodes by hash + * @param rootHash The hash of the root node + * @return A stream non-null nodes in the breadth-first traversal order. + */ + public static Stream> breadthFirstDecoder( + final NodeLoader nodeLoader, final Bytes32 rootHash) { + return breadthFirstDecoder(nodeLoader, rootHash, Integer.MAX_VALUE); + } + + private static class BreadthFirstIterator implements Iterator> { + + private final int maxDepth; + private final StoredNodeFactory nodeFactory; + + private int currentDepth = 0; + private final List> currentNodes = new ArrayList<>(); + private final List> nextNodes = new ArrayList<>(); + + BreadthFirstIterator(final NodeLoader nodeLoader, final Bytes32 rootHash, final int maxDepth) { + this.maxDepth = maxDepth; + this.nodeFactory = + new StoredNodeFactory<>(nodeLoader, Function.identity(), Function.identity()); + + nodeLoader + .getNode(Bytes.EMPTY, rootHash) + .map(h -> TrieNodeDecoder.decode(Bytes.EMPTY, h)) + .ifPresent(currentNodes::add); + } + + @Override + public boolean hasNext() { + return !currentNodes.isEmpty() && currentDepth <= maxDepth; + } + + @Override + public Node next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + + final Node nextNode = currentNodes.remove(0); + + final List> children = new ArrayList<>(nextNode.getChildren()); + while (!children.isEmpty()) { + Node child = children.remove(0); + if (Objects.equals(child, NullNode.instance())) { + // Ignore null nodes + continue; + } + if (child.isReferencedByHash()) { + // Retrieve hash-referenced child + final Optional> maybeChildNode = nodeFactory.retrieve(null, child.getHash()); + if (!maybeChildNode.isPresent()) { + continue; + } + child = maybeChildNode.get(); + } + nextNodes.add(child); + } + + // Set up next level + if (currentNodes.isEmpty()) { + currentDepth += 1; + currentNodes.addAll(nextNodes); + nextNodes.clear(); + } + + return nextNode; + } + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/InMemoryKeyValueStorage.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/InMemoryKeyValueStorage.java new file mode 100644 index 00000000000..745d9d44123 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/InMemoryKeyValueStorage.java @@ -0,0 +1,190 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.storage; + +import com.google.common.collect.ImmutableSet; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.tuweni.bytes.Bytes; + +import java.io.PrintStream; +import java.util.*; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class InMemoryKeyValueStorage implements KeyValueStorage { + + private final Map hashValueStore; + private final ReadWriteLock rwLock = new ReentrantReadWriteLock(); + + public InMemoryKeyValueStorage() { + this(new HashMap<>()); + } + + protected InMemoryKeyValueStorage(final Map hashValueStore) { + this.hashValueStore = hashValueStore; + } + + @Override + public void clear() { + final Lock lock = rwLock.writeLock(); + lock.lock(); + try { + hashValueStore.clear(); + } finally { + lock.unlock(); + } + } + + @Override + public boolean containsKey(final byte[] key) throws StorageException { + return get(key).isPresent(); + } + + @Override + public Optional get(final byte[] key) throws StorageException { + final Lock lock = rwLock.readLock(); + lock.lock(); + try { + return Optional.ofNullable(hashValueStore.get(Bytes.wrap(key))); + } finally { + lock.unlock(); + } + } + + @Override + public Set getAllKeysThat(final Predicate returnCondition) { + return stream() + .filter(pair -> returnCondition.test(pair.getKey())) + .map(Pair::getKey) + .collect(Collectors.collectingAndThen( + Collectors.toSet(), + Collections::unmodifiableSet + )); + } + + @Override + public Set getAllValuesFromKeysThat(final Predicate returnCondition) { + return stream() + .filter(pair -> returnCondition.test(pair.getKey())) + .map(Pair::getValue) + .collect(Collectors.collectingAndThen( + Collectors.toSet(), + Collections::unmodifiableSet + )); + } + + @Override + public Stream> stream() { + final Lock lock = rwLock.readLock(); + lock.lock(); + try { + return ImmutableSet.copyOf(hashValueStore.entrySet()).stream() + .map(bytesEntry -> Pair.of(bytesEntry.getKey().toArrayUnsafe(), bytesEntry.getValue())); + } finally { + lock.unlock(); + } + } + + @Override + public Stream streamKeys() { + final Lock lock = rwLock.readLock(); + lock.lock(); + try { + return ImmutableSet.copyOf(hashValueStore.entrySet()).stream() + .map(bytesEntry -> bytesEntry.getKey().toArrayUnsafe()); + } finally { + lock.unlock(); + } + } + + @Override + public boolean tryDelete(final byte[] key) { + final Lock lock = rwLock.writeLock(); + if (lock.tryLock()) { + try { + hashValueStore.remove(Bytes.wrap(key)); + } finally { + lock.unlock(); + } + return true; + } + return false; + } + + @Override + public void close() {} + + @Override + public KeyValueStorageTransaction startTransaction() { + return new KeyValueStorageTransactionTransitionValidatorDecorator(new InMemoryTransaction()); + } + + public Set keySet() { + return ImmutableSet.copyOf((hashValueStore.keySet())); + } + + private class InMemoryTransaction implements KeyValueStorageTransaction { + + private Map updatedValues = new HashMap<>(); + private Set removedKeys = new HashSet<>(); + + @Override + public void put(final byte[] key, final byte[] value) { + updatedValues.put(Bytes.wrap(key), value); + removedKeys.remove(Bytes.wrap(key)); + } + + @Override + public void remove(final byte[] key) { + removedKeys.add(Bytes.wrap(key)); + updatedValues.remove(Bytes.wrap(key)); + } + + @Override + public void commit() throws StorageException { + final Lock lock = rwLock.writeLock(); + lock.lock(); + try { + hashValueStore.putAll(updatedValues); + removedKeys.forEach(hashValueStore::remove); + updatedValues = null; + removedKeys = null; + } finally { + lock.unlock(); + } + } + + @Override + public void rollback() { + updatedValues.clear(); + removedKeys.clear(); + } + } + + public void dump(final PrintStream ps) { + final Lock lock = rwLock.readLock(); + lock.lock(); + try { + hashValueStore.forEach( + (k, v) -> ps.printf(" %s : %s%n", k.toHexString(), Bytes.wrap(v).toHexString())); + } finally { + lock.unlock(); + } + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/InvalidConfigurationException.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/InvalidConfigurationException.java new file mode 100644 index 00000000000..612199d9eaa --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/InvalidConfigurationException.java @@ -0,0 +1,21 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.storage; + +public class InvalidConfigurationException extends IllegalArgumentException { + public InvalidConfigurationException(final String message) { + super(message); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/KeyValueStorage.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/KeyValueStorage.java new file mode 100644 index 00000000000..e28a83fdf8e --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/KeyValueStorage.java @@ -0,0 +1,108 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.storage; + +import org.apache.commons.lang3.tuple.Pair; + +import java.io.Closeable; +import java.util.Optional; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Stream; + +/** + * Responsible for storing values against keys. + * + *

Behaviour expected with regard to key to value mapping is that of a map, one key maps to one + * value, when a new value is added with an existing key, that key now points at the new value. + * + *

All keys and values must be non-null. + */ +@Unstable +public interface KeyValueStorage extends Closeable { + + /** + * Deletes all keys and values from the storage. + * + * @throws StorageException problem encountered when attempting to clear storage. + */ + void clear() throws StorageException; + + /** + * Whether the key-value storage contains the given key. + * + * @param key a key that might be contained in the key-value storage. + * @return true when the given key is present in keyset, false + * otherwise. + * @throws StorageException problem encountered when interacting with the key set. + */ + boolean containsKey(byte[] key) throws StorageException; + + /** + * Retrieves the value associated with a given key. + * + * @param key whose associated value is being retrieved. + * @return an {@link Optional} containing the value associated with the specified key, otherwise + * empty. + * @throws StorageException problem encountered during the retrieval attempt. + */ + Optional get(byte[] key) throws StorageException; + + /** + * Returns a stream of all keys and values. + * + * @return A stream of all keys and values in storage. + * @throws StorageException problem encountered during the retrieval attempt. + */ + Stream> stream() throws StorageException; + + /** + * Returns a stream of all keys. + * + * @return A stream of all keys in storage. + * @throws StorageException problem encountered during the retrieval attempt. + */ + Stream streamKeys() throws StorageException; + + /** + * Delete the value corresponding to the given key if a write lock can be instantly acquired on + * the underlying storage. Do nothing otherwise. + * + * @param key The key to delete. + * @throws StorageException any problem encountered during the deletion attempt. + * @return false if the lock on the underlying storage could not be instantly acquired, true + * otherwise + */ + boolean tryDelete(byte[] key) throws StorageException; + + /** + * Performs an evaluation against each key in the store, returning the set of entries that pass. + * + * @param returnCondition predicate to evaluate each key against, unless the result is {@code + * null}, the key is added to the returned list of keys. + * @return the set of keys that pass the condition. + */ + Set getAllKeysThat(Predicate returnCondition); + + Set getAllValuesFromKeysThat(final Predicate returnCondition); + + /** + * Begins a fresh transaction, for sequencing operations for later atomic execution. + * + * @return transaciton to sequence key-value operations. + * @throws StorageException problem encountered when starting a new transaction. + */ + KeyValueStorageTransaction startTransaction() throws StorageException; +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/KeyValueStorageTransaction.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/KeyValueStorageTransaction.java new file mode 100644 index 00000000000..26a0f29f6fe --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/KeyValueStorageTransaction.java @@ -0,0 +1,48 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.storage; + +/** A transaction that can atomically commit a sequence of operations to a key-value store. */ +@Unstable +public interface KeyValueStorageTransaction { + + /** + * Associates the specified value with the specified key. + * + *

If a previously value had been store against the given key, the old value is replaced by the + * given value. + * + * @param key the given value is to be associated with. + * @param value associated with the specified key. + */ + void put(byte[] key, byte[] value); + + /** + * When the given key is present, the key and mapped value will be removed from storage. + * + * @param key the key and mapped value that will be removed. + */ + void remove(byte[] key); + + /** + * Performs an atomic commit of all the operations queued in the transaction. + * + * @throws StorageException problem was encountered preventing the commit + */ + void commit() throws StorageException; + + /** Reset the transaction to a state prior to any operations being queued. */ + void rollback(); +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/KeyValueStorageTransactionTransitionValidatorDecorator.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/KeyValueStorageTransactionTransitionValidatorDecorator.java new file mode 100644 index 00000000000..e618b634fd2 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/KeyValueStorageTransactionTransitionValidatorDecorator.java @@ -0,0 +1,55 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.storage; + +import static com.google.common.base.Preconditions.checkState; + +public class KeyValueStorageTransactionTransitionValidatorDecorator + implements KeyValueStorageTransaction { + + private final KeyValueStorageTransaction transaction; + private boolean active = true; + + public KeyValueStorageTransactionTransitionValidatorDecorator( + final KeyValueStorageTransaction toDecorate) { + this.transaction = toDecorate; + } + + @Override + public void put(final byte[] key, final byte[] value) { + checkState(active, "Cannot invoke put() on a completed transaction."); + transaction.put(key, value); + } + + @Override + public void remove(final byte[] key) { + checkState(active, "Cannot invoke remove() on a completed transaction."); + transaction.remove(key); + } + + @Override + public final void commit() throws StorageException { + checkState(active, "Cannot commit a completed transaction."); + active = false; + transaction.commit(); + } + + @Override + public final void rollback() { + checkState(active, "Cannot rollback a completed transaction."); + active = false; + transaction.rollback(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBConfiguration.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBConfiguration.java new file mode 100644 index 00000000000..fdbba6cf9a9 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBConfiguration.java @@ -0,0 +1,80 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.storage; + +import java.nio.file.Path; + +public class RocksDBConfiguration { + + private final Path databaseDir; + private final int maxOpenFiles; + private final String label; + private final int maxBackgroundCompactions; + private final int backgroundThreadCount; + private final long cacheCapacity; + private final long writeBufferSize; + private final boolean isHighSpec; + + public RocksDBConfiguration( + final Path databaseDir, + final int maxOpenFiles, + final int maxBackgroundCompactions, + final int backgroundThreadCount, + final long cacheCapacity, + final long writeBufferSize, + final String label, + final boolean isHighSpec) { + this.maxBackgroundCompactions = maxBackgroundCompactions; + this.backgroundThreadCount = backgroundThreadCount; + this.databaseDir = databaseDir; + this.maxOpenFiles = maxOpenFiles; + this.cacheCapacity = cacheCapacity; + this.writeBufferSize = writeBufferSize; + this.label = label; + this.isHighSpec = isHighSpec; + } + + public Path getDatabaseDir() { + return databaseDir; + } + + public int getMaxOpenFiles() { + return maxOpenFiles; + } + + public int getMaxBackgroundCompactions() { + return maxBackgroundCompactions; + } + + public int getBackgroundThreadCount() { + return backgroundThreadCount; + } + + public long getCacheCapacity() { + return cacheCapacity; + } + + public long getWriteBufferSize() { + return writeBufferSize; + } + + public String getLabel() { + return label; + } + + public boolean isHighSpec() { + return isHighSpec; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBConfigurationBuilder.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBConfigurationBuilder.java new file mode 100644 index 00000000000..f830bc56906 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBConfigurationBuilder.java @@ -0,0 +1,96 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.storage; + +import java.nio.file.Path; + +public class RocksDBConfigurationBuilder { + public static final int DEFAULT_MAX_OPEN_FILES = -1; + public static final long DEFAULT_CACHE_CAPACITY = 1 * 1024 * 1024 * 1024L; + public static final long DEFAULT_WRITE_BUFFER_SIZE = 256 * 1024 * 1024L; + public static final int DEFAULT_MAX_BACKGROUND_COMPACTIONS = Runtime.getRuntime().availableProcessors(); + public static final int DEFAULT_BACKGROUND_THREAD_COUNT = 4; + public static final boolean DEFAULT_IS_HIGH_SPEC = false; + private Path databaseDir; + private String label = "blockchain"; + private int maxOpenFiles = DEFAULT_MAX_OPEN_FILES; + private long cacheCapacity = DEFAULT_CACHE_CAPACITY; + private long writeBufferSize = DEFAULT_WRITE_BUFFER_SIZE; + private int maxBackgroundCompactions = DEFAULT_MAX_BACKGROUND_COMPACTIONS; + private int backgroundThreadCount = DEFAULT_BACKGROUND_THREAD_COUNT; + private boolean isHighSpec = DEFAULT_IS_HIGH_SPEC; + + public RocksDBConfigurationBuilder databaseDir(final Path databaseDir) { + this.databaseDir = databaseDir; + return this; + } + + public RocksDBConfigurationBuilder maxOpenFiles(final int maxOpenFiles) { + this.maxOpenFiles = maxOpenFiles; + return this; + } + + public RocksDBConfigurationBuilder label(final String label) { + this.label = label; + return this; + } + + public RocksDBConfigurationBuilder cacheCapacity(final long cacheCapacity) { + this.cacheCapacity = cacheCapacity; + return this; + } + + public RocksDBConfigurationBuilder writeBufferSize(final long writeBufferSize) { + this.writeBufferSize = writeBufferSize; + return this; + } + + public RocksDBConfigurationBuilder maxBackgroundCompactions(final int maxBackgroundCompactions) { + this.maxBackgroundCompactions = maxBackgroundCompactions; + return this; + } + + public RocksDBConfigurationBuilder backgroundThreadCount(final int backgroundThreadCount) { + this.backgroundThreadCount = backgroundThreadCount; + return this; + } + + public RocksDBConfigurationBuilder isHighSpec(final boolean isHighSpec) { + this.isHighSpec = isHighSpec; + return this; + } + + public static RocksDBConfigurationBuilder from(final RocksDBFactoryConfiguration configuration) { + return new RocksDBConfigurationBuilder() + .backgroundThreadCount(configuration.getBackgroundThreadCount()) + .cacheCapacity(configuration.getCacheCapacity()) + .writeBufferSize(configuration.getWriteBufferSize()) + .maxBackgroundCompactions(configuration.getMaxBackgroundCompactions()) + .maxOpenFiles(configuration.getMaxOpenFiles()) + .isHighSpec(configuration.isHighSpec()); + } + + public RocksDBConfiguration build() { + return new RocksDBConfiguration( + databaseDir, + maxOpenFiles, + maxBackgroundCompactions, + backgroundThreadCount, + cacheCapacity, + writeBufferSize, + label, + isHighSpec); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBFactoryConfiguration.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBFactoryConfiguration.java new file mode 100644 index 00000000000..1b4419656a9 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBFactoryConfiguration.java @@ -0,0 +1,64 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.storage; + +public class RocksDBFactoryConfiguration { + + private final int maxOpenFiles; + private final int maxBackgroundCompactions; + private final int backgroundThreadCount; + private final long cacheCapacity; + private final long writeBufferSize; + private final boolean isHighSpec; + + public RocksDBFactoryConfiguration( + final int maxOpenFiles, + final int maxBackgroundCompactions, + final int backgroundThreadCount, + final long cacheCapacity, + final long writeBufferSize, + final boolean isHighSpec) { + this.maxBackgroundCompactions = maxBackgroundCompactions; + this.backgroundThreadCount = backgroundThreadCount; + this.maxOpenFiles = maxOpenFiles; + this.cacheCapacity = cacheCapacity; + this.writeBufferSize = writeBufferSize; + this.isHighSpec = isHighSpec; + } + + public int getMaxOpenFiles() { + return maxOpenFiles; + } + + public int getMaxBackgroundCompactions() { + return maxBackgroundCompactions; + } + + public int getBackgroundThreadCount() { + return backgroundThreadCount; + } + + public long getCacheCapacity() { + return cacheCapacity; + } + + public long getWriteBufferSize() { + return writeBufferSize; + } + + public boolean isHighSpec() { + return isHighSpec; + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBKeyValueStorage.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBKeyValueStorage.java new file mode 100644 index 00000000000..c00b23502db --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBKeyValueStorage.java @@ -0,0 +1,190 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.storage; + +import org.apache.commons.lang3.tuple.Pair; +import org.rocksdb.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collections; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class RocksDBKeyValueStorage implements KeyValueStorage { + + static { + loadNativeLibrary(); + } + + private static final Logger LOG = LoggerFactory.getLogger(RocksDBKeyValueStorage.class); + + private final Options options; + private final OptimisticTransactionDB db; + private final AtomicBoolean closed = new AtomicBoolean(false); + private final WriteOptions tryDeleteOptions = + new WriteOptions().setNoSlowdown(true).setIgnoreMissingColumnFamilies(true); + + public RocksDBKeyValueStorage(final RocksDBConfiguration configuration) { + + try { + final Statistics stats = new Statistics(); + options = + new Options() + .setCreateIfMissing(true) + .setMaxOpenFiles(configuration.getMaxOpenFiles()) + .setTableFormatConfig(createBlockBasedTableConfig(configuration)) + .setMaxBackgroundCompactions(configuration.getMaxBackgroundCompactions()) + .setStatistics(stats); + options.getEnv().setBackgroundThreads(configuration.getBackgroundThreadCount()); + + db = OptimisticTransactionDB.open(options, configuration.getDatabaseDir().toString()); + } catch (final RocksDBException e) { + throw new StorageException(e); + } + } + + @Override + public void clear() throws StorageException { + try (final RocksIterator rocksIterator = db.newIterator()) { + rocksIterator.seekToFirst(); + if (rocksIterator.isValid()) { + final byte[] firstKey = rocksIterator.key(); + rocksIterator.seekToLast(); + if (rocksIterator.isValid()) { + final byte[] lastKey = rocksIterator.key(); + db.deleteRange(firstKey, lastKey); + db.delete(lastKey); + } + } + } catch (final RocksDBException e) { + throw new StorageException(e); + } + } + + @Override + public boolean containsKey(final byte[] key) throws StorageException { + return get(key).isPresent(); + } + + @Override + public Optional get(final byte[] key) throws StorageException { + throwIfClosed(); + + try { + return Optional.ofNullable(db.get(key)); + } catch (final RocksDBException e) { + throw new StorageException(e); + } + } + + @Override + public Set getAllKeysThat(final Predicate returnCondition) { + return stream() + .filter(pair -> returnCondition.test(pair.getKey())) + .map(Pair::getKey) + .collect(Collectors.collectingAndThen( + Collectors.toSet(), + Collections::unmodifiableSet + )); + } + + @Override + public Stream> stream() { + final RocksIterator rocksIterator = db.newIterator(); + rocksIterator.seekToFirst(); + return RocksDbIterator.create(rocksIterator).toStream(); + } + + @Override + public Stream streamKeys() { + final RocksIterator rocksIterator = db.newIterator(); + rocksIterator.seekToFirst(); + return RocksDbIterator.create(rocksIterator).toStreamKeys(); + } + + @Override + public Set getAllValuesFromKeysThat(final Predicate returnCondition) { + return stream() + .filter(pair -> returnCondition.test(pair.getKey())) + .map(Pair::getValue) + .collect(Collectors.collectingAndThen( + Collectors.toSet(), + Collections::unmodifiableSet + )); + } + + @Override + public boolean tryDelete(final byte[] key) { + try { + db.delete(tryDeleteOptions, key); + return true; + } catch (RocksDBException e) { + if (e.getStatus().getCode() == Status.Code.Incomplete) { + return false; + } else { + throw new StorageException(e); + } + } + } + + @Override + public KeyValueStorageTransaction startTransaction() throws StorageException { + throwIfClosed(); + final WriteOptions options = new WriteOptions(); + options.setIgnoreMissingColumnFamilies(true); + return new KeyValueStorageTransactionTransitionValidatorDecorator( + new RocksDBTransaction(db.beginTransaction(options), options)); + } + + @Override + public void close() { + if (closed.compareAndSet(false, true)) { + tryDeleteOptions.close(); + options.close(); + db.close(); + } + } + + private BlockBasedTableConfig createBlockBasedTableConfig(final RocksDBConfiguration config) { + final LRUCache cache = new LRUCache(config.getCacheCapacity()); + return new BlockBasedTableConfig().setBlockCache(cache); + } + + private void throwIfClosed() { + if (closed.get()) { + LOG.error("Attempting to use a closed RocksDBKeyValueStorage"); + throw new IllegalStateException("Storage has been closed"); + } + } + + private static void loadNativeLibrary() { + try { + RocksDB.loadLibrary(); + } catch (final ExceptionInInitializerError e) { + if (e.getCause() instanceof UnsupportedOperationException) { + LOG.info("Unable to load RocksDB library", e); + throw new InvalidConfigurationException( + "Unsupported platform detected. On Windows, ensure you have 64bit Java installed."); + } else { + throw e; + } + } + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBTransaction.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBTransaction.java new file mode 100644 index 00000000000..3c252100ef2 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBTransaction.java @@ -0,0 +1,96 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.storage; + +import org.rocksdb.RocksDBException; +import org.rocksdb.Transaction; +import org.rocksdb.WriteOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RocksDBTransaction implements KeyValueStorageTransaction { + private static final Logger logger = LoggerFactory.getLogger(RocksDBTransaction.class); + private static final String NO_SPACE_LEFT_ON_DEVICE = "No space left on device"; + + private final Transaction innerTx; + private final WriteOptions options; + + RocksDBTransaction( + final Transaction innerTx, final WriteOptions options) { + this.innerTx = innerTx; + this.options = options; + } + + @Override + public void put(final byte[] key, final byte[] value) { + try { + innerTx.put(key, value); + } catch (final RocksDBException e) { + if (e.getMessage().contains(NO_SPACE_LEFT_ON_DEVICE)) { + logger.error(e.getMessage()); + System.exit(0); + } + throw new StorageException(e); + } + } + + @Override + public void remove(final byte[] key) { + try { + innerTx.delete(key); + } catch (final RocksDBException e) { + if (e.getMessage().contains(NO_SPACE_LEFT_ON_DEVICE)) { + logger.error(e.getMessage()); + System.exit(0); + } + throw new StorageException(e); + } + } + + @Override + public void commit() throws StorageException { + try { + innerTx.commit(); + } catch (final RocksDBException e) { + if (e.getMessage().contains(NO_SPACE_LEFT_ON_DEVICE)) { + logger.error(e.getMessage()); + System.exit(0); + } + throw new StorageException(e); + } finally { + close(); + } + } + + @Override + public void rollback() { + try { + innerTx.rollback(); + } catch (final RocksDBException e) { + if (e.getMessage().contains(NO_SPACE_LEFT_ON_DEVICE)) { + logger.error(e.getMessage()); + System.exit(0); + } + throw new StorageException(e); + } finally { + close(); + } + } + + private void close() { + innerTx.close(); + options.close(); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDbIterator.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDbIterator.java new file mode 100644 index 00000000000..94e109ecad4 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDbIterator.java @@ -0,0 +1,140 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.hyperledger.besu.storage; + +import org.apache.commons.lang3.tuple.Pair; +import org.rocksdb.RocksDBException; +import org.rocksdb.RocksIterator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import static com.google.common.base.Preconditions.checkState; + +public class RocksDbIterator implements Iterator>, AutoCloseable { + private static final Logger LOG = LoggerFactory.getLogger(RocksDbIterator.class); + + private final RocksIterator rocksIterator; + private final AtomicBoolean closed = new AtomicBoolean(false); + + private RocksDbIterator(final RocksIterator rocksIterator) { + this.rocksIterator = rocksIterator; + } + + public static RocksDbIterator create(final RocksIterator rocksIterator) { + return new RocksDbIterator(rocksIterator); + } + + @Override + public boolean hasNext() { + assertOpen(); + return rocksIterator.isValid(); + } + + @Override + public Pair next() { + assertOpen(); + try { + rocksIterator.status(); + } catch (final RocksDBException e) { + LOG.error( + String.format("%s encountered a problem while iterating.", getClass().getSimpleName()), + e); + } + if (!hasNext()) { + throw new NoSuchElementException(); + } + final byte[] key = rocksIterator.key(); + final byte[] value = rocksIterator.value(); + rocksIterator.next(); + return Pair.of(key, value); + } + + public byte[] nextKey() { + assertOpen(); + try { + rocksIterator.status(); + } catch (final RocksDBException e) { + LOG.error( + String.format("%s encountered a problem while iterating.", getClass().getSimpleName()), + e); + } + if (!hasNext()) { + throw new NoSuchElementException(); + } + final byte[] key = rocksIterator.key(); + rocksIterator.next(); + return key; + } + + public Stream> toStream() { + assertOpen(); + final Spliterator> spliterator = + Spliterators.spliteratorUnknownSize( + this, + Spliterator.IMMUTABLE + | Spliterator.DISTINCT + | Spliterator.NONNULL + | Spliterator.ORDERED + | Spliterator.SORTED); + + return StreamSupport.stream(spliterator, false).onClose(this::close); + } + + public Stream toStreamKeys() { + assertOpen(); + final Spliterator spliterator = + Spliterators.spliteratorUnknownSize( + new Iterator() { + @Override + public boolean hasNext() { + return RocksDbIterator.this.hasNext(); + } + + @Override + public byte[] next() { + return RocksDbIterator.this.nextKey(); + } + }, + Spliterator.IMMUTABLE + | Spliterator.DISTINCT + | Spliterator.NONNULL + | Spliterator.ORDERED + | Spliterator.SORTED); + + return StreamSupport.stream(spliterator, false).onClose(this::close); + } + + private void assertOpen() { + checkState( + !closed.get(), + String.format("Attempt to read from a closed %s", getClass().getSimpleName())); + } + + @Override + public void close() { + if (closed.compareAndSet(false, true)) { + rocksIterator.close(); + } + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/StorageException.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/StorageException.java new file mode 100644 index 00000000000..130eb5f6b7d --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/StorageException.java @@ -0,0 +1,49 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.storage; + +/** Base exception class for problems encountered in the domain for storage. */ +public class StorageException extends RuntimeException { + + /** + * Constructs a new storage exception with the specified cause. + * + * @param cause saved for later retrieval by the {@link #getCause()} method). (A {@code null} + * value is permitted, and indicates that the cause is nonexistent or unknown.) + */ + public StorageException(final Throwable cause) { + super(cause); + } + + /** + * Constructs a new storage exception with the specified detail message and cause. + * + * @param message the detail that may be retrieved later by Throwable.getMessage(). + * @param cause saved for later retrieval by the {@link #getCause()} method). (A {@code null} + * value is permitted, and indicates that the cause is nonexistent or unknown.) + */ + public StorageException(final String message, final Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new storage exception with the specified detail message. + * + * @param message the detail that may be retrieved later by Throwable.getMessage(). + */ + public StorageException(final String message) { + super(message); + } +} diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/Unstable.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/Unstable.java new file mode 100644 index 00000000000..9a35a8ef1a1 --- /dev/null +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/Unstable.java @@ -0,0 +1,30 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.storage; + +import java.lang.annotation.Retention; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.CLASS; + +/** + * This annotation is an indicator that the interface or method may evolve in a way that it not + * backwards compatible. Such as deleting methods, changing signatures, and adding checked + * exceptions. Authors are advised to exercise caution when using these APIs. + */ +@Retention(CLASS) +@java.lang.annotation.Target({METHOD, TYPE}) +public @interface Unstable {} diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/BufferBytesTest.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/BufferBytesTest.java new file mode 100644 index 00000000000..b48c82eb6fe --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/BufferBytesTest.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import io.vertx.core.buffer.Buffer; + +class BufferBytesTest extends CommonBytesTests { + + @Override + Bytes h(String hex) { + return Bytes.wrapBuffer(Buffer.buffer(Bytes.fromHexString(hex).toArrayUnsafe())); + } + + @Override + MutableBytes m(int size) { + return MutableBytes.wrapBuffer(Buffer.buffer(new byte[size])); + } + + @Override + Bytes w(byte[] bytes) { + return Bytes.wrapBuffer(Buffer.buffer(Bytes.of(bytes).toArray())); + } + + @Override + Bytes of(int... bytes) { + return Bytes.wrapBuffer(Buffer.buffer(Bytes.of(bytes).toArray())); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/ByteBufBytesTest.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/ByteBufBytesTest.java new file mode 100644 index 00000000000..c006e863137 --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/ByteBufBytesTest.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import io.netty.buffer.Unpooled; + +class ByteBufBytesTest extends CommonBytesTests { + + @Override + Bytes h(String hex) { + return Bytes.wrapByteBuf(Unpooled.copiedBuffer(Bytes.fromHexString(hex).toArrayUnsafe())); + } + + @Override + MutableBytes m(int size) { + return MutableBytes.wrapByteBuf(Unpooled.copiedBuffer(new byte[size])); + } + + @Override + Bytes w(byte[] bytes) { + return Bytes.wrapByteBuf(Unpooled.copiedBuffer(Bytes.of(bytes).toArray())); + } + + @Override + Bytes of(int... bytes) { + return Bytes.wrapByteBuf(Unpooled.copiedBuffer(Bytes.of(bytes).toArray())); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/ByteBufferBytesTest.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/ByteBufferBytesTest.java new file mode 100644 index 00000000000..9904f89d76c --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/ByteBufferBytesTest.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import java.nio.ByteBuffer; + +class ByteBufferBytesTest extends CommonBytesTests { + + @Override + Bytes h(String hex) { + return Bytes.wrapByteBuffer(ByteBuffer.wrap(Bytes.fromHexString(hex).toArrayUnsafe())); + } + + @Override + MutableBytes m(int size) { + return MutableBytes.wrapByteBuffer(ByteBuffer.allocate(size)); + } + + @Override + Bytes w(byte[] bytes) { + return Bytes.wrapByteBuffer(ByteBuffer.wrap(Bytes.of(bytes).toArray())); + } + + @Override + Bytes of(int... bytes) { + return Bytes.wrapByteBuffer(ByteBuffer.wrap(Bytes.of(bytes).toArray())); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/Bytes32Test.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/Bytes32Test.java new file mode 100644 index 00000000000..b1936f5a83b --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/Bytes32Test.java @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class Bytes32Test { + + @Test + void testConcatenation() { + Bytes wrapped = Bytes.wrap(Bytes.wrap(new byte[32]), Bytes.wrap(new byte[6])); + assertEquals(37, wrapped.slice(0, 37).size()); + Bytes wrappedCopy = wrapped.slice(0, 37).copy(); + assertEquals(wrapped.slice(0, 37), wrappedCopy); + } + + @Test + void constantBytes32slice() { + assertEquals(Bytes32.ZERO.slice(12, 20).size(), 20); + } + + @Test + void constantBytesslice() { + assertEquals(Bytes.repeat((byte) 1, 63).slice(12, 20).size(), 20); + } + + @Test + void testMutableBytes32WrapWithOffset() { + Bytes bytes = Bytes + .fromHexString( + "0x00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"); + MutableBytes mutableBytes = MutableBytes.create(48); + bytes.copyTo(mutableBytes); + assertEquals( + "0x112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00", + Bytes32.wrap(mutableBytes, 1).toHexString()); + } + + @Test + void testMutableBytes32SliceWithOffset() { + Bytes bytes = Bytes + .fromHexString( + "0x00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"); + MutableBytes mutableBytes = MutableBytes.create(48); + bytes.copyTo(mutableBytes); + assertEquals("0x11", mutableBytes.slice(1, 1).toHexString()); + assertEquals("0x1122", mutableBytes.slice(1, 2).toHexString()); + assertEquals("0x112233445566778899aa", mutableBytes.slice(1, 10).toHexString()); + assertEquals("0x112233445566778899aabbccddeeff", mutableBytes.slice(1, 15).toHexString()); + assertEquals( + "0x112233445566778899aabbccddeeff00112233445566778899aabbccddee", + mutableBytes.slice(1, 30).toHexString()); + assertEquals( + "0x112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00", + mutableBytes.slice(1, 32).toHexString()); + assertEquals( + "0x112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddee", + mutableBytes.slice(1, 46).toHexString()); + } + + @Test + void testBytes32SliceWithOffset() { + Bytes bytes = Bytes + .fromHexString( + "0x00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"); + assertEquals("0x11", bytes.slice(1, 1).toHexString()); + assertEquals("0x1122", bytes.slice(1, 2).toHexString()); + assertEquals("0x112233445566778899aa", bytes.slice(1, 10).toHexString()); + assertEquals("0x112233445566778899aabbccddeeff", bytes.slice(1, 15).toHexString()); + assertEquals("0x112233445566778899aabbccddeeff00112233445566778899aabbccddee", bytes.slice(1, 30).toHexString()); + assertEquals( + "0x112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00", + bytes.slice(1, 32).toHexString()); + assertEquals( + "0x112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899aabbccddee", + bytes.slice(1, 46).toHexString()); + } + + @Test + void failsWhenWrappingArraySmallerThan32() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes32.wrap(new byte[31])); + assertEquals("Expected 32 bytes but got 31", exception.getMessage()); + } + + @Test + void failsWhenWrappingArrayLargerThan32() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes32.wrap(new byte[33])); + assertEquals("Expected 32 bytes but got 33", exception.getMessage()); + } + + @Test + void leftPadAValueToBytes32() { + Bytes32 b32 = Bytes32.leftPad(Bytes.of(1, 2, 3)); + assertEquals(32, b32.size()); + for (int i = 0; i < 28; ++i) { + assertEquals((byte) 0, b32.get(i)); + } + assertEquals((byte) 1, b32.get(29)); + assertEquals((byte) 2, b32.get(30)); + assertEquals((byte) 3, b32.get(31)); + } + + @Test + void rightPadAValueToBytes32() { + Bytes32 b32 = Bytes32.rightPad(Bytes.of(1, 2, 3)); + assertEquals(32, b32.size()); + for (int i = 3; i < 32; ++i) { + assertEquals((byte) 0, b32.get(i)); + } + assertEquals((byte) 1, b32.get(0)); + assertEquals((byte) 2, b32.get(1)); + assertEquals((byte) 3, b32.get(2)); + } + + @Test + void failsWhenLeftPaddingValueLargerThan32() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes32.leftPad(MutableBytes.create(33))); + assertEquals("Expected at most 32 bytes but got 33", exception.getMessage()); + } + + @Test + void failsWhenRightPaddingValueLargerThan32() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes32.rightPad(MutableBytes.create(33))); + assertEquals("Expected at most 32 bytes but got 33", exception.getMessage()); + } + + @Test + void testWrapSlicesCorrectly() { + Bytes input = Bytes + .fromHexString( + "0xA99A76ED7796F7BE22D5B7E85DEEB7C5677E88E511E0B337618F8C4EB61349B4BF2D153F649F7B53359FE8B94A38E44C00000000000000000000000000000000"); + Bytes32 value = Bytes32.wrap(input, 0); + assertEquals(Bytes.fromHexString("0xA99A76ED7796F7BE22D5B7E85DEEB7C5677E88E511E0B337618F8C4EB61349B4"), value); + + Bytes32 secondValue = Bytes32.wrap(input, 32); + assertEquals( + Bytes.fromHexString("0xBF2D153F649F7B53359FE8B94A38E44C00000000000000000000000000000000"), + secondValue); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/Bytes48Test.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/Bytes48Test.java new file mode 100644 index 00000000000..67aab201f8f --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/Bytes48Test.java @@ -0,0 +1,134 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class Bytes48Test { + + @Test + void failsWhenWrappingArraySmallerThan48() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes48.wrap(new byte[47])); + assertEquals("Expected 48 bytes but got 47", exception.getMessage()); + } + + @Test + void failsWhenWrappingArrayLargerThan48() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes48.wrap(new byte[49])); + assertEquals("Expected 48 bytes but got 49", exception.getMessage()); + } + + @Test + void rightPadAValueToBytes48() { + Bytes48 b48 = Bytes48.rightPad(Bytes.of(1, 2, 3)); + assertEquals(48, b48.size()); + for (int i = 3; i < 48; ++i) { + assertEquals((byte) 0, b48.get(i)); + } + assertEquals((byte) 1, b48.get(0)); + assertEquals((byte) 2, b48.get(1)); + assertEquals((byte) 3, b48.get(2)); + } + + @Test + void leftPadAValueToBytes48() { + Bytes48 b48 = Bytes48.leftPad(Bytes.of(1, 2, 3)); + assertEquals(48, b48.size()); + for (int i = 0; i < 28; ++i) { + assertEquals((byte) 0, b48.get(i)); + } + assertEquals((byte) 1, b48.get(45)); + assertEquals((byte) 2, b48.get(46)); + assertEquals((byte) 3, b48.get(47)); + } + + @Test + void failsWhenLeftPaddingValueLargerThan48() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes48.leftPad(MutableBytes.create(49))); + assertEquals("Expected at most 48 bytes but got 49", exception.getMessage()); + } + + @Test + void failsWhenRightPaddingValueLargerThan48() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes48.rightPad(MutableBytes.create(49))); + assertEquals("Expected at most 48 bytes but got 49", exception.getMessage()); + } + + @Test + void hexString() { + Bytes initial = Bytes48.random(); + assertEquals(initial, Bytes48.fromHexStringLenient(initial.toHexString())); + assertEquals(initial, Bytes48.fromHexString(initial.toHexString())); + assertEquals(initial, Bytes48.fromHexStringStrict(initial.toHexString())); + } + + @Test + void size() { + assertEquals(48, Bytes48.random().size()); + } + + @Test + void not() { + assertEquals( + Bytes48 + .fromHexString( + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), + Bytes48.leftPad(Bytes.EMPTY).not()); + } + + @Test + void wrap() { + Bytes source = Bytes.random(96); + Bytes48 value = Bytes48.wrap(source, 2); + assertEquals(source.slice(2, 48), value); + } + + @Test + void leftPad() { + Bytes48 source = Bytes48.random(); + assertSame(source, Bytes48.leftPad(source)); + assertSame(source, Bytes48.rightPad(source)); + } + + @Test + void or() { + Bytes48 one = Bytes48 + .fromHexString( + "0x0000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffff"); + Bytes48 two = Bytes48 + .fromHexString( + "0xffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000"); + assertEquals( + Bytes48 + .fromHexString( + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), + one.or(two)); + } + + @Test + void and() { + Bytes48 one = Bytes48 + .fromHexString( + "0x0000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffff"); + Bytes48 two = Bytes48 + .fromHexString( + "0xffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000"); + assertEquals( + Bytes48 + .fromHexString( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + one.and(two)); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/BytesTest.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/BytesTest.java new file mode 100644 index 00000000000..81288d980e5 --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/BytesTest.java @@ -0,0 +1,700 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.Arrays; +import java.util.stream.Stream; + +import static java.nio.ByteOrder.LITTLE_ENDIAN; +import static org.junit.jupiter.api.Assertions.*; + +class BytesTest extends CommonBytesTests { + + @Override + Bytes h(String hex) { + return Bytes.fromHexString(hex); + } + + @Override + MutableBytes m(int size) { + return MutableBytes.create(size); + } + + @Override + Bytes w(byte[] bytes) { + return Bytes.wrap(bytes); + } + + @Override + Bytes of(int... bytes) { + return Bytes.of(bytes); + } + + @Test + void wrapEmpty() { + Bytes wrap = Bytes.wrap(new byte[0]); + assertEquals(Bytes.EMPTY, wrap); + } + + @ParameterizedTest + @MethodSource("wrapProvider") + void wrap(Object arr) { + byte[] bytes = (byte[]) arr; + Bytes value = Bytes.wrap(bytes); + assertEquals(bytes.length, value.size()); + assertArrayEquals(value.toArray(), bytes); + } + + @SuppressWarnings("UnusedMethod") + private static Stream wrapProvider() { + return Stream + .of( + Arguments.of(new Object[] {new byte[10]}), + Arguments.of(new Object[] {new byte[] {1}}), + Arguments.of(new Object[] {new byte[] {1, 2, 3, 4}}), + Arguments.of(new Object[] {new byte[] {-1, 127, -128}})); + } + + @Test + void wrapNull() { + assertThrows(NullPointerException.class, () -> Bytes.wrap((byte[]) null)); + } + + /** + * Checks that modifying a wrapped array modifies the value itself. + */ + @Test + void wrapReflectsUpdates() { + byte[] bytes = new byte[] {1, 2, 3, 4, 5}; + Bytes value = Bytes.wrap(bytes); + + assertEquals(bytes.length, value.size()); + assertArrayEquals(value.toArray(), bytes); + + bytes[1] = 127; + bytes[3] = 127; + + assertEquals(bytes.length, value.size()); + assertArrayEquals(value.toArray(), bytes); + } + + @Test + void wrapSliceEmpty() { + assertEquals(Bytes.EMPTY, Bytes.wrap(new byte[0], 0, 0)); + assertEquals(Bytes.EMPTY, Bytes.wrap(new byte[] {1, 2, 3}, 0, 0)); + assertEquals(Bytes.EMPTY, Bytes.wrap(new byte[] {1, 2, 3}, 2, 0)); + } + + @ParameterizedTest + @MethodSource("wrapSliceProvider") + void wrapSlice(Object arr, int offset, int length) { + assertWrapSlice((byte[]) arr, offset, length); + } + + @SuppressWarnings("UnusedMethod") + private static Stream wrapSliceProvider() { + return Stream + .of( + Arguments.of(new byte[] {1, 2, 3, 4}, 0, 4), + Arguments.of(new byte[] {1, 2, 3, 4}, 0, 2), + Arguments.of(new byte[] {1, 2, 3, 4}, 2, 1), + Arguments.of(new byte[] {1, 2, 3, 4}, 2, 2)); + } + + private void assertWrapSlice(byte[] bytes, int offset, int length) { + Bytes value = Bytes.wrap(bytes, offset, length); + assertEquals(length, value.size()); + assertArrayEquals(value.toArray(), Arrays.copyOfRange(bytes, offset, offset + length)); + } + + @Test + void wrapSliceNull() { + assertThrows(NullPointerException.class, () -> Bytes.wrap(null, 0, 2)); + } + + @Test + void wrapSliceNegativeOffset() { + assertThrows(IndexOutOfBoundsException.class, () -> assertWrapSlice(new byte[] {1, 2, 3, 4}, -1, 4)); + } + + @Test + void wrapSliceOutOfBoundOffset() { + assertThrows(IndexOutOfBoundsException.class, () -> assertWrapSlice(new byte[] {1, 2, 3, 4}, 5, 1)); + } + + @Test + void wrapSliceNegativeLength() { + Throwable exception = + assertThrows(IllegalArgumentException.class, () -> assertWrapSlice(new byte[] {1, 2, 3, 4}, 0, -2)); + assertEquals("Invalid negative length", exception.getMessage()); + } + + @Test + void wrapSliceTooBig() { + Throwable exception = + assertThrows(IllegalArgumentException.class, () -> assertWrapSlice(new byte[] {1, 2, 3, 4}, 2, 3)); + assertEquals("Provided length 3 is too big: the value has only 2 bytes from offset 2", exception.getMessage()); + } + + /** + * Checks that modifying a wrapped array modifies the value itself, but only if within the wrapped slice. + */ + @Test + void wrapSliceReflectsUpdates() { + byte[] bytes = new byte[] {1, 2, 3, 4, 5}; + assertWrapSlice(bytes, 2, 2); + bytes[2] = 127; + bytes[3] = 127; + assertWrapSlice(bytes, 2, 2); + + Bytes wrapped = Bytes.wrap(bytes, 2, 2); + Bytes copy = wrapped.copy(); + + // Modify the bytes outside of the wrapped slice and check this doesn't affect the value (that + // it is still equal to the copy from before the updates) + bytes[0] = 127; + assertEquals(copy, wrapped); + + // Sanity check for copy(): modify within the wrapped slice and check the copy differs now. + bytes[2] = 42; + assertEquals("0x2a7f", wrapped.toHexString()); + assertEquals(Bytes.fromHexString("0x7f7f"), copy); + } + + @Test + void ofBytes() { + assertArrayEquals(Bytes.of().toArray(), new byte[] {}); + assertArrayEquals(Bytes.of((byte) 1, (byte) 2).toArray(), new byte[] {1, 2}); + assertArrayEquals(Bytes.of((byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5).toArray(), new byte[] {1, 2, 3, 4, 5}); + assertArrayEquals(Bytes.of((byte) -1, (byte) 2, (byte) -3).toArray(), new byte[] {-1, 2, -3}); + } + + @Test + void ofInts() { + assertArrayEquals(Bytes.of(1, 2).toArray(), new byte[] {1, 2}); + assertArrayEquals(Bytes.of(1, 2, 3, 4, 5).toArray(), new byte[] {1, 2, 3, 4, 5}); + assertArrayEquals(Bytes.of(0xff, 0x7f, 0x80).toArray(), new byte[] {-1, 127, -128}); + } + + @Test + void ofIntsTooBig() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.of(2, 3, 256)); + assertEquals("3th value 256 does not fit a byte", exception.getMessage()); + } + + @Test + void ofIntsTooLow() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.of(2, -1, 3)); + assertEquals("2th value -1 does not fit a byte", exception.getMessage()); + } + + @Test + void minimalBytes() { + assertEquals(h("0x"), Bytes.minimalBytes(0)); + assertEquals(h("0x01"), Bytes.minimalBytes(1)); + assertEquals(h("0x04"), Bytes.minimalBytes(4)); + assertEquals(h("0x10"), Bytes.minimalBytes(16)); + assertEquals(h("0xFF"), Bytes.minimalBytes(255)); + assertEquals(h("0x0100"), Bytes.minimalBytes(256)); + assertEquals(h("0x0200"), Bytes.minimalBytes(512)); + assertEquals(h("0x010000"), Bytes.minimalBytes(1L << 16)); + assertEquals(h("0x01000000"), Bytes.minimalBytes(1L << 24)); + assertEquals(h("0x0100000000"), Bytes.minimalBytes(1L << 32)); + assertEquals(h("0x010000000000"), Bytes.minimalBytes(1L << 40)); + assertEquals(h("0x01000000000000"), Bytes.minimalBytes(1L << 48)); + assertEquals(h("0x0100000000000000"), Bytes.minimalBytes(1L << 56)); + assertEquals(h("0xFFFFFFFFFFFFFFFF"), Bytes.minimalBytes(-1L)); + } + + @Test + void ofUnsignedShort() { + assertEquals(h("0x0000"), Bytes.ofUnsignedShort(0)); + assertEquals(h("0x0001"), Bytes.ofUnsignedShort(1)); + assertEquals(h("0x0100"), Bytes.ofUnsignedShort(256)); + assertEquals(h("0xFFFF"), Bytes.ofUnsignedShort(65535)); + } + + @Test + void ofUnsignedShortLittleEndian() { + assertEquals(h("0x0000"), Bytes.ofUnsignedShort(0, LITTLE_ENDIAN)); + assertEquals(h("0x0100"), Bytes.ofUnsignedShort(1, LITTLE_ENDIAN)); + assertEquals(h("0x0001"), Bytes.ofUnsignedShort(256, LITTLE_ENDIAN)); + assertEquals(h("0xFFFF"), Bytes.ofUnsignedShort(65535, LITTLE_ENDIAN)); + } + + @Test + void ofUnsignedShortNegative() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.ofUnsignedShort(-1)); + assertEquals( + "Value -1 cannot be represented as an unsigned short (it is negative or too big)", + exception.getMessage()); + } + + @Test + void ofUnsignedShortTooBig() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.ofUnsignedShort(65536)); + assertEquals( + "Value 65536 cannot be represented as an unsigned short (it is negative or too big)", + exception.getMessage()); + } + + @Test + void asUnsignedBigIntegerConstants() { + assertEquals(bi("0"), Bytes.EMPTY.toUnsignedBigInteger()); + assertEquals(bi("1"), Bytes.of(1).toUnsignedBigInteger()); + } + + @Test + void asSignedBigIntegerConstants() { + assertEquals(bi("0"), Bytes.EMPTY.toBigInteger()); + assertEquals(bi("1"), Bytes.of(1).toBigInteger()); + } + + @Test + void fromHexStringLenient() { + assertEquals(Bytes.of(), Bytes.fromHexStringLenient("")); + assertEquals(Bytes.of(), Bytes.fromHexStringLenient("0x")); + assertEquals(Bytes.of(0), Bytes.fromHexStringLenient("0")); + assertEquals(Bytes.of(0), Bytes.fromHexStringLenient("0x0")); + assertEquals(Bytes.of(0), Bytes.fromHexStringLenient("00")); + assertEquals(Bytes.of(0), Bytes.fromHexStringLenient("0x00")); + assertEquals(Bytes.of(1), Bytes.fromHexStringLenient("0x1")); + assertEquals(Bytes.of(1), Bytes.fromHexStringLenient("0x01")); + assertEquals(Bytes.of(0x01, 0xff, 0x2a), Bytes.fromHexStringLenient("1FF2A")); + assertEquals(Bytes.of(0x01, 0xff, 0x2a), Bytes.fromHexStringLenient("0x1FF2A")); + assertEquals(Bytes.of(0x01, 0xff, 0x2a), Bytes.fromHexStringLenient("0x1ff2a")); + assertEquals(Bytes.of(0x01, 0xff, 0x2a), Bytes.fromHexStringLenient("0x1fF2a")); + assertEquals(Bytes.of(0x01, 0xff, 0x2a), Bytes.fromHexStringLenient("01FF2A")); + assertEquals(Bytes.of(0x01, 0xff, 0x2a), Bytes.fromHexStringLenient("0x01FF2A")); + assertEquals(Bytes.of(0x01, 0xff, 0x2a), Bytes.fromHexStringLenient("0x01ff2A")); + } + + @Test + void compareTo() { + assertEquals(1, Bytes.of(0x05).compareTo(Bytes.of(0x01))); + assertEquals(1, Bytes.of(0x05).compareTo(Bytes.of(0x01))); + assertEquals(1, Bytes.of(0xef).compareTo(Bytes.of(0x01))); + assertEquals(1, Bytes.of(0xef).compareTo(Bytes.of(0x00, 0x01))); + assertEquals(1, Bytes.of(0x00, 0x00, 0xef).compareTo(Bytes.of(0x00, 0x01))); + assertEquals(1, Bytes.of(0x00, 0xef).compareTo(Bytes.of(0x00, 0x00, 0x01))); + assertEquals(1, Bytes.of(0xef, 0xf0).compareTo(Bytes.of(0xff))); + assertEquals(1, Bytes.of(0xef, 0xf0).compareTo(Bytes.of(0x01))); + assertEquals(1, Bytes.of(0xef, 0xf1).compareTo(Bytes.of(0xef, 0xf0))); + assertEquals(1, Bytes.of(0x00, 0x00, 0x01).compareTo(Bytes.of(0x00, 0x00))); + assertEquals(0, Bytes.of(0xef, 0xf0).compareTo(Bytes.of(0xef, 0xf0))); + assertEquals(-1, Bytes.of(0xef, 0xf0).compareTo(Bytes.of(0xef, 0xf5))); + assertEquals(-1, Bytes.of(0xef).compareTo(Bytes.of(0xff))); + assertEquals(-1, Bytes.of(0x01).compareTo(Bytes.of(0xff))); + assertEquals(-1, Bytes.of(0x01).compareTo(Bytes.of(0x01, 0xff))); + assertEquals(-1, Bytes.of(0x00, 0x00, 0x01).compareTo(Bytes.of(0x00, 0x02))); + assertEquals(-1, Bytes.of(0x00, 0x01).compareTo(Bytes.of(0x00, 0x00, 0x05))); + assertEquals(0, Bytes.fromHexString("0x0000").compareTo(Bytes.fromHexString("0x00"))); + assertEquals(0, Bytes.fromHexString("0x00").compareTo(Bytes.fromHexString("0x0000"))); + assertEquals(0, Bytes.fromHexString("0x000000").compareTo(Bytes.fromHexString("0x000000"))); + assertEquals(-1, Bytes.fromHexString("0x000001").compareTo(Bytes.fromHexString("0x0001"))); + } + + @Test + void fromHexStringLenientInvalidInput() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.fromHexStringLenient("foo")); + assertEquals("Illegal character 'o' found at index 1 in hex binary representation", exception.getMessage()); + } + + @Test + void fromHexStringLenientLeftPadding() { + assertEquals(Bytes.of(), Bytes.fromHexStringLenient("", 0)); + assertEquals(Bytes.of(0), Bytes.fromHexStringLenient("", 1)); + assertEquals(Bytes.of(0, 0), Bytes.fromHexStringLenient("", 2)); + assertEquals(Bytes.of(0, 0), Bytes.fromHexStringLenient("0x", 2)); + assertEquals(Bytes.of(0, 0, 0), Bytes.fromHexStringLenient("0", 3)); + assertEquals(Bytes.of(0, 0, 0), Bytes.fromHexStringLenient("0x0", 3)); + assertEquals(Bytes.of(0, 0, 0), Bytes.fromHexStringLenient("00", 3)); + assertEquals(Bytes.of(0, 0, 0), Bytes.fromHexStringLenient("0x00", 3)); + assertEquals(Bytes.of(0, 0, 1), Bytes.fromHexStringLenient("0x1", 3)); + assertEquals(Bytes.of(0, 0, 1), Bytes.fromHexStringLenient("0x01", 3)); + assertEquals(Bytes.of(0x01, 0xff, 0x2a), Bytes.fromHexStringLenient("1FF2A", 3)); + assertEquals(Bytes.of(0x00, 0x01, 0xff, 0x2a), Bytes.fromHexStringLenient("0x1FF2A", 4)); + assertEquals(Bytes.of(0x00, 0x00, 0x01, 0xff, 0x2a), Bytes.fromHexStringLenient("0x1ff2a", 5)); + assertEquals(Bytes.of(0x00, 0x01, 0xff, 0x2a), Bytes.fromHexStringLenient("0x1fF2a", 4)); + assertEquals(Bytes.of(0x00, 0x01, 0xff, 0x2a), Bytes.fromHexStringLenient("01FF2A", 4)); + assertEquals(Bytes.of(0x01, 0xff, 0x2a), Bytes.fromHexStringLenient("0x01FF2A", 3)); + assertEquals(Bytes.of(0x01, 0xff, 0x2a), Bytes.fromHexStringLenient("0x01ff2A", 3)); + } + + @Test + void fromHexStringLenientLeftPaddingInvalidInput() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.fromHexStringLenient("foo", 10)); + assertEquals("Illegal character 'o' found at index 1 in hex binary representation", exception.getMessage()); + } + + @Test + void fromHexStringLenientLeftPaddingInvalidSize() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.fromHexStringLenient("0x001F34", 2)); + assertEquals("Hex value is too large: expected at most 2 bytes but got 3", exception.getMessage()); + } + + @Test + void fromHexString() { + assertEquals(Bytes.of(), Bytes.fromHexString("0x")); + assertEquals(Bytes.of(0), Bytes.fromHexString("00")); + assertEquals(Bytes.of(0), Bytes.fromHexString("0x00")); + assertEquals(Bytes.of(1), Bytes.fromHexString("0x01")); + assertEquals(Bytes.of(1, 0xff, 0x2a), Bytes.fromHexString("01FF2A")); + assertEquals(Bytes.of(1, 0xff, 0x2a), Bytes.fromHexString("0x01FF2A")); + assertEquals(Bytes.of(1, 0xff, 0x2a), Bytes.fromHexString("0x01ff2a")); + assertEquals(Bytes.of(1, 0xff, 0x2a), Bytes.fromHexString("0x01fF2a")); + } + + @Test + void fromHexStringInvalidInput() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.fromHexString("fooo")); + assertEquals("Illegal character 'o' found at index 1 in hex binary representation", exception.getMessage()); + } + + @Test + void fromHexStringNotLenient() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.fromHexString("0x100")); + assertEquals("Invalid odd-length hex binary representation", exception.getMessage()); + } + + @Test + void fromHexStringLeftPadding() { + assertEquals(Bytes.of(), Bytes.fromHexString("0x", 0)); + assertEquals(Bytes.of(0, 0), Bytes.fromHexString("0x", 2)); + assertEquals(Bytes.of(0, 0, 0, 0), Bytes.fromHexString("0x", 4)); + assertEquals(Bytes.of(0, 0), Bytes.fromHexString("00", 2)); + assertEquals(Bytes.of(0, 0), Bytes.fromHexString("0x00", 2)); + assertEquals(Bytes.of(0, 0, 1), Bytes.fromHexString("0x01", 3)); + assertEquals(Bytes.of(0x00, 0x01, 0xff, 0x2a), Bytes.fromHexString("01FF2A", 4)); + assertEquals(Bytes.of(0x01, 0xff, 0x2a), Bytes.fromHexString("0x01FF2A", 3)); + assertEquals(Bytes.of(0x00, 0x00, 0x01, 0xff, 0x2a), Bytes.fromHexString("0x01ff2a", 5)); + assertEquals(Bytes.of(0x00, 0x00, 0x01, 0xff, 0x2a), Bytes.fromHexString("0x01fF2a", 5)); + } + + @Test + void fromHexStringLeftPaddingInvalidInput() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.fromHexString("fooo", 4)); + assertEquals("Illegal character 'o' found at index 1 in hex binary representation", exception.getMessage()); + } + + @Test + void fromHexStringLeftPaddingNotLenient() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.fromHexString("0x100", 4)); + assertEquals("Invalid odd-length hex binary representation", exception.getMessage()); + } + + @Test + void fromHexStringLeftPaddingInvalidSize() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes.fromHexStringLenient("0x001F34", 2)); + assertEquals("Hex value is too large: expected at most 2 bytes but got 3", exception.getMessage()); + } + + @Test + void fromBase64Roundtrip() { + Bytes value = Bytes.fromBase64String("deadbeefISDAbest"); + assertEquals("deadbeefISDAbest", value.toBase64String()); + } + + @Test + void littleEndianRoundtrip() { + int val = Integer.MAX_VALUE - 5; + Bytes littleEndianEncoded = Bytes.ofUnsignedInt(val, LITTLE_ENDIAN); + assertEquals(4, littleEndianEncoded.size()); + Bytes bigEndianEncoded = Bytes.ofUnsignedInt(val); + assertEquals(bigEndianEncoded.get(0), littleEndianEncoded.get(3)); + assertEquals(bigEndianEncoded.get(1), littleEndianEncoded.get(2)); + assertEquals(bigEndianEncoded.get(2), littleEndianEncoded.get(1)); + assertEquals(bigEndianEncoded.get(3), littleEndianEncoded.get(0)); + + int read = littleEndianEncoded.toInt(LITTLE_ENDIAN); + assertEquals(val, read); + } + + @Test + void littleEndianLongRoundtrip() { + long val = 1L << 46; + Bytes littleEndianEncoded = Bytes.ofUnsignedLong(val, LITTLE_ENDIAN); + assertEquals(8, littleEndianEncoded.size()); + Bytes bigEndianEncoded = Bytes.ofUnsignedLong(val); + assertEquals(bigEndianEncoded.get(0), littleEndianEncoded.get(7)); + assertEquals(bigEndianEncoded.get(1), littleEndianEncoded.get(6)); + assertEquals(bigEndianEncoded.get(2), littleEndianEncoded.get(5)); + assertEquals(bigEndianEncoded.get(3), littleEndianEncoded.get(4)); + assertEquals(bigEndianEncoded.get(4), littleEndianEncoded.get(3)); + assertEquals(bigEndianEncoded.get(5), littleEndianEncoded.get(2)); + assertEquals(bigEndianEncoded.get(6), littleEndianEncoded.get(1)); + assertEquals(bigEndianEncoded.get(7), littleEndianEncoded.get(0)); + + long read = littleEndianEncoded.toLong(LITTLE_ENDIAN); + assertEquals(val, read); + } + + @Test + void reverseBytes() { + Bytes bytes = Bytes.fromHexString("0x000102030405"); + assertEquals(Bytes.fromHexString("0x050403020100"), bytes.reverse()); + } + + @Test + void reverseBytesEmptyArray() { + Bytes bytes = Bytes.fromHexString("0x"); + assertEquals(Bytes.fromHexString("0x"), bytes.reverse()); + } + + @Test + void mutableBytesIncrement() { + MutableBytes one = MutableBytes.of(1); + one.increment(); + assertEquals(Bytes.of(2), one); + } + + @Test + void mutableBytesIncrementMax() { + MutableBytes maxed = MutableBytes.of(1, 0xFF); + maxed.increment(); + assertEquals(Bytes.of(2, 0), maxed); + } + + @Test + void mutableBytesIncrementOverflow() { + MutableBytes maxed = MutableBytes.of(0xFF, 0xFF, 0xFF); + maxed.increment(); + assertEquals(Bytes.of(0, 0, 0), maxed); + } + + @Test + void mutableBytesDecrement() { + MutableBytes one = MutableBytes.of(2); + one.decrement(); + assertEquals(Bytes.of(1), one); + } + + @Test + void mutableBytesDecrementMax() { + MutableBytes maxed = MutableBytes.of(1, 0); + maxed.decrement(); + assertEquals(Bytes.of(0, 0xFF), maxed); + } + + @Test + void mutableBytesDecrementOverflow() { + MutableBytes maxed = MutableBytes.of(0x00, 0x00, 0x00); + maxed.decrement(); + assertEquals(Bytes.of(0xFF, 0xFF, 0xFF), maxed); + } + + @Test + void concatenation() { + MutableBytes value1 = MutableBytes.wrap(Bytes.fromHexString("deadbeef").toArrayUnsafe()); + Bytes result = Bytes.concatenate(value1, value1); + assertEquals(Bytes.fromHexString("deadbeefdeadbeef"), result); + value1.set(0, (byte) 0); + assertEquals(Bytes.fromHexString("deadbeefdeadbeef"), result); + } + + @Test + void wrap() { + MutableBytes value1 = MutableBytes.wrap(Bytes.fromHexString("deadbeef").toArrayUnsafe()); + Bytes result = Bytes.wrap(value1, value1); + assertEquals(Bytes.fromHexString("deadbeefdeadbeef"), result); + value1.set(0, (byte) 0); + assertEquals(Bytes.fromHexString("0x00adbeef00adbeef"), result); + } + + @Test + void random() { + Bytes value = Bytes.random(20); + assertNotEquals(value, Bytes.random(20)); + assertEquals(20, value.size()); + } + + @Test + void getInt() { + Bytes value = Bytes.fromHexString("0x00000001"); + assertEquals(1, value.getInt(0)); + assertEquals(16777216, value.getInt(0, LITTLE_ENDIAN)); + assertEquals(1, value.toInt()); + assertEquals(16777216, value.toInt(LITTLE_ENDIAN)); + } + + @Test + void getLong() { + Bytes value = Bytes.fromHexString("0x0000000000000001"); + assertEquals(1, value.getLong(0)); + assertEquals(72057594037927936L, value.getLong(0, LITTLE_ENDIAN)); + assertEquals(1, value.toLong()); + assertEquals(72057594037927936L, value.toLong(LITTLE_ENDIAN)); + } + + @Test + void numberOfLeadingZeros() { + Bytes value = Bytes.fromHexString("0x00000001"); + assertEquals(31, value.numberOfLeadingZeros()); + } + + @Test + void and() { + Bytes value = Bytes.fromHexString("0x01000001").and(Bytes.fromHexString("0x01000000")); + assertEquals(Bytes.fromHexString("0x01000000"), value); + } + + @Test + void andResult() { + MutableBytes result = MutableBytes.create(4); + Bytes.fromHexString("0x01000001").and(Bytes.fromHexString("0x01000000"), result); + assertEquals(Bytes.fromHexString("0x01000000"), result); + } + + @Test + void or() { + Bytes value = Bytes.fromHexString("0x01000001").or(Bytes.fromHexString("0x01000000")); + assertEquals(Bytes.fromHexString("0x01000001"), value); + } + + @Test + void orResult() { + MutableBytes result = MutableBytes.create(4); + Bytes.fromHexString("0x01000001").or(Bytes.fromHexString("0x01000000"), result); + assertEquals(Bytes.fromHexString("0x01000001"), result); + } + + @Test + void xor() { + Bytes value = Bytes.fromHexString("0x01000001").xor(Bytes.fromHexString("0x01000000")); + assertEquals(Bytes.fromHexString("0x00000001"), value); + } + + @Test + void xorResult() { + MutableBytes result = MutableBytes.create(4); + Bytes.fromHexString("0x01000001").xor(Bytes.fromHexString("0x01000000"), result); + assertEquals(Bytes.fromHexString("0x00000001"), result); + } + + @Test + void not() { + Bytes value = Bytes.fromHexString("0x01000001").not(); + assertEquals(Bytes.fromHexString("0xfefffffe"), value); + } + + @Test + void notResult() { + MutableBytes result = MutableBytes.create(4); + Bytes.fromHexString("0x01000001").not(result); + assertEquals(Bytes.fromHexString("0xfefffffe"), result); + } + + @Test + void shiftRight() { + Bytes value = Bytes.fromHexString("0x01000001").shiftRight(2); + assertEquals(Bytes.fromHexString("0x00400000"), value); + } + + @Test + void shiftRightResult() { + MutableBytes result = MutableBytes.create(4); + Bytes.fromHexString("0x01000001").shiftRight(2, result); + assertEquals(Bytes.fromHexString("0x00400000"), result); + } + + @Test + void shiftLeft() { + Bytes value = Bytes.fromHexString("0x01000001").shiftLeft(2); + assertEquals(Bytes.fromHexString("0x04000004"), value); + } + + @Test + void shiftLeftResult() { + MutableBytes result = MutableBytes.create(4); + Bytes.fromHexString("0x01000001").shiftLeft(2, result); + assertEquals(Bytes.fromHexString("0x04000004"), result); + } + + @Test + void commonPrefix() { + Bytes value = Bytes.fromHexString("0x01234567"); + Bytes value2 = Bytes.fromHexString("0x01236789"); + assertEquals(2, value.commonPrefixLength(value2)); + assertEquals(Bytes.fromHexString("0x0123"), value.commonPrefix(value2)); + } + + @Test + void testWrapByteBufEmpty() { + ByteBuf buffer = Unpooled.buffer(0); + assertSame(Bytes.EMPTY, Bytes.wrapByteBuf(buffer)); + } + + @Test + void testWrapByteBufWithIndexEmpty() { + ByteBuf buffer = Unpooled.buffer(3); + assertSame(Bytes.EMPTY, Bytes.wrapByteBuf(buffer, 3, 0)); + } + + @Test + void testWrapByteBufSizeWithOffset() { + ByteBuf buffer = Unpooled.buffer(10); + assertEquals(1, Bytes.wrapByteBuf(buffer, 1, 1).size()); + } + + @Test + void testWrapByteBufSize() { + ByteBuf buffer = Unpooled.buffer(20); + assertEquals(20, Bytes.wrapByteBuf(buffer).size()); + } + + @Test + void testWrapByteBufReadableBytes() { + ByteBuf buffer = Unpooled.buffer(20).writeByte(3); + assertEquals(1, Bytes.wrapByteBuf(buffer, 0, buffer.readableBytes()).size()); + } + + @Test + void segmentBytes() { + Bytes b = Bytes + .wrap( + Bytes32.ZERO, + Bytes32.random(), + Bytes32.rightPad(Bytes.fromHexStringLenient("0x1")), + Bytes.fromHexString("0xf000")); + Bytes32[] result = Bytes.segment(b); + assertEquals(4, result.length); + assertEquals(Bytes32.rightPad(Bytes.fromHexString("0xf000")), result[3]); + } + + @Test + void segments() { + Bytes value = Bytes.fromHexString("0x7b600035f660115760006000526001601ff35b60016000526001601ff3600052601c6000f3"); + Bytes32[] result = Bytes.segment(value); + assertEquals(Bytes.fromHexString("0x7b600035f660115760006000526001601ff35b60016000526001601ff3600052"), result[0]); + assertEquals(Bytes.fromHexString("0x601c6000f3000000000000000000000000000000000000000000000000000000"), result[1]); + } + + @Test + void testTrimLeadingZeros() { + Bytes b = Bytes.fromHexString("0x000000f300567800"); + assertEquals(Bytes.fromHexString("0xf300567800"), b.trimLeadingZeros()); + } + + @Test + void testTrimTrailingZeros() { + Bytes b = Bytes.fromHexString("0x000000f300567800"); + assertEquals(Bytes.fromHexString("0x000000f3005678"), b.trimTrailingZeros()); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/CommonBytesTests.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/CommonBytesTests.java new file mode 100644 index 00000000000..7e717dfe01d --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/CommonBytesTests.java @@ -0,0 +1,687 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import io.netty.buffer.Unpooled; +import io.vertx.core.buffer.Buffer; +import org.junit.jupiter.api.Test; + +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.function.Function; + +import static org.junit.jupiter.api.Assertions.*; + +abstract class CommonBytesTests { + + abstract Bytes h(String hex); + + abstract MutableBytes m(int size); + + abstract Bytes w(byte[] bytes); + + abstract Bytes of(int... bytes); + + BigInteger bi(String decimal) { + return new BigInteger(decimal); + } + + @Test + void asUnsignedBigInteger() { + // Make sure things are interpreted unsigned. + assertEquals(bi("255"), h("0xFF").toUnsignedBigInteger()); + + // Try 2^100 + Long.MAX_VALUE, as an easy to define a big not too special big integer. + BigInteger expected = BigInteger.valueOf(2).pow(100).add(BigInteger.valueOf(Long.MAX_VALUE)); + + // 2^100 is a one followed by 100 zeros, that's 12 bytes of zeros (=96) plus 4 more zeros (so + // 0x10 == 16). + MutableBytes v = m(13); + v.set(0, (byte) 16); + v.setLong(v.size() - 8, Long.MAX_VALUE); + assertEquals(expected, v.toUnsignedBigInteger()); + } + + @Test + void testAsSignedBigInteger() { + // Make sure things are interpreted signed. + assertEquals(bi("-1"), h("0xFF").toBigInteger()); + + // Try 2^100 + Long.MAX_VALUE, as an easy to define a big but not too special big integer. + BigInteger expected = BigInteger.valueOf(2).pow(100).add(BigInteger.valueOf(Long.MAX_VALUE)); + + // 2^100 is a one followed by 100 zeros, that's 12 bytes of zeros (=96) plus 4 more zeros (so + // 0x10 == 16). + MutableBytes v = m(13); + v.set(0, (byte) 16); + v.setLong(v.size() - 8, Long.MAX_VALUE); + assertEquals(expected, v.toBigInteger()); + + // And for a large negative one, we use -(2^100 + Long.MAX_VALUE), which is: + // 2^100 + Long.MAX_VALUE = 0x10(4 bytes of 0)7F( 7 bytes of 1) + // inverse = 0xEF(4 bytes of 1)80( 7 bytes of 0) + // +1 = 0xEF(4 bytes of 1)80(6 bytes of 0)01 + expected = expected.negate(); + v = m(13); + v.set(0, (byte) 0xEF); + for (int i = 1; i < 5; i++) { + v.set(i, (byte) 0xFF); + } + v.set(5, (byte) 0x80); + // 6 bytes of 0 + v.set(12, (byte) 1); + assertEquals(expected, v.toBigInteger()); + } + + @Test + void testSize() { + assertEquals(0, w(new byte[0]).size()); + assertEquals(1, w(new byte[1]).size()); + assertEquals(10, w(new byte[10]).size()); + } + + @Test + void testGet() { + Bytes v = w(new byte[] {1, 2, 3, 4}); + assertEquals((int) (byte) 1, (int) v.get(0)); + assertEquals((int) (byte) 2, (int) v.get(1)); + assertEquals((int) (byte) 3, (int) v.get(2)); + assertEquals((int) (byte) 4, (int) v.get(3)); + } + + @Test + void testGetNegativeIndex() { + assertThrows(IndexOutOfBoundsException.class, () -> w(new byte[] {1, 2, 3, 4}).get(-1)); + } + + @Test + void testGetOutOfBound() { + assertThrows(IndexOutOfBoundsException.class, () -> w(new byte[] {1, 2, 3, 4}).get(4)); + } + + @Test + void testGetInt() { + Bytes value = w(new byte[] {0, 0, 1, 0, -1, -1, -1, -1}); + + // 0x00000100 = 256 + assertEquals(256, value.getInt(0)); + // 0x000100FF = 65536 + 255 = 65791 + assertEquals(65791, value.getInt(1)); + // 0x0100FFFF = 16777216 (2^24) + (65536 - 1) = 16842751 + assertEquals(16842751, value.getInt(2)); + // 0xFFFFFFFF = -1 + assertEquals(-1, value.getInt(4)); + } + + @Test + void testGetIntNegativeIndex() { + assertThrows(IndexOutOfBoundsException.class, () -> w(new byte[] {1, 2, 3, 4}).getInt(-1)); + } + + @Test + void testGetIntOutOfBound() { + assertThrows(IndexOutOfBoundsException.class, () -> w(new byte[] {1, 2, 3, 4}).getInt(4)); + } + + @Test + void testGetIntNotEnoughBytes() { + assertThrows(IndexOutOfBoundsException.class, () -> w(new byte[] {1, 2, 3, 4}).getInt(1)); + } + + @Test + void testAsInt() { + assertEquals(0, Bytes.EMPTY.toInt()); + Bytes value1 = w(new byte[] {0, 0, 1, 0}); + // 0x00000100 = 256 + assertEquals(256, value1.toInt()); + assertEquals(256, value1.slice(2).toInt()); + + Bytes value2 = w(new byte[] {0, 1, 0, -1}); + // 0x000100FF = 65536 + 255 = 65791 + assertEquals(65791, value2.toInt()); + assertEquals(65791, value2.slice(1).toInt()); + + Bytes value3 = w(new byte[] {1, 0, -1, -1}); + // 0x0100FFFF = 16777216 (2^24) + (65536 - 1) = 16842751 + assertEquals(16842751, value3.toInt()); + + Bytes value4 = w(new byte[] {-1, -1, -1, -1}); + // 0xFFFFFFFF = -1 + assertEquals(-1, value4.toInt()); + } + + @Test + void testAsIntTooManyBytes() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> w(new byte[] {1, 2, 3, 4, 5}).toInt()); + assertEquals("Value of size 5 has more than 4 bytes", exception.getMessage()); + } + + @Test + void testGetLong() { + Bytes value1 = w(new byte[] {0, 0, 1, 0, -1, -1, -1, -1, 0, 0}); + // 0x00000100FFFFFFFF = (2^40) + (2^32) - 1 = 1103806595071 + assertEquals(1103806595071L, value1.getLong(0)); + // 0x 000100FFFFFFFF00 = (2^48) + (2^40) - 1 - 255 = 282574488338176 + assertEquals(282574488338176L, value1.getLong(1)); + + Bytes value2 = w(new byte[] {-1, -1, -1, -1, -1, -1, -1, -1}); + assertEquals(-1L, value2.getLong(0)); + } + + @Test + void testGetLongNegativeIndex() { + assertThrows(IndexOutOfBoundsException.class, () -> w(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}).getLong(-1)); + } + + @Test + void testGetLongOutOfBound() { + assertThrows(IndexOutOfBoundsException.class, () -> w(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}).getLong(8)); + } + + @Test + void testGetLongNotEnoughBytes() { + assertThrows(IndexOutOfBoundsException.class, () -> w(new byte[] {1, 2, 3, 4}).getLong(0)); + } + + @Test + void testAsLong() { + assertEquals(0, Bytes.EMPTY.toLong()); + Bytes value1 = w(new byte[] {0, 0, 1, 0, -1, -1, -1, -1}); + // 0x00000100FFFFFFFF = (2^40) + (2^32) - 1 = 1103806595071 + assertEquals(1103806595071L, value1.toLong()); + assertEquals(1103806595071L, value1.slice(2).toLong()); + Bytes value2 = w(new byte[] {0, 1, 0, -1, -1, -1, -1, 0}); + // 0x000100FFFFFFFF00 = (2^48) + (2^40) - 1 - 255 = 282574488338176 + assertEquals(282574488338176L, value2.toLong()); + assertEquals(282574488338176L, value2.slice(1).toLong()); + + Bytes value3 = w(new byte[] {-1, -1, -1, -1, -1, -1, -1, -1}); + assertEquals(-1L, value3.toLong()); + } + + @Test + void testAsLongTooManyBytes() { + Throwable exception = + assertThrows(IllegalArgumentException.class, () -> w(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}).toLong()); + assertEquals("Value of size 9 has more than 8 bytes", exception.getMessage()); + } + + @Test + void testSlice() { + assertEquals(h("0x"), h("0x0123456789").slice(0, 0)); + assertEquals(h("0x"), h("0x0123456789").slice(2, 0)); + assertEquals(h("0x01"), h("0x0123456789").slice(0, 1)); + assertEquals(h("0x0123"), h("0x0123456789").slice(0, 2)); + + assertEquals(h("0x4567"), h("0x0123456789").slice(2, 2)); + assertEquals(h("0x23456789"), h("0x0123456789").slice(1, 4)); + } + + @Test + void testSliceNegativeOffset() { + assertThrows(IndexOutOfBoundsException.class, () -> h("0x012345").slice(-1, 2)); + } + + @Test + void testSliceOffsetOutOfBound() { + assertThrows(IndexOutOfBoundsException.class, () -> h("0x012345").slice(3, 2)); + } + + @Test + void testSliceTooLong() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> h("0x012345").slice(1, 3)); + assertEquals( + "Provided length 3 is too big: the value has size 3 and has only 2 bytes from 1", + exception.getMessage()); + } + + @Test + void testMutableCopy() { + Bytes v = h("0x012345"); + MutableBytes mutableCopy = v.mutableCopy(); + + // Initially, copy must be equal. + assertEquals(mutableCopy, v); + + // Upon modification, original should not have been modified. + mutableCopy.set(0, (byte) -1); + assertNotEquals(mutableCopy, v); + assertEquals(h("0x012345"), v); + assertEquals(h("0xFF2345"), mutableCopy); + } + + @Test + void testCopyTo() { + MutableBytes dest; + + // The follow does nothing, but simply making sure it doesn't throw. + dest = MutableBytes.EMPTY; + Bytes.EMPTY.copyTo(dest); + assertEquals(Bytes.EMPTY, dest); + + dest = MutableBytes.create(1); + of(1).copyTo(dest); + assertEquals(h("0x01"), dest); + + dest = MutableBytes.create(1); + of(10).copyTo(dest); + assertEquals(h("0x0A"), dest); + + dest = MutableBytes.create(2); + of(0xff, 0x03).copyTo(dest); + assertEquals(h("0xFF03"), dest); + + dest = MutableBytes.create(4); + of(0xff, 0x03).copyTo(dest.mutableSlice(1, 2)); + assertEquals(h("0x00FF0300"), dest); + } + + @Test + void testCopyToTooSmall() { + Throwable exception = + assertThrows(IllegalArgumentException.class, () -> of(1, 2, 3).copyTo(MutableBytes.create(2))); + assertEquals("Cannot copy 3 bytes to destination of non-equal size 2", exception.getMessage()); + } + + @Test + void testCopyToTooBig() { + Throwable exception = + assertThrows(IllegalArgumentException.class, () -> of(1, 2, 3).copyTo(MutableBytes.create(4))); + assertEquals("Cannot copy 3 bytes to destination of non-equal size 4", exception.getMessage()); + } + + @Test + void testCopyToWithOffset() { + MutableBytes dest; + + dest = MutableBytes.wrap(new byte[] {1, 2, 3}); + Bytes.EMPTY.copyTo(dest, 0); + assertEquals(h("0x010203"), dest); + + dest = MutableBytes.wrap(new byte[] {1, 2, 3}); + of(1).copyTo(dest, 1); + assertEquals(h("0x010103"), dest); + + dest = MutableBytes.wrap(new byte[] {1, 2, 3}); + of(2).copyTo(dest, 0); + assertEquals(h("0x020203"), dest); + + dest = MutableBytes.wrap(new byte[] {1, 2, 3}); + of(1, 1).copyTo(dest, 1); + assertEquals(h("0x010101"), dest); + + dest = MutableBytes.create(4); + of(0xff, 0x03).copyTo(dest, 1); + assertEquals(h("0x00FF0300"), dest); + } + + @Test + void testCopyToWithOffsetTooSmall() { + Throwable exception = + assertThrows(IllegalArgumentException.class, () -> of(1, 2, 3).copyTo(MutableBytes.create(4), 2)); + assertEquals("Cannot copy 3 bytes, destination has only 2 bytes from index 2", exception.getMessage()); + } + + @Test + void testCopyToWithNegativeOffset() { + assertThrows(IndexOutOfBoundsException.class, () -> of(1, 2, 3).copyTo(MutableBytes.create(10), -1)); + } + + @Test + void testCopyToWithOutOfBoundIndex() { + assertThrows(IndexOutOfBoundsException.class, () -> of(1, 2, 3).copyTo(MutableBytes.create(10), 10)); + } + + @Test + void testAppendTo() { + testAppendTo(Bytes.EMPTY, Buffer.buffer(), Bytes.EMPTY); + testAppendTo(Bytes.EMPTY, Buffer.buffer(h("0x1234").toArrayUnsafe()), h("0x1234")); + testAppendTo(h("0x1234"), Buffer.buffer(), h("0x1234")); + testAppendTo(h("0x5678"), Buffer.buffer(h("0x1234").toArrayUnsafe()), h("0x12345678")); + } + + private void testAppendTo(Bytes toAppend, Buffer buffer, Bytes expected) { + toAppend.appendTo(buffer); + assertEquals(expected, Bytes.wrap(buffer.getBytes())); + } + + @Test + void testIsZero() { + assertTrue(Bytes.EMPTY.isZero()); + assertTrue(Bytes.of(0).isZero()); + assertTrue(Bytes.of(0, 0, 0).isZero()); + + assertFalse(Bytes.of(1).isZero()); + assertFalse(Bytes.of(1, 0, 0).isZero()); + assertFalse(Bytes.of(0, 0, 1).isZero()); + assertFalse(Bytes.of(0, 0, 1, 0, 0).isZero()); + } + + @Test + void testIsEmpty() { + assertTrue(Bytes.EMPTY.isEmpty()); + + assertFalse(Bytes.of(0).isEmpty()); + assertFalse(Bytes.of(0, 0, 0).isEmpty()); + assertFalse(Bytes.of(1).isEmpty()); + } + + @Test + void findsCommonPrefix() { + Bytes v = Bytes.of(1, 2, 3, 4, 5, 6, 7); + Bytes o = Bytes.of(1, 2, 3, 4, 4, 3, 2); + assertEquals(4, v.commonPrefixLength(o)); + assertEquals(Bytes.of(1, 2, 3, 4), v.commonPrefix(o)); + } + + @Test + void findsCommonPrefixOfShorter() { + Bytes v = Bytes.of(1, 2, 3, 4, 5, 6, 7); + Bytes o = Bytes.of(1, 2, 3, 4); + assertEquals(4, v.commonPrefixLength(o)); + assertEquals(Bytes.of(1, 2, 3, 4), v.commonPrefix(o)); + } + + @Test + void findsCommonPrefixOfLonger() { + Bytes v = Bytes.of(1, 2, 3, 4); + Bytes o = Bytes.of(1, 2, 3, 4, 4, 3, 2); + assertEquals(4, v.commonPrefixLength(o)); + assertEquals(Bytes.of(1, 2, 3, 4), v.commonPrefix(o)); + } + + @Test + void findsCommonPrefixOfSliced() { + Bytes v = Bytes.of(1, 2, 3, 4).slice(2, 2); + Bytes o = Bytes.of(3, 4, 3, 3, 2).slice(3, 2); + assertEquals(1, v.commonPrefixLength(o)); + assertEquals(Bytes.of(3), v.commonPrefix(o)); + } + + @Test + void testTrimLeadingZeroes() { + assertEquals(h("0x"), h("0x").trimLeadingZeros()); + assertEquals(h("0x"), h("0x00").trimLeadingZeros()); + assertEquals(h("0x"), h("0x00000000").trimLeadingZeros()); + + assertEquals(h("0x01"), h("0x01").trimLeadingZeros()); + assertEquals(h("0x01"), h("0x00000001").trimLeadingZeros()); + + assertEquals(h("0x3010"), h("0x3010").trimLeadingZeros()); + assertEquals(h("0x3010"), h("0x00003010").trimLeadingZeros()); + + assertEquals(h("0xFFFFFFFF"), h("0xFFFFFFFF").trimLeadingZeros()); + assertEquals(h("0xFFFFFFFF"), h("0x000000000000FFFFFFFF").trimLeadingZeros()); + } + + @Test + void testQuantityHexString() { + assertEquals("0x0", h("0x").toQuantityHexString()); + assertEquals("0x0", h("0x0000").toQuantityHexString()); + assertEquals("0x1000001", h("0x01000001").toQuantityHexString()); + } + + @Test + void testHexString() { + assertEquals("0x", h("0x").toShortHexString()); + assertEquals("0x", h("0x0000").toShortHexString()); + assertEquals("0x1000001", h("0x01000001").toShortHexString()); + + assertEquals("0000", h("0x0000").toUnprefixedHexString()); + assertEquals("1234", h("0x1234").toUnprefixedHexString()); + assertEquals("0022", h("0x0022").toUnprefixedHexString()); + } + + @Test + void testEllipsisHexString() { + assertEquals("0x", h("0x").toEllipsisHexString()); + assertEquals("0x0000", h("0x0000").toEllipsisHexString()); + assertEquals("0x01000001", h("0x01000001").toEllipsisHexString()); + assertEquals("0x0100000001", h("0x0100000001").toEllipsisHexString()); + assertEquals("0x0100..0001", h("0x010000000001").toEllipsisHexString()); + assertEquals("0x1234..5678", h("0x123456789abcdef012345678").toEllipsisHexString()); + assertEquals("0x1234..789a", h("0x123456789abcdef0123456789a").toEllipsisHexString()); + assertEquals("0x1234..9abc", h("0x123456789abcdef0123456789abc").toEllipsisHexString()); + assertEquals("0x1234..bcde", h("0x123456789abcdef0123456789abcde").toEllipsisHexString()); + assertEquals("0x1234..def0", h("0x123456789abcdef0123456789abcdef0").toEllipsisHexString()); + assertEquals("0x1234..def0", h("0x123456789abcdef0123456789abcdef0").toEllipsisHexString()); + } + + @Test + void slideToEnd() { + assertEquals(Bytes.of(1, 2, 3, 4), Bytes.of(1, 2, 3, 4).slice(0)); + assertEquals(Bytes.of(2, 3, 4), Bytes.of(1, 2, 3, 4).slice(1)); + assertEquals(Bytes.of(3, 4), Bytes.of(1, 2, 3, 4).slice(2)); + assertEquals(Bytes.of(4), Bytes.of(1, 2, 3, 4).slice(3)); + } + + @Test + void slicePastEndReturnsEmpty() { + assertEquals(Bytes.EMPTY, Bytes.of(1, 2, 3, 4).slice(4)); + assertEquals(Bytes.EMPTY, Bytes.of(1, 2, 3, 4).slice(5)); + } + + @Test + void testUpdate() throws NoSuchAlgorithmException { + // Digest the same byte array in 4 ways: + // 1) directly from the array + // 2) after wrapped using the update() method + // 3) after wrapped and copied using the update() method + // 4) after wrapped but getting the byte manually + // and check all compute the same digest. + MessageDigest md1 = MessageDigest.getInstance("SHA-1"); + MessageDigest md2 = MessageDigest.getInstance("SHA-1"); + MessageDigest md3 = MessageDigest.getInstance("SHA-1"); + MessageDigest md4 = MessageDigest.getInstance("SHA-1"); + + byte[] toDigest = new BigInteger("12324029423415041783577517238472017314").toByteArray(); + Bytes wrapped = w(toDigest); + + byte[] digest1 = md1.digest(toDigest); + + wrapped.update(md2); + byte[] digest2 = md2.digest(); + + wrapped.copy().update(md3); + byte[] digest3 = md3.digest(); + + for (int i = 0; i < wrapped.size(); i++) + md4.update(wrapped.get(i)); + byte[] digest4 = md4.digest(); + + assertArrayEquals(digest2, digest1); + assertArrayEquals(digest3, digest1); + assertArrayEquals(digest4, digest1); + } + + @Test + void testArrayExtraction() { + // extractArray() and getArrayUnsafe() have essentially the same contract... + testArrayExtraction(Bytes::toArray); + testArrayExtraction(Bytes::toArrayUnsafe); + + // But on top of the basic, extractArray() guarantees modifying the returned array is safe from + // impacting the original value (not that getArrayUnsafe makes no guarantees here one way or + // another, so there is nothing to test). + byte[] orig = new byte[] {1, 2, 3, 4}; + Bytes value = w(orig); + byte[] extracted = value.toArray(); + assertArrayEquals(orig, extracted); + Arrays.fill(extracted, (byte) -1); + assertArrayEquals(extracted, new byte[] {-1, -1, -1, -1}); + assertArrayEquals(orig, new byte[] {1, 2, 3, 4}); + assertEquals(of(1, 2, 3, 4), value); + } + + private void testArrayExtraction(Function extractor) { + byte[] bytes = new byte[0]; + assertArrayEquals(extractor.apply(Bytes.EMPTY), bytes); + + byte[][] toTest = new byte[][] {new byte[] {1}, new byte[] {1, 2, 3, 4, 5, 6}, new byte[] {-1, -1, 0, -1}}; + for (byte[] array : toTest) { + assertArrayEquals(extractor.apply(w(array)), array); + } + + // Test slightly more complex interactions + assertArrayEquals(extractor.apply(w(new byte[] {1, 2, 3, 4, 5}).slice(2, 2)), new byte[] {3, 4}); + assertArrayEquals(extractor.apply(w(new byte[] {1, 2, 3, 4, 5}).slice(2, 0)), new byte[] {}); + } + + @Test + void testToString() { + assertEquals("0x", Bytes.EMPTY.toString()); + + assertEquals("0x01", of(1).toString()); + assertEquals("0x0aff03", of(0x0a, 0xff, 0x03).toString()); + } + + @Test + void testHasLeadingZeroByte() { + assertFalse(Bytes.fromHexString("0x").hasLeadingZeroByte()); + assertTrue(Bytes.fromHexString("0x0012").hasLeadingZeroByte()); + assertFalse(Bytes.fromHexString("0x120012").hasLeadingZeroByte()); + } + + @Test + void testNumberOfLeadingZeroBytes() { + assertEquals(0, Bytes.fromHexString("0x12").numberOfLeadingZeroBytes()); + assertEquals(1, Bytes.fromHexString("0x0012").numberOfLeadingZeroBytes()); + assertEquals(2, Bytes.fromHexString("0x000012").numberOfLeadingZeroBytes()); + assertEquals(0, Bytes.fromHexString("0x").numberOfLeadingZeroBytes()); + assertEquals(1, Bytes.fromHexString("0x00").numberOfLeadingZeroBytes()); + assertEquals(2, Bytes.fromHexString("0x0000").numberOfLeadingZeroBytes()); + assertEquals(3, Bytes.fromHexString("0x000000").numberOfLeadingZeroBytes()); + } + + @Test + void testNumberOfTrailingZeroBytes() { + assertEquals(0, Bytes.fromHexString("0x12").numberOfTrailingZeroBytes()); + assertEquals(1, Bytes.fromHexString("0x1200").numberOfTrailingZeroBytes()); + assertEquals(2, Bytes.fromHexString("0x120000").numberOfTrailingZeroBytes()); + assertEquals(0, Bytes.fromHexString("0x").numberOfTrailingZeroBytes()); + assertEquals(1, Bytes.fromHexString("0x00").numberOfTrailingZeroBytes()); + assertEquals(2, Bytes.fromHexString("0x0000").numberOfTrailingZeroBytes()); + assertEquals(3, Bytes.fromHexString("0x000000").numberOfTrailingZeroBytes()); + } + + @Test + void testHasLeadingZeroBit() { + assertFalse(Bytes.fromHexString("0x").hasLeadingZero()); + assertTrue(Bytes.fromHexString("0x01").hasLeadingZero()); + assertFalse(Bytes.fromHexString("0xFF0012").hasLeadingZero()); + } + + @Test + void testEquals() { + SecureRandom random = new SecureRandom(); + byte[] key = new byte[32]; + random.nextBytes(key); + Bytes b = w(key); + Bytes b2 = w(key); + assertEquals(b.hashCode(), b2.hashCode()); + } + + @Test + void testEqualsWithOffset() { + SecureRandom random = new SecureRandom(); + byte[] key = new byte[32]; + random.nextBytes(key); + Bytes b = w(key).slice(16, 4); + Bytes b2 = w(key).slice(16, 8).slice(0, 4); + assertEquals(b, b2); + } + + @Test + void testHashCode() { + SecureRandom random = new SecureRandom(); + byte[] key = new byte[32]; + random.nextBytes(key); + Bytes b = w(key); + Bytes b2 = w(key); + assertEquals(b.hashCode(), b2.hashCode()); + } + + @Test + void testHashCodeWithOffset() { + SecureRandom random = new SecureRandom(); + byte[] key = new byte[32]; + random.nextBytes(key); + Bytes b = w(key).slice(16, 16); + Bytes b2 = w(key).slice(16, 16); + assertEquals(b.hashCode(), b2.hashCode()); + } + + @Test + void testHashCodeWithByteBufferWrappingBytes() { + SecureRandom random = new SecureRandom(); + byte[] key = new byte[32]; + random.nextBytes(key); + Bytes b = w(key); + Bytes other = Bytes.wrapByteBuffer(ByteBuffer.wrap(key)); + assertEquals(b.hashCode(), other.hashCode()); + } + + @Test + void testEqualsWithByteBufferWrappingBytes() { + SecureRandom random = new SecureRandom(); + byte[] key = new byte[32]; + random.nextBytes(key); + Bytes b = w(key); + Bytes other = Bytes.wrapByteBuffer(ByteBuffer.wrap(key)); + assertEquals(b, other); + } + + @Test + void testHashCodeWithBufferWrappingBytes() { + SecureRandom random = new SecureRandom(); + byte[] key = new byte[32]; + random.nextBytes(key); + Bytes b = w(key); + Bytes other = Bytes.wrapBuffer(Buffer.buffer(key)); + assertEquals(b.hashCode(), other.hashCode()); + } + + @Test + void testEqualsWithBufferWrappingBytes() { + SecureRandom random = new SecureRandom(); + byte[] key = new byte[32]; + random.nextBytes(key); + Bytes b = w(key); + Bytes other = Bytes.wrapBuffer(Buffer.buffer(key)); + assertEquals(b, other); + } + + @Test + void testHashCodeWithByteBufWrappingBytes() { + SecureRandom random = new SecureRandom(); + byte[] key = new byte[32]; + random.nextBytes(key); + Bytes b = w(key); + Bytes other = Bytes.wrapByteBuf(Unpooled.copiedBuffer(key)); + assertEquals(b.hashCode(), other.hashCode()); + } + + @Test + void testEqualsWithByteBufWrappingBytes() { + SecureRandom random = new SecureRandom(); + byte[] key = new byte[32]; + random.nextBytes(key); + Bytes b = w(key); + Bytes other = Bytes.wrapByteBuf(Unpooled.copiedBuffer(key)); + assertEquals(b, other); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/ConcatenatedBytesTest.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/ConcatenatedBytesTest.java new file mode 100644 index 00000000000..195b84d18b2 --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/ConcatenatedBytesTest.java @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.InOrder; + +import java.security.MessageDigest; +import java.util.Arrays; +import java.util.stream.Stream; + +import static org.apache.tuweni.bytes.Bytes.fromHexString; +import static org.apache.tuweni.bytes.Bytes.wrap; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; + +class ConcatenatedBytesTest { + + @ParameterizedTest + @MethodSource("concatenatedWrapProvider") + void concatenatedWrap(Object arr1, Object arr2) { + byte[] first = (byte[]) arr1; + byte[] second = (byte[]) arr2; + byte[] res = wrap(wrap(first), wrap(second)).toArray(); + assertArrayEquals(Arrays.copyOfRange(res, 0, first.length), first); + assertArrayEquals(Arrays.copyOfRange(res, first.length, res.length), second); + } + + @SuppressWarnings("UnusedMethod") + private static Stream concatenatedWrapProvider() { + return Stream + .of( + Arguments.of(new byte[] {}, new byte[] {}), + Arguments.of(new byte[] {}, new byte[] {1, 2, 3}), + Arguments.of(new byte[] {1, 2, 3}, new byte[] {}), + Arguments.of(new byte[] {1, 2, 3}, new byte[] {4, 5})); + } + + @Test + void testConcatenatedWrapReflectsUpdates() { + byte[] first = new byte[] {1, 2, 3}; + byte[] second = new byte[] {4, 5}; + byte[] expected1 = new byte[] {1, 2, 3, 4, 5}; + Bytes res = wrap(wrap(first), wrap(second)); + assertArrayEquals(res.toArray(), expected1); + + first[1] = 42; + second[0] = 42; + byte[] expected2 = new byte[] {1, 42, 3, 42, 5}; + assertArrayEquals(res.toArray(), expected2); + } + + @Test + void shouldReadConcatenatedValue() { + Bytes bytes = wrap(fromHexString("0x01234567"), fromHexString("0x89ABCDEF")); + assertEquals(8, bytes.size()); + assertEquals("0x0123456789abcdef", bytes.toHexString()); + } + + @Test + void shouldSliceConcatenatedValue() { + Bytes bytes = wrap( + fromHexString("0x01234567"), + fromHexString("0x89ABCDEF"), + fromHexString("0x01234567"), + fromHexString("0x89ABCDEF")); + assertEquals("0x", bytes.slice(4, 0).toHexString()); + assertEquals("0x0123456789abcdef0123456789abcdef", bytes.slice(0, 16).toHexString()); + assertEquals("0x01234567", bytes.slice(0, 4).toHexString()); + assertEquals("0x0123", bytes.slice(0, 2).toHexString()); + assertEquals("0x6789", bytes.slice(3, 2).toHexString()); + assertEquals("0x89abcdef", bytes.slice(4, 4).toHexString()); + assertEquals("0xabcd", bytes.slice(5, 2).toHexString()); + assertEquals("0xef012345", bytes.slice(7, 4).toHexString()); + assertEquals("0x01234567", bytes.slice(8, 4).toHexString()); + assertEquals("0x456789abcdef", bytes.slice(10, 6).toHexString()); + assertEquals("0x89abcdef", bytes.slice(12, 4).toHexString()); + } + + @Test + void shouldReadDeepConcatenatedValue() { + Bytes bytes = wrap( + wrap(fromHexString("0x01234567"), fromHexString("0x89ABCDEF")), + wrap(fromHexString("0x01234567"), fromHexString("0x89ABCDEF")), + fromHexString("0x01234567"), + fromHexString("0x89ABCDEF")); + assertEquals(24, bytes.size()); + assertEquals("0x0123456789abcdef0123456789abcdef0123456789abcdef", bytes.toHexString()); + } + + @Test + void testCopy() { + Bytes bytes = wrap(fromHexString("0x01234567"), fromHexString("0x89ABCDEF")); + assertEquals(bytes, bytes.copy()); + assertEquals(bytes, bytes.mutableCopy()); + } + + @Test + void testCopyTo() { + Bytes bytes = wrap(fromHexString("0x0123"), fromHexString("0x4567")); + MutableBytes dest = MutableBytes.create(32); + bytes.copyTo(dest, 10); + assertEquals(Bytes.fromHexString("0x0000000000000000000001234567000000000000000000000000000000000000"), dest); + } + + @Test + void testHashcodeUpdates() { + MutableBytes dest = MutableBytes.create(32); + Bytes bytes = wrap(dest, fromHexString("0x4567")); + int hashCode = bytes.hashCode(); + dest.set(1, (byte) 123); + assertNotEquals(hashCode, bytes.hashCode()); + } + + @Test + void shouldUpdateMessageDigest() { + Bytes value1 = fromHexString("0x01234567"); + Bytes value2 = fromHexString("0x89ABCDEF"); + Bytes value3 = fromHexString("0x01234567"); + Bytes bytes = wrap(value1, value2, value3); + MessageDigest digest = mock(MessageDigest.class); + bytes.update(digest); + + final InOrder inOrder = inOrder(digest); + inOrder.verify(digest).update(value1.toArrayUnsafe(), 0, 4); + inOrder.verify(digest).update(value2.toArrayUnsafe(), 0, 4); + inOrder.verify(digest).update(value3.toArrayUnsafe(), 0, 4); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateBytes32Test.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateBytes32Test.java new file mode 100644 index 00000000000..073718d8974 --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateBytes32Test.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class DelegateBytes32Test { + + @Test + void failsWhenWrappingArraySmallerThan32() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes32.wrap(Bytes.wrap(new byte[31]))); + assertEquals("Expected 32 bytes but got 31", exception.getMessage()); + } + + @Test + void failsWhenWrappingArrayLargerThan32() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes32.wrap(Bytes.wrap(new byte[33]))); + assertEquals("Expected 32 bytes but got 33", exception.getMessage()); + } + + @Test + void failsWhenLeftPaddingValueLargerThan32() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes32.leftPad(MutableBytes.create(33))); + assertEquals("Expected at most 32 bytes but got 33", exception.getMessage()); + } + + @Test + void failsWhenRightPaddingValueLargerThan32() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes32.rightPad(MutableBytes.create(33))); + assertEquals("Expected at most 32 bytes but got 33", exception.getMessage()); + } + + @Test + void testSize() { + assertEquals(32, new DelegatingBytes32(Bytes32.random()).size()); + } + + @Test + void testCopy() { + Bytes bytes = new DelegatingBytes32(Bytes32.random()).copy(); + assertEquals(bytes, bytes.copy()); + assertEquals(bytes, bytes.mutableCopy()); + } + + @Test + void testSlice() { + Bytes bytes = new DelegatingBytes32(Bytes32.random()).copy(); + assertEquals(Bytes.wrap(new byte[] {bytes.get(2), bytes.get(3), bytes.get(4)}), bytes.slice(2, 3)); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateBytes48Test.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateBytes48Test.java new file mode 100644 index 00000000000..7332d826335 --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateBytes48Test.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class DelegateBytes48Test { + + @Test + void failsWhenWrappingArraySmallerThan48() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes48.wrap(Bytes.wrap(new byte[47]))); + assertEquals("Expected 48 bytes but got 47", exception.getMessage()); + } + + @Test + void failsWhenWrappingArrayLargerThan48() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes48.wrap(Bytes.wrap(new byte[49]))); + assertEquals("Expected 48 bytes but got 49", exception.getMessage()); + } + + @Test + void failsWhenLeftPaddingValueLargerThan48() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes48.leftPad(MutableBytes.create(49))); + assertEquals("Expected at most 48 bytes but got 49", exception.getMessage()); + } + + @Test + void failsWhenRightPaddingValueLargerThan48() { + Throwable exception = assertThrows(IllegalArgumentException.class, () -> Bytes48.rightPad(MutableBytes.create(49))); + assertEquals("Expected at most 48 bytes but got 49", exception.getMessage()); + } + + @Test + void testSize() { + assertEquals(48, new DelegatingBytes48(Bytes48.random()).size()); + } + + @Test + void testCopy() { + Bytes bytes = new DelegatingBytes48(Bytes48.random()).copy(); + assertEquals(bytes, bytes.copy()); + assertEquals(bytes, bytes.mutableCopy()); + } + + @Test + void testSlice() { + Bytes bytes = new DelegatingBytes48(Bytes48.random()).copy(); + assertEquals(Bytes.wrap(new byte[] {bytes.get(2), bytes.get(3), bytes.get(4)}), bytes.slice(2, 3)); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateBytesTest.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateBytesTest.java new file mode 100644 index 00000000000..66b1be4abb3 --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateBytesTest.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +class DelegateBytesTest extends CommonBytesTests { + + @Override + Bytes h(String hex) { + return new DelegatingBytes(Bytes.fromHexString(hex)); + } + + @Override + MutableBytes m(int size) { + // no-op + return MutableBytes.create(size); + } + + @Override + Bytes w(byte[] bytes) { + return new DelegatingBytes(Bytes.wrap(bytes)); + } + + @Override + Bytes of(int... bytes) { + return new DelegatingBytes(Bytes.of(bytes)); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateMutableBytes32Test.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateMutableBytes32Test.java new file mode 100644 index 00000000000..44efd2a0ca9 --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateMutableBytes32Test.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class DelegateMutableBytes32Test { + + @Test + void failsWhenWrappingArraySmallerThan32() { + Throwable exception = + assertThrows(IllegalArgumentException.class, () -> MutableBytes32.wrap(MutableBytes.wrap(new byte[31]))); + assertEquals("Expected 32 bytes but got 31", exception.getMessage()); + } + + @Test + void failsWhenWrappingArrayLargerThan32() { + Throwable exception = + assertThrows(IllegalArgumentException.class, () -> MutableBytes32.wrap(MutableBytes.wrap(new byte[33]))); + assertEquals("Expected 32 bytes but got 33", exception.getMessage()); + } + + @Test + void testSize() { + assertEquals(32, DelegatingMutableBytes32.delegateTo(MutableBytes32.create()).size()); + } + + @Test + void testCopy() { + Bytes bytes = DelegatingMutableBytes32.delegateTo(MutableBytes32.create()).copy(); + assertEquals(bytes, bytes.copy()); + assertEquals(bytes, bytes.mutableCopy()); + } + + @Test + void testSlice() { + Bytes bytes = DelegatingMutableBytes32.delegateTo(MutableBytes32.create()).copy(); + assertEquals(Bytes.wrap(new byte[] {bytes.get(2), bytes.get(3), bytes.get(4)}), bytes.slice(2, 3)); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateMutableBytes48Test.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateMutableBytes48Test.java new file mode 100644 index 00000000000..95e4fd2c5cf --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/DelegateMutableBytes48Test.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class DelegateMutableBytes48Test { + + @Test + void failsWhenWrappingArraySmallerThan48() { + Throwable exception = + assertThrows(IllegalArgumentException.class, () -> MutableBytes48.wrap(MutableBytes.wrap(new byte[47]))); + assertEquals("Expected 48 bytes but got 47", exception.getMessage()); + } + + @Test + void failsWhenWrappingArrayLargerThan48() { + Throwable exception = + assertThrows(IllegalArgumentException.class, () -> MutableBytes48.wrap(MutableBytes.wrap(new byte[49]))); + assertEquals("Expected 48 bytes but got 49", exception.getMessage()); + } + + @Test + void testSize() { + assertEquals(48, DelegatingMutableBytes48.delegateTo(MutableBytes48.create()).size()); + } + + @Test + void testCopy() { + Bytes bytes = DelegatingMutableBytes48.delegateTo(MutableBytes48.create()).copy(); + assertEquals(bytes, bytes.copy()); + assertEquals(bytes, bytes.mutableCopy()); + } + + @Test + void testSlice() { + Bytes bytes = DelegatingMutableBytes48.delegateTo(MutableBytes48.create()).copy(); + assertEquals(Bytes.wrap(new byte[] {bytes.get(2), bytes.get(3), bytes.get(4)}), bytes.slice(2, 3)); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/MutableBytesTest.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/MutableBytesTest.java new file mode 100644 index 00000000000..494c657d73e --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/bytes/MutableBytesTest.java @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.bytes; + +import io.netty.buffer.Unpooled; +import io.vertx.core.buffer.Buffer; +import org.junit.jupiter.api.Test; + +import java.nio.ByteBuffer; + +import static org.junit.jupiter.api.Assertions.*; + +class MutableBytesTest { + + @Test + void testMutableBytesWrap() { + MutableBytes b = MutableBytes.wrap(Bytes.fromHexString("deadbeef").toArrayUnsafe(), 1, 3); + assertEquals(Bytes.fromHexString("adbeef"), b); + } + + @Test + void testClear() { + MutableBytes b = MutableBytes.wrap(Bytes.fromHexString("deadbeef").toArrayUnsafe()); + b.clear(); + assertEquals(Bytes.fromHexString("00000000"), b); + } + + @Test + void testFill() { + MutableBytes b = MutableBytes.create(2); + b.fill((byte) 34); + assertEquals(Bytes.fromHexString("0x2222"), b); + } + + @Test + void testDecrementAndIncrement() { + MutableBytes b = MutableBytes.create(2); + b.increment(); + assertEquals(Bytes.fromHexString("0x0001"), b); + b.decrement(); + assertEquals(Bytes.fromHexString("0x0000"), b); + + b.fill((byte) 0xFF); + b.decrement(); + assertEquals(Bytes.fromHexString("0xFFFE"), b); + + b = MutableBytes.wrap(Bytes.fromHexString("0x00FF").toArrayUnsafe()); + b.increment(); + assertEquals(Bytes.fromHexString("0x0100"), b); + } + + @Test + void setLong() { + MutableBytes b = MutableBytes.create(8); + b.setLong(0, 256); + assertEquals(Bytes.fromHexString("0x0000000000000100"), b); + } + + @Test + void setInt() { + MutableBytes b = MutableBytes.create(4); + b.setInt(0, 256); + assertEquals(Bytes.fromHexString("0x00000100"), b); + } + + @Test + void setIntOverflow() { + MutableBytes b = MutableBytes.create(2); + assertThrows(IndexOutOfBoundsException.class, () -> { + b.setInt(0, 18096); + }); + } + + @Test + void setLongOverflow() { + MutableBytes b = MutableBytes.create(6); + assertThrows(IndexOutOfBoundsException.class, () -> { + b.setLong(0, Long.MAX_VALUE); + }); + } + + @Test + void wrap32() { + MutableBytes b = MutableBytes.create(32); + assertTrue(b instanceof MutableBytes32); + b = MutableBytes.wrap(Bytes.random(36).toArrayUnsafe(), 4, 32); + assertTrue(b instanceof MutableBytes32); + } + + @Test + void wrapEmpty() { + MutableBytes b = MutableBytes.wrapBuffer(Buffer.buffer()); + assertSame(MutableBytes.EMPTY, b); + b = MutableBytes.wrapByteBuf(Unpooled.buffer(0)); + assertSame(MutableBytes.EMPTY, b); + b = MutableBytes.wrapBuffer(Buffer.buffer(), 3, 0); + assertSame(MutableBytes.EMPTY, b); + b = MutableBytes.wrapByteBuf(Unpooled.buffer(), 4, 0); + assertSame(MutableBytes.EMPTY, b); + } + + @Test + void testHashcodeUpdates() { + MutableBytes dest = MutableBytes.create(32); + int hashCode = dest.hashCode(); + dest.set(1, (byte) 123); + assertNotEquals(hashCode, dest.hashCode()); + } + + @Test + void testHashcodeUpdatesBuffer() { + MutableBytes dest = MutableBytes.wrapBuffer(Buffer.buffer(new byte[4])); + int hashCode = dest.hashCode(); + dest.set(1, (byte) 123); + assertNotEquals(hashCode, dest.hashCode()); + } + + @Test + void testHashcodeUpdatesByteBuffer() { + MutableBytes dest = MutableBytes.wrapByteBuffer(ByteBuffer.wrap(new byte[4])); + int hashCode = dest.hashCode(); + dest.set(1, (byte) 123); + assertNotEquals(hashCode, dest.hashCode()); + } + + @Test + void testHashcodeUpdatesByteBuf() { + MutableBytes dest = MutableBytes.wrapByteBuf(Unpooled.buffer(4)); + int hashCode = dest.hashCode(); + dest.set(1, (byte) 123); + assertNotEquals(hashCode, dest.hashCode()); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/BaseUInt256ValueTest.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/BaseUInt256ValueTest.java new file mode 100644 index 00000000000..b196c266870 --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/BaseUInt256ValueTest.java @@ -0,0 +1,1035 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.math.BigInteger; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +// This test is in a `test` sub-package to ensure that it does not have access to package-private +// methods within the bigints package, as it should be testing the usage of the public API. +class BaseUInt256ValueTest { + + private static class Value extends BaseUInt256Value { + static final Value MAX_VALUE = new Value(UInt256.MAX_VALUE); + + Value(UInt256 v) { + super(v, Value::new); + } + + Value(long v) { + super(v, Value::new); + } + + Value(BigInteger s) { + super(s, Value::new); + } + } + + private static Value v(long v) { + return new Value(v); + } + + private static Value biv(String s) { + return new Value(new BigInteger(s)); + } + + private static Value hv(String s) { + return new Value(UInt256.fromHexString(s)); + } + + @ParameterizedTest + @MethodSource("addProvider") + void add(Value v1, Value v2, Value expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addProvider() { + return Stream + .of( + Arguments.of(v(1), v(0), v(1)), + Arguments.of(v(5), v(0), v(5)), + Arguments.of(v(0), v(1), v(1)), + Arguments.of(v(0), v(100), v(100)), + Arguments.of(v(2), v(2), v(4)), + Arguments.of(v(100), v(90), v(190)), + Arguments.of(biv("13492324908428420834234908342"), v(10), biv("13492324908428420834234908352")), + Arguments + .of(biv("13492324908428420834234908342"), v(23422141424214L), biv("13492324908428444256376332556")), + Arguments.of(Value.MAX_VALUE, v(1), v(0)), + Arguments.of(Value.MAX_VALUE, v(2), v(1)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0"), + v(1), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1")), + Arguments + .of(hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), v(1), Value.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addUInt256Provider") + void addUInt256(Value v1, UInt256 v2, Value expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addUInt256Provider() { + return Stream + .of( + Arguments.of(v(1), UInt256.ZERO, v(1)), + Arguments.of(v(5), UInt256.ZERO, v(5)), + Arguments.of(v(0), UInt256.ONE, v(1)), + Arguments.of(v(0), UInt256.valueOf(100), v(100)), + Arguments.of(v(2), UInt256.valueOf(2), v(4)), + Arguments.of(v(100), UInt256.valueOf(90), v(190)), + Arguments + .of(biv("13492324908428420834234908342"), UInt256.valueOf(10), biv("13492324908428420834234908352")), + Arguments + .of( + biv("13492324908428420834234908342"), + UInt256.valueOf(23422141424214L), + biv("13492324908428444256376332556")), + Arguments.of(Value.MAX_VALUE, UInt256.valueOf(1), v(0)), + Arguments.of(Value.MAX_VALUE, UInt256.valueOf(2), v(1)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0"), + UInt256.valueOf(1), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1")), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + UInt256.valueOf(1), + Value.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addLongProvider") + void addLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addLongProvider() { + return Stream + .of( + Arguments.of(v(1), 0L, v(1)), + Arguments.of(v(5), 0L, v(5)), + Arguments.of(v(0), 1L, v(1)), + Arguments.of(v(0), 100L, v(100)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(100), 90L, v(190)), + Arguments.of(biv("13492324908428420834234908342"), 10L, biv("13492324908428420834234908352")), + Arguments.of(biv("13492324908428420834234908342"), 23422141424214L, biv("13492324908428444256376332556")), + Arguments.of(Value.MAX_VALUE, 1L, v(0)), + Arguments.of(Value.MAX_VALUE, 2L, v(1)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0"), + 1L, + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1")), + Arguments.of(hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), 1L, Value.MAX_VALUE), + Arguments.of(v(10), -5L, v(5)), + Arguments.of(v(0), -1L, Value.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addModProvider") + void addMod(Value v1, Value v2, UInt256 m, Value expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModProvider() { + return Stream + .of( + Arguments.of(v(0), v(1), UInt256.valueOf(2), v(1)), + Arguments.of(v(1), v(1), UInt256.valueOf(2), v(0)), + Arguments.of(Value.MAX_VALUE.subtract(2), v(1), UInt256.MAX_VALUE, Value.MAX_VALUE.subtract(1)), + Arguments.of(Value.MAX_VALUE.subtract(1), v(1), UInt256.MAX_VALUE, v(0)), + Arguments.of(v(2), v(1), UInt256.valueOf(2), v(1)), + Arguments.of(v(3), v(2), UInt256.valueOf(6), v(5)), + Arguments.of(v(3), v(4), UInt256.valueOf(2), v(1))); + } + + @Test + void shouldThrowForAddModOfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(v(1), UInt256.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModUInt256UInt256Provider") + void addModUInt256UInt256(Value v1, UInt256 v2, UInt256 m, Value expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModUInt256UInt256Provider() { + return Stream + .of( + Arguments.of(v(0), UInt256.ONE, UInt256.valueOf(2), v(1)), + Arguments.of(v(1), UInt256.ONE, UInt256.valueOf(2), v(0)), + Arguments.of(Value.MAX_VALUE.subtract(2), UInt256.ONE, UInt256.MAX_VALUE, Value.MAX_VALUE.subtract(1)), + Arguments.of(Value.MAX_VALUE.subtract(1), UInt256.ONE, UInt256.MAX_VALUE, v(0)), + Arguments.of(v(2), UInt256.ONE, UInt256.valueOf(2), v(1)), + Arguments.of(v(3), UInt256.valueOf(2), UInt256.valueOf(6), v(5)), + Arguments.of(v(3), UInt256.valueOf(4), UInt256.valueOf(2), v(1))); + } + + @Test + void shouldThrowForAddModLongUInt256OfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, UInt256.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModLongUInt256Provider") + void addModLongUInt256(Value v1, long v2, UInt256 m, Value expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModLongUInt256Provider() { + return Stream + .of( + Arguments.of(v(0), 1L, UInt256.valueOf(2), v(1)), + Arguments.of(v(1), 1L, UInt256.valueOf(2), v(0)), + Arguments.of(Value.MAX_VALUE.subtract(2), 1L, UInt256.MAX_VALUE, Value.MAX_VALUE.subtract(1)), + Arguments.of(Value.MAX_VALUE.subtract(1), 1L, UInt256.MAX_VALUE, v(0)), + Arguments.of(v(2), 1L, UInt256.valueOf(2), v(1)), + Arguments.of(v(2), -1L, UInt256.valueOf(2), v(1)), + Arguments.of(v(1), -7L, UInt256.valueOf(5), v(4))); + } + + @Test + void shouldThrowForAddModUInt256UInt256OfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(UInt256.ONE, UInt256.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModLongLongProvider") + void addModLongLong(Value v1, long v2, long m, Value expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModLongLongProvider() { + return Stream + .of(Arguments.of(v(0), 1L, 2L, v(1)), Arguments.of(v(1), 1L, 2L, v(0)), Arguments.of(v(2), 1L, 2L, v(1))); + } + + @Test + void shouldThrowForAddModLongLongOfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, 0)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForAddModLongLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, -5)); + assertEquals("addMod unsigned with negative modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("subtractProvider") + void subtract(Value v1, Value v2, Value expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractProvider() { + return Stream + .of( + Arguments.of(v(1), v(0), v(1)), + Arguments.of(v(5), v(0), v(5)), + Arguments.of(v(2), v(1), v(1)), + Arguments.of(v(100), v(100), v(0)), + Arguments.of(biv("13492324908428420834234908342"), v(10), biv("13492324908428420834234908332")), + Arguments + .of(biv("13492324908428420834234908342"), v(23422141424214L), biv("13492324908428397412093484128")), + Arguments.of(v(0), v(1), Value.MAX_VALUE), + Arguments.of(v(1), v(2), Value.MAX_VALUE), + Arguments + .of(Value.MAX_VALUE, v(1), hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"))); + } + + @ParameterizedTest + @MethodSource("subtractUInt256Provider") + void subtractUInt256(Value v1, UInt256 v2, Value expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractUInt256Provider() { + return Stream + .of( + Arguments.of(v(1), UInt256.ZERO, v(1)), + Arguments.of(v(5), UInt256.ZERO, v(5)), + Arguments.of(v(2), UInt256.ONE, v(1)), + Arguments.of(v(100), UInt256.valueOf(100), v(0)), + Arguments + .of(biv("13492324908428420834234908342"), UInt256.valueOf(10), biv("13492324908428420834234908332")), + Arguments + .of( + biv("13492324908428420834234908342"), + UInt256.valueOf(23422141424214L), + biv("13492324908428397412093484128")), + Arguments.of(v(0), UInt256.ONE, Value.MAX_VALUE), + Arguments.of(v(1), UInt256.valueOf(2), Value.MAX_VALUE), + Arguments + .of( + Value.MAX_VALUE, + UInt256.ONE, + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"))); + } + + @ParameterizedTest + @MethodSource("subtractLongProvider") + void subtractLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractLongProvider() { + return Stream + .of( + Arguments.of(v(1), 0L, v(1)), + Arguments.of(v(5), 0L, v(5)), + Arguments.of(v(2), 1L, v(1)), + Arguments.of(v(100), 100L, v(0)), + Arguments.of(biv("13492324908428420834234908342"), 10L, biv("13492324908428420834234908332")), + Arguments.of(biv("13492324908428420834234908342"), 23422141424214L, biv("13492324908428397412093484128")), + Arguments.of(v(0), 1L, Value.MAX_VALUE), + Arguments.of(v(1), 2L, Value.MAX_VALUE), + Arguments.of(Value.MAX_VALUE, 1L, hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE")), + Arguments.of(v(0), -1L, v(1)), + Arguments.of(v(0), -100L, v(100)), + Arguments.of(v(2), -2L, v(4))); + } + + @ParameterizedTest + @MethodSource("multiplyProvider") + void multiply(Value v1, Value v2, Value expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyProvider() { + return Stream + .of( + Arguments.of(v(0), v(1), v(0)), + Arguments.of(v(1), v(0), v(0)), + Arguments.of(v(1), v(20), v(20)), + Arguments.of(v(20), v(1), v(20)), + Arguments.of(hv("0x0a0000000000"), v(1), hv("0x0a0000000000")), + Arguments.of(v(1), hv("0x0a0000000000"), hv("0x0a0000000000")), + Arguments.of(v(0), v(2), v(0)), + Arguments.of(v(1), v(2), v(2)), + Arguments.of(v(2), v(2), v(4)), + Arguments.of(v(3), v(2), v(6)), + Arguments.of(v(4), v(2), v(8)), + Arguments.of(v(10), v(18), v(180)), + Arguments.of(biv("13492324908428420834234908341"), v(2), biv("26984649816856841668469816682")), + Arguments.of(biv("13492324908428420834234908342"), v(2), biv("26984649816856841668469816684")), + Arguments.of(v(2), v(8), v(16)), + Arguments.of(v(7), v(8), v(56)), + Arguments.of(v(8), v(8), v(64)), + Arguments.of(v(17), v(8), v(136)), + Arguments.of(biv("13492324908428420834234908342"), v(8), biv("107938599267427366673879266736")), + Arguments.of(biv("13492324908428420834234908342"), v(2048), biv("27632281412461405868513092284416")), + Arguments.of(biv("13492324908428420834234908342"), v(131072), biv("1768466010397529975584837906202624")), + Arguments.of(v(22), v(0), v(0))); + } + + @ParameterizedTest + @MethodSource("multiplyUInt256Provider") + void multiplyUInt256(Value v1, UInt256 v2, Value expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyUInt256Provider() { + return Stream + .of( + Arguments.of(v(0), UInt256.valueOf(1), v(0)), + Arguments.of(v(1), UInt256.valueOf(0), v(0)), + Arguments.of(v(1), UInt256.valueOf(20), v(20)), + Arguments.of(v(20), UInt256.valueOf(1), v(20)), + + Arguments.of(hv("0x0a0000000000"), UInt256.valueOf(1), hv("0x0a0000000000")), + Arguments.of(v(1), UInt256.fromHexString("0x0a0000000000"), hv("0x0a0000000000")), + Arguments.of(v(0), UInt256.valueOf(2), v(0)), + Arguments.of(v(1), UInt256.valueOf(2), v(2)), + Arguments.of(v(2), UInt256.valueOf(2), v(4)), + Arguments.of(v(3), UInt256.valueOf(2), v(6)), + Arguments.of(v(4), UInt256.valueOf(2), v(8)), + Arguments.of(v(10), UInt256.valueOf(18), v(180)), + Arguments + .of(biv("13492324908428420834234908341"), UInt256.valueOf(2), biv("26984649816856841668469816682")), + Arguments + .of(biv("13492324908428420834234908342"), UInt256.valueOf(2), biv("26984649816856841668469816684")), + Arguments.of(v(2), UInt256.valueOf(8), v(16)), + Arguments.of(v(7), UInt256.valueOf(8), v(56)), + Arguments.of(v(8), UInt256.valueOf(8), v(64)), + Arguments.of(v(17), UInt256.valueOf(8), v(136)), + Arguments + .of(biv("13492324908428420834234908342"), UInt256.valueOf(8), biv("107938599267427366673879266736")), + Arguments + .of( + biv("13492324908428420834234908342"), + UInt256.valueOf(2048), + biv("27632281412461405868513092284416")), + Arguments + .of( + biv("13492324908428420834234908342"), + UInt256.valueOf(131072), + biv("1768466010397529975584837906202624")), + Arguments.of(v(22), UInt256.ZERO, v(0)), + Arguments + .of( + hv("0x0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + UInt256.valueOf(2), + hv("0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE")), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + UInt256.valueOf(2), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"))); + } + + @ParameterizedTest + @MethodSource("multiplyLongProvider") + void multiplyLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyLongProvider() { + return Stream + .of( + Arguments.of(v(0), 1L, v(0)), + Arguments.of(v(1), 0L, v(0)), + Arguments.of(v(1), 20L, v(20)), + Arguments.of(v(20), 1L, v(20)), + Arguments.of(hv("0x0a0000000000"), 1L, hv("0x0a0000000000")), + Arguments.of(v(1), 10995116277760L, hv("0x0a0000000000")), + Arguments.of(v(7), 1152921504606846976L, hv("0x07000000000000000")), + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(2)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(3), 2L, v(6)), + Arguments.of(v(4), 2L, v(8)), + Arguments.of(v(10), 18L, v(180)), + Arguments.of(biv("13492324908428420834234908341"), 2L, biv("26984649816856841668469816682")), + Arguments.of(biv("13492324908428420834234908342"), 2L, biv("26984649816856841668469816684")), + Arguments.of(v(2), 8L, v(16)), + Arguments.of(v(7), 8L, v(56)), + Arguments.of(v(8), 8L, v(64)), + Arguments.of(v(17), 8L, v(136)), + Arguments.of(biv("13492324908428420834234908342"), 8L, biv("107938599267427366673879266736")), + Arguments.of(biv("13492324908428420834234908342"), 2048L, biv("27632281412461405868513092284416")), + Arguments.of(biv("13492324908428420834234908342"), 131072L, biv("1768466010397529975584837906202624")), + Arguments.of(v(22), 0L, v(0)), + Arguments + .of( + hv("0x0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 2L, + hv("0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE")), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 2L, + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"))); + } + + @Test + void shouldThrowForMultiplyLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(2).multiply(-5)); + assertEquals("multiply unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModProvider") + void multiplyMod(Value v1, Value v2, UInt256 m, Value expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModProvider() { + return Stream + .of( + Arguments.of(v(0), v(5), UInt256.valueOf(2), v(0)), + Arguments.of(v(2), v(3), UInt256.valueOf(7), v(6)), + Arguments.of(v(2), v(3), UInt256.valueOf(6), v(0)), + Arguments.of(v(2), v(0), UInt256.valueOf(6), v(0)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + v(2), + UInt256.MAX_VALUE, + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD"))); + } + + @Test + void shouldThrowForMultiplyModOfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).multiplyMod(v(1), UInt256.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModUInt256UInt256Provider") + void multiplyModUInt256UInt256(Value v1, UInt256 v2, UInt256 m, Value expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModUInt256UInt256Provider() { + return Stream + .of( + Arguments.of(v(0), UInt256.valueOf(5), UInt256.valueOf(2), v(0)), + Arguments.of(v(2), UInt256.valueOf(3), UInt256.valueOf(7), v(6)), + Arguments.of(v(2), UInt256.valueOf(3), UInt256.valueOf(6), v(0)), + Arguments.of(v(2), UInt256.ZERO, UInt256.valueOf(6), v(0)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + UInt256.valueOf(2), + UInt256.MAX_VALUE, + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD"))); + } + + @Test + void shouldThrowForMultiplyModUInt256UInt256OfModZero() { + Throwable exception = + assertThrows(ArithmeticException.class, () -> v(0).multiplyMod(UInt256.valueOf(5), UInt256.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModLongUInt256Provider") + void multiplyModLongUInt256(Value v1, long v2, UInt256 m, Value expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModLongUInt256Provider() { + return Stream + .of( + Arguments.of(v(0), 5L, UInt256.valueOf(2), v(0)), + Arguments.of(v(2), 3L, UInt256.valueOf(7), v(6)), + Arguments.of(v(2), 3L, UInt256.valueOf(6), v(0)), + Arguments.of(v(2), 0L, UInt256.valueOf(6), v(0)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + 2L, + UInt256.MAX_VALUE, + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD"))); + } + + @Test + void shouldThrowForMultiplyModLongUInt256OfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(3).multiplyMod(1L, UInt256.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongUInt256OfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).multiplyMod(-1, UInt256.valueOf(2))); + assertEquals("multiplyMod unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModLongLongProvider") + void multiplyModLongLong(Value v1, long v2, long m, Value expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModLongLongProvider() { + return Stream + .of( + Arguments.of(v(0), 5L, 2L, v(0)), + Arguments.of(v(2), 3L, 7L, v(6)), + Arguments.of(v(2), 3L, 6L, v(0)), + Arguments.of(v(2), 0L, 6L, v(0)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + 2L, + Long.MAX_VALUE, + hv("0x000000000000000000000000000000000000000000000000000000000000001C"))); + } + + @Test + void shouldThrowForMultiplyModLongLongOfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).multiplyMod(1, 0)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongLongOfModNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(2).multiplyMod(5, -7)); + assertEquals("multiplyMod unsigned with negative modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(3).multiplyMod(-1, 2)); + assertEquals("multiplyMod unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideProvider") + void divide(Value v1, Value v2, Value expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideProvider() { + return Stream + .of( + Arguments.of(v(0), v(2), v(0)), + Arguments.of(v(1), v(2), v(0)), + Arguments.of(v(2), v(2), v(1)), + Arguments.of(v(3), v(2), v(1)), + Arguments.of(v(4), v(2), v(2)), + Arguments.of(biv("13492324908428420834234908341"), v(2), biv("6746162454214210417117454170")), + Arguments.of(biv("13492324908428420834234908342"), v(2), biv("6746162454214210417117454171")), + Arguments.of(biv("13492324908428420834234908343"), v(2), biv("6746162454214210417117454171")), + Arguments.of(v(2), v(8), v(0)), + Arguments.of(v(7), v(8), v(0)), + Arguments.of(v(8), v(8), v(1)), + Arguments.of(v(9), v(8), v(1)), + Arguments.of(v(17), v(8), v(2)), + Arguments.of(v(1024), v(8), v(128)), + Arguments.of(v(1026), v(8), v(128)), + Arguments.of(biv("13492324908428420834234908342"), v(8), biv("1686540613553552604279363542")), + Arguments.of(biv("13492324908428420834234908342"), v(2048), biv("6588049271693564860466263")), + Arguments.of(biv("13492324908428420834234908342"), v(131072), biv("102938269870211950944785"))); + } + + @Test + void shouldThrowForDivideByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(v(0))); + assertEquals("divide by zero", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideUInt256Provider") + void divideUInt256(Value v1, UInt256 v2, Value expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideUInt256Provider() { + return Stream + .of( + Arguments.of(v(0), UInt256.valueOf(2), v(0)), + Arguments.of(v(1), UInt256.valueOf(2), v(0)), + Arguments.of(v(2), UInt256.valueOf(2), v(1)), + Arguments.of(v(3), UInt256.valueOf(2), v(1)), + Arguments.of(v(4), UInt256.valueOf(2), v(2)), + Arguments.of(biv("13492324908428420834234908341"), UInt256.valueOf(2), biv("6746162454214210417117454170")), + Arguments.of(biv("13492324908428420834234908342"), UInt256.valueOf(2), biv("6746162454214210417117454171")), + Arguments.of(biv("13492324908428420834234908343"), UInt256.valueOf(2), biv("6746162454214210417117454171")), + Arguments.of(v(2), UInt256.valueOf(8), v(0)), + Arguments.of(v(7), UInt256.valueOf(8), v(0)), + Arguments.of(v(8), UInt256.valueOf(8), v(1)), + Arguments.of(v(9), UInt256.valueOf(8), v(1)), + Arguments.of(v(17), UInt256.valueOf(8), v(2)), + Arguments.of(v(1024), UInt256.valueOf(8), v(128)), + Arguments.of(v(1026), UInt256.valueOf(8), v(128)), + Arguments.of(biv("13492324908428420834234908342"), UInt256.valueOf(8), biv("1686540613553552604279363542")), + Arguments.of(biv("13492324908428420834234908342"), UInt256.valueOf(2048), biv("6588049271693564860466263")), + Arguments + .of(biv("13492324908428420834234908342"), UInt256.valueOf(131072), biv("102938269870211950944785"))); + } + + @Test + void shouldThrowForDivideUInt256ByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(UInt256.ZERO)); + assertEquals("divide by zero", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideLongProvider") + void divideLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(0)), + Arguments.of(v(2), 2L, v(1)), + Arguments.of(v(3), 2L, v(1)), + Arguments.of(v(4), 2L, v(2)), + Arguments.of(biv("13492324908428420834234908341"), 2L, biv("6746162454214210417117454170")), + Arguments.of(biv("13492324908428420834234908342"), 2L, biv("6746162454214210417117454171")), + Arguments.of(biv("13492324908428420834234908343"), 2L, biv("6746162454214210417117454171")), + Arguments.of(v(2), 8L, v(0)), + Arguments.of(v(7), 8L, v(0)), + Arguments.of(v(8), 8L, v(1)), + Arguments.of(v(9), 8L, v(1)), + Arguments.of(v(17), 8L, v(2)), + Arguments.of(v(1024), 8L, v(128)), + Arguments.of(v(1026), 8L, v(128)), + Arguments.of(biv("13492324908428420834234908342"), 8L, biv("1686540613553552604279363542")), + Arguments.of(biv("13492324908428420834234908342"), 2048L, biv("6588049271693564860466263")), + Arguments.of(biv("13492324908428420834234908342"), 131072L, biv("102938269870211950944785"))); + } + + @Test + void shouldThrowForDivideLongByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(0)); + assertEquals("divide by zero", exception.getMessage()); + } + + @Test + void shouldThrowForDivideLongByNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(-5)); + assertEquals("divide unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("powUInt256Provider") + void powUInt256(Value v1, UInt256 v2, Value expected) { + assertValueEquals(expected, v1.pow(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream powUInt256Provider() { + return Stream + .of( + Arguments.of(v(0), UInt256.valueOf(2), v(0)), + Arguments.of(v(2), UInt256.valueOf(2), v(4)), + Arguments.of(v(2), UInt256.valueOf(8), v(256)), + Arguments.of(v(3), UInt256.valueOf(3), v(27)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0"), + UInt256.valueOf(3), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A920E119A2F000"))); + } + + @ParameterizedTest + @MethodSource("powLongProvider") + void powLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.pow(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream powLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(2), 8L, v(256)), + Arguments.of(v(3), 3L, v(27)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0"), + 3L, + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A920E119A2F000")), + Arguments.of(v(3), -3L, hv("0x2F684BDA12F684BDA12F684BDA12F684BDA12F684BDA12F684BDA12F684BDA13"))); + } + + @ParameterizedTest + @MethodSource("modUInt256Provider") + void modUInt256(Value v1, UInt256 v2, Value expected) { + assertValueEquals(expected, v1.mod(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream modUInt256Provider() { + return Stream + .of( + Arguments.of(v(0), UInt256.valueOf(2), v(0)), + Arguments.of(v(1), UInt256.valueOf(2), v(1)), + Arguments.of(v(2), UInt256.valueOf(2), v(0)), + Arguments.of(v(3), UInt256.valueOf(2), v(1)), + Arguments.of(biv("13492324908428420834234908342"), UInt256.valueOf(2), v(0)), + Arguments.of(biv("13492324908428420834234908343"), UInt256.valueOf(2), v(1)), + Arguments.of(v(0), UInt256.valueOf(8), v(0)), + Arguments.of(v(1), UInt256.valueOf(8), v(1)), + Arguments.of(v(2), UInt256.valueOf(8), v(2)), + Arguments.of(v(3), UInt256.valueOf(8), v(3)), + Arguments.of(v(7), UInt256.valueOf(8), v(7)), + Arguments.of(v(8), UInt256.valueOf(8), v(0)), + Arguments.of(v(9), UInt256.valueOf(8), v(1)), + Arguments.of(v(1024), UInt256.valueOf(8), v(0)), + Arguments.of(v(1026), UInt256.valueOf(8), v(2)), + Arguments.of(biv("13492324908428420834234908342"), UInt256.valueOf(8), v(6)), + Arguments.of(biv("13492324908428420834234908343"), UInt256.valueOf(8), v(7)), + Arguments.of(biv("13492324908428420834234908344"), UInt256.valueOf(8), v(0))); + } + + @Test + void shouldThrowForModUInt256ByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(UInt256.ZERO)); + assertEquals("mod by zero", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("modLongProvider") + void modLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.mod(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream modLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(1)), + Arguments.of(v(2), 2L, v(0)), + Arguments.of(v(3), 2L, v(1)), + Arguments.of(biv("13492324908428420834234908342"), 2L, v(0)), + Arguments.of(biv("13492324908428420834234908343"), 2L, v(1)), + Arguments.of(v(0), 8L, v(0)), + Arguments.of(v(1), 8L, v(1)), + Arguments.of(v(2), 8L, v(2)), + Arguments.of(v(3), 8L, v(3)), + Arguments.of(v(7), 8L, v(7)), + Arguments.of(v(8), 8L, v(0)), + Arguments.of(v(9), 8L, v(1)), + Arguments.of(v(1024), 8L, v(0)), + Arguments.of(v(1026), 8L, v(2)), + Arguments.of(biv("13492324908428420834234908342"), 8L, v(6)), + Arguments.of(biv("13492324908428420834234908343"), 8L, v(7)), + Arguments.of(biv("13492324908428420834234908344"), 8L, v(0))); + } + + @Test + void shouldThrowForModLongByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(0)); + assertEquals("mod by zero", exception.getMessage()); + } + + @Test + void shouldReturnZeroForMod0LongByZero() { + assertEquals(UInt256.ZERO, v(5).mod0(0).toUInt256()); + } + + @Test + void shouldThrowForModLongByNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(-5)); + assertEquals("mod by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("compareToProvider") + void compareTo(Value v1, Value v2, int expected) { + assertEquals(expected, v1.compareTo(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream compareToProvider() { + return Stream + .of( + Arguments.of(v(5), v(5), 0), + Arguments.of(v(5), v(3), 1), + Arguments.of(v(5), v(6), -1), + Arguments + .of( + hv("0x0000000000000000000000000000000000000000000000000000000000000000"), + hv("0x0000000000000000000000000000000000000000000000000000000000000000"), + 0), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 0), + Arguments + .of( + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 0), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0x0000000000000000000000000000000000000000000000000000000000000000"), + 1), + Arguments + .of( + hv("0x0000000000000000000000000000000000000000000000000000000000000000"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + -1), + Arguments + .of( + hv("0x000000000000000000000000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 1), + Arguments + .of( + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + -1)); + } + + @ParameterizedTest + @MethodSource("toBytesProvider") + void toBytesTest(Value value, Bytes expected) { + assertEquals(expected, value.toBytes()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream toBytesProvider() { + return Stream + .of( + Arguments + .of( + hv("0x00"), + Bytes.fromHexString("0x0000000000000000000000000000000000000000000000000000000000000000")), + Arguments + .of( + hv("0x01000000"), + Bytes.fromHexString("0x0000000000000000000000000000000000000000000000000000000001000000")), + Arguments + .of( + hv("0x0100000000"), + Bytes.fromHexString("0x0000000000000000000000000000000000000000000000000000000100000000")), + Arguments + .of( + hv("0xf100000000ab"), + Bytes.fromHexString("0x0000000000000000000000000000000000000000000000000000f100000000ab")), + Arguments + .of( + hv("0x0400000000000000000000000000000000000000000000000000f100000000ab"), + Bytes.fromHexString("0x0400000000000000000000000000000000000000000000000000f100000000ab"))); + } + + @ParameterizedTest + @MethodSource("toMinimalBytesProvider") + void toMinimalBytesTest(Value value, Bytes expected) { + assertEquals(expected, value.toMinimalBytes()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream toMinimalBytesProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), Bytes.EMPTY), + Arguments.of(hv("0x01000000"), Bytes.fromHexString("0x01000000")), + Arguments.of(hv("0x0100000000"), Bytes.fromHexString("0x0100000000")), + Arguments.of(hv("0xf100000000ab"), Bytes.fromHexString("0xf100000000ab")), + Arguments + .of( + hv("0x0400000000000000000000000000000000000000000000000000f100000000ab"), + Bytes.fromHexString("0x0400000000000000000000000000000000000000000000000000f100000000ab"))); + } + + @ParameterizedTest + @MethodSource("numberOfLeadingZerosProvider") + void numberOfLeadingZeros(Value value, int expected) { + assertEquals(expected, value.numberOfLeadingZeros()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream numberOfLeadingZerosProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), 256), + Arguments.of(hv("0x01"), 255), + Arguments.of(hv("0x02"), 254), + Arguments.of(hv("0x03"), 254), + Arguments.of(hv("0x0F"), 252), + Arguments.of(hv("0x8F"), 248), + Arguments.of(hv("0x100000000"), 223)); + } + + @ParameterizedTest + @MethodSource("bitLengthProvider") + void bitLength(Value value, int expected) { + assertEquals(expected, value.bitLength()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream bitLengthProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), 0), + Arguments.of(hv("0x01"), 1), + Arguments.of(hv("0x02"), 2), + Arguments.of(hv("0x03"), 2), + Arguments.of(hv("0x0F"), 4), + Arguments.of(hv("0x8F"), 8), + Arguments.of(hv("0x100000000"), 33)); + } + + @ParameterizedTest + @MethodSource("addExactProvider") + void addExact(Value value, Value operand) { + assertThrows(ArithmeticException.class, () -> value.addExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addExactProvider() { + return Stream.of(Arguments.of(Value.MAX_VALUE, v(1)), Arguments.of(Value.MAX_VALUE, Value.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addExactLongProvider") + void addExactLong(Value value, long operand) { + assertThrows(ArithmeticException.class, () -> value.addExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addExactLongProvider() { + return Stream + .of(Arguments.of(Value.MAX_VALUE, 3), Arguments.of(Value.MAX_VALUE, Long.MAX_VALUE), Arguments.of(v(0), -1)); + } + + @ParameterizedTest + @MethodSource("subtractExactProvider") + void subtractExact(Value value, Value operand) { + assertThrows(ArithmeticException.class, () -> value.subtractExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractExactProvider() { + return Stream.of(Arguments.of(v(0), v(1)), Arguments.of(v(0), Value.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("subtractExactLongProvider") + void subtractExactLong(Value value, long operand) { + assertThrows(ArithmeticException.class, () -> value.subtractExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractExactLongProvider() { + return Stream.of(Arguments.of(v(0), 1), Arguments.of(v(0), Long.MAX_VALUE), Arguments.of(Value.MAX_VALUE, -1)); + } + + @SuppressWarnings("UnusedMethod") + private void assertValueEquals(Value expected, Value actual) { + String msg = String.format("Expected %s but got %s", expected.toHexString(), actual.toHexString()); + assertEquals(expected, actual, msg); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/BaseUInt32ValueTest.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/BaseUInt32ValueTest.java new file mode 100644 index 00000000000..0eca3f9561f --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/BaseUInt32ValueTest.java @@ -0,0 +1,795 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +// This test is in a `test` sub-package to ensure that it does not have access to package-private +// methods within the bigints package, as it should be testing the usage of the public API. +class BaseUInt32ValueTest { + + private static class Value extends BaseUInt32Value { + static final Value MAX_VALUE = new Value(UInt32.MAX_VALUE); + + Value(UInt32 v) { + super(v, Value::new); + } + + Value(int v) { + super(v, Value::new); + } + } + + private static Value v(int v) { + return new Value(v); + } + + private static Value hv(String s) { + return new Value(UInt32.fromHexString(s)); + } + + @ParameterizedTest + @MethodSource("addProvider") + void add(Value v1, Value v2, Value expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addProvider() { + return Stream + .of( + Arguments.of(v(1), v(0), v(1)), + Arguments.of(v(5), v(0), v(5)), + Arguments.of(v(0), v(1), v(1)), + Arguments.of(v(0), v(100), v(100)), + Arguments.of(v(2), v(2), v(4)), + Arguments.of(v(100), v(90), v(190)), + Arguments.of(Value.MAX_VALUE, v(1), v(0)), + Arguments.of(Value.MAX_VALUE, v(2), v(1)), + Arguments.of(hv("0xFFFFFFF0"), v(1), hv("0xFFFFFFF1")), + Arguments.of(hv("0xFFFFFFFE"), v(1), Value.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addUInt32Provider") + void addUInt32(Value v1, UInt32 v2, Value expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addUInt32Provider() { + return Stream + .of( + Arguments.of(v(1), UInt32.ZERO, v(1)), + Arguments.of(v(5), UInt32.ZERO, v(5)), + Arguments.of(v(0), UInt32.ONE, v(1)), + Arguments.of(v(0), UInt32.valueOf(100), v(100)), + Arguments.of(v(2), UInt32.valueOf(2), v(4)), + Arguments.of(v(100), UInt32.valueOf(90), v(190)), + Arguments.of(Value.MAX_VALUE, UInt32.valueOf(1), v(0)), + Arguments.of(Value.MAX_VALUE, UInt32.valueOf(2), v(1)), + Arguments.of(hv("0xFFFFFFF0"), UInt32.valueOf(1), hv("0xFFFFFFF1")), + Arguments.of(hv("0xFFFFFFFE"), UInt32.valueOf(1), Value.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addLongProvider") + void addLong(Value v1, int v2, Value expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addLongProvider() { + return Stream + .of( + Arguments.of(v(1), 0, v(1)), + Arguments.of(v(5), 0, v(5)), + Arguments.of(v(0), 1, v(1)), + Arguments.of(v(0), 100, v(100)), + Arguments.of(v(2), 2, v(4)), + Arguments.of(v(100), 90, v(190)), + Arguments.of(Value.MAX_VALUE, 1, v(0)), + Arguments.of(Value.MAX_VALUE, 2, v(1)), + Arguments.of(hv("0xFFFFFFF0"), 1, hv("0xFFFFFFF1")), + Arguments.of(hv("0xFFFFFFFE"), 1, Value.MAX_VALUE), + Arguments.of(v(10), -5, v(5)), + Arguments.of(v(0), -1, Value.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addModProvider") + void addMod(Value v1, Value v2, UInt32 m, Value expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModProvider() { + return Stream + .of( + Arguments.of(v(0), v(1), UInt32.valueOf(2), v(1)), + Arguments.of(v(1), v(1), UInt32.valueOf(2), v(0)), + Arguments.of(Value.MAX_VALUE.subtract(2), v(1), UInt32.MAX_VALUE, Value.MAX_VALUE.subtract(1)), + Arguments.of(Value.MAX_VALUE.subtract(1), v(1), UInt32.MAX_VALUE, v(0)), + Arguments.of(v(2), v(1), UInt32.valueOf(2), v(1)), + Arguments.of(v(3), v(2), UInt32.valueOf(6), v(5)), + Arguments.of(v(3), v(4), UInt32.valueOf(2), v(1))); + } + + @Test + void shouldThrowForAddModOfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(v(1), UInt32.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModUInt32UInt32Provider") + void addModUInt32UInt32(Value v1, UInt32 v2, UInt32 m, Value expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModUInt32UInt32Provider() { + return Stream + .of( + Arguments.of(v(0), UInt32.ONE, UInt32.valueOf(2), v(1)), + Arguments.of(v(1), UInt32.ONE, UInt32.valueOf(2), v(0)), + Arguments.of(Value.MAX_VALUE.subtract(2), UInt32.ONE, UInt32.MAX_VALUE, Value.MAX_VALUE.subtract(1)), + Arguments.of(Value.MAX_VALUE.subtract(1), UInt32.ONE, UInt32.MAX_VALUE, v(0)), + Arguments.of(v(2), UInt32.ONE, UInt32.valueOf(2), v(1)), + Arguments.of(v(3), UInt32.valueOf(2), UInt32.valueOf(6), v(5)), + Arguments.of(v(3), UInt32.valueOf(4), UInt32.valueOf(2), v(1))); + } + + @Test + void shouldThrowForAddModLongUInt32OfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, UInt32.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModLongUInt32Provider") + void addModLongUInt32(Value v1, int v2, UInt32 m, Value expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModLongUInt32Provider() { + return Stream + .of( + Arguments.of(v(0), 1, UInt32.valueOf(2), v(1)), + Arguments.of(v(1), 1, UInt32.valueOf(2), v(0)), + Arguments.of(Value.MAX_VALUE.subtract(2), 1, UInt32.MAX_VALUE, Value.MAX_VALUE.subtract(1)), + Arguments.of(Value.MAX_VALUE.subtract(1), 1, UInt32.MAX_VALUE, v(0)), + Arguments.of(v(2), 1, UInt32.valueOf(2), v(1)), + Arguments.of(v(2), -1, UInt32.valueOf(2), v(1)), + Arguments.of(v(1), -7, UInt32.valueOf(5), v(4))); + } + + @Test + void shouldThrowForAddModUInt32UInt32OfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(UInt32.ONE, UInt32.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModLongLongProvider") + void addModLongLong(Value v1, int v2, int m, Value expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModLongLongProvider() { + return Stream.of(Arguments.of(v(0), 1, 2, v(1)), Arguments.of(v(1), 1, 2, v(0)), Arguments.of(v(2), 1, 2, v(1))); + } + + @Test + void shouldThrowForAddModLongLongOfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, 0)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForAddModLongLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, -5)); + assertEquals("addMod unsigned with negative modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("subtractProvider") + void subtract(Value v1, Value v2, Value expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractProvider() { + return Stream + .of( + Arguments.of(v(1), v(0), v(1)), + Arguments.of(v(5), v(0), v(5)), + Arguments.of(v(2), v(1), v(1)), + Arguments.of(v(100), v(100), v(0)), + Arguments.of(v(0), v(1), Value.MAX_VALUE), + Arguments.of(v(1), v(2), Value.MAX_VALUE), + Arguments.of(Value.MAX_VALUE, v(1), hv("0xFFFFFFFE"))); + } + + @ParameterizedTest + @MethodSource("subtractUInt32Provider") + void subtractUInt32(Value v1, UInt32 v2, Value expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractUInt32Provider() { + return Stream + .of( + Arguments.of(v(1), UInt32.ZERO, v(1)), + Arguments.of(v(5), UInt32.ZERO, v(5)), + Arguments.of(v(2), UInt32.ONE, v(1)), + Arguments.of(v(100), UInt32.valueOf(100), v(0)), + Arguments.of(v(0), UInt32.ONE, Value.MAX_VALUE), + Arguments.of(v(1), UInt32.valueOf(2), Value.MAX_VALUE), + Arguments.of(Value.MAX_VALUE, UInt32.ONE, hv("0xFFFFFFFE"))); + } + + @ParameterizedTest + @MethodSource("subtractLongProvider") + void subtractLong(Value v1, int v2, Value expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractLongProvider() { + return Stream + .of( + Arguments.of(v(1), 0, v(1)), + Arguments.of(v(5), 0, v(5)), + Arguments.of(v(2), 1, v(1)), + Arguments.of(v(100), 100, v(0)), + Arguments.of(v(0), 1, Value.MAX_VALUE), + Arguments.of(v(1), 2, Value.MAX_VALUE), + Arguments.of(Value.MAX_VALUE, 1, hv("0xFFFFFFFE")), + Arguments.of(v(0), -1, v(1)), + Arguments.of(v(0), -100, v(100)), + Arguments.of(v(2), -2, v(4))); + } + + @ParameterizedTest + @MethodSource("multiplyProvider") + void multiply(Value v1, Value v2, Value expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyProvider() { + return Stream + .of( + Arguments.of(v(0), v(2), v(0)), + Arguments.of(v(1), v(2), v(2)), + Arguments.of(v(2), v(2), v(4)), + Arguments.of(v(3), v(2), v(6)), + Arguments.of(v(4), v(2), v(8)), + Arguments.of(v(10), v(18), v(180)), + Arguments.of(v(2), v(8), v(16)), + Arguments.of(v(7), v(8), v(56)), + Arguments.of(v(8), v(8), v(64)), + Arguments.of(v(17), v(8), v(136)), + Arguments.of(v(22), v(0), v(0))); + } + + @ParameterizedTest + @MethodSource("multiplyUInt32Provider") + void multiplyUInt32(Value v1, UInt32 v2, Value expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyUInt32Provider() { + return Stream + .of( + Arguments.of(v(0), UInt32.valueOf(2), v(0)), + Arguments.of(v(1), UInt32.valueOf(2), v(2)), + Arguments.of(v(2), UInt32.valueOf(2), v(4)), + Arguments.of(v(3), UInt32.valueOf(2), v(6)), + Arguments.of(v(4), UInt32.valueOf(2), v(8)), + Arguments.of(v(10), UInt32.valueOf(18), v(180)), + Arguments.of(v(2), UInt32.valueOf(8), v(16)), + Arguments.of(v(7), UInt32.valueOf(8), v(56)), + Arguments.of(v(8), UInt32.valueOf(8), v(64)), + Arguments.of(v(17), UInt32.valueOf(8), v(136)), + Arguments.of(v(22), UInt32.ZERO, v(0)), + Arguments.of(hv("0xFFFFFFFF"), UInt32.valueOf(2), hv("0xFFFFFFFE")), + Arguments.of(hv("0xFFFFFFFF"), UInt32.valueOf(2), hv("0xFFFFFFFE"))); + } + + @ParameterizedTest + @MethodSource("multiplyLongProvider") + void multiplyLong(Value v1, int v2, Value expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2, v(0)), + Arguments.of(v(1), 2, v(2)), + Arguments.of(v(2), 2, v(4)), + Arguments.of(v(3), 2, v(6)), + Arguments.of(v(4), 2, v(8)), + Arguments.of(v(10), 18, v(180)), + Arguments.of(v(2), 8, v(16)), + Arguments.of(v(7), 8, v(56)), + Arguments.of(v(8), 8, v(64)), + Arguments.of(v(17), 8, v(136)), + Arguments.of(v(22), 0, v(0)), + Arguments.of(hv("0xFFFFFFFF"), 2, hv("0xFFFFFFFE")), + Arguments.of(hv("0xFFFFFFFF"), 2, hv("0xFFFFFFFE"))); + } + + @Test + void shouldThrowForMultiplyLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(2).multiply(-5)); + assertEquals("multiply unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModProvider") + void multiplyMod(Value v1, Value v2, UInt32 m, Value expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModProvider() { + return Stream + .of( + Arguments.of(v(0), v(5), UInt32.valueOf(2), v(0)), + Arguments.of(v(2), v(3), UInt32.valueOf(7), v(6)), + Arguments.of(v(2), v(3), UInt32.valueOf(6), v(0)), + Arguments.of(v(2), v(0), UInt32.valueOf(6), v(0)), + Arguments.of(hv("0xFFFFFFFE"), v(2), UInt32.MAX_VALUE, hv("0xFFFFFFFD"))); + } + + @Test + void shouldThrowForMultiplyModOfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).multiplyMod(v(1), UInt32.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModUInt32UInt32Provider") + void multiplyModUInt32UInt32(Value v1, UInt32 v2, UInt32 m, Value expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModUInt32UInt32Provider() { + return Stream + .of( + Arguments.of(v(0), UInt32.valueOf(5), UInt32.valueOf(2), v(0)), + Arguments.of(v(2), UInt32.valueOf(3), UInt32.valueOf(7), v(6)), + Arguments.of(v(2), UInt32.valueOf(3), UInt32.valueOf(6), v(0)), + Arguments.of(v(2), UInt32.ZERO, UInt32.valueOf(6), v(0)), + Arguments.of(hv("0xFFFFFFFE"), UInt32.valueOf(2), UInt32.MAX_VALUE, hv("0xFFFFFFFD"))); + } + + @Test + void shouldThrowForMultiplyModUInt32UInt32OfModZero() { + Throwable exception = + assertThrows(ArithmeticException.class, () -> v(0).multiplyMod(UInt32.valueOf(5), UInt32.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModLongUInt32Provider") + void multiplyModLongUInt32(Value v1, int v2, UInt32 m, Value expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModLongUInt32Provider() { + return Stream + .of( + Arguments.of(v(0), 5, UInt32.valueOf(2), v(0)), + Arguments.of(v(2), 3, UInt32.valueOf(7), v(6)), + Arguments.of(v(2), 3, UInt32.valueOf(6), v(0)), + Arguments.of(v(2), 0, UInt32.valueOf(6), v(0)), + Arguments.of(hv("0xFFFFFFFE"), 2, UInt32.MAX_VALUE, hv("0xFFFFFFFD"))); + } + + @Test + void shouldThrowForMultiplyModLongUInt32OfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(3).multiplyMod(1, UInt32.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongUInt32OfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).multiplyMod(-1, UInt32.valueOf(2))); + assertEquals("multiplyMod unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModLongLongProvider") + void multiplyModLongLong(Value v1, int v2, int m, Value expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModLongLongProvider() { + return Stream + .of( + Arguments.of(v(0), 5, 2, v(0)), + Arguments.of(v(2), 3, 7, v(6)), + Arguments.of(v(2), 3, 6, v(0)), + Arguments.of(v(2), 0, 6, v(0)), + Arguments.of(hv("0x0FFFFFFE"), 2, Integer.MAX_VALUE, hv("0x1FFFFFFC"))); + } + + @Test + void shouldThrowForMultiplyModLongLongOfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).multiplyMod(1, 0)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongLongOfModNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(2).multiplyMod(5, -7)); + assertEquals("multiplyMod unsigned with negative modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(3).multiplyMod(-1, 2)); + assertEquals("multiplyMod unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideProvider") + void divide(Value v1, Value v2, Value expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideProvider() { + return Stream + .of( + Arguments.of(v(0), v(2), v(0)), + Arguments.of(v(1), v(2), v(0)), + Arguments.of(v(2), v(2), v(1)), + Arguments.of(v(3), v(2), v(1)), + Arguments.of(v(4), v(2), v(2)), + Arguments.of(v(2), v(8), v(0)), + Arguments.of(v(7), v(8), v(0)), + Arguments.of(v(8), v(8), v(1)), + Arguments.of(v(9), v(8), v(1)), + Arguments.of(v(17), v(8), v(2)), + Arguments.of(v(1024), v(8), v(128)), + Arguments.of(v(1026), v(8), v(128))); + } + + @Test + void shouldThrowForDivideByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(v(0))); + assertEquals("divide by zero", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideUInt32Provider") + void divideUInt32(Value v1, UInt32 v2, Value expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideUInt32Provider() { + return Stream + .of( + Arguments.of(v(0), UInt32.valueOf(2), v(0)), + Arguments.of(v(1), UInt32.valueOf(2), v(0)), + Arguments.of(v(2), UInt32.valueOf(2), v(1)), + Arguments.of(v(3), UInt32.valueOf(2), v(1)), + Arguments.of(v(4), UInt32.valueOf(2), v(2)), + Arguments.of(v(2), UInt32.valueOf(8), v(0)), + Arguments.of(v(7), UInt32.valueOf(8), v(0)), + Arguments.of(v(8), UInt32.valueOf(8), v(1)), + Arguments.of(v(9), UInt32.valueOf(8), v(1)), + Arguments.of(v(17), UInt32.valueOf(8), v(2)), + Arguments.of(v(1024), UInt32.valueOf(8), v(128)), + Arguments.of(v(1026), UInt32.valueOf(8), v(128))); + } + + @Test + void shouldThrowForDivideUInt32ByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(UInt32.ZERO)); + assertEquals("divide by zero", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideLongProvider") + void divideLong(Value v1, int v2, Value expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2, v(0)), + Arguments.of(v(1), 2, v(0)), + Arguments.of(v(2), 2, v(1)), + Arguments.of(v(3), 2, v(1)), + Arguments.of(v(4), 2, v(2)), + Arguments.of(v(2), 8, v(0)), + Arguments.of(v(7), 8, v(0)), + Arguments.of(v(8), 8, v(1)), + Arguments.of(v(9), 8, v(1)), + Arguments.of(v(17), 8, v(2)), + Arguments.of(v(1024), 8, v(128)), + Arguments.of(v(1026), 8, v(128))); + } + + @Test + void shouldThrowForDivideLongByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(0)); + assertEquals("divide by zero", exception.getMessage()); + } + + @Test + void shouldThrowForDivideLongByNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(-5)); + assertEquals("divide unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("powUInt32Provider") + void powUInt32(Value v1, UInt32 v2, Value expected) { + assertValueEquals(expected, v1.pow(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream powUInt32Provider() { + return Stream + .of( + Arguments.of(v(0), UInt32.valueOf(2), v(0)), + Arguments.of(v(2), UInt32.valueOf(2), v(4)), + Arguments.of(v(2), UInt32.valueOf(8), v(256)), + Arguments.of(v(3), UInt32.valueOf(3), v(27))); + } + + @ParameterizedTest + @MethodSource("powLongProvider") + void powLong(Value v1, int v2, Value expected) { + assertValueEquals(expected, v1.pow(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream powLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2, v(0)), + Arguments.of(v(2), 2, v(4)), + Arguments.of(v(2), 8, v(256)), + Arguments.of(v(3), 3, v(27))); + } + + @ParameterizedTest + @MethodSource("modUInt32Provider") + void modUInt32(Value v1, UInt32 v2, Value expected) { + assertValueEquals(expected, v1.mod(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream modUInt32Provider() { + return Stream + .of( + Arguments.of(v(0), UInt32.valueOf(2), v(0)), + Arguments.of(v(1), UInt32.valueOf(2), v(1)), + Arguments.of(v(2), UInt32.valueOf(2), v(0)), + Arguments.of(v(3), UInt32.valueOf(2), v(1)), + Arguments.of(v(0), UInt32.valueOf(8), v(0)), + Arguments.of(v(1), UInt32.valueOf(8), v(1)), + Arguments.of(v(2), UInt32.valueOf(8), v(2)), + Arguments.of(v(3), UInt32.valueOf(8), v(3)), + Arguments.of(v(7), UInt32.valueOf(8), v(7)), + Arguments.of(v(8), UInt32.valueOf(8), v(0)), + Arguments.of(v(9), UInt32.valueOf(8), v(1)), + Arguments.of(v(1024), UInt32.valueOf(8), v(0)), + Arguments.of(v(1026), UInt32.valueOf(8), v(2))); + } + + @Test + void shouldThrowForModUInt32ByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(UInt32.ZERO)); + assertEquals("mod by zero", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("modLongProvider") + void modLong(Value v1, int v2, Value expected) { + assertValueEquals(expected, v1.mod(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream modLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2, v(0)), + Arguments.of(v(1), 2, v(1)), + Arguments.of(v(2), 2, v(0)), + Arguments.of(v(3), 2, v(1)), + Arguments.of(v(0), 8, v(0)), + Arguments.of(v(1), 8, v(1)), + Arguments.of(v(2), 8, v(2)), + Arguments.of(v(3), 8, v(3)), + Arguments.of(v(7), 8, v(7)), + Arguments.of(v(8), 8, v(0)), + Arguments.of(v(9), 8, v(1)), + Arguments.of(v(1024), 8, v(0)), + Arguments.of(v(1026), 8, v(2))); + } + + @Test + void shouldThrowForModLongByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(0)); + assertEquals("mod by zero", exception.getMessage()); + } + + @Test + void shouldThrowForModLongByNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(-5)); + assertEquals("mod by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("compareToProvider") + void compareTo(Value v1, Value v2, int expected) { + assertEquals(expected, v1.compareTo(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream compareToProvider() { + return Stream + .of( + Arguments.of(v(5), v(5), 0), + Arguments.of(v(5), v(3), 1), + Arguments.of(v(5), v(6), -1), + Arguments.of(hv("0x00000000"), hv("0x00000000"), 0), + Arguments.of(hv("0xFFFFFFFF"), hv("0xFFFFFFFF"), 0), + Arguments.of(hv("0x0000FFFF"), hv("0x0000FFFF"), 0), + Arguments.of(hv("0xFFFFFFFF"), hv("0x00000000"), 1), + Arguments.of(hv("0x00000000"), hv("0xFFFFFFFF"), -1), + Arguments.of(hv("0x0001FFFF"), hv("0x0000FFFF"), 1), + Arguments.of(hv("0x0000FFFE"), hv("0x0000FFFF"), -1)); + } + + @ParameterizedTest + @MethodSource("toBytesProvider") + void toBytesTest(Value value, Bytes expected) { + assertEquals(expected, value.toBytes()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream toBytesProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), Bytes.fromHexString("0x00000000")), + Arguments.of(hv("0x01000000"), Bytes.fromHexString("0x01000000"))); + } + + @ParameterizedTest + @MethodSource("toMinimalBytesProvider") + void toMinimalBytesTest(Value value, Bytes expected) { + assertEquals(expected, value.toMinimalBytes()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream toMinimalBytesProvider() { + return Stream + .of(Arguments.of(hv("0x00"), Bytes.EMPTY), Arguments.of(hv("0x01000000"), Bytes.fromHexString("0x01000000"))); + } + + @ParameterizedTest + @MethodSource("numberOfLeadingZerosProvider") + void numberOfLeadingZeros(Value value, int expected) { + assertEquals(expected, value.numberOfLeadingZeros()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream numberOfLeadingZerosProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), 32), + Arguments.of(hv("0x01"), 31), + Arguments.of(hv("0x02"), 30), + Arguments.of(hv("0x03"), 30), + Arguments.of(hv("0x0F"), 28), + Arguments.of(hv("0x8F"), 24)); + } + + @ParameterizedTest + @MethodSource("bitLengthProvider") + void bitLength(Value value, int expected) { + assertEquals(expected, value.bitLength()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream bitLengthProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), 0), + Arguments.of(hv("0x01"), 1), + Arguments.of(hv("0x02"), 2), + Arguments.of(hv("0x03"), 2), + Arguments.of(hv("0x0F"), 4), + Arguments.of(hv("0x8F"), 8)); + } + + @ParameterizedTest + @MethodSource("addExactProvider") + void addExact(Value value, Value operand) { + assertThrows(ArithmeticException.class, () -> value.addExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addExactProvider() { + return Stream.of(Arguments.of(Value.MAX_VALUE, v(1)), Arguments.of(Value.MAX_VALUE, Value.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addExactLongProvider") + void addExactLong(Value value, int operand) { + assertThrows(ArithmeticException.class, () -> value.addExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addExactLongProvider() { + return Stream + .of(Arguments.of(Value.MAX_VALUE, 3), Arguments.of(Value.MAX_VALUE, Integer.MAX_VALUE), Arguments.of(v(0), -1)); + } + + @ParameterizedTest + @MethodSource("subtractExactProvider") + void subtractExact(Value value, Value operand) { + assertThrows(ArithmeticException.class, () -> value.subtractExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractExactProvider() { + return Stream.of(Arguments.of(v(0), v(1)), Arguments.of(v(0), Value.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("subtractExactLongProvider") + void subtractExactLong(Value value, int operand) { + assertThrows(ArithmeticException.class, () -> value.subtractExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractExactLongProvider() { + return Stream.of(Arguments.of(v(0), 1), Arguments.of(v(0), Integer.MAX_VALUE), Arguments.of(Value.MAX_VALUE, -1)); + } + + private void assertValueEquals(Value expected, Value actual) { + String msg = String.format("Expected %s but got %s", expected.toHexString(), actual.toHexString()); + assertEquals(expected, actual, msg); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/BaseUInt384ValueTest.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/BaseUInt384ValueTest.java new file mode 100644 index 00000000000..f8c9e1fd7fb --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/BaseUInt384ValueTest.java @@ -0,0 +1,921 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.math.BigInteger; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +// This test is in a `test` sub-package to ensure that it does not have access to package-private +// methods within the bigints package, as it should be testing the usage of the public API. +class BaseUInt384ValueTest { + + private static class Value extends BaseUInt384Value { + static final Value MAX_VALUE = new Value(UInt384.MAX_VALUE); + + Value(UInt384 v) { + super(v, Value::new); + } + + Value(long v) { + super(v, Value::new); + } + + Value(BigInteger s) { + super(s, Value::new); + } + } + + private static Value v(long v) { + return new Value(v); + } + + private static Value biv(String s) { + return new Value(new BigInteger(s)); + } + + private static Value hv(String s) { + return new Value(UInt384.fromHexString(s)); + } + + @ParameterizedTest + @MethodSource("addProvider") + void add(Value v1, Value v2, Value expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addProvider() { + return Stream + .of( + Arguments.of(v(1), v(0), v(1)), + Arguments.of(v(5), v(0), v(5)), + Arguments.of(v(0), v(1), v(1)), + Arguments.of(v(0), v(100), v(100)), + Arguments.of(v(2), v(2), v(4)), + Arguments.of(v(100), v(90), v(190)), + Arguments.of(biv("9223372036854775807"), v(1), biv("9223372036854775808")), + Arguments.of(biv("13492324908428420834234908342"), v(10), biv("13492324908428420834234908352")), + Arguments + .of(biv("13492324908428420834234908342"), v(23422141424214L), biv("13492324908428444256376332556")), + Arguments.of(new Value(UInt384.MAX_VALUE), v(1), v(0)), + Arguments.of(new Value(UInt384.MAX_VALUE), v(2), v(1)), + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0"), + v(1), + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1")), + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + v(1), + new Value(UInt384.MAX_VALUE))); + } + + @ParameterizedTest + @MethodSource("addLongProvider") + void addLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addLongProvider() { + return Stream + .of( + Arguments.of(v(1), 0L, v(1)), + Arguments.of(v(5), 0L, v(5)), + Arguments.of(v(0), 1L, v(1)), + Arguments.of(v(0), 100L, v(100)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(100), 90L, v(190)), + Arguments.of(biv("13492324908428420834234908342"), 10L, biv("13492324908428420834234908352")), + Arguments.of(biv("13492324908428420834234908342"), 23422141424214L, biv("13492324908428444256376332556")), + Arguments.of(new Value(UInt384.MAX_VALUE), 1L, v(0)), + Arguments.of(new Value(UInt384.MAX_VALUE), 2L, v(1)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0"), + 1L, + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1")), + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + 1L, + new Value(UInt384.MAX_VALUE)), + Arguments.of(v(10), -5L, v(5)), + Arguments.of(v(0), -1L, new Value(UInt384.MAX_VALUE))); + } + + @ParameterizedTest + @MethodSource("addModProvider") + void addMod(Value v1, Value v2, UInt384 m, Value expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModProvider() { + return Stream + .of( + Arguments.of(v(0), v(1), UInt384.valueOf(2), v(1)), + Arguments.of(v(1), v(1), UInt384.valueOf(2), v(0)), + Arguments + .of( + new Value(UInt384.MAX_VALUE.subtract(2)), + v(1), + UInt384.MAX_VALUE, + new Value(UInt384.MAX_VALUE.subtract(1))), + Arguments.of(new Value(UInt384.MAX_VALUE.subtract(1)), v(1), UInt384.MAX_VALUE, v(0)), + Arguments.of(v(2), v(1), UInt384.valueOf(2), v(1)), + Arguments.of(v(3), v(2), UInt384.valueOf(6), v(5)), + Arguments.of(v(3), v(4), UInt384.valueOf(2), v(1))); + } + + @Test + void shouldThrowForAddModOfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(v(1), UInt384.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModUInt384UInt384Provider") + void addModUInt384UInt384(Value v1, Value v2, UInt384 m, Value expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModUInt384UInt384Provider() { + return Stream + .of( + Arguments.of(v(0), v(1), UInt384.valueOf(2), v(1)), + Arguments.of(v(1), v(1), UInt384.valueOf(2), v(0)), + Arguments + .of( + new Value(UInt384.MAX_VALUE.subtract(2)), + v(1), + UInt384.MAX_VALUE, + new Value(UInt384.MAX_VALUE.subtract(1))), + Arguments.of(new Value(UInt384.MAX_VALUE.subtract(1)), new Value(UInt384.ONE), UInt384.MAX_VALUE, v(0)), + Arguments.of(v(2), new Value(UInt384.ONE), UInt384.valueOf(2), v(1)), + Arguments.of(v(3), v(2), UInt384.valueOf(6), v(5)), + Arguments.of(v(3), v(4), UInt384.valueOf(2), v(1))); + } + + @Test + void shouldThrowForAddModLongUInt384OfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, UInt384.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModLongUInt384Provider") + void addModLongUInt384(Value v1, long v2, UInt384 m, Value expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModLongUInt384Provider() { + return Stream + .of( + Arguments.of(v(0), 1L, UInt384.valueOf(2), v(1)), + Arguments.of(v(1), 1L, UInt384.valueOf(2), v(0)), + Arguments + .of( + new Value(UInt384.MAX_VALUE.subtract(2)), + 1L, + UInt384.MAX_VALUE, + new Value(UInt384.MAX_VALUE.subtract(1))), + Arguments.of(new Value(UInt384.MAX_VALUE.subtract(1)), 1L, UInt384.MAX_VALUE, v(0)), + Arguments.of(v(2), 1L, UInt384.valueOf(2), v(1)), + Arguments.of(v(2), -1L, UInt384.valueOf(2), v(1)), + Arguments.of(v(1), -7L, UInt384.valueOf(5), v(4))); + } + + @Test + void shouldThrowForAddModUInt384UInt384OfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(UInt384.ONE, UInt384.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModLongLongProvider") + void addModLongLong(Value v1, long v2, long m, Value expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModLongLongProvider() { + return Stream + .of(Arguments.of(v(0), 1L, 2L, v(1)), Arguments.of(v(1), 1L, 2L, v(0)), Arguments.of(v(2), 1L, 2L, v(1))); + } + + @Test + void shouldThrowForAddModLongLongOfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, 0)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForAddModLongLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, -5)); + assertEquals("addMod unsigned with negative modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("subtractProvider") + void subtract(Value v1, Value v2, Value expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractProvider() { + return Stream + .of( + Arguments.of(v(1), v(0), v(1)), + Arguments.of(v(5), v(0), v(5)), + Arguments.of(v(2), v(1), v(1)), + Arguments.of(v(100), v(100), v(0)), + Arguments.of(biv("13492324908428420834234908342"), v(10), biv("13492324908428420834234908332")), + Arguments + .of(biv("13492324908428420834234908342"), v(23422141424214L), biv("13492324908428397412093484128")), + Arguments.of(v(0), v(1), new Value(UInt384.MAX_VALUE)), + Arguments + .of( + v(1), + v(2), + new Value(UInt384.MAX_VALUE), + Arguments + .of( + UInt384.MAX_VALUE, + v(1), + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE")))); + } + + @ParameterizedTest + @MethodSource("subtractLongProvider") + void subtractLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractLongProvider() { + return Stream + .of( + Arguments.of(v(1), 0L, v(1)), + Arguments.of(v(5), 0L, v(5)), + Arguments.of(v(2), 1L, v(1)), + Arguments.of(v(100), 100L, v(0)), + Arguments.of(biv("13492324908428420834234908342"), 10L, biv("13492324908428420834234908332")), + Arguments.of(biv("13492324908428420834234908342"), 23422141424214L, biv("13492324908428397412093484128")), + Arguments.of(v(0), 1L, new Value(UInt384.MAX_VALUE)), + Arguments.of(v(1), 2L, new Value(UInt384.MAX_VALUE)), + Arguments + .of( + new Value(UInt384.MAX_VALUE), + 1L, + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE")), + Arguments.of(v(0), -1L, v(1)), + Arguments.of(v(0), -100L, v(100)), + Arguments.of(v(2), -2L, v(4))); + } + + @ParameterizedTest + @MethodSource("multiplyProvider") + void multiply(Value v1, Value v2, Value expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyProvider() { + return Stream + .of( + Arguments.of(v(0), v(2), v(0)), + Arguments.of(v(1), v(2), v(2)), + Arguments.of(v(2), v(2), v(4)), + Arguments.of(v(3), v(2), v(6)), + Arguments.of(v(4), v(2), v(8)), + Arguments.of(v(10), v(18), v(180)), + Arguments.of(biv("13492324908428420834234908341"), v(2), biv("26984649816856841668469816682")), + Arguments.of(biv("13492324908428420834234908342"), v(2), biv("26984649816856841668469816684")), + Arguments.of(v(2), v(8), v(16)), + Arguments.of(v(7), v(8), v(56)), + Arguments.of(v(8), v(8), v(64)), + Arguments.of(v(17), v(8), v(136)), + Arguments.of(biv("13492324908428420834234908342"), v(8), biv("107938599267427366673879266736")), + Arguments.of(biv("13492324908428420834234908342"), v(2048), biv("27632281412461405868513092284416")), + Arguments.of(biv("13492324908428420834234908342"), v(131072), biv("1768466010397529975584837906202624")), + Arguments.of(v(22), v(0), v(0))); + } + + @ParameterizedTest + @MethodSource("multiplyLongProvider") + void multiplyLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(2)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(3), 2L, v(6)), + Arguments.of(v(4), 2L, v(8)), + Arguments.of(v(10), 18L, v(180)), + Arguments.of(biv("13492324908428420834234908341"), 2L, biv("26984649816856841668469816682")), + Arguments.of(biv("13492324908428420834234908342"), 2L, biv("26984649816856841668469816684")), + Arguments.of(v(2), 8L, v(16)), + Arguments.of(v(7), 8L, v(56)), + Arguments.of(v(8), 8L, v(64)), + Arguments.of(v(17), 8L, v(136)), + Arguments.of(biv("13492324908428420834234908342"), 8L, biv("107938599267427366673879266736")), + Arguments.of(biv("13492324908428420834234908342"), 2048L, biv("27632281412461405868513092284416")), + Arguments.of(biv("13492324908428420834234908342"), 131072L, biv("1768466010397529975584837906202624")), + Arguments.of(v(22), 0L, v(0)), + Arguments + .of( + hv( + "0x0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 2L, + hv( + "0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE")), + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 2L, + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"))); + } + + @Test + void shouldThrowForMultiplyLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(2).multiply(-5)); + assertEquals("multiply unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModProvider") + void multiplyMod(Value v1, Value v2, UInt384 m, Value expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModProvider() { + return Stream + .of( + Arguments.of(v(0), v(5), UInt384.valueOf(2), v(0)), + Arguments.of(v(2), v(3), UInt384.valueOf(7), v(6)), + Arguments.of(v(2), v(3), UInt384.valueOf(6), v(0)), + Arguments.of(v(2), v(0), UInt384.valueOf(6), v(0)), + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + v(2), + UInt384.MAX_VALUE, + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD"))); + } + + @Test + void shouldThrowForMultiplyModOfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).multiplyMod(v(1), UInt384.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModLongUInt384Provider") + void multiplyModLongUInt384(Value v1, long v2, UInt384 m, Value expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModLongUInt384Provider() { + return Stream + .of( + Arguments.of(v(0), 5L, UInt384.valueOf(2), v(0)), + Arguments.of(v(2), 3L, UInt384.valueOf(7), v(6)), + Arguments.of(v(2), 3L, UInt384.valueOf(6), v(0)), + Arguments.of(v(2), 0L, UInt384.valueOf(6), v(0)), + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + 2L, + UInt384.MAX_VALUE, + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD"))); + } + + @Test + void shouldThrowForMultiplyModLongUInt384OfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).multiplyMod(1L, UInt384.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongUInt384OfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(3).multiplyMod(-1, UInt384.valueOf(2))); + assertEquals("multiplyMod unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModLongLongProvider") + void multiplyModLongLong(Value v1, long v2, long m, Value expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModLongLongProvider() { + return Stream + .of( + Arguments.of(v(0), 5L, 2L, v(0)), + Arguments.of(v(2), 3L, 7L, v(6)), + Arguments.of(v(2), 3L, 6L, v(0)), + Arguments.of(v(2), 0L, 6L, v(0)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + 2L, + Long.MAX_VALUE, + hv("0x000000000000000000000000000000000000000000000000000000000000001C"))); + } + + @Test + void shouldThrowForMultiplyModLongLongOfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).multiplyMod(1, 0)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongLongOfModNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(2).multiplyMod(5, -7)); + assertEquals("multiplyMod unsigned with negative modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(3).multiplyMod(-1, 2)); + assertEquals("multiplyMod unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideProvider") + void divide(Value v1, Value v2, Value expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideProvider() { + return Stream + .of( + Arguments.of(v(0), v(2), v(0)), + Arguments.of(v(1), v(2), v(0)), + Arguments.of(v(2), v(2), v(1)), + Arguments.of(v(3), v(2), v(1)), + Arguments.of(v(4), v(2), v(2)), + Arguments.of(biv("13492324908428420834234908341"), v(2), biv("6746162454214210417117454170")), + Arguments.of(biv("13492324908428420834234908342"), v(2), biv("6746162454214210417117454171")), + Arguments.of(biv("13492324908428420834234908343"), v(2), biv("6746162454214210417117454171")), + Arguments.of(v(2), v(8), v(0)), + Arguments.of(v(7), v(8), v(0)), + Arguments.of(v(8), v(8), v(1)), + Arguments.of(v(9), v(8), v(1)), + Arguments.of(v(17), v(8), v(2)), + Arguments.of(v(1024), v(8), v(128)), + Arguments.of(v(1026), v(8), v(128)), + Arguments.of(biv("13492324908428420834234908342"), v(8), biv("1686540613553552604279363542")), + Arguments.of(biv("13492324908428420834234908342"), v(2048), biv("6588049271693564860466263")), + Arguments.of(biv("13492324908428420834234908342"), v(131072), biv("102938269870211950944785"))); + } + + @Test + void shouldThrowForDivideByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(v(0))); + assertEquals("divide by zero", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideLongProvider") + void divideLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(0)), + Arguments.of(v(2), 2L, v(1)), + Arguments.of(v(3), 2L, v(1)), + Arguments.of(v(4), 2L, v(2)), + Arguments.of(biv("13492324908428420834234908341"), 2L, biv("6746162454214210417117454170")), + Arguments.of(biv("13492324908428420834234908342"), 2L, biv("6746162454214210417117454171")), + Arguments.of(biv("13492324908428420834234908343"), 2L, biv("6746162454214210417117454171")), + Arguments.of(v(2), 8L, v(0)), + Arguments.of(v(7), 8L, v(0)), + Arguments.of(v(8), 8L, v(1)), + Arguments.of(v(9), 8L, v(1)), + Arguments.of(v(17), 8L, v(2)), + Arguments.of(v(1024), 8L, v(128)), + Arguments.of(v(1026), 8L, v(128)), + Arguments.of(biv("13492324908428420834234908342"), 8L, biv("1686540613553552604279363542")), + Arguments.of(biv("13492324908428420834234908342"), 2048L, biv("6588049271693564860466263")), + Arguments.of(biv("13492324908428420834234908342"), 131072L, biv("102938269870211950944785"))); + } + + @Test + void shouldThrowForDivideLongByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(0)); + assertEquals("divide by zero", exception.getMessage()); + } + + @Test + void shouldThrowForDivideLongByNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(-5)); + assertEquals("divide unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("powUInt384Provider") + void powUInt384(Value v1, UInt384 v2, Value expected) { + assertValueEquals(expected, v1.pow(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream powUInt384Provider() { + return Stream + .of( + Arguments.of(v(0), UInt384.valueOf(2), v(0)), + Arguments.of(v(2), UInt384.valueOf(2), v(4)), + Arguments.of(v(2), UInt384.valueOf(8), v(256)), + Arguments.of(v(3), UInt384.valueOf(3), v(27)), + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0"), + UInt384.valueOf(3), + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A920E119A2F000"))); + } + + @ParameterizedTest + @MethodSource("powLongProvider") + void powLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.pow(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream powLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(2), 8L, v(256)), + Arguments.of(v(3), 3L, v(27)), + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0"), + 3L, + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A920E119A2F000")), + Arguments + .of( + v(3), + -3L, + hv( + "0x4BDA12F684BDA12F684BDA12F684BDA12F684BDA12F684BDA12F684BDA12F684BDA12F684BDA12F684BDA12F684BDA13"))); + } + + @ParameterizedTest + @MethodSource("modLongProvider") + void modLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.mod(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream modLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(1)), + Arguments.of(v(2), 2L, v(0)), + Arguments.of(v(3), 2L, v(1)), + Arguments.of(biv("13492324908428420834234908342"), 2L, v(0)), + Arguments.of(biv("13492324908428420834234908343"), 2L, v(1)), + Arguments.of(v(0), 8L, v(0)), + Arguments.of(v(1), 8L, v(1)), + Arguments.of(v(2), 8L, v(2)), + Arguments.of(v(3), 8L, v(3)), + Arguments.of(v(7), 8L, v(7)), + Arguments.of(v(8), 8L, v(0)), + Arguments.of(v(9), 8L, v(1)), + Arguments.of(v(1024), 8L, v(0)), + Arguments.of(v(1026), 8L, v(2)), + Arguments.of(biv("13492324908428420834234908342"), 8L, v(6)), + Arguments.of(biv("13492324908428420834234908343"), 8L, v(7)), + Arguments.of(biv("13492324908428420834234908344"), 8L, v(0))); + } + + @Test + void shouldThrowForModLongByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(0)); + assertEquals("mod by zero", exception.getMessage()); + } + + @Test + void shouldThrowForModLongByNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(-5)); + assertEquals("mod by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("intValueProvider") + void intValue(Value value, int expected) { + assertEquals(expected, value.intValue()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream intValueProvider() { + return Stream + .of( + Arguments.of(hv("0x"), 0), + Arguments.of(hv("0x00"), 0), + Arguments.of(hv("0x00000000"), 0), + Arguments.of(hv("0x01"), 1), + Arguments.of(hv("0x0001"), 1), + Arguments.of(hv("0x000001"), 1), + Arguments.of(hv("0x00000001"), 1), + Arguments.of(hv("0x0100"), 256), + Arguments.of(hv("0x000100"), 256), + Arguments.of(hv("0x00000100"), 256)); + } + + @Test + void shouldThrowForIntValueOfOversizeValue() { + Throwable exception = assertThrows(ArithmeticException.class, () -> hv("0x0100000000").intValue()); + assertEquals("Value does not fit a 4 byte int", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("longValueProvider") + void longValue(Value value, long expected) { + assertEquals(expected, value.toLong()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream longValueProvider() { + return Stream + .of( + Arguments.of(hv("0x"), 0L), + Arguments.of(hv("0x00"), 0L), + Arguments.of(hv("0x00000000"), 0L), + Arguments.of(hv("0x01"), 1L), + Arguments.of(hv("0x0001"), 1L), + Arguments.of(hv("0x000001"), 1L), + Arguments.of(hv("0x00000001"), 1L), + Arguments.of(hv("0x0000000001"), 1L), + Arguments.of(hv("0x000000000001"), 1L), + Arguments.of(hv("0x0100"), 256L), + Arguments.of(hv("0x000100"), 256L), + Arguments.of(hv("0x00000100"), 256L), + Arguments.of(hv("0x00000100"), 256L), + Arguments.of(hv("0x000000000100"), 256L), + Arguments.of(hv("0x00000000000100"), 256L), + Arguments.of(hv("0x0000000000000100"), 256L), + Arguments.of(hv("0xFFFFFFFF"), (1L << 32) - 1)); + } + + @Test + void shouldThrowForLongValueOfOversizeValue() { + Throwable exception = assertThrows(ArithmeticException.class, () -> hv("0x010000000000000000").toLong()); + assertEquals("Value does not fit a 8 byte long", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("compareToProvider") + void compareTo(Value v1, Value v2, int expected) { + assertEquals(expected, v1.compareTo(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream compareToProvider() { + return Stream + .of( + Arguments.of(v(5), v(5), 0), + Arguments.of(v(5), v(3), 1), + Arguments.of(v(5), v(6), -1), + Arguments + .of( + hv("0x0000000000000000000000000000000000000000000000000000000000000000"), + hv("0x0000000000000000000000000000000000000000000000000000000000000000"), + 0), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 0), + Arguments + .of( + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 0), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0x0000000000000000000000000000000000000000000000000000000000000000"), + 1), + Arguments + .of( + hv("0x0000000000000000000000000000000000000000000000000000000000000000"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + -1), + Arguments + .of( + hv("0x000000000000000000000000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 1), + Arguments + .of( + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + -1)); + } + + @ParameterizedTest + @MethodSource("toBytesProvider") + void toBytesTest(Value value, Bytes expected) { + assertEquals(expected, value.toBytes()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream toBytesProvider() { + return Stream + .of( + Arguments + .of( + hv("0x00"), + Bytes + .fromHexString( + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")), + Arguments + .of( + hv("0x01000000"), + Bytes + .fromHexString( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000")), + Arguments + .of( + hv("0x0100000000"), + Bytes + .fromHexString( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000")), + Arguments + .of( + hv("0xf100000000ab"), + Bytes + .fromHexString( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000f100000000ab")), + Arguments + .of( + hv("0x0400000000000000000000000000000000000000000000000000f100000000ab"), + Bytes + .fromHexString( + "0x000000000000000000000000000000000400000000000000000000000000000000000000000000000000f100000000ab"))); + } + + @ParameterizedTest + @MethodSource("toMinimalBytesProvider") + void toMinimalBytesTest(Value value, Bytes expected) { + assertEquals(expected, value.toMinimalBytes()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream toMinimalBytesProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), Bytes.EMPTY), + Arguments.of(hv("0x01000000"), Bytes.fromHexString("0x01000000")), + Arguments.of(hv("0x0100000000"), Bytes.fromHexString("0x0100000000")), + Arguments.of(hv("0xf100000000ab"), Bytes.fromHexString("0xf100000000ab")), + Arguments + .of( + hv("0x0400000000000000000000000000000000000000000000000000f100000000ab"), + Bytes.fromHexString("0x0400000000000000000000000000000000000000000000000000f100000000ab"))); + } + + @ParameterizedTest + @MethodSource("numberOfLeadingZerosProvider") + void numberOfLeadingZeros(Value value, int expected) { + assertEquals(expected, value.numberOfLeadingZeros()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream numberOfLeadingZerosProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), 384), + Arguments.of(hv("0x01"), 383), + Arguments.of(hv("0x02"), 382), + Arguments.of(hv("0x03"), 382), + Arguments.of(hv("0x0F"), 380), + Arguments.of(hv("0x8F"), 376), + Arguments.of(hv("0x100000000"), 351)); + } + + @ParameterizedTest + @MethodSource("bitLengthProvider") + void bitLength(Value value, int expected) { + assertEquals(expected, value.bitLength()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream bitLengthProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), 0), + Arguments.of(hv("0x01"), 1), + Arguments.of(hv("0x02"), 2), + Arguments.of(hv("0x03"), 2), + Arguments.of(hv("0x0F"), 4), + Arguments.of(hv("0x8F"), 8), + Arguments.of(hv("0x100000000"), 33)); + } + + @ParameterizedTest + @MethodSource("addExactProvider") + void addExact(Value value, Value operand) { + assertThrows(ArithmeticException.class, () -> value.addExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addExactProvider() { + return Stream.of(Arguments.of(Value.MAX_VALUE, v(1)), Arguments.of(Value.MAX_VALUE, Value.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addExactLongProvider") + void addExactLong(Value value, long operand) { + assertThrows(ArithmeticException.class, () -> value.addExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addExactLongProvider() { + return Stream + .of(Arguments.of(Value.MAX_VALUE, 3), Arguments.of(Value.MAX_VALUE, Long.MAX_VALUE), Arguments.of(v(0), -1)); + } + + @ParameterizedTest + @MethodSource("subtractExactProvider") + void subtractExact(Value value, Value operand) { + assertThrows(ArithmeticException.class, () -> value.subtractExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractExactProvider() { + return Stream.of(Arguments.of(v(0), v(1)), Arguments.of(v(0), Value.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("subtractExactLongProvider") + void subtractExactLong(Value value, long operand) { + assertThrows(ArithmeticException.class, () -> value.subtractExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractExactLongProvider() { + return Stream.of(Arguments.of(v(0), 1), Arguments.of(v(0), Long.MAX_VALUE), Arguments.of(Value.MAX_VALUE, -1)); + } + + private void assertValueEquals(Value expected, Value actual) { + String msg = String.format("Expected %s but got %s", expected.toHexString(), actual.toHexString()); + assertEquals(expected, actual, msg); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/BaseUInt64ValueTest.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/BaseUInt64ValueTest.java new file mode 100644 index 00000000000..3c96949d9ac --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/BaseUInt64ValueTest.java @@ -0,0 +1,805 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +// This test is in a `test` sub-package to ensure that it does not have access to package-private +// methods within the bigints package, as it should be testing the usage of the public API. +class BaseUInt64ValueTest { + + private static class Value extends BaseUInt64Value { + static final Value MAX_VALUE = new Value(UInt64.MAX_VALUE); + + Value(UInt64 v) { + super(v, Value::new); + } + + Value(long v) { + super(v, Value::new); + } + } + + private static Value v(long v) { + return new Value(v); + } + + private static Value hv(String s) { + return new Value(UInt64.fromHexString(s)); + } + + @ParameterizedTest + @MethodSource("addProvider") + void add(Value v1, Value v2, Value expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addProvider() { + return Stream + .of( + Arguments.of(v(1), v(0), v(1)), + Arguments.of(v(5), v(0), v(5)), + Arguments.of(v(0), v(1), v(1)), + Arguments.of(v(0), v(100), v(100)), + Arguments.of(v(2), v(2), v(4)), + Arguments.of(v(100), v(90), v(190)), + Arguments.of(Value.MAX_VALUE, v(1), v(0)), + Arguments.of(Value.MAX_VALUE, v(2), v(1)), + Arguments.of(hv("0xFFFFFFFFFFFFFFF0"), v(1), hv("0xFFFFFFFFFFFFFFF1")), + Arguments.of(hv("0xFFFFFFFFFFFFFFFE"), v(1), Value.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addUInt64Provider") + void addUInt64(Value v1, UInt64 v2, Value expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addUInt64Provider() { + return Stream + .of( + Arguments.of(v(1), UInt64.ZERO, v(1)), + Arguments.of(v(5), UInt64.ZERO, v(5)), + Arguments.of(v(0), UInt64.ONE, v(1)), + Arguments.of(v(0), UInt64.valueOf(100), v(100)), + Arguments.of(v(2), UInt64.valueOf(2), v(4)), + Arguments.of(v(100), UInt64.valueOf(90), v(190)), + Arguments.of(Value.MAX_VALUE, UInt64.valueOf(1), v(0)), + Arguments.of(Value.MAX_VALUE, UInt64.valueOf(2), v(1)), + Arguments.of(hv("0xFFFFFFFFFFFFFFF0"), UInt64.valueOf(1), hv("0xFFFFFFFFFFFFFFF1")), + Arguments.of(hv("0xFFFFFFFFFFFFFFFE"), UInt64.valueOf(1), Value.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addLongProvider") + void addLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addLongProvider() { + return Stream + .of( + Arguments.of(v(1), 0L, v(1)), + Arguments.of(v(5), 0L, v(5)), + Arguments.of(v(0), 1L, v(1)), + Arguments.of(v(0), 100L, v(100)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(100), 90L, v(190)), + Arguments.of(Value.MAX_VALUE, 1L, v(0)), + Arguments.of(Value.MAX_VALUE, 2L, v(1)), + Arguments.of(hv("0xFFFFFFFFFFFFFFF0"), 1L, hv("0xFFFFFFFFFFFFFFF1")), + Arguments.of(hv("0xFFFFFFFFFFFFFFFE"), 1L, Value.MAX_VALUE), + Arguments.of(v(10), -5L, v(5)), + Arguments.of(v(0), -1L, Value.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addModProvider") + void addMod(Value v1, Value v2, UInt64 m, Value expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModProvider() { + return Stream + .of( + Arguments.of(v(0), v(1), UInt64.valueOf(2), v(1)), + Arguments.of(v(1), v(1), UInt64.valueOf(2), v(0)), + Arguments.of(Value.MAX_VALUE.subtract(2), v(1), UInt64.MAX_VALUE, Value.MAX_VALUE.subtract(1)), + Arguments.of(Value.MAX_VALUE.subtract(1), v(1), UInt64.MAX_VALUE, v(0)), + Arguments.of(v(2), v(1), UInt64.valueOf(2), v(1)), + Arguments.of(v(3), v(2), UInt64.valueOf(6), v(5)), + Arguments.of(v(3), v(4), UInt64.valueOf(2), v(1))); + } + + @Test + void shouldThrowForAddModOfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(v(1), UInt64.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModUInt64UInt64Provider") + void addModUInt64UInt64(Value v1, UInt64 v2, UInt64 m, Value expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModUInt64UInt64Provider() { + return Stream + .of( + Arguments.of(v(0), UInt64.ONE, UInt64.valueOf(2), v(1)), + Arguments.of(v(1), UInt64.ONE, UInt64.valueOf(2), v(0)), + Arguments.of(Value.MAX_VALUE.subtract(2), UInt64.ONE, UInt64.MAX_VALUE, Value.MAX_VALUE.subtract(1)), + Arguments.of(Value.MAX_VALUE.subtract(1), UInt64.ONE, UInt64.MAX_VALUE, v(0)), + Arguments.of(v(2), UInt64.ONE, UInt64.valueOf(2), v(1)), + Arguments.of(v(3), UInt64.valueOf(2), UInt64.valueOf(6), v(5)), + Arguments.of(v(3), UInt64.valueOf(4), UInt64.valueOf(2), v(1))); + } + + @Test + void shouldThrowForAddModLongUInt64OfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, UInt64.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModLongUInt64Provider") + void addModLongUInt64(Value v1, long v2, UInt64 m, Value expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModLongUInt64Provider() { + return Stream + .of( + Arguments.of(v(0), 1L, UInt64.valueOf(2), v(1)), + Arguments.of(v(1), 1L, UInt64.valueOf(2), v(0)), + Arguments.of(Value.MAX_VALUE.subtract(2), 1L, UInt64.MAX_VALUE, Value.MAX_VALUE.subtract(1)), + Arguments.of(Value.MAX_VALUE.subtract(1), 1L, UInt64.MAX_VALUE, v(0)), + Arguments.of(v(2), 1L, UInt64.valueOf(2), v(1)), + Arguments.of(v(2), -1L, UInt64.valueOf(2), v(1)), + Arguments.of(v(1), -7L, UInt64.valueOf(5), v(4))); + } + + @Test + void shouldThrowForAddModUInt64UInt64OfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(UInt64.ONE, UInt64.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModLongLongProvider") + void addModLongLong(Value v1, long v2, long m, Value expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModLongLongProvider() { + return Stream + .of(Arguments.of(v(0), 1L, 2L, v(1)), Arguments.of(v(1), 1L, 2L, v(0)), Arguments.of(v(2), 1L, 2L, v(1))); + } + + @Test + void shouldThrowForAddModLongLongOfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, 0)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForAddModLongLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, -5)); + assertEquals("addMod unsigned with negative modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("subtractProvider") + void subtract(Value v1, Value v2, Value expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractProvider() { + return Stream + .of( + Arguments.of(v(1), v(0), v(1)), + Arguments.of(v(5), v(0), v(5)), + Arguments.of(v(2), v(1), v(1)), + Arguments.of(v(100), v(100), v(0)), + Arguments.of(v(0), v(1), Value.MAX_VALUE), + Arguments.of(v(1), v(2), Value.MAX_VALUE), + Arguments.of(Value.MAX_VALUE, v(1), hv("0xFFFFFFFFFFFFFFFE"))); + } + + @ParameterizedTest + @MethodSource("subtractUInt64Provider") + void subtractUInt64(Value v1, UInt64 v2, Value expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractUInt64Provider() { + return Stream + .of( + Arguments.of(v(1), UInt64.ZERO, v(1)), + Arguments.of(v(5), UInt64.ZERO, v(5)), + Arguments.of(v(2), UInt64.ONE, v(1)), + Arguments.of(v(100), UInt64.valueOf(100), v(0)), + Arguments.of(v(0), UInt64.ONE, Value.MAX_VALUE), + Arguments.of(v(1), UInt64.valueOf(2), Value.MAX_VALUE), + Arguments.of(Value.MAX_VALUE, UInt64.ONE, hv("0xFFFFFFFFFFFFFFFE"))); + } + + @ParameterizedTest + @MethodSource("subtractLongProvider") + void subtractLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractLongProvider() { + return Stream + .of( + Arguments.of(v(1), 0L, v(1)), + Arguments.of(v(5), 0L, v(5)), + Arguments.of(v(2), 1L, v(1)), + Arguments.of(v(100), 100L, v(0)), + Arguments.of(v(0), 1L, Value.MAX_VALUE), + Arguments.of(v(1), 2L, Value.MAX_VALUE), + Arguments.of(Value.MAX_VALUE, 1L, hv("0xFFFFFFFFFFFFFFFE")), + Arguments.of(v(0), -1L, v(1)), + Arguments.of(v(0), -100L, v(100)), + Arguments.of(v(2), -2L, v(4))); + } + + @ParameterizedTest + @MethodSource("multiplyProvider") + void multiply(Value v1, Value v2, Value expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyProvider() { + return Stream + .of( + Arguments.of(v(0), v(2), v(0)), + Arguments.of(v(1), v(2), v(2)), + Arguments.of(v(2), v(2), v(4)), + Arguments.of(v(3), v(2), v(6)), + Arguments.of(v(4), v(2), v(8)), + Arguments.of(v(10), v(18), v(180)), + Arguments.of(v(2), v(8), v(16)), + Arguments.of(v(7), v(8), v(56)), + Arguments.of(v(8), v(8), v(64)), + Arguments.of(v(17), v(8), v(136)), + Arguments.of(v(22), v(0), v(0))); + } + + @ParameterizedTest + @MethodSource("multiplyUInt64Provider") + void multiplyUInt64(Value v1, UInt64 v2, Value expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyUInt64Provider() { + return Stream + .of( + Arguments.of(v(0), UInt64.valueOf(2), v(0)), + Arguments.of(v(1), UInt64.valueOf(2), v(2)), + Arguments.of(v(2), UInt64.valueOf(2), v(4)), + Arguments.of(v(3), UInt64.valueOf(2), v(6)), + Arguments.of(v(4), UInt64.valueOf(2), v(8)), + Arguments.of(v(10), UInt64.valueOf(18), v(180)), + Arguments.of(v(2), UInt64.valueOf(8), v(16)), + Arguments.of(v(7), UInt64.valueOf(8), v(56)), + Arguments.of(v(8), UInt64.valueOf(8), v(64)), + Arguments.of(v(17), UInt64.valueOf(8), v(136)), + Arguments.of(v(22), UInt64.ZERO, v(0)), + Arguments.of(hv("0xFFFFFFFFFFFFFFFF"), UInt64.valueOf(2), hv("0xFFFFFFFFFFFFFFFE")), + Arguments.of(hv("0xFFFFFFFFFFFFFFFF"), UInt64.valueOf(2), hv("0xFFFFFFFFFFFFFFFE"))); + } + + @ParameterizedTest + @MethodSource("multiplyLongProvider") + void multiplyLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(2)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(3), 2L, v(6)), + Arguments.of(v(4), 2L, v(8)), + Arguments.of(v(10), 18L, v(180)), + Arguments.of(v(2), 8L, v(16)), + Arguments.of(v(7), 8L, v(56)), + Arguments.of(v(8), 8L, v(64)), + Arguments.of(v(17), 8L, v(136)), + Arguments.of(v(22), 0L, v(0)), + Arguments.of(hv("0xFFFFFFFFFFFFFFFF"), 2L, hv("0xFFFFFFFFFFFFFFFE")), + Arguments.of(hv("0xFFFFFFFFFFFFFFFF"), 2L, hv("0xFFFFFFFFFFFFFFFE"))); + } + + @Test + void shouldThrowForMultiplyLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(2).multiply(-5)); + assertEquals("multiply unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModProvider") + void multiplyMod(Value v1, Value v2, UInt64 m, Value expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModProvider() { + return Stream + .of( + Arguments.of(v(0), v(5), UInt64.valueOf(2), v(0)), + Arguments.of(v(2), v(3), UInt64.valueOf(7), v(6)), + Arguments.of(v(2), v(3), UInt64.valueOf(6), v(0)), + Arguments.of(v(2), v(0), UInt64.valueOf(6), v(0)), + Arguments.of(hv("0xFFFFFFFFFFFFFFFE"), v(2), UInt64.MAX_VALUE, hv("0xFFFFFFFFFFFFFFFD"))); + } + + @Test + void shouldThrowForMultiplyModOfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).multiplyMod(v(1), UInt64.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModUInt64UInt64Provider") + void multiplyModUInt64UInt64(Value v1, UInt64 v2, UInt64 m, Value expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModUInt64UInt64Provider() { + return Stream + .of( + Arguments.of(v(0), UInt64.valueOf(5), UInt64.valueOf(2), v(0)), + Arguments.of(v(2), UInt64.valueOf(3), UInt64.valueOf(7), v(6)), + Arguments.of(v(2), UInt64.valueOf(3), UInt64.valueOf(6), v(0)), + Arguments.of(v(2), UInt64.ZERO, UInt64.valueOf(6), v(0)), + Arguments.of(hv("0xFFFFFFFFFFFFFFFE"), UInt64.valueOf(2), UInt64.MAX_VALUE, hv("0xFFFFFFFFFFFFFFFD"))); + } + + @Test + void shouldThrowForMultiplyModUInt64UInt64OfModZero() { + Throwable exception = + assertThrows(ArithmeticException.class, () -> v(0).multiplyMod(UInt64.valueOf(5), UInt64.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModLongUInt64Provider") + void multiplyModLongUInt64(Value v1, long v2, UInt64 m, Value expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModLongUInt64Provider() { + return Stream + .of( + Arguments.of(v(0), 5L, UInt64.valueOf(2), v(0)), + Arguments.of(v(2), 3L, UInt64.valueOf(7), v(6)), + Arguments.of(v(2), 3L, UInt64.valueOf(6), v(0)), + Arguments.of(v(2), 0L, UInt64.valueOf(6), v(0)), + Arguments.of(hv("0xFFFFFFFFFFFFFFFE"), 2L, UInt64.MAX_VALUE, hv("0xFFFFFFFFFFFFFFFD"))); + } + + @Test + void shouldThrowForMultiplyModLongUInt64OfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(3).multiplyMod(1L, UInt64.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongUInt64OfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).multiplyMod(-1, UInt64.valueOf(2))); + assertEquals("multiplyMod unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModLongLongProvider") + void multiplyModLongLong(Value v1, long v2, long m, Value expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModLongLongProvider() { + return Stream + .of( + Arguments.of(v(0), 5L, 2L, v(0)), + Arguments.of(v(2), 3L, 7L, v(6)), + Arguments.of(v(2), 3L, 6L, v(0)), + Arguments.of(v(2), 0L, 6L, v(0)), + Arguments.of(hv("0x0FFFFFFFFFFFFFFE"), 2L, Long.MAX_VALUE, hv("0x1FFFFFFFFFFFFFFC"))); + } + + @Test + void shouldThrowForMultiplyModLongLongOfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).multiplyMod(1, 0)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongLongOfModNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(2).multiplyMod(5, -7)); + assertEquals("multiplyMod unsigned with negative modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(3).multiplyMod(-1, 2)); + assertEquals("multiplyMod unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideProvider") + void divide(Value v1, Value v2, Value expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideProvider() { + return Stream + .of( + Arguments.of(v(0), v(2), v(0)), + Arguments.of(v(1), v(2), v(0)), + Arguments.of(v(2), v(2), v(1)), + Arguments.of(v(3), v(2), v(1)), + Arguments.of(v(4), v(2), v(2)), + Arguments.of(v(2), v(8), v(0)), + Arguments.of(v(7), v(8), v(0)), + Arguments.of(v(8), v(8), v(1)), + Arguments.of(v(9), v(8), v(1)), + Arguments.of(v(17), v(8), v(2)), + Arguments.of(v(1024), v(8), v(128)), + Arguments.of(v(1026), v(8), v(128))); + } + + @Test + void shouldThrowForDivideByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(v(0))); + assertEquals("divide by zero", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideUInt64Provider") + void divideUInt64(Value v1, UInt64 v2, Value expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideUInt64Provider() { + return Stream + .of( + Arguments.of(v(0), UInt64.valueOf(2), v(0)), + Arguments.of(v(1), UInt64.valueOf(2), v(0)), + Arguments.of(v(2), UInt64.valueOf(2), v(1)), + Arguments.of(v(3), UInt64.valueOf(2), v(1)), + Arguments.of(v(4), UInt64.valueOf(2), v(2)), + Arguments.of(v(2), UInt64.valueOf(8), v(0)), + Arguments.of(v(7), UInt64.valueOf(8), v(0)), + Arguments.of(v(8), UInt64.valueOf(8), v(1)), + Arguments.of(v(9), UInt64.valueOf(8), v(1)), + Arguments.of(v(17), UInt64.valueOf(8), v(2)), + Arguments.of(v(1024), UInt64.valueOf(8), v(128)), + Arguments.of(v(1026), UInt64.valueOf(8), v(128))); + } + + @Test + void shouldThrowForDivideUInt64ByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(UInt64.ZERO)); + assertEquals("divide by zero", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideLongProvider") + void divideLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(0)), + Arguments.of(v(2), 2L, v(1)), + Arguments.of(v(3), 2L, v(1)), + Arguments.of(v(4), 2L, v(2)), + Arguments.of(v(2), 8L, v(0)), + Arguments.of(v(7), 8L, v(0)), + Arguments.of(v(8), 8L, v(1)), + Arguments.of(v(9), 8L, v(1)), + Arguments.of(v(17), 8L, v(2)), + Arguments.of(v(1024), 8L, v(128)), + Arguments.of(v(1026), 8L, v(128))); + } + + @Test + void shouldThrowForDivideLongByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(0)); + assertEquals("divide by zero", exception.getMessage()); + } + + @Test + void shouldThrowForDivideLongByNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(-5)); + assertEquals("divide unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("powUInt64Provider") + void powUInt64(Value v1, UInt64 v2, Value expected) { + assertValueEquals(expected, v1.pow(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream powUInt64Provider() { + return Stream + .of( + Arguments.of(v(0), UInt64.valueOf(2), v(0)), + Arguments.of(v(2), UInt64.valueOf(2), v(4)), + Arguments.of(v(2), UInt64.valueOf(8), v(256)), + Arguments.of(v(3), UInt64.valueOf(3), v(27)), + Arguments.of(hv("0xFFFFFFFFFFF0F0F0"), UInt64.valueOf(3), hv("0xF2A920E119A2F000"))); + } + + @ParameterizedTest + @MethodSource("powLongProvider") + void powLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.pow(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream powLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(2), 8L, v(256)), + Arguments.of(v(3), 3L, v(27))); + } + + @ParameterizedTest + @MethodSource("modUInt64Provider") + void modUInt64(Value v1, UInt64 v2, Value expected) { + assertValueEquals(expected, v1.mod(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream modUInt64Provider() { + return Stream + .of( + Arguments.of(v(0), UInt64.valueOf(2), v(0)), + Arguments.of(v(1), UInt64.valueOf(2), v(1)), + Arguments.of(v(2), UInt64.valueOf(2), v(0)), + Arguments.of(v(3), UInt64.valueOf(2), v(1)), + Arguments.of(v(0), UInt64.valueOf(8), v(0)), + Arguments.of(v(1), UInt64.valueOf(8), v(1)), + Arguments.of(v(2), UInt64.valueOf(8), v(2)), + Arguments.of(v(3), UInt64.valueOf(8), v(3)), + Arguments.of(v(7), UInt64.valueOf(8), v(7)), + Arguments.of(v(8), UInt64.valueOf(8), v(0)), + Arguments.of(v(9), UInt64.valueOf(8), v(1)), + Arguments.of(v(1024), UInt64.valueOf(8), v(0)), + Arguments.of(v(1026), UInt64.valueOf(8), v(2))); + } + + @Test + void shouldThrowForModUInt64ByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(UInt64.ZERO)); + assertEquals("mod by zero", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("modLongProvider") + void modLong(Value v1, long v2, Value expected) { + assertValueEquals(expected, v1.mod(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream modLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(1)), + Arguments.of(v(2), 2L, v(0)), + Arguments.of(v(3), 2L, v(1)), + Arguments.of(v(0), 8L, v(0)), + Arguments.of(v(1), 8L, v(1)), + Arguments.of(v(2), 8L, v(2)), + Arguments.of(v(3), 8L, v(3)), + Arguments.of(v(7), 8L, v(7)), + Arguments.of(v(8), 8L, v(0)), + Arguments.of(v(9), 8L, v(1)), + Arguments.of(v(1024), 8L, v(0)), + Arguments.of(v(1026), 8L, v(2))); + } + + @Test + void shouldThrowForModLongByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(0)); + assertEquals("mod by zero", exception.getMessage()); + } + + @Test + void shouldThrowForModLongByNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(-5)); + assertEquals("mod by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("compareToProvider") + void compareTo(Value v1, Value v2, int expected) { + assertEquals(expected, v1.compareTo(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream compareToProvider() { + return Stream + .of( + Arguments.of(v(5), v(5), 0), + Arguments.of(v(5), v(3), 1), + Arguments.of(v(5), v(6), -1), + Arguments.of(hv("0x0000000000000000"), hv("0x0000000000000000"), 0), + Arguments.of(hv("0xFFFFFFFFFFFFFFFF"), hv("0xFFFFFFFFFFFFFFFF"), 0), + Arguments.of(hv("0x00000000FFFFFFFF"), hv("0x00000000FFFFFFFF"), 0), + Arguments.of(hv("0xFFFFFFFFFFFFFFFF"), hv("0x0000000000000000"), 1), + Arguments.of(hv("0x0000000000000000"), hv("0xFFFFFFFFFFFFFFFF"), -1), + Arguments.of(hv("0x00000001FFFFFFFF"), hv("0x00000000FFFFFFFF"), 1), + Arguments.of(hv("0x00000000FFFFFFFE"), hv("0x00000000FFFFFFFF"), -1)); + } + + @ParameterizedTest + @MethodSource("toBytesProvider") + void toBytesTest(Value value, Bytes expected) { + assertEquals(expected, value.toBytes()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream toBytesProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), Bytes.fromHexString("0x0000000000000000")), + Arguments.of(hv("0x01000000"), Bytes.fromHexString("0x0000000001000000")), + Arguments.of(hv("0x0100000000"), Bytes.fromHexString("0x0000000100000000")), + Arguments.of(hv("0xf100000000ab"), Bytes.fromHexString("0x0000f100000000ab"))); + } + + @ParameterizedTest + @MethodSource("toMinimalBytesProvider") + void toMinimalBytesTest(Value value, Bytes expected) { + assertEquals(expected, value.toMinimalBytes()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream toMinimalBytesProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), Bytes.EMPTY), + Arguments.of(hv("0x01000000"), Bytes.fromHexString("0x01000000")), + Arguments.of(hv("0x0100000000"), Bytes.fromHexString("0x0100000000")), + Arguments.of(hv("0xf100000000ab"), Bytes.fromHexString("0xf100000000ab"))); + } + + @ParameterizedTest + @MethodSource("numberOfLeadingZerosProvider") + void numberOfLeadingZeros(Value value, int expected) { + assertEquals(expected, value.numberOfLeadingZeros()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream numberOfLeadingZerosProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), 64), + Arguments.of(hv("0x01"), 63), + Arguments.of(hv("0x02"), 62), + Arguments.of(hv("0x03"), 62), + Arguments.of(hv("0x0F"), 60), + Arguments.of(hv("0x8F"), 56), + Arguments.of(hv("0x100000000"), 31)); + } + + @ParameterizedTest + @MethodSource("bitLengthProvider") + void bitLength(Value value, int expected) { + assertEquals(expected, value.bitLength()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream bitLengthProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), 0), + Arguments.of(hv("0x01"), 1), + Arguments.of(hv("0x02"), 2), + Arguments.of(hv("0x03"), 2), + Arguments.of(hv("0x0F"), 4), + Arguments.of(hv("0x8F"), 8), + Arguments.of(hv("0x100000000"), 33)); + } + + @ParameterizedTest + @MethodSource("addExactProvider") + void addExact(Value value, Value operand) { + assertThrows(ArithmeticException.class, () -> value.addExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addExactProvider() { + return Stream.of(Arguments.of(Value.MAX_VALUE, v(1)), Arguments.of(Value.MAX_VALUE, Value.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addExactLongProvider") + void addExactLong(Value value, long operand) { + assertThrows(ArithmeticException.class, () -> value.addExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addExactLongProvider() { + return Stream + .of(Arguments.of(Value.MAX_VALUE, 3), Arguments.of(Value.MAX_VALUE, Long.MAX_VALUE), Arguments.of(v(0), -1)); + } + + @ParameterizedTest + @MethodSource("subtractExactProvider") + void subtractExact(Value value, Value operand) { + assertThrows(ArithmeticException.class, () -> value.subtractExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractExactProvider() { + return Stream.of(Arguments.of(v(0), v(1)), Arguments.of(v(0), Value.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("subtractExactLongProvider") + void subtractExactLong(Value value, long operand) { + assertThrows(ArithmeticException.class, () -> value.subtractExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractExactLongProvider() { + return Stream.of(Arguments.of(v(0), 1), Arguments.of(v(0), Long.MAX_VALUE), Arguments.of(Value.MAX_VALUE, -1)); + } + + private void assertValueEquals(Value expected, Value actual) { + String msg = String.format("Expected %s but got %s", expected.toHexString(), actual.toHexString()); + assertEquals(expected, actual, msg); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/UInt256Test.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/UInt256Test.java new file mode 100644 index 00000000000..a899161e7e5 --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/UInt256Test.java @@ -0,0 +1,1175 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.math.BigInteger; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class UInt256Test { + + private static UInt256 v(long v) { + return UInt256.valueOf(v); + } + + private static UInt256 biv(String s) { + return UInt256.valueOf(new BigInteger(s)); + } + + private static UInt256 hv(String s) { + return UInt256.fromHexString(s); + } + + @Test + void valueOfLong() { + assertThrows(IllegalArgumentException.class, () -> UInt256.valueOf(-1)); + assertThrows(IllegalArgumentException.class, () -> UInt256.valueOf(Long.MIN_VALUE)); + assertThrows(IllegalArgumentException.class, () -> UInt256.valueOf(~0L)); + } + + @Test + void valueOfBigInteger() { + assertThrows(IllegalArgumentException.class, () -> UInt256.valueOf(BigInteger.valueOf(-1))); + assertThrows(IllegalArgumentException.class, () -> UInt256.valueOf(BigInteger.valueOf(2).pow(256))); + } + + @ParameterizedTest + @MethodSource("addProvider") + void add(UInt256 v1, UInt256 v2, UInt256 expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addProvider() { + return Stream + .of( + Arguments.of(v(1), v(0), v(1)), + Arguments.of(v(5), v(0), v(5)), + Arguments.of(v(0), v(1), v(1)), + Arguments.of(v(0), v(100), v(100)), + Arguments.of(v(2), v(2), v(4)), + Arguments.of(v(100), v(90), v(190)), + Arguments.of(biv("9223372036854775807"), v(1), biv("9223372036854775808")), + Arguments.of(biv("13492324908428420834234908342"), v(10), biv("13492324908428420834234908352")), + Arguments + .of(biv("13492324908428420834234908342"), v(23422141424214L), biv("13492324908428444256376332556")), + Arguments.of(UInt256.MAX_VALUE, v(1), v(0)), + Arguments.of(UInt256.MAX_VALUE, v(2), v(1)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0"), + v(1), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1")), + Arguments + .of(hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), v(1), UInt256.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addLongProvider") + void addLong(UInt256 v1, long v2, UInt256 expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addLongProvider() { + return Stream + .of( + Arguments.of(v(1), 0L, v(1)), + Arguments.of(v(5), 0L, v(5)), + Arguments.of(v(0), 1L, v(1)), + Arguments.of(v(0), 100L, v(100)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(100), 90L, v(190)), + Arguments.of(biv("13492324908428420834234908342"), 10L, biv("13492324908428420834234908352")), + Arguments.of(biv("13492324908428420834234908342"), 23422141424214L, biv("13492324908428444256376332556")), + Arguments.of(UInt256.MAX_VALUE, 1L, v(0)), + Arguments.of(UInt256.MAX_VALUE, 2L, v(1)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0"), + 1L, + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1")), + Arguments + .of(hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), 1L, UInt256.MAX_VALUE), + Arguments.of(v(10), -5L, v(5)), + Arguments.of(v(0), -1L, UInt256.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addModProvider") + void addMod(UInt256 v1, UInt256 v2, UInt256 m, UInt256 expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModProvider() { + return Stream + .of( + Arguments.of(v(0), v(1), UInt256.valueOf(2), v(1)), + Arguments.of(v(1), v(1), UInt256.valueOf(2), v(0)), + Arguments.of(UInt256.MAX_VALUE.subtract(2), v(1), UInt256.MAX_VALUE, UInt256.MAX_VALUE.subtract(1)), + Arguments.of(UInt256.MAX_VALUE.subtract(1), v(1), UInt256.MAX_VALUE, v(0)), + Arguments.of(v(2), v(1), UInt256.valueOf(2), v(1)), + Arguments.of(v(3), v(2), UInt256.valueOf(6), v(5)), + Arguments.of(v(3), v(4), UInt256.valueOf(2), v(1))); + } + + @Test + void shouldThrowForAddModOfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(v(1), UInt256.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModUInt256UInt256Provider") + void addModUInt256UInt256(UInt256 v1, UInt256 v2, UInt256 m, UInt256 expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModUInt256UInt256Provider() { + return Stream + .of( + Arguments.of(v(0), UInt256.ONE, UInt256.valueOf(2), v(1)), + Arguments.of(v(1), UInt256.ONE, UInt256.valueOf(2), v(0)), + Arguments.of(UInt256.MAX_VALUE.subtract(2), UInt256.ONE, UInt256.MAX_VALUE, UInt256.MAX_VALUE.subtract(1)), + Arguments.of(UInt256.MAX_VALUE.subtract(1), UInt256.ONE, UInt256.MAX_VALUE, v(0)), + Arguments.of(v(2), UInt256.ONE, UInt256.valueOf(2), v(1)), + Arguments.of(v(3), UInt256.valueOf(2), UInt256.valueOf(6), v(5)), + Arguments.of(v(3), UInt256.valueOf(4), UInt256.valueOf(2), v(1))); + } + + @Test + void shouldThrowForAddModLongUInt256OfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, UInt256.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModLongUInt256Provider") + void addModLongUInt256(UInt256 v1, long v2, UInt256 m, UInt256 expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModLongUInt256Provider() { + return Stream + .of( + Arguments.of(v(0), 1L, UInt256.valueOf(2), v(1)), + Arguments.of(v(1), 1L, UInt256.valueOf(2), v(0)), + Arguments.of(UInt256.MAX_VALUE.subtract(2), 1L, UInt256.MAX_VALUE, UInt256.MAX_VALUE.subtract(1)), + Arguments.of(UInt256.MAX_VALUE.subtract(1), 1L, UInt256.MAX_VALUE, v(0)), + Arguments.of(v(2), 1L, UInt256.valueOf(2), v(1)), + Arguments.of(v(2), -1L, UInt256.valueOf(2), v(1)), + Arguments.of(v(1), -7L, UInt256.valueOf(5), v(4))); + } + + @Test + void shouldThrowForAddModUInt256UInt256OfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(UInt256.ONE, UInt256.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModLongLongProvider") + void addModLongLong(UInt256 v1, long v2, long m, UInt256 expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModLongLongProvider() { + return Stream + .of(Arguments.of(v(0), 1L, 2L, v(1)), Arguments.of(v(1), 1L, 2L, v(0)), Arguments.of(v(2), 1L, 2L, v(1))); + } + + @Test + void shouldThrowForAddModLongLongOfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, 0)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForAddModLongLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, -5)); + assertEquals("addMod unsigned with negative modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("subtractProvider") + void subtract(UInt256 v1, UInt256 v2, UInt256 expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractProvider() { + return Stream + .of( + Arguments.of(v(1), v(0), v(1)), + Arguments.of(v(5), v(0), v(5)), + Arguments.of(v(2), v(1), v(1)), + Arguments.of(v(100), v(100), v(0)), + Arguments.of(biv("13492324908428420834234908342"), v(10), biv("13492324908428420834234908332")), + Arguments + .of(biv("13492324908428420834234908342"), v(23422141424214L), biv("13492324908428397412093484128")), + Arguments.of(v(0), v(1), UInt256.MAX_VALUE), + Arguments.of(v(1), v(2), UInt256.MAX_VALUE), + Arguments + .of(UInt256.MAX_VALUE, v(1), hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"))); + } + + @ParameterizedTest + @MethodSource("subtractLongProvider") + void subtractLong(UInt256 v1, long v2, UInt256 expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractLongProvider() { + return Stream + .of( + Arguments.of(v(1), 0L, v(1)), + Arguments.of(v(5), 0L, v(5)), + Arguments.of(v(2), 1L, v(1)), + Arguments.of(v(100), 100L, v(0)), + Arguments.of(biv("13492324908428420834234908342"), 10L, biv("13492324908428420834234908332")), + Arguments.of(biv("13492324908428420834234908342"), 23422141424214L, biv("13492324908428397412093484128")), + Arguments.of(v(0), 1L, UInt256.MAX_VALUE), + Arguments.of(v(1), 2L, UInt256.MAX_VALUE), + Arguments + .of(UInt256.MAX_VALUE, 1L, hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE")), + Arguments.of(v(0), -1L, v(1)), + Arguments.of(v(0), -100L, v(100)), + Arguments.of(v(2), -2L, v(4))); + } + + @ParameterizedTest + @MethodSource("multiplyProvider") + void multiply(UInt256 v1, UInt256 v2, UInt256 expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyProvider() { + return Stream + .of( + Arguments.of(v(0), v(1), v(0)), + Arguments.of(v(1), v(0), v(0)), + Arguments.of(v(1), v(20), v(20)), + Arguments.of(hv("0x0a0000000000"), v(1), hv("0x0a0000000000")), + Arguments.of(v(1), hv("0x0a0000000000"), hv("0x0a0000000000")), + Arguments.of(v(0), v(2), v(0)), + Arguments.of(v(1), v(2), v(2)), + Arguments.of(v(2), v(2), v(4)), + Arguments.of(v(3), v(2), v(6)), + Arguments.of(v(4), v(2), v(8)), + Arguments.of(v(10), v(18), v(180)), + Arguments.of(biv("13492324908428420834234908341"), v(2), biv("26984649816856841668469816682")), + Arguments.of(biv("13492324908428420834234908342"), v(2), biv("26984649816856841668469816684")), + Arguments.of(v(2), v(8), v(16)), + Arguments.of(v(7), v(8), v(56)), + Arguments.of(v(8), v(8), v(64)), + Arguments.of(v(17), v(8), v(136)), + Arguments.of(biv("13492324908428420834234908342"), v(8), biv("107938599267427366673879266736")), + Arguments.of(biv("13492324908428420834234908342"), v(2048), biv("27632281412461405868513092284416")), + Arguments.of(biv("13492324908428420834234908342"), v(131072), biv("1768466010397529975584837906202624")), + Arguments.of(v(22), v(0), v(0))); + } + + @ParameterizedTest + @MethodSource("multiplyLongProvider") + void multiplyLong(UInt256 v1, long v2, UInt256 expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyLongProvider() { + return Stream + .of( + Arguments.of(v(0), 1L, v(0)), + Arguments.of(v(1), 0L, v(0)), + Arguments.of(v(1), 20L, v(20)), + Arguments.of(v(20), 1L, v(20)), + Arguments.of(hv("0x0a0000000000"), 1L, hv("0x0a0000000000")), + Arguments.of(v(1), 10995116277760L, hv("0x0a0000000000")), + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(2)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(3), 2L, v(6)), + Arguments.of(v(4), 2L, v(8)), + Arguments.of(v(10), 18L, v(180)), + Arguments.of(biv("13492324908428420834234908341"), 2L, biv("26984649816856841668469816682")), + Arguments.of(biv("13492324908428420834234908342"), 2L, biv("26984649816856841668469816684")), + Arguments.of(v(2), 8L, v(16)), + Arguments.of(v(7), 8L, v(56)), + Arguments.of(v(8), 8L, v(64)), + Arguments.of(v(17), 8L, v(136)), + Arguments.of(biv("13492324908428420834234908342"), 8L, biv("107938599267427366673879266736")), + Arguments.of(biv("13492324908428420834234908342"), 2048L, biv("27632281412461405868513092284416")), + Arguments.of(biv("13492324908428420834234908342"), 131072L, biv("1768466010397529975584837906202624")), + Arguments.of(v(22), 0L, v(0)), + Arguments + .of( + hv("0x0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 2L, + hv("0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE")), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 2L, + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"))); + } + + @Test + void shouldThrowForMultiplyLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(2).multiply(-5)); + assertEquals("multiply unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModProvider") + void multiplyMod(UInt256 v1, UInt256 v2, UInt256 m, UInt256 expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModProvider() { + return Stream + .of( + Arguments.of(v(0), v(5), UInt256.valueOf(2), v(0)), + Arguments.of(v(2), v(3), UInt256.valueOf(7), v(6)), + Arguments.of(v(2), v(3), UInt256.valueOf(6), v(0)), + Arguments.of(v(2), v(0), UInt256.valueOf(6), v(0)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + v(2), + UInt256.MAX_VALUE, + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD"))); + } + + @Test + void shouldThrowForMultiplyModOfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).multiplyMod(v(1), UInt256.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModLongUInt256Provider") + void multiplyModLongUInt256(UInt256 v1, long v2, UInt256 m, UInt256 expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModLongUInt256Provider() { + return Stream + .of( + Arguments.of(v(0), 5L, UInt256.valueOf(2), v(0)), + Arguments.of(v(2), 3L, UInt256.valueOf(7), v(6)), + Arguments.of(v(2), 3L, UInt256.valueOf(6), v(0)), + Arguments.of(v(2), 0L, UInt256.valueOf(6), v(0)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + 2L, + UInt256.MAX_VALUE, + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD"))); + } + + @Test + void shouldThrowForMultiplyModLongUInt256OfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).multiplyMod(1L, UInt256.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongUInt256OfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(3).multiplyMod(-1, UInt256.valueOf(2))); + assertEquals("multiplyMod unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModLongLongProvider") + void multiplyModLongLong(UInt256 v1, long v2, long m, UInt256 expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModLongLongProvider() { + return Stream + .of( + Arguments.of(v(0), 5L, 2L, v(0)), + Arguments.of(v(2), 3L, 7L, v(6)), + Arguments.of(v(2), 3L, 6L, v(0)), + Arguments.of(v(2), 0L, 6L, v(0)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + 2L, + Long.MAX_VALUE, + hv("0x000000000000000000000000000000000000000000000000000000000000001C"))); + } + + @Test + void shouldThrowForMultiplyModLongLongOfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).multiplyMod(1, 0)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongLongOfModNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(2).multiplyMod(5, -7)); + assertEquals("multiplyMod unsigned with negative modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(3).multiplyMod(-1, 2)); + assertEquals("multiplyMod unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideProvider") + void divide(UInt256 v1, UInt256 v2, UInt256 expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideProvider() { + return Stream + .of( + Arguments.of(v(0), v(2), v(0)), + Arguments.of(v(1), v(2), v(0)), + Arguments.of(v(2), v(2), v(1)), + Arguments.of(v(3), v(2), v(1)), + Arguments.of(v(4), v(2), v(2)), + Arguments.of(biv("13492324908428420834234908341"), v(2), biv("6746162454214210417117454170")), + Arguments.of(biv("13492324908428420834234908342"), v(2), biv("6746162454214210417117454171")), + Arguments.of(biv("13492324908428420834234908343"), v(2), biv("6746162454214210417117454171")), + Arguments.of(v(2), v(8), v(0)), + Arguments.of(v(7), v(8), v(0)), + Arguments.of(v(8), v(8), v(1)), + Arguments.of(v(9), v(8), v(1)), + Arguments.of(v(17), v(8), v(2)), + Arguments.of(v(1024), v(8), v(128)), + Arguments.of(v(1026), v(8), v(128)), + Arguments.of(biv("13492324908428420834234908342"), v(8), biv("1686540613553552604279363542")), + Arguments.of(biv("13492324908428420834234908342"), v(2048), biv("6588049271693564860466263")), + Arguments.of(biv("13492324908428420834234908342"), v(131072), biv("102938269870211950944785"))); + } + + @Test + void shouldThrowForDivideByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(v(0))); + assertEquals("divide by zero", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideCeilProvider") + void divideCeil(UInt256 v1, UInt256 v2, UInt256 expected) { + assertValueEquals(expected, v1.divideCeil(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideCeilProvider() { + return Stream + .of( + Arguments.of(v(0), v(2), v(0)), + Arguments.of(v(1), v(2), v(1)), + Arguments.of(v(2), v(2), v(1)), + Arguments.of(v(3), v(2), v(2)), + Arguments.of(v(4), v(2), v(2)), + Arguments.of(biv("13492324908428420834234908341"), v(2), biv("6746162454214210417117454171")), + Arguments.of(biv("13492324908428420834234908342"), v(2), biv("6746162454214210417117454171")), + Arguments.of(biv("13492324908428420834234908343"), v(2), biv("6746162454214210417117454172")), + Arguments.of(v(2), v(8), v(1)), + Arguments.of(v(7), v(8), v(1)), + Arguments.of(v(8), v(8), v(1)), + Arguments.of(v(9), v(8), v(2)), + Arguments.of(v(17), v(8), v(3)), + Arguments.of(v(1024), v(8), v(128)), + Arguments.of(v(1026), v(8), v(129)), + Arguments.of(biv("13492324908428420834234908342"), v(8), biv("1686540613553552604279363543")), + Arguments.of(biv("13492324908428420834234908342"), v(2048), biv("6588049271693564860466264")), + Arguments.of(biv("13492324908428420834234908342"), v(131072), biv("102938269870211950944786"))); + } + + @Test + void shouldThrowForDivideCeilByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divideCeil(v(0))); + assertEquals("divide by zero", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideLongProvider") + void divideLong(UInt256 v1, long v2, UInt256 expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(0)), + Arguments.of(v(2), 2L, v(1)), + Arguments.of(v(3), 2L, v(1)), + Arguments.of(v(4), 2L, v(2)), + Arguments.of(biv("13492324908428420834234908341"), 2L, biv("6746162454214210417117454170")), + Arguments.of(biv("13492324908428420834234908342"), 2L, biv("6746162454214210417117454171")), + Arguments.of(biv("13492324908428420834234908343"), 2L, biv("6746162454214210417117454171")), + Arguments.of(v(2), 8L, v(0)), + Arguments.of(v(7), 8L, v(0)), + Arguments.of(v(8), 8L, v(1)), + Arguments.of(v(9), 8L, v(1)), + Arguments.of(v(17), 8L, v(2)), + Arguments.of(v(1024), 8L, v(128)), + Arguments.of(v(1026), 8L, v(128)), + Arguments.of(biv("13492324908428420834234908342"), 8L, biv("1686540613553552604279363542")), + Arguments.of(biv("13492324908428420834234908342"), 2048L, biv("6588049271693564860466263")), + Arguments.of(biv("13492324908428420834234908342"), 131072L, biv("102938269870211950944785"))); + } + + @Test + void shouldThrowForDivideLongByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(0)); + assertEquals("divide by zero", exception.getMessage()); + } + + @Test + void shouldThrowForDivideLongByNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(-5)); + assertEquals("divide unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("powUInt256Provider") + void powUInt256(UInt256 v1, UInt256 v2, UInt256 expected) { + assertValueEquals(expected, v1.pow(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream powUInt256Provider() { + return Stream + .of( + Arguments.of(v(0), UInt256.valueOf(2), v(0)), + Arguments.of(v(2), UInt256.valueOf(2), v(4)), + Arguments.of(v(2), UInt256.valueOf(8), v(256)), + Arguments.of(v(3), UInt256.valueOf(3), v(27)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0"), + UInt256.valueOf(3), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A920E119A2F000"))); + } + + @ParameterizedTest + @MethodSource("powLongProvider") + void powLong(UInt256 v1, long v2, UInt256 expected) { + assertValueEquals(expected, v1.pow(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream powLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(2), 8L, v(256)), + Arguments.of(v(3), 3L, v(27)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0"), + 3L, + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A920E119A2F000")), + Arguments.of(v(3), -3L, hv("0x2F684BDA12F684BDA12F684BDA12F684BDA12F684BDA12F684BDA12F684BDA13"))); + } + + @ParameterizedTest + @MethodSource("modLongProvider") + void modLong(UInt256 v1, long v2, UInt256 expected) { + assertValueEquals(expected, v1.mod(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream modLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(1)), + Arguments.of(v(2), 2L, v(0)), + Arguments.of(v(3), 2L, v(1)), + Arguments.of(biv("13492324908428420834234908342"), 2L, v(0)), + Arguments.of(biv("13492324908428420834234908343"), 2L, v(1)), + Arguments.of(v(0), 8L, v(0)), + Arguments.of(v(1), 8L, v(1)), + Arguments.of(v(2), 8L, v(2)), + Arguments.of(v(3), 8L, v(3)), + Arguments.of(v(7), 8L, v(7)), + Arguments.of(v(8), 8L, v(0)), + Arguments.of(v(9), 8L, v(1)), + Arguments.of(v(1024), 8L, v(0)), + Arguments.of(v(1026), 8L, v(2)), + Arguments.of(biv("13492324908428420834234908342"), 8L, v(6)), + Arguments.of(biv("13492324908428420834234908343"), 8L, v(7)), + Arguments.of(biv("13492324908428420834234908344"), 8L, v(0))); + } + + @Test + void shouldThrowForModLongByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(0)); + assertEquals("mod by zero", exception.getMessage()); + } + + @Test + void shouldThrowForModLongByNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(-5)); + assertEquals("mod by negative", exception.getMessage()); + } + + @Test + void shouldReturnZeroForMod0LongByZero() { + assertEquals(UInt256.ZERO, v(5).mod0(0)); + } + + @Test + void shouldThrowForMod0LongByNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod0(-5)); + assertEquals("mod by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("andProvider") + void and(UInt256 v1, UInt256 v2, UInt256 expected) { + assertValueEquals(expected, v1.and(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream andProvider() { + return Stream + .of( + Arguments + .of( + hv("0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000"), + hv("0x0000000000000000000000000000000000000000000000000000000000000000")), + Arguments + .of( + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000"), + hv("0x000000000000000000000000000000FF00000000000000000000000000000000"))); + } + + @ParameterizedTest + @MethodSource("orProvider") + void or(UInt256 v1, UInt256 v2, UInt256 expected) { + assertValueEquals(expected, v1.or(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream orProvider() { + return Stream + .of( + Arguments + .of( + hv("0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")), + Arguments + .of( + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")), + Arguments + .of( + hv("0x0000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))); + } + + @ParameterizedTest + @MethodSource("xorProvider") + void xor(UInt256 v1, UInt256 v2, UInt256 expected) { + assertValueEquals(expected, v1.xor(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream xorProvider() { + return Stream + .of( + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0x0000000000000000000000000000000000000000000000000000000000000000")), + Arguments + .of( + hv("0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")), + Arguments + .of( + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))); + } + + @ParameterizedTest + @MethodSource("notProvider") + void not(UInt256 value, UInt256 expected) { + assertValueEquals(expected, value.not()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream notProvider() { + return Stream + .of( + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0x0000000000000000000000000000000000000000000000000000000000000000")), + Arguments + .of( + hv("0x0000000000000000000000000000000000000000000000000000000000000000"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")), + Arguments + .of( + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000"))); + } + + @ParameterizedTest + @MethodSource("shiftLeftProvider") + void shiftLeft(UInt256 value, int distance, UInt256 expected) { + assertValueEquals(expected, value.shiftLeft(distance)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream shiftLeftProvider() { + return Stream + .of( + Arguments.of(hv("0x01"), 1, hv("0x02")), + Arguments.of(hv("0x01"), 2, hv("0x04")), + Arguments.of(hv("0x01"), 8, hv("0x0100")), + Arguments.of(hv("0x01"), 9, hv("0x0200")), + Arguments.of(hv("0x01"), 16, hv("0x10000")), + Arguments.of(hv("0x00FF00"), 4, hv("0x0FF000")), + Arguments.of(hv("0x00FF00"), 8, hv("0xFF0000")), + Arguments.of(hv("0x00FF00"), 1, hv("0x01FE00")), + Arguments + .of( + hv("0x0000000000000000000000000000000000000000000000000000000000000001"), + 16, + hv("0x0000000000000000000000000000000000000000000000000000000000010000")), + Arguments + .of( + hv("0x0000000000000000000000000000000000000000000000000000000000000001"), + 15, + hv("0x0000000000000000000000000000000000000000000000000000000000008000")), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 55, + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80000000000000")), + Arguments + .of( + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 202, + hv("0xFFFFFFFFFFFFFC00000000000000000000000000000000000000000000000000"))); + } + + @ParameterizedTest + @MethodSource("shiftRightProvider") + void shiftRight(UInt256 value, int distance, UInt256 expected) { + assertValueEquals(expected, value.shiftRight(distance)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream shiftRightProvider() { + return Stream + .of( + Arguments.of(hv("0x01"), 1, hv("0x00")), + Arguments.of(hv("0x10"), 1, hv("0x08")), + Arguments.of(hv("0x10"), 2, hv("0x04")), + Arguments.of(hv("0x10"), 8, hv("0x00")), + Arguments.of(hv("0x1000"), 4, hv("0x0100")), + Arguments.of(hv("0x1000"), 5, hv("0x0080")), + Arguments.of(hv("0x1000"), 8, hv("0x0010")), + Arguments.of(hv("0x1000"), 9, hv("0x0008")), + Arguments.of(hv("0x1000"), 16, hv("0x0000")), + Arguments.of(hv("0x00FF00"), 4, hv("0x000FF0")), + Arguments.of(hv("0x00FF00"), 8, hv("0x0000FF")), + Arguments.of(hv("0x00FF00"), 1, hv("0x007F80")), + Arguments + .of( + hv("0x1000000000000000000000000000000000000000000000000000000000000000"), + 16, + hv("0x0000100000000000000000000000000000000000000000000000000000000000")), + Arguments + .of( + hv("0x1000000000000000000000000000000000000000000000000000000000000000"), + 15, + hv("0x0000200000000000000000000000000000000000000000000000000000000000")), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 55, + hv("0x00000000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000"), + 202, + hv("0x000000000000000000000000000000000000000000000000003FFFFFFFFFFFFF"))); + } + + @ParameterizedTest + @MethodSource("intValueProvider") + void intValue(UInt256 value, int expected) { + assertEquals(expected, value.intValue()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream intValueProvider() { + return Stream + .of( + Arguments.of(hv("0x"), 0), + Arguments.of(hv("0x00"), 0), + Arguments.of(hv("0x00000000"), 0), + Arguments.of(hv("0x01"), 1), + Arguments.of(hv("0x0001"), 1), + Arguments.of(hv("0x000001"), 1), + Arguments.of(hv("0x00000001"), 1), + Arguments.of(hv("0x0100"), 256), + Arguments.of(hv("0x000100"), 256), + Arguments.of(hv("0x00000100"), 256)); + } + + @Test + void shouldThrowForIntValueOfOversizeValue() { + Throwable exception = assertThrows(ArithmeticException.class, () -> hv("0x0100000000").intValue()); + assertEquals("Value does not fit a 4 byte int", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("longValueProvider") + void longValue(UInt256 value, long expected) { + assertEquals(expected, value.toLong()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream longValueProvider() { + return Stream + .of( + Arguments.of(hv("0x"), 0L), + Arguments.of(hv("0x00"), 0L), + Arguments.of(hv("0x00000000"), 0L), + Arguments.of(hv("0x01"), 1L), + Arguments.of(hv("0x0001"), 1L), + Arguments.of(hv("0x000001"), 1L), + Arguments.of(hv("0x00000001"), 1L), + Arguments.of(hv("0x0000000001"), 1L), + Arguments.of(hv("0x000000000001"), 1L), + Arguments.of(hv("0x0100"), 256L), + Arguments.of(hv("0x000100"), 256L), + Arguments.of(hv("0x00000100"), 256L), + Arguments.of(hv("0x00000100"), 256L), + Arguments.of(hv("0x000000000100"), 256L), + Arguments.of(hv("0x00000000000100"), 256L), + Arguments.of(hv("0x0000000000000100"), 256L), + Arguments.of(hv("0xFFFFFFFF"), (1L << 32) - 1)); + } + + @Test + void shouldThrowForLongValueOfOversizeValue() { + Throwable exception = assertThrows(ArithmeticException.class, () -> hv("0x010000000000000000").toLong()); + assertEquals("Value does not fit a 8 byte long", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("compareToProvider") + void compareTo(UInt256 v1, UInt256 v2, int expected) { + assertEquals(expected, v1.compareTo(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream compareToProvider() { + return Stream + .of( + Arguments.of(v(5), v(5), 0), + Arguments.of(v(5), v(3), 1), + Arguments.of(v(5), v(6), -1), + Arguments + .of( + hv("0x0000000000000000000000000000000000000000000000000000000000000000"), + hv("0x0000000000000000000000000000000000000000000000000000000000000000"), + 0), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 0), + Arguments + .of( + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 0), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0x0000000000000000000000000000000000000000000000000000000000000000"), + 1), + Arguments + .of( + hv("0x0000000000000000000000000000000000000000000000000000000000000000"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + -1), + Arguments + .of( + hv("0x000000000000000000000000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 1), + Arguments + .of( + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + -1)); + } + + @ParameterizedTest + @MethodSource("toBytesProvider") + void toBytesTest(UInt256 value, Bytes expected) { + assertEquals(expected, value.toBytes()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream toBytesProvider() { + return Stream + .of( + Arguments + .of( + hv("0x00"), + Bytes.fromHexString("0x0000000000000000000000000000000000000000000000000000000000000000")), + Arguments + .of( + hv("0x01000000"), + Bytes.fromHexString("0x0000000000000000000000000000000000000000000000000000000001000000")), + Arguments + .of( + hv("0x0100000000"), + Bytes.fromHexString("0x0000000000000000000000000000000000000000000000000000000100000000")), + Arguments + .of( + hv("0xf100000000ab"), + Bytes.fromHexString("0x0000000000000000000000000000000000000000000000000000f100000000ab")), + Arguments + .of( + hv("0x0400000000000000000000000000000000000000000000000000f100000000ab"), + Bytes.fromHexString("0x0400000000000000000000000000000000000000000000000000f100000000ab"))); + } + + @ParameterizedTest + @MethodSource("fromBytesProvider") + void fromBytesTest(Bytes value, UInt256 expected, boolean isBytes32) { + assertEquals(expected.toBytes(), UInt256.fromBytes(value).toBytes()); + assertEquals(expected, UInt256.fromBytes(value)); + assertEquals(isBytes32, value instanceof Bytes32); + } + + @SuppressWarnings("UnusedMethod") + private static Stream fromBytesProvider() { + String onesString = "11111111111111111111111111111111"; + String twosString = "22222222222222222222222222222222"; + String eString = "e000000000e000000000e000000000e0"; + Bytes onesBytes = Bytes.fromHexString(onesString); + Bytes twosBytes = Bytes.fromHexString(twosString); + Bytes eBytes = Bytes.fromHexString(eString); + Bytes onetwoBytes = Bytes.fromHexString(onesString + twosString); + Bytes oneeBytes = Bytes.fromHexString(onesString + eString); + return Stream + .of( + // Mutable Bytes + Arguments.of(Bytes.concatenate(onesBytes), hv(onesString), false), + Arguments.of(Bytes.concatenate(eBytes), hv(eString), false), + Arguments.of(Bytes.concatenate(onesBytes, twosBytes), hv(onesString + twosString), true), + Arguments.of(Bytes.concatenate(onesBytes, eBytes), hv(onesString + eString), true), + // Array Wrapping Bytes + Arguments.of(Bytes.fromHexString(onesString), hv(onesString), false), + Arguments.of(Bytes.fromHexString(eString), hv(eString), false), + Arguments.of(Bytes.fromHexString(onesString + twosString), hv(onesString + twosString), true), + Arguments.of(Bytes.fromHexString(onesString + eString), hv(onesString + eString), true), + // Delegating Bytes32 + Arguments.of(Bytes32.wrap(onetwoBytes), hv(onesString + twosString), true), + Arguments.of(Bytes32.wrap(oneeBytes), hv(onesString + eString), true)); + } + + @ParameterizedTest + @MethodSource("toMinimalBytesProvider") + void toMinimalBytesTest(UInt256 value, Bytes expected) { + assertEquals(expected, value.toMinimalBytes()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream toMinimalBytesProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), Bytes.EMPTY), + Arguments.of(hv("0x01000000"), Bytes.fromHexString("0x01000000")), + Arguments.of(hv("0x0100000000"), Bytes.fromHexString("0x0100000000")), + Arguments.of(hv("0xf100000000ab"), Bytes.fromHexString("0xf100000000ab")), + Arguments + .of( + hv("0x0400000000000000000000000000000000000000000000000000f100000000ab"), + Bytes.fromHexString("0x0400000000000000000000000000000000000000000000000000f100000000ab"))); + } + + @ParameterizedTest + @MethodSource("numberOfLeadingZerosProvider") + void numberOfLeadingZeros(UInt256 value, int expected) { + assertEquals(expected, value.numberOfLeadingZeros()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream numberOfLeadingZerosProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), 256), + Arguments.of(hv("0x01"), 255), + Arguments.of(hv("0x02"), 254), + Arguments.of(hv("0x03"), 254), + Arguments.of(hv("0x0F"), 252), + Arguments.of(hv("0x8F"), 248), + Arguments.of(hv("0x100000000"), 223)); + } + + @ParameterizedTest + @MethodSource("bitLengthProvider") + void bitLength(UInt256 value, int expected) { + assertEquals(expected, value.bitLength()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream bitLengthProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), 0), + Arguments.of(hv("0x01"), 1), + Arguments.of(hv("0x02"), 2), + Arguments.of(hv("0x03"), 2), + Arguments.of(hv("0x0F"), 4), + Arguments.of(hv("0x8F"), 8), + Arguments.of(hv("0x100000000"), 33)); + } + + @ParameterizedTest + @MethodSource("addExactProvider") + void addExact(UInt256 value, UInt256 operand) { + assertThrows(ArithmeticException.class, () -> value.addExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addExactProvider() { + return Stream.of(Arguments.of(UInt256.MAX_VALUE, v(1)), Arguments.of(UInt256.MAX_VALUE, UInt256.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addExactLongProvider") + void addExactLong(UInt256 value, long operand) { + assertThrows(ArithmeticException.class, () -> value.addExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addExactLongProvider() { + return Stream + .of( + Arguments.of(UInt256.MAX_VALUE, 3), + Arguments.of(UInt256.MAX_VALUE, Long.MAX_VALUE), + Arguments.of(v(0), -1)); + } + + @ParameterizedTest + @MethodSource("subtractExactProvider") + void subtractExact(UInt256 value, UInt256 operand) { + assertThrows(ArithmeticException.class, () -> value.subtractExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractExactProvider() { + return Stream.of(Arguments.of(v(0), v(1)), Arguments.of(v(0), UInt256.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("subtractExactLongProvider") + void subtractExactLong(UInt256 value, long operand) { + assertThrows(ArithmeticException.class, () -> value.subtractExact(operand)); + } + + @Test + void testGet() { + UInt256 value = UInt256.ONE; + assertEquals(1, value.get(31)); + UInt256 value5 = UInt256.valueOf(5); + assertEquals(5, value5.get(31)); + UInt256 value255 = UInt256.valueOf(255); + assertEquals((byte) 0xff, value255.get(31)); + UInt256 value256 = UInt256.valueOf(256); + assertEquals(1, value256.get(30)); + + for (int i = 0; i < 32; i++) { + assertEquals(0, UInt256.ZERO.get(i)); + } + } + + @Test + void testHashcode() { + UInt256 value = UInt256.ZERO; + assertEquals(2111290369, value.hashCode()); + UInt256 valueOne = UInt256.ONE; + assertEquals(2111290370, valueOne.hashCode()); + } + + @Test + void testOverflowSubtraction() { + UInt256 value = UInt256.fromHexString("0x8000000000000000000000000000000000000000000000000000000000000000"); + UInt256 result = UInt256.ZERO.subtract(value); + assertEquals(value, result); + } + + @Test + void testEquals() { + UInt256 value = UInt256.ZERO; + assertEquals(Bytes32.leftPad(Bytes.of(0)), value); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractExactLongProvider() { + return Stream.of(Arguments.of(v(0), 1), Arguments.of(v(0), Long.MAX_VALUE), Arguments.of(UInt256.MAX_VALUE, -1)); + } + + private void assertValueEquals(UInt256 expected, UInt256 actual) { + String msg = String.format("Expected %s but got %s", expected.toHexString(), actual.toHexString()); + assertEquals(expected, actual, msg); + } + + @Test + void testToDecimalString() { + assertEquals("3456", UInt256.valueOf(3456).toDecimalString()); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/UInt32Test.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/UInt32Test.java new file mode 100644 index 00000000000..eba2e992164 --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/UInt32Test.java @@ -0,0 +1,867 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.math.BigInteger; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; + +class UInt32Test { + + private static UInt32 v(int v) { + return UInt32.valueOf(v); + } + + private static UInt32 hv(String s) { + return UInt32.fromHexString(s); + } + + private static Bytes b(String s) { + return Bytes.fromHexString(s); + } + + @Test + void valueOfInt() { + assertThrows(IllegalArgumentException.class, () -> UInt32.valueOf(-1)); + assertThrows(IllegalArgumentException.class, () -> UInt32.valueOf(Integer.MIN_VALUE)); + assertThrows(IllegalArgumentException.class, () -> UInt32.valueOf(~0)); + } + + @Test + void valueOfBigInteger() { + assertThrows(IllegalArgumentException.class, () -> UInt32.valueOf(BigInteger.valueOf(-1))); + assertThrows(IllegalArgumentException.class, () -> UInt32.valueOf(BigInteger.valueOf(2).pow(32))); + } + + @ParameterizedTest + @MethodSource("addProvider") + void add(UInt32 v1, UInt32 v2, UInt32 expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addProvider() { + return Stream + .of( + Arguments.of(v(1), v(0), v(1)), + Arguments.of(v(5), v(0), v(5)), + Arguments.of(v(0), v(1), v(1)), + Arguments.of(v(0), v(100), v(100)), + Arguments.of(v(2), v(2), v(4)), + Arguments.of(v(100), v(90), v(190)), + Arguments.of(UInt32.MAX_VALUE, v(1), v(0)), + Arguments.of(UInt32.MAX_VALUE, v(2), v(1)), + Arguments.of(hv("0xFFFFFFF0"), v(1), hv("0xFFFFFFF1")), + Arguments.of(hv("0xFFFFFFFE"), v(1), UInt32.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addLongProvider") + void addLong(UInt32 v1, int v2, UInt32 expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addLongProvider() { + return Stream + .of( + Arguments.of(v(1), 0, v(1)), + Arguments.of(v(5), 0, v(5)), + Arguments.of(v(0), 1, v(1)), + Arguments.of(v(0), 100, v(100)), + Arguments.of(v(2), 2, v(4)), + Arguments.of(v(100), 90, v(190)), + Arguments.of(UInt32.MAX_VALUE, 1, v(0)), + Arguments.of(UInt32.MAX_VALUE, 2, v(1)), + Arguments.of(hv("0xFFFFFFF0"), 1, hv("0xFFFFFFF1")), + Arguments.of(hv("0xFFFFFFFE"), 1, UInt32.MAX_VALUE), + Arguments.of(v(10), -5, v(5)), + Arguments.of(v(0), -1, UInt32.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addModProvider") + void addMod(UInt32 v1, UInt32 v2, UInt32 m, UInt32 expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModProvider() { + return Stream + .of( + Arguments.of(v(0), v(1), UInt32.valueOf(2), v(1)), + Arguments.of(v(1), v(1), UInt32.valueOf(2), v(0)), + Arguments.of(UInt32.MAX_VALUE.subtract(2), v(1), UInt32.MAX_VALUE, UInt32.MAX_VALUE.subtract(1)), + Arguments.of(UInt32.MAX_VALUE.subtract(1), v(1), UInt32.MAX_VALUE, v(0)), + Arguments.of(v(2), v(1), UInt32.valueOf(2), v(1)), + Arguments.of(v(3), v(2), UInt32.valueOf(6), v(5)), + Arguments.of(v(3), v(4), UInt32.valueOf(2), v(1))); + } + + @Test + void shouldThrowForAddModOfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(v(1), UInt32.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModUInt32UInt32Provider") + void addModUInt32UInt32(UInt32 v1, UInt32 v2, UInt32 m, UInt32 expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModUInt32UInt32Provider() { + return Stream + .of( + Arguments.of(v(0), UInt32.ONE, UInt32.valueOf(2), v(1)), + Arguments.of(v(1), UInt32.ONE, UInt32.valueOf(2), v(0)), + Arguments.of(UInt32.MAX_VALUE.subtract(2), UInt32.ONE, UInt32.MAX_VALUE, UInt32.MAX_VALUE.subtract(1)), + Arguments.of(UInt32.MAX_VALUE.subtract(1), UInt32.ONE, UInt32.MAX_VALUE, v(0)), + Arguments.of(v(2), UInt32.ONE, UInt32.valueOf(2), v(1)), + Arguments.of(v(3), UInt32.valueOf(2), UInt32.valueOf(6), v(5)), + Arguments.of(v(3), UInt32.valueOf(4), UInt32.valueOf(2), v(1))); + } + + @Test + void shouldThrowForAddModLongUInt32OfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, UInt32.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModLongUInt32Provider") + void addModLongUInt32(UInt32 v1, long v2, UInt32 m, UInt32 expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModLongUInt32Provider() { + return Stream + .of( + Arguments.of(v(0), 1, UInt32.valueOf(2), v(1)), + Arguments.of(v(1), 1, UInt32.valueOf(2), v(0)), + Arguments.of(UInt32.MAX_VALUE.subtract(2), 1, UInt32.MAX_VALUE, UInt32.MAX_VALUE.subtract(1)), + Arguments.of(UInt32.MAX_VALUE.subtract(1), 1, UInt32.MAX_VALUE, v(0)), + Arguments.of(v(2), 1, UInt32.valueOf(2), v(1)), + Arguments.of(v(2), -1, UInt32.valueOf(2), v(1)), + Arguments.of(v(1), -7, UInt32.valueOf(5), v(4))); + } + + @Test + void shouldThrowForAddModUInt32UInt32OfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(UInt32.ONE, UInt32.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModLongLongProvider") + void addModLongLong(UInt32 v1, long v2, long m, UInt32 expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModLongLongProvider() { + return Stream.of(Arguments.of(v(0), 1, 2, v(1)), Arguments.of(v(1), 1, 2, v(0)), Arguments.of(v(2), 1, 2, v(1))); + } + + @Test + void shouldThrowForAddModLongLongOfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, 0)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForAddModLongLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, -5)); + assertEquals("addMod unsigned with negative modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("subtractProvider") + void subtract(UInt32 v1, UInt32 v2, UInt32 expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractProvider() { + return Stream + .of( + Arguments.of(v(1), v(0), v(1)), + Arguments.of(v(5), v(0), v(5)), + Arguments.of(v(2), v(1), v(1)), + Arguments.of(v(100), v(100), v(0)), + Arguments.of(v(0), v(1), UInt32.MAX_VALUE), + Arguments.of(v(1), v(2), UInt32.MAX_VALUE), + Arguments.of(UInt32.MAX_VALUE, v(1), hv("0xFFFFFFFE"))); + } + + @ParameterizedTest + @MethodSource("subtractLongProvider") + void subtractLong(UInt32 v1, int v2, UInt32 expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractLongProvider() { + return Stream + .of( + Arguments.of(v(1), 0, v(1)), + Arguments.of(v(5), 0, v(5)), + Arguments.of(v(2), 1, v(1)), + Arguments.of(v(100), 100, v(0)), + Arguments.of(v(0), 1, UInt32.MAX_VALUE), + Arguments.of(v(1), 2, UInt32.MAX_VALUE), + Arguments.of(UInt32.MAX_VALUE, 1, hv("0xFFFFFFFE")), + Arguments.of(v(0), -1, v(1)), + Arguments.of(v(0), -100, v(100)), + Arguments.of(v(2), -2, v(4))); + } + + @ParameterizedTest + @MethodSource("multiplyProvider") + void multiply(UInt32 v1, UInt32 v2, UInt32 expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyProvider() { + return Stream + .of( + Arguments.of(v(1), v(1), v(1)), + Arguments.of(v(0), v(2), v(0)), + Arguments.of(v(1), v(2), v(2)), + Arguments.of(v(2), v(2), v(4)), + Arguments.of(v(3), v(2), v(6)), + Arguments.of(v(4), v(2), v(8)), + Arguments.of(v(10), v(18), v(180)), + Arguments.of(v(2), v(8), v(16)), + Arguments.of(v(7), v(8), v(56)), + Arguments.of(v(8), v(8), v(64)), + Arguments.of(v(17), v(8), v(136)), + Arguments.of(v(22), v(0), v(0))); + } + + @ParameterizedTest + @MethodSource("multiplyLongProvider") + void multiplyLong(UInt32 v1, int v2, UInt32 expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyLongProvider() { + return Stream + .of( + Arguments.of(v(1), 1, v(1)), + Arguments.of(v(0), 2, v(0)), + Arguments.of(v(1), 2, v(2)), + Arguments.of(v(2), 2, v(4)), + Arguments.of(v(3), 2, v(6)), + Arguments.of(v(4), 2, v(8)), + Arguments.of(v(10), 18, v(180)), + Arguments.of(v(2), 8, v(16)), + Arguments.of(v(7), 8, v(56)), + Arguments.of(v(8), 8, v(64)), + Arguments.of(v(17), 8, v(136)), + Arguments.of(v(22), 0, v(0)), + Arguments.of(hv("0x0FFFFFFF"), 2, hv("0x1FFFFFFE")), + Arguments.of(hv("0xFFFFFFFF"), 2, hv("0xFFFFFFFE"))); + } + + @Test + void shouldThrowForMultiplyLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(2).multiply(-5)); + assertEquals("multiply unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModProvider") + void multiplyMod(UInt32 v1, UInt32 v2, UInt32 m, UInt32 expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModProvider() { + return Stream + .of( + Arguments.of(v(0), v(5), UInt32.valueOf(2), v(0)), + Arguments.of(v(2), v(3), UInt32.valueOf(7), v(6)), + Arguments.of(v(2), v(3), UInt32.valueOf(6), v(0)), + Arguments.of(v(2), v(0), UInt32.valueOf(6), v(0)), + Arguments.of(hv("0x0FFFFFFE"), v(2), UInt32.MAX_VALUE, hv("0x1FFFFFFC"))); + } + + @Test + void shouldThrowForMultiplyModOfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).multiplyMod(v(1), UInt32.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModLongUInt32Provider") + void multiplyModLongUInt32(UInt32 v1, int v2, UInt32 m, UInt32 expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModLongUInt32Provider() { + return Stream + .of( + Arguments.of(v(0), 5, UInt32.valueOf(2), v(0)), + Arguments.of(v(2), 3, UInt32.valueOf(7), v(6)), + Arguments.of(v(2), 3, UInt32.valueOf(6), v(0)), + Arguments.of(v(2), 0, UInt32.valueOf(6), v(0)), + Arguments.of(hv("0x0FFFFFFE"), 2, UInt32.MAX_VALUE, hv("0x1FFFFFFC"))); + } + + @Test + void shouldThrowForMultiplyModLongUInt32OfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).multiplyMod(1, UInt32.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongUInt32OfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(3).multiplyMod(-1, UInt32.valueOf(2))); + assertEquals("multiplyMod unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModLongLongProvider") + void multiplyModLongLong(UInt32 v1, int v2, int m, UInt32 expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModLongLongProvider() { + return Stream + .of( + Arguments.of(v(0), 5, 2, v(0)), + Arguments.of(v(2), 3, 7, v(6)), + Arguments.of(v(2), 3, 6, v(0)), + Arguments.of(v(2), 0, 6, v(0)), + Arguments.of(hv("0x0FFFFFFE"), 2, Integer.MAX_VALUE, hv("0x1FFFFFFC"))); + } + + @Test + void shouldThrowForMultiplyModLongLongOfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).multiplyMod(1, 0)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongLongOfModNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(2).multiplyMod(5, -7)); + assertEquals("multiplyMod unsigned with negative modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(3).multiplyMod(-1, 2)); + assertEquals("multiplyMod unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideProvider") + void divide(UInt32 v1, UInt32 v2, UInt32 expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideProvider() { + return Stream + .of( + Arguments.of(v(1), v(1), v(1)), + Arguments.of(v(0), v(2), v(0)), + Arguments.of(v(1), v(2), v(0)), + Arguments.of(v(2), v(2), v(1)), + Arguments.of(v(3), v(2), v(1)), + Arguments.of(v(4), v(2), v(2)), + Arguments.of(v(2), v(8), v(0)), + Arguments.of(v(7), v(8), v(0)), + Arguments.of(v(8), v(8), v(1)), + Arguments.of(v(9), v(8), v(1)), + Arguments.of(v(17), v(8), v(2)), + Arguments.of(v(1024), v(8), v(128)), + Arguments.of(v(1026), v(8), v(128))); + } + + @Test + void shouldThrowForDivideByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(v(0))); + assertEquals("divide by zero", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideLongProvider") + void divideLong(UInt32 v1, int v2, UInt32 expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideLongProvider() { + return Stream + .of( + Arguments.of(v(1), 1, v(1)), + Arguments.of(v(0), 2, v(0)), + Arguments.of(v(1), 2, v(0)), + Arguments.of(v(2), 2, v(1)), + Arguments.of(v(3), 2, v(1)), + Arguments.of(v(4), 2, v(2)), + Arguments.of(v(2), 8, v(0)), + Arguments.of(v(7), 8, v(0)), + Arguments.of(v(8), 8, v(1)), + Arguments.of(v(9), 8, v(1)), + Arguments.of(v(17), 8, v(2)), + Arguments.of(v(1024), 8, v(128)), + Arguments.of(v(1026), 8, v(128))); + } + + @Test + void shouldThrowForDivideLongByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(0)); + assertEquals("divide by zero", exception.getMessage()); + } + + @Test + void shouldThrowForDivideLongByNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(-5)); + assertEquals("divide unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("powUInt32Provider") + void powUInt32(UInt32 v1, UInt32 v2, UInt32 expected) { + assertValueEquals(expected, v1.pow(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream powUInt32Provider() { + return Stream + .of( + Arguments.of(v(0), UInt32.valueOf(2), v(0)), + Arguments.of(v(2), UInt32.valueOf(2), v(4)), + Arguments.of(v(2), UInt32.valueOf(8), v(256)), + Arguments.of(v(3), UInt32.valueOf(3), v(27)), + Arguments.of(hv("0xFFF0F0F0"), UInt32.valueOf(3), hv("0x19A2F000"))); + } + + @ParameterizedTest + @MethodSource("powLongProvider") + void powLong(UInt32 v1, long v2, UInt32 expected) { + assertValueEquals(expected, v1.pow(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream powLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2, v(0)), + Arguments.of(v(2), 2, v(4)), + Arguments.of(v(2), 8, v(256)), + Arguments.of(v(3), 3, v(27)), + Arguments.of(hv("0xFFF0F0F0"), 3, hv("0x19A2F000"))); + } + + @ParameterizedTest + @MethodSource("modLongProvider") + void modLong(UInt32 v1, int v2, UInt32 expected) { + assertValueEquals(expected, v1.mod(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream modLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2, v(0)), + Arguments.of(v(1), 2, v(1)), + Arguments.of(v(2), 2, v(0)), + Arguments.of(v(3), 2, v(1)), + Arguments.of(v(0), 8, v(0)), + Arguments.of(v(1), 8, v(1)), + Arguments.of(v(2), 8, v(2)), + Arguments.of(v(3), 8, v(3)), + Arguments.of(v(7), 8, v(7)), + Arguments.of(v(8), 8, v(0)), + Arguments.of(v(9), 8, v(1)), + Arguments.of(v(1024), 8, v(0)), + Arguments.of(v(1026), 8, v(2))); + } + + @Test + void shouldThrowForModLongByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(0)); + assertEquals("mod by zero", exception.getMessage()); + } + + @Test + void shouldThrowForModLongByNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(-5)); + assertEquals("mod by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("andProvider") + void and(UInt32 v1, Object v2, UInt32 expected) { + if (v2 instanceof UInt32) { + assertValueEquals(expected, v1.and((UInt32) v2)); + } else if (v2 instanceof Bytes) { + assertValueEquals(expected, v1.and((Bytes) v2)); + } else { + throw new IllegalArgumentException(); + } + } + + @SuppressWarnings("UnusedMethod") + private static Stream andProvider() { + return Stream + .of( + Arguments.of(hv("0x0000FFFF"), b("0xFFFF0000"), hv("0x00000000")), + Arguments.of(hv("0x0000FFFF"), b("0xFFFFFF00"), hv("0x0000FF00")), + Arguments.of(hv("0x0000FFFF"), hv("0xFFFF0000"), hv("0x00000000")), + Arguments.of(hv("0x0000FFFF"), hv("0xFFFFFF00"), hv("0x0000FF00"))); + } + + @ParameterizedTest + @MethodSource("orProvider") + void or(UInt32 v1, Object v2, UInt32 expected) { + if (v2 instanceof UInt32) { + assertValueEquals(expected, v1.or((UInt32) v2)); + } else if (v2 instanceof Bytes) { + assertValueEquals(expected, v1.or((Bytes) v2)); + } else { + throw new IllegalArgumentException(); + } + } + + @SuppressWarnings("UnusedMethod") + private static Stream orProvider() { + return Stream + .of( + Arguments.of(hv("0x0000FFFF"), b("0xFFFF0000"), hv("0xFFFFFFFF")), + Arguments.of(hv("0x0000FFFF"), b("0xFFFF0000"), hv("0xFFFFFFFF")), + Arguments.of(hv("0x000000FF"), b("0xFFFF0000"), hv("0xFFFF00FF")), + Arguments.of(hv("0x0000FFFF"), hv("0xFFFF0000"), hv("0xFFFFFFFF")), + Arguments.of(hv("0x0000FFFF"), hv("0xFFFF0000"), hv("0xFFFFFFFF")), + Arguments.of(hv("0x000000FF"), hv("0xFFFF0000"), hv("0xFFFF00FF"))); + } + + @ParameterizedTest + @MethodSource("xorProvider") + void xor(UInt32 v1, Object v2, UInt32 expected) { + if (v2 instanceof UInt32) { + assertValueEquals(expected, v1.xor((UInt32) v2)); + } else if (v2 instanceof Bytes) { + assertValueEquals(expected, v1.xor((Bytes) v2)); + } else { + throw new IllegalArgumentException(); + } + } + + @SuppressWarnings("UnusedMethod") + private static Stream xorProvider() { + return Stream + .of( + Arguments.of(hv("0xFFFFFFFF"), b("0xFFFFFFFF"), hv("0x00000000")), + Arguments.of(hv("0x0000FFFF"), b("0xFFFF0000"), hv("0xFFFFFFFF")), + Arguments.of(hv("0x0000FFFF"), b("0xFFFFFF00"), hv("0xFFFF00FF")), + Arguments.of(hv("0xFFFFFFFF"), hv("0xFFFFFFFF"), hv("0x00000000")), + Arguments.of(hv("0x0000FFFF"), hv("0xFFFF0000"), hv("0xFFFFFFFF")), + Arguments.of(hv("0x0000FFFF"), hv("0xFFFFFF00"), hv("0xFFFF00FF"))); + } + + @ParameterizedTest + @MethodSource("notProvider") + void not(UInt32 value, UInt32 expected) { + assertValueEquals(expected, value.not()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream notProvider() { + return Stream + .of( + Arguments.of(hv("0xFFFFFFFF"), hv("0x00000000")), + Arguments.of(hv("0x00000000"), hv("0xFFFFFFFF")), + Arguments.of(hv("0x0000FFFF"), hv("0xFFFF0000"))); + } + + @ParameterizedTest + @MethodSource("shiftLeftProvider") + void shiftLeft(UInt32 value, int distance, UInt32 expected) { + assertValueEquals(expected, value.shiftLeft(distance)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream shiftLeftProvider() { + return Stream + .of( + Arguments.of(hv("0x01"), 0, hv("0x01")), + Arguments.of(hv("0x01"), 1, hv("0x02")), + Arguments.of(hv("0x01"), 2, hv("0x04")), + Arguments.of(hv("0x01"), 8, hv("0x0100")), + Arguments.of(hv("0x01"), 9, hv("0x0200")), + Arguments.of(hv("0x01"), 16, hv("0x10000")), + Arguments.of(hv("0x00FF00"), 4, hv("0x0FF000")), + Arguments.of(hv("0x00FF00"), 8, hv("0xFF0000")), + Arguments.of(hv("0x00FF00"), 1, hv("0x01FE00")), + Arguments.of(hv("0x00000001"), 16, hv("0x00010000")), + Arguments.of(hv("0x00000001"), 15, hv("0x00008000")), + Arguments.of(hv("0xFFFFFFFF"), 23, hv("0xFF800000")), + Arguments.of(hv("0x0000FFFF"), 18, hv("0xFFFC0000"))); + } + + @ParameterizedTest + @MethodSource("shiftRightProvider") + void shiftRight(UInt32 value, int distance, UInt32 expected) { + assertValueEquals(expected, value.shiftRight(distance)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream shiftRightProvider() { + return Stream + .of( + Arguments.of(hv("0x01"), 0, hv("0x01")), + Arguments.of(hv("0x01"), 1, hv("0x00")), + Arguments.of(hv("0x10"), 1, hv("0x08")), + Arguments.of(hv("0x10"), 2, hv("0x04")), + Arguments.of(hv("0x10"), 8, hv("0x00")), + Arguments.of(hv("0x1000"), 4, hv("0x0100")), + Arguments.of(hv("0x1000"), 5, hv("0x0080")), + Arguments.of(hv("0x1000"), 8, hv("0x0010")), + Arguments.of(hv("0x1000"), 9, hv("0x0008")), + Arguments.of(hv("0x1000"), 16, hv("0x0000")), + Arguments.of(hv("0x00FF00"), 4, hv("0x000FF0")), + Arguments.of(hv("0x00FF00"), 8, hv("0x0000FF")), + Arguments.of(hv("0x00FF00"), 1, hv("0x007F80")), + Arguments.of(hv("0x100000"), 16, hv("0x000010")), + Arguments.of(hv("0x100000"), 15, hv("0x000020")), + Arguments.of(hv("0xFFFFFFFF"), 23, hv("0x000001FF")), + Arguments.of(hv("0xFFFFFFFF"), 202, hv("0x00000000"))); + } + + @ParameterizedTest + @MethodSource("intValueProvider") + void intValue(UInt32 value, int expected) { + assertEquals(expected, value.intValue()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream intValueProvider() { + return Stream + .of( + Arguments.of(hv("0x"), 0), + Arguments.of(hv("0x00"), 0), + Arguments.of(hv("0x00000000"), 0), + Arguments.of(hv("0x01"), 1), + Arguments.of(hv("0x0001"), 1), + Arguments.of(hv("0x000001"), 1), + Arguments.of(hv("0x00000001"), 1), + Arguments.of(hv("0x0100"), 256), + Arguments.of(hv("0x000100"), 256), + Arguments.of(hv("0x00000100"), 256)); + } + + @ParameterizedTest + @MethodSource("longValueProvider") + void longValue(UInt32 value, long expected) { + assertEquals(expected, value.toLong()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream longValueProvider() { + return Stream + .of( + Arguments.of(hv("0x"), 0L), + Arguments.of(hv("0x00"), 0L), + Arguments.of(hv("0x00000000"), 0L), + Arguments.of(hv("0x01"), 1L), + Arguments.of(hv("0x0001"), 1L), + Arguments.of(hv("0x000001"), 1L), + Arguments.of(hv("0x0100"), 256L), + Arguments.of(hv("0x000100"), 256L), + Arguments.of(hv("0x00000100"), 256L), + Arguments.of(hv("0xFFFFFFFF"), (1L << 32) - 1)); + } + + @ParameterizedTest + @MethodSource("compareToProvider") + void compareTo(UInt32 v1, UInt32 v2, int expected) { + assertEquals(expected, v1.compareTo(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream compareToProvider() { + return Stream + .of( + Arguments.of(v(5), v(5), 0), + Arguments.of(v(5), v(3), 1), + Arguments.of(v(5), v(6), -1), + Arguments.of(hv("0x00000000"), hv("0x00000000"), 0), + Arguments.of(hv("0xFFFFFFFF"), hv("0xFFFFFFFF"), 0), + Arguments.of(hv("0x0000FFFF"), hv("0x0000FFFF"), 0), + Arguments.of(hv("0xFFFFFFFF"), hv("0x00000000"), 1), + Arguments.of(hv("0x00000000"), hv("0xFFFFFFFF"), -1), + Arguments.of(hv("0x0001FFFF"), hv("0x0000FFFF"), 1), + Arguments.of(hv("0x0000FFFE"), hv("0x0000FFFF"), -1)); + } + + @ParameterizedTest + @MethodSource("toBytesProvider") + void toBytesTest(UInt32 value, Bytes expected) { + assertEquals(expected, value.toBytes()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream toBytesProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), Bytes.fromHexString("0x00000000")), + Arguments.of(hv("0x01000000"), Bytes.fromHexString("0x01000000")), + Arguments.of(hv("0xf10000ab"), Bytes.fromHexString("0xF10000AB"))); + } + + @ParameterizedTest + @MethodSource("toMinimalBytesProvider") + void toMinimalBytesTest(UInt32 value, Bytes expected) { + assertEquals(expected, value.toMinimalBytes()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream toMinimalBytesProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), Bytes.EMPTY), + Arguments.of(hv("0x01000000"), Bytes.fromHexString("0x01000000")), + Arguments.of(hv("0xf10000ab"), Bytes.fromHexString("0xf10000ab")), + Arguments.of(hv("0x01000000"), Bytes.fromHexString("0x01000000"))); + } + + @ParameterizedTest + @MethodSource("numberOfLeadingZerosProvider") + void numberOfLeadingZeros(UInt32 value, int expected) { + assertEquals(expected, value.numberOfLeadingZeros()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream numberOfLeadingZerosProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), 32), + Arguments.of(hv("0x01"), 31), + Arguments.of(hv("0x02"), 30), + Arguments.of(hv("0x03"), 30), + Arguments.of(hv("0x0F"), 28), + Arguments.of(hv("0x8F"), 24), + Arguments.of(hv("0x1000000"), 7)); + } + + @ParameterizedTest + @MethodSource("bitLengthProvider") + void bitLength(UInt32 value, int expected) { + assertEquals(expected, value.bitLength()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream bitLengthProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), 0), + Arguments.of(hv("0x01"), 1), + Arguments.of(hv("0x02"), 2), + Arguments.of(hv("0x03"), 2), + Arguments.of(hv("0x0F"), 4), + Arguments.of(hv("0x8F"), 8), + Arguments.of(hv("0x10000000"), 29)); + } + + @ParameterizedTest + @MethodSource("addExactProvider") + void addExact(UInt32 value, UInt32 operand) { + assertThrows(ArithmeticException.class, () -> value.addExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addExactProvider() { + return Stream.of(Arguments.of(UInt32.MAX_VALUE, v(1)), Arguments.of(UInt32.MAX_VALUE, UInt32.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addExactLongProvider") + void addExactLong(UInt32 value, int operand) { + assertThrows(ArithmeticException.class, () -> value.addExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addExactLongProvider() { + return Stream + .of( + Arguments.of(UInt32.MAX_VALUE, 3), + Arguments.of(UInt32.MAX_VALUE, Integer.MAX_VALUE), + Arguments.of(v(0), -1)); + } + + @ParameterizedTest + @MethodSource("subtractExactProvider") + void subtractExact(UInt32 value, UInt32 operand) { + assertThrows(ArithmeticException.class, () -> value.subtractExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractExactProvider() { + return Stream.of(Arguments.of(v(0), v(1)), Arguments.of(v(0), UInt32.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("subtractExactLongProvider") + void subtractExactLong(UInt32 value, int operand) { + assertThrows(ArithmeticException.class, () -> value.subtractExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractExactLongProvider() { + return Stream.of(Arguments.of(v(0), 1), Arguments.of(v(0), Integer.MAX_VALUE), Arguments.of(UInt32.MAX_VALUE, -1)); + } + + private void assertValueEquals(UInt32 expected, UInt32 actual) { + String msg = String.format("Expected %s but got %s", expected.toHexString(), actual.toHexString()); + assertEquals(expected, actual, msg); + } + + @Test + void testToUInt32() { + UInt32 value = UInt32.valueOf(42); + assertSame(value, value.toUInt32()); + } + + @Test + void toIntTooLarge() { + assertThrows(ArithmeticException.class, UInt32.MAX_VALUE::intValue); + } + + @Test + void toLongTooLarge() { + assertEquals(4294967295L, UInt32.MAX_VALUE.toLong()); + } + + @Test + void testToDecimalString() { + assertEquals("3456", UInt32.valueOf(3456).toDecimalString()); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/UInt384Test.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/UInt384Test.java new file mode 100644 index 00000000000..eee43a4d81f --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/UInt384Test.java @@ -0,0 +1,1103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.math.BigInteger; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class UInt384Test { + + private static UInt384 v(long v) { + return UInt384.valueOf(v); + } + + private static UInt384 biv(String s) { + return UInt384.valueOf(new BigInteger(s)); + } + + private static UInt384 hv(String s) { + return UInt384.fromHexString(s); + } + + @Test + void valueOfLong() { + assertThrows(IllegalArgumentException.class, () -> UInt384.valueOf(-1)); + assertThrows(IllegalArgumentException.class, () -> UInt384.valueOf(Long.MIN_VALUE)); + assertThrows(IllegalArgumentException.class, () -> UInt384.valueOf(~0L)); + } + + @Test + void valueOfBigInteger() { + assertThrows(IllegalArgumentException.class, () -> UInt384.valueOf(BigInteger.valueOf(-1))); + assertThrows(IllegalArgumentException.class, () -> UInt384.valueOf(BigInteger.valueOf(2).pow(384))); + } + + @ParameterizedTest + @MethodSource("addProvider") + void add(UInt384 v1, UInt384 v2, UInt384 expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addProvider() { + return Stream + .of( + Arguments.of(v(1), v(0), v(1)), + Arguments.of(v(5), v(0), v(5)), + Arguments.of(v(0), v(1), v(1)), + Arguments.of(v(0), v(100), v(100)), + Arguments.of(v(2), v(2), v(4)), + Arguments.of(v(100), v(90), v(190)), + Arguments.of(biv("9223372036854775807"), v(1), biv("9223372036854775808")), + Arguments.of(biv("13492324908428420834234908342"), v(10), biv("13492324908428420834234908352")), + Arguments + .of(biv("13492324908428420834234908342"), v(23422141424214L), biv("13492324908428444256376332556")), + Arguments.of(UInt384.MAX_VALUE, v(1), v(0)), + Arguments.of(UInt384.MAX_VALUE, v(2), v(1)), + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0"), + v(1), + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1")), + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + v(1), + UInt384.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addLongProvider") + void addLong(UInt384 v1, long v2, UInt384 expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addLongProvider() { + return Stream + .of( + Arguments.of(v(1), 0L, v(1)), + Arguments.of(v(5), 0L, v(5)), + Arguments.of(v(0), 1L, v(1)), + Arguments.of(v(0), 100L, v(100)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(100), 90L, v(190)), + Arguments.of(biv("13492324908428420834234908342"), 10L, biv("13492324908428420834234908352")), + Arguments.of(biv("13492324908428420834234908342"), 23422141424214L, biv("13492324908428444256376332556")), + Arguments.of(UInt384.MAX_VALUE, 1L, v(0)), + Arguments.of(UInt384.MAX_VALUE, 2L, v(1)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0"), + 1L, + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1")), + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + 1L, + UInt384.MAX_VALUE), + Arguments.of(v(10), -5L, v(5)), + Arguments.of(v(0), -1L, UInt384.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addModProvider") + void addMod(UInt384 v1, UInt384 v2, UInt384 m, UInt384 expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModProvider() { + return Stream + .of( + Arguments.of(v(0), v(1), UInt384.valueOf(2), v(1)), + Arguments.of(v(1), v(1), UInt384.valueOf(2), v(0)), + Arguments.of(UInt384.MAX_VALUE.subtract(2), v(1), UInt384.MAX_VALUE, UInt384.MAX_VALUE.subtract(1)), + Arguments.of(UInt384.MAX_VALUE.subtract(1), v(1), UInt384.MAX_VALUE, v(0)), + Arguments.of(v(2), v(1), UInt384.valueOf(2), v(1)), + Arguments.of(v(3), v(2), UInt384.valueOf(6), v(5)), + Arguments.of(v(3), v(4), UInt384.valueOf(2), v(1))); + } + + @Test + void shouldThrowForAddModOfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(v(1), UInt384.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModUInt384UInt384Provider") + void addModUInt384UInt384(UInt384 v1, UInt384 v2, UInt384 m, UInt384 expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModUInt384UInt384Provider() { + return Stream + .of( + Arguments.of(v(0), UInt384.ONE, UInt384.valueOf(2), v(1)), + Arguments.of(v(1), UInt384.ONE, UInt384.valueOf(2), v(0)), + Arguments.of(UInt384.MAX_VALUE.subtract(2), UInt384.ONE, UInt384.MAX_VALUE, UInt384.MAX_VALUE.subtract(1)), + Arguments.of(UInt384.MAX_VALUE.subtract(1), UInt384.ONE, UInt384.MAX_VALUE, v(0)), + Arguments.of(v(2), UInt384.ONE, UInt384.valueOf(2), v(1)), + Arguments.of(v(3), UInt384.valueOf(2), UInt384.valueOf(6), v(5)), + Arguments.of(v(3), UInt384.valueOf(4), UInt384.valueOf(2), v(1))); + } + + @Test + void shouldThrowForAddModLongUInt384OfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, UInt384.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModLongUInt384Provider") + void addModLongUInt384(UInt384 v1, long v2, UInt384 m, UInt384 expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModLongUInt384Provider() { + return Stream + .of( + Arguments.of(v(0), 1L, UInt384.valueOf(2), v(1)), + Arguments.of(v(1), 1L, UInt384.valueOf(2), v(0)), + Arguments.of(UInt384.MAX_VALUE.subtract(2), 1L, UInt384.MAX_VALUE, UInt384.MAX_VALUE.subtract(1)), + Arguments.of(UInt384.MAX_VALUE.subtract(1), 1L, UInt384.MAX_VALUE, v(0)), + Arguments.of(v(2), 1L, UInt384.valueOf(2), v(1)), + Arguments.of(v(2), -1L, UInt384.valueOf(2), v(1)), + Arguments.of(v(1), -7L, UInt384.valueOf(5), v(4))); + } + + @Test + void shouldThrowForAddModUInt384UInt384OfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(UInt384.ONE, UInt384.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModLongLongProvider") + void addModLongLong(UInt384 v1, long v2, long m, UInt384 expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModLongLongProvider() { + return Stream + .of(Arguments.of(v(0), 1L, 2L, v(1)), Arguments.of(v(1), 1L, 2L, v(0)), Arguments.of(v(2), 1L, 2L, v(1))); + } + + @Test + void shouldThrowForAddModLongLongOfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, 0)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForAddModLongLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, -5)); + assertEquals("addMod unsigned with negative modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("subtractProvider") + void subtract(UInt384 v1, UInt384 v2, UInt384 expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractProvider() { + return Stream + .of( + Arguments.of(v(1), v(0), v(1)), + Arguments.of(v(5), v(0), v(5)), + Arguments.of(v(2), v(1), v(1)), + Arguments.of(v(100), v(100), v(0)), + Arguments.of(biv("13492324908428420834234908342"), v(10), biv("13492324908428420834234908332")), + Arguments + .of(biv("13492324908428420834234908342"), v(23422141424214L), biv("13492324908428397412093484128")), + Arguments.of(v(0), v(1), UInt384.MAX_VALUE), + Arguments.of(v(1), v(2), UInt384.MAX_VALUE), + Arguments + .of( + UInt384.MAX_VALUE, + v(1), + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"))); + } + + @ParameterizedTest + @MethodSource("subtractLongProvider") + void subtractLong(UInt384 v1, long v2, UInt384 expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractLongProvider() { + return Stream + .of( + Arguments.of(v(1), 0L, v(1)), + Arguments.of(v(5), 0L, v(5)), + Arguments.of(v(2), 1L, v(1)), + Arguments.of(v(100), 100L, v(0)), + Arguments.of(biv("13492324908428420834234908342"), 10L, biv("13492324908428420834234908332")), + Arguments.of(biv("13492324908428420834234908342"), 23422141424214L, biv("13492324908428397412093484128")), + Arguments.of(v(0), 1L, UInt384.MAX_VALUE), + Arguments.of(v(1), 2L, UInt384.MAX_VALUE), + Arguments + .of( + UInt384.MAX_VALUE, + 1L, + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE")), + Arguments.of(v(0), -1L, v(1)), + Arguments.of(v(0), -100L, v(100)), + Arguments.of(v(2), -2L, v(4))); + } + + @ParameterizedTest + @MethodSource("multiplyProvider") + void multiply(UInt384 v1, UInt384 v2, UInt384 expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyProvider() { + return Stream + .of( + Arguments.of(v(0), v(2), v(0)), + Arguments.of(v(1), v(2), v(2)), + Arguments.of(v(2), v(2), v(4)), + Arguments.of(v(3), v(2), v(6)), + Arguments.of(v(4), v(2), v(8)), + Arguments.of(v(10), v(18), v(180)), + Arguments.of(biv("13492324908428420834234908341"), v(2), biv("26984649816856841668469816682")), + Arguments.of(biv("13492324908428420834234908342"), v(2), biv("26984649816856841668469816684")), + Arguments.of(v(2), v(8), v(16)), + Arguments.of(v(7), v(8), v(56)), + Arguments.of(v(8), v(8), v(64)), + Arguments.of(v(17), v(8), v(136)), + Arguments.of(biv("13492324908428420834234908342"), v(8), biv("107938599267427366673879266736")), + Arguments.of(biv("13492324908428420834234908342"), v(2048), biv("27632281412461405868513092284416")), + Arguments.of(biv("13492324908428420834234908342"), v(131072), biv("1768466010397529975584837906202624")), + Arguments.of(v(22), v(0), v(0))); + } + + @ParameterizedTest + @MethodSource("multiplyLongProvider") + void multiplyLong(UInt384 v1, long v2, UInt384 expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(2)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(3), 2L, v(6)), + Arguments.of(v(4), 2L, v(8)), + Arguments.of(v(10), 18L, v(180)), + Arguments.of(biv("13492324908428420834234908341"), 2L, biv("26984649816856841668469816682")), + Arguments.of(biv("13492324908428420834234908342"), 2L, biv("26984649816856841668469816684")), + Arguments.of(v(2), 8L, v(16)), + Arguments.of(v(7), 8L, v(56)), + Arguments.of(v(8), 8L, v(64)), + Arguments.of(v(17), 8L, v(136)), + Arguments.of(biv("13492324908428420834234908342"), 8L, biv("107938599267427366673879266736")), + Arguments.of(biv("13492324908428420834234908342"), 2048L, biv("27632281412461405868513092284416")), + Arguments.of(biv("13492324908428420834234908342"), 131072L, biv("1768466010397529975584837906202624")), + Arguments.of(v(22), 0L, v(0)), + Arguments + .of( + hv( + "0x0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 2L, + hv( + "0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE")), + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 2L, + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"))); + } + + @Test + void shouldThrowForMultiplyLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(2).multiply(-5)); + assertEquals("multiply unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModProvider") + void multiplyMod(UInt384 v1, UInt384 v2, UInt384 m, UInt384 expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModProvider() { + return Stream + .of( + Arguments.of(v(0), v(5), UInt384.valueOf(2), v(0)), + Arguments.of(v(2), v(3), UInt384.valueOf(7), v(6)), + Arguments.of(v(2), v(3), UInt384.valueOf(6), v(0)), + Arguments.of(v(2), v(0), UInt384.valueOf(6), v(0)), + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + v(2), + UInt384.MAX_VALUE, + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD"))); + } + + @Test + void shouldThrowForMultiplyModOfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).multiplyMod(v(1), UInt384.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModLongUInt384Provider") + void multiplyModLongUInt384(UInt384 v1, long v2, UInt384 m, UInt384 expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModLongUInt384Provider() { + return Stream + .of( + Arguments.of(v(0), 5L, UInt384.valueOf(2), v(0)), + Arguments.of(v(2), 3L, UInt384.valueOf(7), v(6)), + Arguments.of(v(2), 3L, UInt384.valueOf(6), v(0)), + Arguments.of(v(2), 0L, UInt384.valueOf(6), v(0)), + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + 2L, + UInt384.MAX_VALUE, + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD"))); + } + + @Test + void shouldThrowForMultiplyModLongUInt384OfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).multiplyMod(1L, UInt384.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongUInt384OfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(3).multiplyMod(-1, UInt384.valueOf(2))); + assertEquals("multiplyMod unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModLongLongProvider") + void multiplyModLongLong(UInt384 v1, long v2, long m, UInt384 expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModLongLongProvider() { + return Stream + .of( + Arguments.of(v(0), 5L, 2L, v(0)), + Arguments.of(v(2), 3L, 7L, v(6)), + Arguments.of(v(2), 3L, 6L, v(0)), + Arguments.of(v(2), 0L, 6L, v(0)), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + 2L, + Long.MAX_VALUE, + hv("0x000000000000000000000000000000000000000000000000000000000000001C"))); + } + + @Test + void shouldThrowForMultiplyModLongLongOfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).multiplyMod(1, 0)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongLongOfModNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(2).multiplyMod(5, -7)); + assertEquals("multiplyMod unsigned with negative modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(3).multiplyMod(-1, 2)); + assertEquals("multiplyMod unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideProvider") + void divide(UInt384 v1, UInt384 v2, UInt384 expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideProvider() { + return Stream + .of( + Arguments.of(v(0), v(2), v(0)), + Arguments.of(v(1), v(2), v(0)), + Arguments.of(v(2), v(2), v(1)), + Arguments.of(v(3), v(2), v(1)), + Arguments.of(v(4), v(2), v(2)), + Arguments.of(biv("13492324908428420834234908341"), v(2), biv("6746162454214210417117454170")), + Arguments.of(biv("13492324908428420834234908342"), v(2), biv("6746162454214210417117454171")), + Arguments.of(biv("13492324908428420834234908343"), v(2), biv("6746162454214210417117454171")), + Arguments.of(v(2), v(8), v(0)), + Arguments.of(v(7), v(8), v(0)), + Arguments.of(v(8), v(8), v(1)), + Arguments.of(v(9), v(8), v(1)), + Arguments.of(v(17), v(8), v(2)), + Arguments.of(v(1024), v(8), v(128)), + Arguments.of(v(1026), v(8), v(128)), + Arguments.of(biv("13492324908428420834234908342"), v(8), biv("1686540613553552604279363542")), + Arguments.of(biv("13492324908428420834234908342"), v(2048), biv("6588049271693564860466263")), + Arguments.of(biv("13492324908428420834234908342"), v(131072), biv("102938269870211950944785"))); + } + + @Test + void shouldThrowForDivideByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(v(0))); + assertEquals("divide by zero", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideLongProvider") + void divideLong(UInt384 v1, long v2, UInt384 expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(0)), + Arguments.of(v(2), 2L, v(1)), + Arguments.of(v(3), 2L, v(1)), + Arguments.of(v(4), 2L, v(2)), + Arguments.of(biv("13492324908428420834234908341"), 2L, biv("6746162454214210417117454170")), + Arguments.of(biv("13492324908428420834234908342"), 2L, biv("6746162454214210417117454171")), + Arguments.of(biv("13492324908428420834234908343"), 2L, biv("6746162454214210417117454171")), + Arguments.of(v(2), 8L, v(0)), + Arguments.of(v(7), 8L, v(0)), + Arguments.of(v(8), 8L, v(1)), + Arguments.of(v(9), 8L, v(1)), + Arguments.of(v(17), 8L, v(2)), + Arguments.of(v(1024), 8L, v(128)), + Arguments.of(v(1026), 8L, v(128)), + Arguments.of(biv("13492324908428420834234908342"), 8L, biv("1686540613553552604279363542")), + Arguments.of(biv("13492324908428420834234908342"), 2048L, biv("6588049271693564860466263")), + Arguments.of(biv("13492324908428420834234908342"), 131072L, biv("102938269870211950944785"))); + } + + @Test + void shouldThrowForDivideLongByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(0)); + assertEquals("divide by zero", exception.getMessage()); + } + + @Test + void shouldThrowForDivideLongByNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(-5)); + assertEquals("divide unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("powUInt384Provider") + void powUInt384(UInt384 v1, UInt384 v2, UInt384 expected) { + assertValueEquals(expected, v1.pow(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream powUInt384Provider() { + return Stream + .of( + Arguments.of(v(0), UInt384.valueOf(2), v(0)), + Arguments.of(v(2), UInt384.valueOf(2), v(4)), + Arguments.of(v(2), UInt384.valueOf(8), v(256)), + Arguments.of(v(3), UInt384.valueOf(3), v(27)), + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0"), + UInt384.valueOf(3), + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A920E119A2F000"))); + } + + @ParameterizedTest + @MethodSource("powLongProvider") + void powLong(UInt384 v1, long v2, UInt384 expected) { + assertValueEquals(expected, v1.pow(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream powLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(2), 8L, v(256)), + Arguments.of(v(3), 3L, v(27)), + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0"), + 3L, + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A920E119A2F000")), + Arguments + .of( + v(3), + -3L, + hv( + "0x4BDA12F684BDA12F684BDA12F684BDA12F684BDA12F684BDA12F684BDA12F684BDA12F684BDA12F684BDA12F684BDA13"))); + } + + @ParameterizedTest + @MethodSource("modLongProvider") + void modLong(UInt384 v1, long v2, UInt384 expected) { + assertValueEquals(expected, v1.mod(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream modLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(1)), + Arguments.of(v(2), 2L, v(0)), + Arguments.of(v(3), 2L, v(1)), + Arguments.of(biv("13492324908428420834234908342"), 2L, v(0)), + Arguments.of(biv("13492324908428420834234908343"), 2L, v(1)), + Arguments.of(v(0), 8L, v(0)), + Arguments.of(v(1), 8L, v(1)), + Arguments.of(v(2), 8L, v(2)), + Arguments.of(v(3), 8L, v(3)), + Arguments.of(v(7), 8L, v(7)), + Arguments.of(v(8), 8L, v(0)), + Arguments.of(v(9), 8L, v(1)), + Arguments.of(v(1024), 8L, v(0)), + Arguments.of(v(1026), 8L, v(2)), + Arguments.of(biv("13492324908428420834234908342"), 8L, v(6)), + Arguments.of(biv("13492324908428420834234908343"), 8L, v(7)), + Arguments.of(biv("13492324908428420834234908344"), 8L, v(0))); + } + + @Test + void shouldThrowForModLongByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(0)); + assertEquals("mod by zero", exception.getMessage()); + } + + @Test + void shouldThrowForModLongByNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(-5)); + assertEquals("mod by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("andProvider") + void and(UInt384 v1, UInt384 v2, UInt384 expected) { + assertValueEquals(expected, v1.and(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream andProvider() { + return Stream + .of( + Arguments + .of( + hv("0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000"), + hv("0x0000000000000000000000000000000000000000000000000000000000000000")), + Arguments + .of( + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000"), + hv("0x000000000000000000000000000000FF00000000000000000000000000000000"))); + } + + @ParameterizedTest + @MethodSource("orProvider") + void or(UInt384 v1, UInt384 v2, UInt384 expected) { + assertValueEquals(expected, v1.or(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream orProvider() { + return Stream + .of( + Arguments + .of( + hv("0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")), + Arguments + .of( + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")), + Arguments + .of( + hv("0x0000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))); + } + + @ParameterizedTest + @MethodSource("xorProvider") + void xor(UInt384 v1, UInt384 v2, UInt384 expected) { + assertValueEquals(expected, v1.xor(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream xorProvider() { + return Stream + .of( + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0x0000000000000000000000000000000000000000000000000000000000000000")), + Arguments + .of( + hv("0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")), + Arguments + .of( + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))); + } + + @ParameterizedTest + @MethodSource("notProvider") + void not(UInt384 value, UInt384 expected) { + assertValueEquals(expected, value.not()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream notProvider() { + return Stream + .of( + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")), + Arguments + .of( + hv( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")), + Arguments + .of( + hv( + "0x00000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000"))); + } + + @ParameterizedTest + @MethodSource("shiftLeftProvider") + void shiftLeft(UInt384 value, int distance, UInt384 expected) { + assertValueEquals(expected, value.shiftLeft(distance)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream shiftLeftProvider() { + return Stream + .of( + Arguments.of(hv("0x01"), 1, hv("0x02")), + Arguments.of(hv("0x01"), 2, hv("0x04")), + Arguments.of(hv("0x01"), 8, hv("0x0100")), + Arguments.of(hv("0x01"), 9, hv("0x0200")), + Arguments.of(hv("0x01"), 16, hv("0x10000")), + Arguments.of(hv("0x00FF00"), 4, hv("0x0FF000")), + Arguments.of(hv("0x00FF00"), 8, hv("0xFF0000")), + Arguments.of(hv("0x00FF00"), 1, hv("0x01FE00")), + Arguments + .of( + hv( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"), + 16, + hv( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000")), + Arguments + .of( + hv( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"), + 15, + hv( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000")), + Arguments + .of( + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 55, + hv( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80000000000000")), + Arguments + .of( + hv( + "0x00000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 330, + hv( + "0xFFFFFFFFFFFFFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000"))); + } + + @ParameterizedTest + @MethodSource("shiftRightProvider") + void shiftRight(UInt384 value, int distance, UInt384 expected) { + assertValueEquals(expected, value.shiftRight(distance)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream shiftRightProvider() { + return Stream + .of( + Arguments.of(hv("0x01"), 1, hv("0x00")), + Arguments.of(hv("0x10"), 1, hv("0x08")), + Arguments.of(hv("0x10"), 2, hv("0x04")), + Arguments.of(hv("0x10"), 8, hv("0x00")), + Arguments.of(hv("0x1000"), 4, hv("0x0100")), + Arguments.of(hv("0x1000"), 5, hv("0x0080")), + Arguments.of(hv("0x1000"), 8, hv("0x0010")), + Arguments.of(hv("0x1000"), 9, hv("0x0008")), + Arguments.of(hv("0x1000"), 16, hv("0x0000")), + Arguments.of(hv("0x00FF00"), 4, hv("0x000FF0")), + Arguments.of(hv("0x00FF00"), 8, hv("0x0000FF")), + Arguments.of(hv("0x00FF00"), 1, hv("0x007F80")), + Arguments + .of( + hv("0x1000000000000000000000000000000000000000000000000000000000000000"), + 16, + hv("0x0000100000000000000000000000000000000000000000000000000000000000")), + Arguments + .of( + hv("0x1000000000000000000000000000000000000000000000000000000000000000"), + 15, + hv("0x0000200000000000000000000000000000000000000000000000000000000000")), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 55, + hv("0x00000000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000"), + 202, + hv("0x000000000000000000000000000000000000000000000000003FFFFFFFFFFFFF"))); + } + + @ParameterizedTest + @MethodSource("intValueProvider") + void intValue(UInt384 value, int expected) { + assertEquals(expected, value.intValue()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream intValueProvider() { + return Stream + .of( + Arguments.of(hv("0x"), 0), + Arguments.of(hv("0x00"), 0), + Arguments.of(hv("0x00000000"), 0), + Arguments.of(hv("0x01"), 1), + Arguments.of(hv("0x0001"), 1), + Arguments.of(hv("0x000001"), 1), + Arguments.of(hv("0x00000001"), 1), + Arguments.of(hv("0x0100"), 256), + Arguments.of(hv("0x000100"), 256), + Arguments.of(hv("0x00000100"), 256)); + } + + @Test + void shouldThrowForIntValueOfOversizeValue() { + Throwable exception = assertThrows(ArithmeticException.class, () -> hv("0x0100000000").intValue()); + assertEquals("Value does not fit a 4 byte int", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("longValueProvider") + void longValue(UInt384 value, long expected) { + assertEquals(expected, value.toLong()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream longValueProvider() { + return Stream + .of( + Arguments.of(hv("0x"), 0L), + Arguments.of(hv("0x00"), 0L), + Arguments.of(hv("0x00000000"), 0L), + Arguments.of(hv("0x01"), 1L), + Arguments.of(hv("0x0001"), 1L), + Arguments.of(hv("0x000001"), 1L), + Arguments.of(hv("0x00000001"), 1L), + Arguments.of(hv("0x0000000001"), 1L), + Arguments.of(hv("0x000000000001"), 1L), + Arguments.of(hv("0x0100"), 256L), + Arguments.of(hv("0x000100"), 256L), + Arguments.of(hv("0x00000100"), 256L), + Arguments.of(hv("0x00000100"), 256L), + Arguments.of(hv("0x000000000100"), 256L), + Arguments.of(hv("0x00000000000100"), 256L), + Arguments.of(hv("0x0000000000000100"), 256L), + Arguments.of(hv("0xFFFFFFFF"), (1L << 32) - 1)); + } + + @Test + void shouldThrowForLongValueOfOversizeValue() { + Throwable exception = assertThrows(ArithmeticException.class, () -> hv("0x010000000000000000").toLong()); + assertEquals("Value does not fit a 8 byte long", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("compareToProvider") + void compareTo(UInt384 v1, UInt384 v2, int expected) { + assertEquals(expected, v1.compareTo(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream compareToProvider() { + return Stream + .of( + Arguments.of(v(5), v(5), 0), + Arguments.of(v(5), v(3), 1), + Arguments.of(v(5), v(6), -1), + Arguments + .of( + hv("0x0000000000000000000000000000000000000000000000000000000000000000"), + hv("0x0000000000000000000000000000000000000000000000000000000000000000"), + 0), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 0), + Arguments + .of( + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 0), + Arguments + .of( + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0x0000000000000000000000000000000000000000000000000000000000000000"), + 1), + Arguments + .of( + hv("0x0000000000000000000000000000000000000000000000000000000000000000"), + hv("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + -1), + Arguments + .of( + hv("0x000000000000000000000000000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + 1), + Arguments + .of( + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"), + hv("0x000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), + -1)); + } + + @ParameterizedTest + @MethodSource("toBytesProvider") + void toBytesTest(UInt384 value, Bytes expected) { + assertEquals(expected, value.toBytes()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream toBytesProvider() { + return Stream + .of( + Arguments + .of( + hv("0x00"), + Bytes + .fromHexString( + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")), + Arguments + .of( + hv("0x01000000"), + Bytes + .fromHexString( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000")), + Arguments + .of( + hv("0x0100000000"), + Bytes + .fromHexString( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000")), + Arguments + .of( + hv("0xf100000000ab"), + Bytes + .fromHexString( + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000f100000000ab")), + Arguments + .of( + hv("0x0400000000000000000000000000000000000000000000000000f100000000ab"), + Bytes + .fromHexString( + "0x000000000000000000000000000000000400000000000000000000000000000000000000000000000000f100000000ab"))); + } + + @ParameterizedTest + @MethodSource("toMinimalBytesProvider") + void toMinimalBytesTest(UInt384 value, Bytes expected) { + assertEquals(expected, value.toMinimalBytes()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream toMinimalBytesProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), Bytes.EMPTY), + Arguments.of(hv("0x01000000"), Bytes.fromHexString("0x01000000")), + Arguments.of(hv("0x0100000000"), Bytes.fromHexString("0x0100000000")), + Arguments.of(hv("0xf100000000ab"), Bytes.fromHexString("0xf100000000ab")), + Arguments + .of( + hv("0x0400000000000000000000000000000000000000000000000000f100000000ab"), + Bytes.fromHexString("0x0400000000000000000000000000000000000000000000000000f100000000ab"))); + } + + @ParameterizedTest + @MethodSource("numberOfLeadingZerosProvider") + void numberOfLeadingZeros(UInt384 value, int expected) { + assertEquals(expected, value.numberOfLeadingZeros()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream numberOfLeadingZerosProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), 384), + Arguments.of(hv("0x01"), 383), + Arguments.of(hv("0x02"), 382), + Arguments.of(hv("0x03"), 382), + Arguments.of(hv("0x0F"), 380), + Arguments.of(hv("0x8F"), 376), + Arguments.of(hv("0x100000000"), 351)); + } + + @ParameterizedTest + @MethodSource("bitLengthProvider") + void bitLength(UInt384 value, int expected) { + assertEquals(expected, value.bitLength()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream bitLengthProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), 0), + Arguments.of(hv("0x01"), 1), + Arguments.of(hv("0x02"), 2), + Arguments.of(hv("0x03"), 2), + Arguments.of(hv("0x0F"), 4), + Arguments.of(hv("0x8F"), 8), + Arguments.of(hv("0x100000000"), 33)); + } + + @ParameterizedTest + @MethodSource("addExactProvider") + void addExact(UInt384 value, UInt384 operand) { + assertThrows(ArithmeticException.class, () -> value.addExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addExactProvider() { + return Stream.of(Arguments.of(UInt384.MAX_VALUE, v(1)), Arguments.of(UInt384.MAX_VALUE, UInt384.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addExactLongProvider") + void addExactLong(UInt384 value, long operand) { + assertThrows(ArithmeticException.class, () -> value.addExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addExactLongProvider() { + return Stream + .of( + Arguments.of(UInt384.MAX_VALUE, 3), + Arguments.of(UInt384.MAX_VALUE, Long.MAX_VALUE), + Arguments.of(v(0), -1)); + } + + @ParameterizedTest + @MethodSource("subtractExactProvider") + void subtractExact(UInt384 value, UInt384 operand) { + assertThrows(ArithmeticException.class, () -> value.subtractExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractExactProvider() { + return Stream.of(Arguments.of(v(0), v(1)), Arguments.of(v(0), UInt384.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("subtractExactLongProvider") + void subtractExactLong(UInt384 value, long operand) { + assertThrows(ArithmeticException.class, () -> value.subtractExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractExactLongProvider() { + return Stream.of(Arguments.of(v(0), 1), Arguments.of(v(0), Long.MAX_VALUE), Arguments.of(UInt384.MAX_VALUE, -1)); + } + + private void assertValueEquals(UInt384 expected, UInt384 actual) { + String msg = String.format("Expected %s but got %s", expected.toHexString(), actual.toHexString()); + assertEquals(expected, actual, msg); + } + + @Test + void testToDecimalString() { + assertEquals("3456", UInt384.valueOf(3456).toDecimalString()); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/UInt64Test.java b/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/UInt64Test.java new file mode 100644 index 00000000000..3ab00c5436b --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/apache/tuweni/units/bigints/UInt64Test.java @@ -0,0 +1,855 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE + * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file + * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.apache.tuweni.units.bigints; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.math.BigInteger; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class UInt64Test { + + private static UInt64 v(long v) { + return UInt64.valueOf(v); + } + + private static UInt64 hv(String s) { + return UInt64.fromHexString(s); + } + + + private static Bytes b(String s) { + return Bytes.fromHexString(s); + } + + @Test + void valueOfLong() { + assertThrows(IllegalArgumentException.class, () -> UInt64.valueOf(-1)); + assertThrows(IllegalArgumentException.class, () -> UInt64.valueOf(Long.MIN_VALUE)); + assertThrows(IllegalArgumentException.class, () -> UInt64.valueOf(~0L)); + } + + @Test + void valueOfBigInteger() { + assertThrows(IllegalArgumentException.class, () -> UInt64.valueOf(BigInteger.valueOf(-1))); + assertThrows(IllegalArgumentException.class, () -> UInt64.valueOf(BigInteger.valueOf(2).pow(64))); + } + + @ParameterizedTest + @MethodSource("addProvider") + void add(UInt64 v1, UInt64 v2, UInt64 expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addProvider() { + return Stream + .of( + Arguments.of(v(1), v(0), v(1)), + Arguments.of(v(5), v(0), v(5)), + Arguments.of(v(0), v(1), v(1)), + Arguments.of(v(0), v(100), v(100)), + Arguments.of(v(2), v(2), v(4)), + Arguments.of(v(100), v(90), v(190)), + Arguments.of(UInt64.MAX_VALUE, v(1), v(0)), + Arguments.of(UInt64.MAX_VALUE, v(2), v(1)), + Arguments.of(hv("0xFFFFFFFFFFFFFFF0"), v(1), hv("0xFFFFFFFFFFFFFFF1")), + Arguments.of(hv("0xFFFFFFFFFFFFFFFE"), v(1), UInt64.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addLongProvider") + void addLong(UInt64 v1, long v2, UInt64 expected) { + assertValueEquals(expected, v1.add(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addLongProvider() { + return Stream + .of( + Arguments.of(v(1), 0L, v(1)), + Arguments.of(v(5), 0L, v(5)), + Arguments.of(v(0), 1L, v(1)), + Arguments.of(v(0), 100L, v(100)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(100), 90L, v(190)), + Arguments.of(UInt64.MAX_VALUE, 1L, v(0)), + Arguments.of(UInt64.MAX_VALUE, 2L, v(1)), + Arguments.of(hv("0xFFFFFFFFFFFFFFF0"), 1L, hv("0xFFFFFFFFFFFFFFF1")), + Arguments.of(hv("0xFFFFFFFFFFFFFFFE"), 1L, UInt64.MAX_VALUE), + Arguments.of(v(10), -5L, v(5)), + Arguments.of(v(0), -1L, UInt64.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addModProvider") + void addMod(UInt64 v1, UInt64 v2, UInt64 m, UInt64 expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModProvider() { + return Stream + .of( + Arguments.of(v(0), v(1), UInt64.valueOf(2), v(1)), + Arguments.of(v(1), v(1), UInt64.valueOf(2), v(0)), + Arguments.of(UInt64.MAX_VALUE.subtract(2), v(1), UInt64.MAX_VALUE, UInt64.MAX_VALUE.subtract(1)), + Arguments.of(UInt64.MAX_VALUE.subtract(1), v(1), UInt64.MAX_VALUE, v(0)), + Arguments.of(v(2), v(1), UInt64.valueOf(2), v(1)), + Arguments.of(v(3), v(2), UInt64.valueOf(6), v(5)), + Arguments.of(v(3), v(4), UInt64.valueOf(2), v(1))); + } + + @Test + void shouldThrowForAddModOfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(v(1), UInt64.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModUInt64UInt64Provider") + void addModUInt64UInt64(UInt64 v1, UInt64 v2, UInt64 m, UInt64 expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModUInt64UInt64Provider() { + return Stream + .of( + Arguments.of(v(0), UInt64.ONE, UInt64.valueOf(2), v(1)), + Arguments.of(v(1), UInt64.ONE, UInt64.valueOf(2), v(0)), + Arguments.of(UInt64.MAX_VALUE.subtract(2), UInt64.ONE, UInt64.MAX_VALUE, UInt64.MAX_VALUE.subtract(1)), + Arguments.of(UInt64.MAX_VALUE.subtract(1), UInt64.ONE, UInt64.MAX_VALUE, v(0)), + Arguments.of(v(2), UInt64.ONE, UInt64.valueOf(2), v(1)), + Arguments.of(v(3), UInt64.valueOf(2), UInt64.valueOf(6), v(5)), + Arguments.of(v(3), UInt64.valueOf(4), UInt64.valueOf(2), v(1))); + } + + @Test + void shouldThrowForAddModLongUInt64OfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, UInt64.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModLongUInt64Provider") + void addModLongUInt64(UInt64 v1, long v2, UInt64 m, UInt64 expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModLongUInt64Provider() { + return Stream + .of( + Arguments.of(v(0), 1L, UInt64.valueOf(2), v(1)), + Arguments.of(v(1), 1L, UInt64.valueOf(2), v(0)), + Arguments.of(UInt64.MAX_VALUE.subtract(2), 1L, UInt64.MAX_VALUE, UInt64.MAX_VALUE.subtract(1)), + Arguments.of(UInt64.MAX_VALUE.subtract(1), 1L, UInt64.MAX_VALUE, v(0)), + Arguments.of(v(2), 1L, UInt64.valueOf(2), v(1)), + Arguments.of(v(2), -1L, UInt64.valueOf(2), v(1)), + Arguments.of(v(1), -7L, UInt64.valueOf(5), v(4))); + } + + @Test + void shouldThrowForAddModUInt64UInt64OfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(UInt64.ONE, UInt64.ZERO)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("addModLongLongProvider") + void addModLongLong(UInt64 v1, long v2, long m, UInt64 expected) { + assertValueEquals(expected, v1.addMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addModLongLongProvider() { + return Stream + .of(Arguments.of(v(0), 1L, 2L, v(1)), Arguments.of(v(1), 1L, 2L, v(0)), Arguments.of(v(2), 1L, 2L, v(1))); + } + + @Test + void shouldThrowForAddModLongLongOfZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, 0)); + assertEquals("addMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForAddModLongLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).addMod(1, -5)); + assertEquals("addMod unsigned with negative modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("subtractProvider") + void subtract(UInt64 v1, UInt64 v2, UInt64 expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractProvider() { + return Stream + .of( + Arguments.of(v(1), v(0), v(1)), + Arguments.of(v(5), v(0), v(5)), + Arguments.of(v(2), v(1), v(1)), + Arguments.of(v(100), v(100), v(0)), + Arguments.of(v(0), v(1), UInt64.MAX_VALUE), + Arguments.of(v(1), v(2), UInt64.MAX_VALUE), + Arguments.of(UInt64.MAX_VALUE, v(1), hv("0xFFFFFFFFFFFFFFFE"))); + } + + @ParameterizedTest + @MethodSource("subtractLongProvider") + void subtractLong(UInt64 v1, long v2, UInt64 expected) { + assertValueEquals(expected, v1.subtract(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractLongProvider() { + return Stream + .of( + Arguments.of(v(1), 0L, v(1)), + Arguments.of(v(5), 0L, v(5)), + Arguments.of(v(2), 1L, v(1)), + Arguments.of(v(100), 100L, v(0)), + Arguments.of(v(0), 1L, UInt64.MAX_VALUE), + Arguments.of(v(1), 2L, UInt64.MAX_VALUE), + Arguments.of(UInt64.MAX_VALUE, 1L, hv("0xFFFFFFFFFFFFFFFE")), + Arguments.of(v(0), -1L, v(1)), + Arguments.of(v(0), -100L, v(100)), + Arguments.of(v(2), -2L, v(4))); + } + + @ParameterizedTest + @MethodSource("multiplyProvider") + void multiply(UInt64 v1, UInt64 v2, UInt64 expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyProvider() { + return Stream + .of( + Arguments.of(v(0), v(2), v(0)), + Arguments.of(v(1), v(2), v(2)), + Arguments.of(v(2), v(2), v(4)), + Arguments.of(v(3), v(2), v(6)), + Arguments.of(v(4), v(2), v(8)), + Arguments.of(v(10), v(18), v(180)), + Arguments.of(v(2), v(8), v(16)), + Arguments.of(v(7), v(8), v(56)), + Arguments.of(v(8), v(8), v(64)), + Arguments.of(v(17), v(8), v(136)), + Arguments.of(v(22), v(0), v(0))); + } + + @ParameterizedTest + @MethodSource("multiplyLongProvider") + void multiplyLong(UInt64 v1, long v2, UInt64 expected) { + assertValueEquals(expected, v1.multiply(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(2)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(3), 2L, v(6)), + Arguments.of(v(4), 2L, v(8)), + Arguments.of(v(10), 18L, v(180)), + Arguments.of(v(2), 8L, v(16)), + Arguments.of(v(7), 8L, v(56)), + Arguments.of(v(8), 8L, v(64)), + Arguments.of(v(17), 8L, v(136)), + Arguments.of(v(22), 0L, v(0)), + Arguments.of(hv("0x0FFFFFFFFFFFFFFF"), 2L, hv("0x1FFFFFFFFFFFFFFE")), + Arguments.of(hv("0xFFFFFFFFFFFFFFFF"), 2L, hv("0xFFFFFFFFFFFFFFFE"))); + } + + @Test + void shouldThrowForMultiplyLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(2).multiply(-5)); + assertEquals("multiply unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModProvider") + void multiplyMod(UInt64 v1, UInt64 v2, UInt64 m, UInt64 expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModProvider() { + return Stream + .of( + Arguments.of(v(0), v(5), UInt64.valueOf(2), v(0)), + Arguments.of(v(2), v(3), UInt64.valueOf(7), v(6)), + Arguments.of(v(2), v(3), UInt64.valueOf(6), v(0)), + Arguments.of(v(2), v(0), UInt64.valueOf(6), v(0)), + Arguments.of(hv("0x0FFFFFFFFFFFFFFE"), v(2), UInt64.MAX_VALUE, hv("0x1FFFFFFFFFFFFFFC"))); + } + + @Test + void shouldThrowForMultiplyModOfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(0).multiplyMod(v(1), UInt64.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModLongUInt64Provider") + void multiplyModLongUInt64(UInt64 v1, long v2, UInt64 m, UInt64 expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModLongUInt64Provider() { + return Stream + .of( + Arguments.of(v(0), 5L, UInt64.valueOf(2), v(0)), + Arguments.of(v(2), 3L, UInt64.valueOf(7), v(6)), + Arguments.of(v(2), 3L, UInt64.valueOf(6), v(0)), + Arguments.of(v(2), 0L, UInt64.valueOf(6), v(0)), + Arguments.of(hv("0x0FFFFFFFFFFFFFFE"), 2L, UInt64.MAX_VALUE, hv("0x1FFFFFFFFFFFFFFC"))); + } + + @Test + void shouldThrowForMultiplyModLongUInt64OfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).multiplyMod(1L, UInt64.ZERO)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongUInt64OfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(3).multiplyMod(-1, UInt64.valueOf(2))); + assertEquals("multiplyMod unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("multiplyModLongLongProvider") + void multiplyModLongLong(UInt64 v1, long v2, long m, UInt64 expected) { + assertValueEquals(expected, v1.multiplyMod(v2, m)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream multiplyModLongLongProvider() { + return Stream + .of( + Arguments.of(v(0), 5L, 2L, v(0)), + Arguments.of(v(2), 3L, 7L, v(6)), + Arguments.of(v(2), 3L, 6L, v(0)), + Arguments.of(v(2), 0L, 6L, v(0)), + Arguments.of(hv("0x0FFFFFFFFFFFFFFE"), 2L, Long.MAX_VALUE, hv("0x1FFFFFFFFFFFFFFC"))); + } + + @Test + void shouldThrowForMultiplyModLongLongOfModZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).multiplyMod(1, 0)); + assertEquals("multiplyMod with zero modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongLongOfModNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(2).multiplyMod(5, -7)); + assertEquals("multiplyMod unsigned with negative modulus", exception.getMessage()); + } + + @Test + void shouldThrowForMultiplyModLongLongOfNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(3).multiplyMod(-1, 2)); + assertEquals("multiplyMod unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideProvider") + void divide(UInt64 v1, UInt64 v2, UInt64 expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideProvider() { + return Stream + .of( + Arguments.of(v(0), v(2), v(0)), + Arguments.of(v(1), v(2), v(0)), + Arguments.of(v(2), v(2), v(1)), + Arguments.of(v(3), v(2), v(1)), + Arguments.of(v(4), v(2), v(2)), + Arguments.of(v(2), v(8), v(0)), + Arguments.of(v(7), v(8), v(0)), + Arguments.of(v(8), v(8), v(1)), + Arguments.of(v(9), v(8), v(1)), + Arguments.of(v(17), v(8), v(2)), + Arguments.of(v(1024), v(8), v(128)), + Arguments.of(v(1026), v(8), v(128))); + } + + @Test + void shouldThrowForDivideByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(v(0))); + assertEquals("divide by zero", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("divideLongProvider") + void divideLong(UInt64 v1, long v2, UInt64 expected) { + assertValueEquals(expected, v1.divide(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream divideLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(0)), + Arguments.of(v(2), 2L, v(1)), + Arguments.of(v(3), 2L, v(1)), + Arguments.of(v(4), 2L, v(2)), + Arguments.of(v(2), 8L, v(0)), + Arguments.of(v(7), 8L, v(0)), + Arguments.of(v(8), 8L, v(1)), + Arguments.of(v(9), 8L, v(1)), + Arguments.of(v(17), 8L, v(2)), + Arguments.of(v(1024), 8L, v(128)), + Arguments.of(v(1026), 8L, v(128))); + } + + @Test + void shouldThrowForDivideLongByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(0)); + assertEquals("divide by zero", exception.getMessage()); + } + + @Test + void shouldThrowForDivideLongByNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).divide(-5)); + assertEquals("divide unsigned by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("powUInt64Provider") + void powUInt64(UInt64 v1, UInt64 v2, UInt64 expected) { + assertValueEquals(expected, v1.pow(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream powUInt64Provider() { + return Stream + .of( + Arguments.of(v(0), UInt64.valueOf(2), v(0)), + Arguments.of(v(2), UInt64.valueOf(2), v(4)), + Arguments.of(v(2), UInt64.valueOf(8), v(256)), + Arguments.of(v(3), UInt64.valueOf(3), v(27)), + Arguments.of(hv("0xFFFFFFFFFFF0F0F0"), UInt64.valueOf(3), hv("0xF2A920E119A2F000"))); + } + + @ParameterizedTest + @MethodSource("powLongProvider") + void powLong(UInt64 v1, long v2, UInt64 expected) { + assertValueEquals(expected, v1.pow(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream powLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(2), 2L, v(4)), + Arguments.of(v(2), 8L, v(256)), + Arguments.of(v(3), 3L, v(27)), + Arguments.of(hv("0xFFFFFFFFFFF0F0F0"), 3L, hv("0xF2A920E119A2F000"))); + } + + @ParameterizedTest + @MethodSource("modLongProvider") + void modLong(UInt64 v1, long v2, UInt64 expected) { + assertValueEquals(expected, v1.mod(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream modLongProvider() { + return Stream + .of( + Arguments.of(v(0), 2L, v(0)), + Arguments.of(v(1), 2L, v(1)), + Arguments.of(v(2), 2L, v(0)), + Arguments.of(v(3), 2L, v(1)), + Arguments.of(v(0), 8L, v(0)), + Arguments.of(v(1), 8L, v(1)), + Arguments.of(v(2), 8L, v(2)), + Arguments.of(v(3), 8L, v(3)), + Arguments.of(v(7), 8L, v(7)), + Arguments.of(v(8), 8L, v(0)), + Arguments.of(v(9), 8L, v(1)), + Arguments.of(v(1024), 8L, v(0)), + Arguments.of(v(1026), 8L, v(2))); + } + + @Test + void shouldThrowForModLongByZero() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(0)); + assertEquals("mod by zero", exception.getMessage()); + } + + @Test + void shouldThrowForModLongByNegative() { + Throwable exception = assertThrows(ArithmeticException.class, () -> v(5).mod(-5)); + assertEquals("mod by negative", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("andProvider") + void and(UInt64 v1, Object v2, UInt64 expected) { + if (v2 instanceof UInt64) { + assertValueEquals(expected, v1.and((UInt64) v2)); + } else if (v2 instanceof Bytes) { + assertValueEquals(expected, v1.and((Bytes) v2)); + } else { + throw new IllegalArgumentException(v2.getClass().getName()); + } + } + + @SuppressWarnings("UnusedMethod") + private static Stream andProvider() { + return Stream + .of( + Arguments.of(hv("0x00000000FFFFFFFF"), hv("0xFFFFFFFF00000000"), hv("0x0000000000000000")), + Arguments.of(hv("0x00000000FFFFFFFF"), hv("0xFFFFFFFFFF000000"), hv("0x00000000FF000000")), + Arguments.of(hv("0x00000000FFFFFFFF"), b("0xFFFFFFFFFF000000"), hv("0x00000000FF000000"))); + } + + @ParameterizedTest + @MethodSource("orProvider") + void or(UInt64 v1, Object v2, UInt64 expected) { + if (v2 instanceof UInt64) { + assertValueEquals(expected, v1.or((UInt64) v2)); + } else if (v2 instanceof Bytes) { + assertValueEquals(expected, v1.or((Bytes) v2)); + } else { + throw new IllegalArgumentException(v2.getClass().getName()); + } + } + + @SuppressWarnings("UnusedMethod") + private static Stream orProvider() { + return Stream + .of( + Arguments.of(hv("0x00000000FFFFFFFF"), hv("0xFFFFFFFF00000000"), hv("0xFFFFFFFFFFFFFFFF")), + Arguments.of(hv("0x00000000FFFFFFFF"), hv("0xFFFFFFFF00000000"), hv("0xFFFFFFFFFFFFFFFF")), + Arguments.of(hv("0x00000000000000FF"), hv("0xFFFFFFFF00000000"), hv("0xFFFFFFFF000000FF")), + Arguments.of(hv("0x00000000000000FF"), b("0xFFFFFFFF00000000"), hv("0xFFFFFFFF000000FF"))); + } + + @ParameterizedTest + @MethodSource("xorProvider") + void xor(UInt64 v1, Object v2, UInt64 expected) { + if (v2 instanceof UInt64) { + assertValueEquals(expected, v1.xor((UInt64) v2)); + } else if (v2 instanceof Bytes) { + assertValueEquals(expected, v1.xor((Bytes) v2)); + } else { + throw new IllegalArgumentException(v2.getClass().getName()); + } + } + + @SuppressWarnings("UnusedMethod") + private static Stream xorProvider() { + return Stream + .of( + Arguments.of(hv("0xFFFFFFFFFFFFFFFF"), hv("0xFFFFFFFFFFFFFFFF"), hv("0x0000000000000000")), + Arguments.of(hv("0x00000000FFFFFFFF"), hv("0xFFFFFFFF00000000"), hv("0xFFFFFFFFFFFFFFFF")), + Arguments.of(hv("0x00000000FFFFFFFF"), hv("0xFFFFFFFFFF000000"), hv("0xFFFFFFFF00FFFFFF")), + Arguments.of(hv("0x00000000FFFFFFFF"), b("0xFFFFFFFFFF000000"), hv("0xFFFFFFFF00FFFFFF"))); + } + + @ParameterizedTest + @MethodSource("notProvider") + void not(UInt64 value, UInt64 expected) { + assertValueEquals(expected, value.not()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream notProvider() { + return Stream + .of( + Arguments.of(hv("0xFFFFFFFFFFFFFFFF"), hv("0x0000000000000000")), + Arguments.of(hv("0x0000000000000000"), hv("0xFFFFFFFFFFFFFFFF")), + Arguments.of(hv("0x00000000FFFFFFFF"), hv("0xFFFFFFFF00000000"))); + } + + @ParameterizedTest + @MethodSource("shiftLeftProvider") + void shiftLeft(UInt64 value, int distance, UInt64 expected) { + assertValueEquals(expected, value.shiftLeft(distance)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream shiftLeftProvider() { + return Stream + .of( + Arguments.of(hv("0x01"), 1, hv("0x02")), + Arguments.of(hv("0x01"), 2, hv("0x04")), + Arguments.of(hv("0x01"), 8, hv("0x0100")), + Arguments.of(hv("0x01"), 9, hv("0x0200")), + Arguments.of(hv("0x01"), 16, hv("0x10000")), + Arguments.of(hv("0x00FF00"), 4, hv("0x0FF000")), + Arguments.of(hv("0x00FF00"), 8, hv("0xFF0000")), + Arguments.of(hv("0x00FF00"), 1, hv("0x01FE00")), + Arguments.of(hv("0x0000000000000001"), 16, hv("0x0000000000010000")), + Arguments.of(hv("0x0000000000000001"), 15, hv("0x0000000000008000")), + Arguments.of(hv("0xFFFFFFFFFFFFFFFF"), 55, hv("0xFF80000000000000")), + Arguments.of(hv("0x00000000FFFFFFFF"), 50, hv("0xFFFC000000000000"))); + } + + @ParameterizedTest + @MethodSource("shiftRightProvider") + void shiftRight(UInt64 value, int distance, UInt64 expected) { + assertValueEquals(expected, value.shiftRight(distance)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream shiftRightProvider() { + return Stream + .of( + Arguments.of(hv("0x01"), 1, hv("0x00")), + Arguments.of(hv("0x10"), 1, hv("0x08")), + Arguments.of(hv("0x10"), 2, hv("0x04")), + Arguments.of(hv("0x10"), 8, hv("0x00")), + Arguments.of(hv("0x1000"), 4, hv("0x0100")), + Arguments.of(hv("0x1000"), 5, hv("0x0080")), + Arguments.of(hv("0x1000"), 8, hv("0x0010")), + Arguments.of(hv("0x1000"), 9, hv("0x0008")), + Arguments.of(hv("0x1000"), 16, hv("0x0000")), + Arguments.of(hv("0x00FF00"), 4, hv("0x000FF0")), + Arguments.of(hv("0x00FF00"), 8, hv("0x0000FF")), + Arguments.of(hv("0x00FF00"), 1, hv("0x007F80")), + Arguments.of(hv("0x1000000000000000"), 16, hv("0x0000100000000000")), + Arguments.of(hv("0x1000000000000000"), 15, hv("0x0000200000000000")), + Arguments.of(hv("0xFFFFFFFFFFFFFFFF"), 55, hv("0x00000000000001FF")), + Arguments.of(hv("0xFFFFFFFFFFFFFFFF"), 202, hv("0x0000000000000000"))); + } + + @ParameterizedTest + @MethodSource("intValueProvider") + void intValue(UInt64 value, int expected) { + assertEquals(expected, value.intValue()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream intValueProvider() { + return Stream + .of( + Arguments.of(hv("0x"), 0), + Arguments.of(hv("0x00"), 0), + Arguments.of(hv("0x00000000"), 0), + Arguments.of(hv("0x01"), 1), + Arguments.of(hv("0x0001"), 1), + Arguments.of(hv("0x000001"), 1), + Arguments.of(hv("0x00000001"), 1), + Arguments.of(hv("0x0100"), 256), + Arguments.of(hv("0x000100"), 256), + Arguments.of(hv("0x00000100"), 256)); + } + + @Test + void shouldThrowForIntValueOfOversizeValue() { + Throwable exception = assertThrows(ArithmeticException.class, () -> hv("0x0100000000").intValue()); + assertEquals("Value does not fit a 4 byte int", exception.getMessage()); + } + + @ParameterizedTest + @MethodSource("longValueProvider") + void longValue(UInt64 value, long expected) { + assertEquals(expected, value.toLong()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream longValueProvider() { + return Stream + .of( + Arguments.of(hv("0x"), 0L), + Arguments.of(hv("0x00"), 0L), + Arguments.of(hv("0x00000000"), 0L), + Arguments.of(hv("0x01"), 1L), + Arguments.of(hv("0x0001"), 1L), + Arguments.of(hv("0x000001"), 1L), + Arguments.of(hv("0x00000001"), 1L), + Arguments.of(hv("0x0000000001"), 1L), + Arguments.of(hv("0x000000000001"), 1L), + Arguments.of(hv("0x0100"), 256L), + Arguments.of(hv("0x000100"), 256L), + Arguments.of(hv("0x00000100"), 256L), + Arguments.of(hv("0x00000100"), 256L), + Arguments.of(hv("0x000000000100"), 256L), + Arguments.of(hv("0x00000000000100"), 256L), + Arguments.of(hv("0x00000000000100"), 256L), + Arguments.of(hv("0xFFFFFFFF"), (1L << 32) - 1)); + } + + @ParameterizedTest + @MethodSource("compareToProvider") + void compareTo(UInt64 v1, UInt64 v2, int expected) { + assertEquals(expected, v1.compareTo(v2)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream compareToProvider() { + return Stream + .of( + Arguments.of(v(5), v(5), 0), + Arguments.of(v(5), v(3), 1), + Arguments.of(v(5), v(6), -1), + Arguments.of(hv("0x0000000000000000"), hv("0x0000000000000000"), 0), + Arguments.of(hv("0xFFFFFFFFFFFFFFFF"), hv("0xFFFFFFFFFFFFFFFF"), 0), + Arguments.of(hv("0x00000000FFFFFFFF"), hv("0x00000000FFFFFFFF"), 0), + Arguments.of(hv("0xFFFFFFFFFFFFFFFF"), hv("0x0000000000000000"), 1), + Arguments.of(hv("0x0000000000000000"), hv("0xFFFFFFFFFFFFFFFF"), -1), + Arguments.of(hv("0x00000001FFFFFFFF"), hv("0x00000000FFFFFFFF"), 1), + Arguments.of(hv("0x00000000FFFFFFFE"), hv("0x00000000FFFFFFFF"), -1)); + } + + @ParameterizedTest + @MethodSource("toBytesProvider") + void toBytesTest(UInt64 value, Bytes expected) { + assertEquals(expected, value.toBytes()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream toBytesProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), Bytes.fromHexString("0x0000000000000000")), + Arguments.of(hv("0x01000000"), Bytes.fromHexString("0x0000000001000000")), + Arguments.of(hv("0x0100000000"), Bytes.fromHexString("0x0000000100000000")), + Arguments.of(hv("0xf100000000ab"), Bytes.fromHexString("0x0000F100000000AB"))); + } + + @ParameterizedTest + @MethodSource("toMinimalBytesProvider") + void toMinimalBytesTest(UInt64 value, Bytes expected) { + assertEquals(expected, value.toMinimalBytes()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream toMinimalBytesProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), Bytes.EMPTY), + Arguments.of(hv("0x01000000"), Bytes.fromHexString("0x01000000")), + Arguments.of(hv("0x0100000000"), Bytes.fromHexString("0x0100000000")), + Arguments.of(hv("0xf100000000ab"), Bytes.fromHexString("0xf100000000ab")), + Arguments.of(hv("0100000000000000"), Bytes.fromHexString("0x0100000000000000"))); + } + + @ParameterizedTest + @MethodSource("numberOfLeadingZerosProvider") + void numberOfLeadingZeros(UInt64 value, int expected) { + assertEquals(expected, value.numberOfLeadingZeros()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream numberOfLeadingZerosProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), 64), + Arguments.of(hv("0x01"), 63), + Arguments.of(hv("0x02"), 62), + Arguments.of(hv("0x03"), 62), + Arguments.of(hv("0x0F"), 60), + Arguments.of(hv("0x8F"), 56), + Arguments.of(hv("0x100000000"), 31)); + } + + @ParameterizedTest + @MethodSource("bitLengthProvider") + void bitLength(UInt64 value, int expected) { + assertEquals(expected, value.bitLength()); + } + + @SuppressWarnings("UnusedMethod") + private static Stream bitLengthProvider() { + return Stream + .of( + Arguments.of(hv("0x00"), 0), + Arguments.of(hv("0x01"), 1), + Arguments.of(hv("0x02"), 2), + Arguments.of(hv("0x03"), 2), + Arguments.of(hv("0x0F"), 4), + Arguments.of(hv("0x8F"), 8), + Arguments.of(hv("0x100000000"), 33)); + } + + @ParameterizedTest + @MethodSource("addExactProvider") + void addExact(UInt64 value, UInt64 operand) { + assertThrows(ArithmeticException.class, () -> value.addExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addExactProvider() { + return Stream.of(Arguments.of(UInt64.MAX_VALUE, v(1)), Arguments.of(UInt64.MAX_VALUE, UInt64.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("addExactLongProvider") + void addExactLong(UInt64 value, long operand) { + assertThrows(ArithmeticException.class, () -> value.addExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream addExactLongProvider() { + return Stream + .of(Arguments.of(UInt64.MAX_VALUE, 3), Arguments.of(UInt64.MAX_VALUE, Long.MAX_VALUE), Arguments.of(v(0), -1)); + } + + @ParameterizedTest + @MethodSource("subtractExactProvider") + void subtractExact(UInt64 value, UInt64 operand) { + assertThrows(ArithmeticException.class, () -> value.subtractExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractExactProvider() { + return Stream.of(Arguments.of(v(0), v(1)), Arguments.of(v(0), UInt64.MAX_VALUE)); + } + + @ParameterizedTest + @MethodSource("subtractExactLongProvider") + void subtractExactLong(UInt64 value, long operand) { + assertThrows(ArithmeticException.class, () -> value.subtractExact(operand)); + } + + @SuppressWarnings("UnusedMethod") + private static Stream subtractExactLongProvider() { + return Stream.of(Arguments.of(v(0), 1), Arguments.of(v(0), Long.MAX_VALUE), Arguments.of(UInt64.MAX_VALUE, -1)); + } + + private void assertValueEquals(UInt64 expected, UInt64 actual) { + String msg = String.format("Expected %s but got %s", expected.toHexString(), actual.toHexString()); + assertEquals(expected, actual, msg); + } + + @Test + void testToDecimalString() { + assertEquals("3456", UInt64.valueOf(3456).toDecimalString()); + } +} \ No newline at end of file diff --git a/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/AbstractKeyValueStorageTest.java b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/AbstractKeyValueStorageTest.java new file mode 100644 index 00000000000..1235e039bcf --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/AbstractKeyValueStorageTest.java @@ -0,0 +1,417 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.commons.lang3.tuple.Pair; +import org.apache.tuweni.bytes.Bytes; +import org.hyperledger.besu.storage.KeyValueStorage; +import org.hyperledger.besu.storage.KeyValueStorageTransaction; +import org.junit.Ignore; +import org.junit.Test; + +import java.util.*; +import java.util.concurrent.CountDownLatch; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; + +@Ignore +public abstract class AbstractKeyValueStorageTest { + + protected abstract KeyValueStorage createStore() throws Exception; + + @Test + public void twoStoresAreIndependent() throws Exception { + final KeyValueStorage store1 = createStore(); + final KeyValueStorage store2 = createStore(); + + final KeyValueStorageTransaction tx = store1.startTransaction(); + final byte[] key = bytesFromHexString("0001"); + final byte[] value = bytesFromHexString("0FFF"); + + tx.put(key, value); + tx.commit(); + + final Optional result = store2.get(key); + assertThat(result).isEmpty(); + } + + @Test + public void put() throws Exception { + final KeyValueStorage store = createStore(); + final byte[] key = bytesFromHexString("0F"); + final byte[] firstValue = bytesFromHexString("0ABC"); + final byte[] secondValue = bytesFromHexString("0DEF"); + + KeyValueStorageTransaction tx = store.startTransaction(); + tx.put(key, firstValue); + tx.commit(); + assertThat(store.get(key)).contains(firstValue); + + tx = store.startTransaction(); + tx.put(key, secondValue); + tx.commit(); + assertThat(store.get(key)).contains(secondValue); + } + + @Test + public void streamKeys() throws Exception { + final KeyValueStorage store = createStore(); + final KeyValueStorageTransaction tx = store.startTransaction(); + final List keys = + Stream.of("0F", "10", "11", "12") + .map(this::bytesFromHexString) + .collect(Collectors.collectingAndThen( + Collectors.toList(), + Collections::unmodifiableList + )); + keys.forEach(key -> tx.put(key, bytesFromHexString("0ABC"))); + tx.commit(); + Set set = store.stream().map(Pair::getKey).collect(Collectors.collectingAndThen( + Collectors.toSet(), + Collections::unmodifiableSet)); + + assertThat(set) + .containsExactlyInAnyOrder(keys.toArray(new byte[][] {})); + } + + @Test + public void getAllKeysThat() throws Exception { + final KeyValueStorage store = createStore(); + final KeyValueStorageTransaction tx = store.startTransaction(); + tx.put(bytesFromHexString("0F"), bytesFromHexString("0ABC")); + tx.put(bytesFromHexString("10"), bytesFromHexString("0ABC")); + tx.put(bytesFromHexString("11"), bytesFromHexString("0ABC")); + tx.put(bytesFromHexString("12"), bytesFromHexString("0ABC")); + tx.commit(); + Set keys = store.getAllKeysThat(bv -> Bytes.wrap(bv).toString().contains("1")); + assertThat(keys.size()).isEqualTo(3); + assertThat(keys) + .containsExactlyInAnyOrder( + bytesFromHexString("10"), bytesFromHexString("11"), bytesFromHexString("12")); + } + + @Test + public void containsKey() throws Exception { + final KeyValueStorage store = createStore(); + final byte[] key = bytesFromHexString("ABCD"); + final byte[] value = bytesFromHexString("DEFF"); + + assertThat(store.containsKey(key)).isFalse(); + + final KeyValueStorageTransaction transaction = store.startTransaction(); + transaction.put(key, value); + transaction.commit(); + + assertThat(store.containsKey(key)).isTrue(); + } + + @Test + public void removeExisting() throws Exception { + final KeyValueStorage store = createStore(); + final byte[] key = bytesFromHexString("0F"); + final byte[] value = bytesFromHexString("0ABC"); + + KeyValueStorageTransaction tx = store.startTransaction(); + tx.put(key, value); + tx.commit(); + + tx = store.startTransaction(); + tx.remove(key); + tx.commit(); + assertThat(store.get(key)).isEmpty(); + } + + @Test + public void removeExistingSameTransaction() throws Exception { + final KeyValueStorage store = createStore(); + final byte[] key = bytesFromHexString("0F"); + final byte[] value = bytesFromHexString("0ABC"); + + KeyValueStorageTransaction tx = store.startTransaction(); + tx.put(key, value); + tx.remove(key); + tx.commit(); + assertThat(store.get(key)).isEmpty(); + } + + @Test + public void removeNonExistent() throws Exception { + final KeyValueStorage store = createStore(); + final byte[] key = bytesFromHexString("0F"); + + KeyValueStorageTransaction tx = store.startTransaction(); + tx.remove(key); + tx.commit(); + assertThat(store.get(key)).isEmpty(); + } + + @Test + public void concurrentUpdate() throws Exception { + final int keyCount = 1000; + final KeyValueStorage store = createStore(); + + final CountDownLatch finishedLatch = new CountDownLatch(2); + final Function updater = + (value) -> + new Thread( + () -> { + try { + for (int i = 0; i < keyCount; i++) { + KeyValueStorageTransaction tx = store.startTransaction(); + tx.put(Bytes.minimalBytes(i).toArrayUnsafe(), value); + tx.commit(); + } + } finally { + finishedLatch.countDown(); + } + }); + + // Run 2 concurrent transactions that write a bunch of values to the same keys + final byte[] a = Bytes.of(10).toArrayUnsafe(); + final byte[] b = Bytes.of(20).toArrayUnsafe(); + updater.apply(a).start(); + updater.apply(b).start(); + + finishedLatch.await(); + + for (int i = 0; i < keyCount; i++) { + final byte[] key = Bytes.minimalBytes(i).toArrayUnsafe(); + final byte[] actual = store.get(key).get(); + assertThat(Arrays.equals(actual, a) || Arrays.equals(actual, b)).isTrue(); + } + + store.close(); + } + + @Test + public void transactionCommit() throws Exception { + final KeyValueStorage store = createStore(); + // Add some values + KeyValueStorageTransaction tx = store.startTransaction(); + tx.put(bytesOf(1), bytesOf(1)); + tx.put(bytesOf(2), bytesOf(2)); + tx.put(bytesOf(3), bytesOf(3)); + tx.commit(); + + // Start transaction that adds, modifies, and removes some values + tx = store.startTransaction(); + tx.put(bytesOf(2), bytesOf(3)); + tx.put(bytesOf(2), bytesOf(4)); + tx.remove(bytesOf(3)); + tx.put(bytesOf(4), bytesOf(8)); + + // Check values before committing have not changed + assertThat(store.get(bytesOf(1))).contains(bytesOf(1)); + assertThat(store.get(bytesOf(2))).contains(bytesOf(2)); + assertThat(store.get(bytesOf(3))).contains(bytesOf(3)); + assertThat(store.get(bytesOf(4))).isEmpty(); + + tx.commit(); + + // Check that values have been updated after commit + assertThat(store.get(bytesOf(1))).contains(bytesOf(1)); + assertThat(store.get(bytesOf(2))).contains(bytesOf(4)); + assertThat(store.get(bytesOf(3))).isEmpty(); + assertThat(store.get(bytesOf(4))).contains(bytesOf(8)); + } + + @Test + public void transactionRollback() throws Exception { + final KeyValueStorage store = createStore(); + // Add some values + KeyValueStorageTransaction tx = store.startTransaction(); + tx.put(bytesOf(1), bytesOf(1)); + tx.put(bytesOf(2), bytesOf(2)); + tx.put(bytesOf(3), bytesOf(3)); + tx.commit(); + + // Start transaction that adds, modifies, and removes some values + tx = store.startTransaction(); + tx.put(bytesOf(2), bytesOf(3)); + tx.put(bytesOf(2), bytesOf(4)); + tx.remove(bytesOf(3)); + tx.put(bytesOf(4), bytesOf(8)); + + // Check values before committing have not changed + assertThat(store.get(bytesOf(1))).contains(bytesOf(1)); + assertThat(store.get(bytesOf(2))).contains(bytesOf(2)); + assertThat(store.get(bytesOf(3))).contains(bytesOf(3)); + assertThat(store.get(bytesOf(4))).isEmpty(); + + tx.rollback(); + + // Check that values have not changed after rollback + assertThat(store.get(bytesOf(1))).contains(bytesOf(1)); + assertThat(store.get(bytesOf(2))).contains(bytesOf(2)); + assertThat(store.get(bytesOf(3))).contains(bytesOf(3)); + assertThat(store.get(bytesOf(4))).isEmpty(); + } + + @Test + public void transactionCommitEmpty() throws Exception { + final KeyValueStorage store = createStore(); + final KeyValueStorageTransaction tx = store.startTransaction(); + tx.commit(); + } + + @Test + public void transactionRollbackEmpty() throws Exception { + final KeyValueStorage store = createStore(); + final KeyValueStorageTransaction tx = store.startTransaction(); + tx.rollback(); + } + + @Test(expected = IllegalStateException.class) + public void transactionPutAfterCommit() throws Exception { + final KeyValueStorage store = createStore(); + final KeyValueStorageTransaction tx = store.startTransaction(); + tx.commit(); + tx.put(bytesOf(1), bytesOf(1)); + } + + @Test(expected = IllegalStateException.class) + public void transactionRemoveAfterCommit() throws Exception { + final KeyValueStorage store = createStore(); + final KeyValueStorageTransaction tx = store.startTransaction(); + tx.commit(); + tx.remove(bytesOf(1)); + } + + @Test(expected = IllegalStateException.class) + public void transactionPutAfterRollback() throws Exception { + final KeyValueStorage store = createStore(); + final KeyValueStorageTransaction tx = store.startTransaction(); + tx.rollback(); + tx.put(bytesOf(1), bytesOf(1)); + } + + @Test(expected = IllegalStateException.class) + public void transactionRemoveAfterRollback() throws Exception { + final KeyValueStorage store = createStore(); + final KeyValueStorageTransaction tx = store.startTransaction(); + tx.rollback(); + tx.remove(bytesOf(1)); + } + + @Test(expected = IllegalStateException.class) + public void transactionCommitAfterRollback() throws Exception { + final KeyValueStorage store = createStore(); + final KeyValueStorageTransaction tx = store.startTransaction(); + tx.rollback(); + tx.commit(); + } + + @Test(expected = IllegalStateException.class) + public void transactionCommitTwice() throws Exception { + final KeyValueStorage store = createStore(); + final KeyValueStorageTransaction tx = store.startTransaction(); + tx.commit(); + tx.commit(); + } + + @Test(expected = IllegalStateException.class) + public void transactionRollbackAfterCommit() throws Exception { + final KeyValueStorage store = createStore(); + final KeyValueStorageTransaction tx = store.startTransaction(); + tx.commit(); + tx.rollback(); + } + + @Test(expected = IllegalStateException.class) + public void transactionRollbackTwice() throws Exception { + final KeyValueStorage store = createStore(); + final KeyValueStorageTransaction tx = store.startTransaction(); + tx.rollback(); + tx.rollback(); + } + + @Test + public void twoTransactions() throws Exception { + final KeyValueStorage store = createStore(); + + final KeyValueStorageTransaction tx1 = store.startTransaction(); + final KeyValueStorageTransaction tx2 = store.startTransaction(); + + tx1.put(bytesOf(1), bytesOf(1)); + tx2.put(bytesOf(2), bytesOf(2)); + + tx1.commit(); + tx2.commit(); + + assertThat(store.get(bytesOf(1))).contains(bytesOf(1)); + assertThat(store.get(bytesOf(2))).contains(bytesOf(2)); + } + + @Test + public void transactionIsolation() throws Exception { + final int keyCount = 1000; + final KeyValueStorage store = createStore(); + + final CountDownLatch finishedLatch = new CountDownLatch(2); + final Function txRunner = + (value) -> + new Thread( + () -> { + final KeyValueStorageTransaction tx = store.startTransaction(); + for (int i = 0; i < keyCount; i++) { + tx.put(Bytes.minimalBytes(i).toArrayUnsafe(), value); + } + try { + tx.commit(); + } finally { + finishedLatch.countDown(); + } + }); + + // Run 2 concurrent transactions that write a bunch of values to the same keys + final byte[] a = bytesOf(10); + final byte[] b = bytesOf(20); + txRunner.apply(a).start(); + txRunner.apply(b).start(); + + finishedLatch.await(); + + // Check that transaction results are isolated (not interleaved) + final List finalValues = new ArrayList<>(keyCount); + for (int i = 0; i < keyCount; i++) { + final byte[] key = Bytes.minimalBytes(i).toArrayUnsafe(); + finalValues.add(store.get(key).get()); + } + + // Expecting the same value for all entries + final byte[] expected = finalValues.get(0); + for (final byte[] actual : finalValues) { + assertThat(actual).containsExactly(expected); + } + + assertThat(Arrays.equals(expected, a) || Arrays.equals(expected, b)).isTrue(); + + store.close(); + } + + /* + * Used to mimic the wrapping with Bytes performed in Besu + */ + protected byte[] bytesFromHexString(final String hex) { + return Bytes.fromHexString(hex).toArrayUnsafe(); + } + + protected byte[] bytesOf(final int... bytes) { + return Bytes.of(bytes).toArrayUnsafe(); + } +} diff --git a/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/AbstractMerklePatriciaTrieTest.java b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/AbstractMerklePatriciaTrieTest.java new file mode 100644 index 00000000000..b32391312da --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/AbstractMerklePatriciaTrieTest.java @@ -0,0 +1,412 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.hyperledger.besu.storage.InMemoryKeyValueStorage; +import org.hyperledger.besu.storage.KeyValueStorage; +import org.junit.Before; +import org.junit.Test; + +import java.util.List; +import java.util.Optional; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertFalse; + +public abstract class AbstractMerklePatriciaTrieTest { + protected MerklePatriciaTrie trie; + + @Before + public void setup() { + trie = createTrie(); + } + + protected abstract MerklePatriciaTrie createTrie(); + + @Test + public void emptyTreeReturnsEmpty() { + assertFalse(trie.get(Bytes.EMPTY).isPresent()); + } + + @Test + public void emptyTreeHasKnownRootHash() { + assertThat(trie.getRootHash().toString()) + .isEqualTo("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"); + } + + @Test + public void throwsOnUpdateWithNull() { + assertThatThrownBy(() -> trie.put(Bytes.EMPTY, (String) null)) + .isInstanceOf(NullPointerException.class); + } + + @Test + public void replaceSingleValue() { + final Bytes key = Bytes.of(1); + final String value1 = "value1"; + trie.put(key, value1); + assertThat(trie.get(key)).isEqualTo(Optional.of(value1)); + + final String value2 = "value2"; + trie.put(key, value2); + assertThat(trie.get(key)).isEqualTo(Optional.of(value2)); + } + + @Test + public void hashChangesWhenSingleValueReplaced() { + final Bytes key = Bytes.of(1); + final String value1 = "value1"; + trie.put(key, value1); + final Bytes32 hash1 = trie.getRootHash(); + + final String value2 = "value2"; + trie.put(key, value2); + final Bytes32 hash2 = trie.getRootHash(); + + assertThat(hash1).isNotEqualTo(hash2); + + trie.put(key, value1); + assertThat(trie.getRootHash()).isEqualTo(hash1); + } + + @Test + public void readPastLeaf() { + final Bytes key1 = Bytes.of(1); + trie.put(key1, "value"); + final Bytes key2 = Bytes.of(1, 3); + assertFalse(trie.get(key2).isPresent()); + } + + @Test + public void branchValue() { + final Bytes key1 = Bytes.of(1); + final Bytes key2 = Bytes.of(16); + + final String value1 = "value1"; + trie.put(key1, value1); + + final String value2 = "value2"; + trie.put(key2, value2); + + assertThat(trie.get(key1)).isEqualTo(Optional.of(value1)); + assertThat(trie.get(key2)).isEqualTo(Optional.of(value2)); + } + + @Test + public void readPastBranch() { + final Bytes key1 = Bytes.of(12); + final Bytes key2 = Bytes.of(12, 54); + + final String value1 = "value1"; + trie.put(key1, value1); + final String value2 = "value2"; + trie.put(key2, value2); + + final Bytes key3 = Bytes.of(3); + assertFalse(trie.get(key3).isPresent()); + } + + @Test + public void branchWithValue() { + final Bytes key1 = Bytes.of(5); + final Bytes key2 = Bytes.EMPTY; + + final String value1 = "value1"; + trie.put(key1, value1); + + final String value2 = "value2"; + trie.put(key2, value2); + + assertThat(trie.get(key1)).isEqualTo(Optional.of(value1)); + assertThat(trie.get(key2)).isEqualTo(Optional.of(value2)); + } + + @Test + public void extendAndBranch() { + final Bytes key1 = Bytes.of(1, 5, 9); + final Bytes key2 = Bytes.of(1, 5, 2); + + final String value1 = "value1"; + trie.put(key1, value1); + + final String value2 = "value2"; + trie.put(key2, value2); + + assertThat(trie.get(key1)).isEqualTo(Optional.of(value1)); + assertThat(trie.get(key2)).isEqualTo(Optional.of(value2)); + assertFalse(trie.get(Bytes.of(1, 4)).isPresent()); + } + + @Test + public void branchFromTopOfExtend() { + final Bytes key1 = Bytes.of(0xfe, 1); + final Bytes key2 = Bytes.of(0xfe, 2); + final Bytes key3 = Bytes.of(0xe1, 1); + + final String value1 = "value1"; + trie.put(key1, value1); + + final String value2 = "value2"; + trie.put(key2, value2); + + final String value3 = "value3"; + trie.put(key3, value3); + + assertThat(trie.get(key1)).isEqualTo(Optional.of(value1)); + assertThat(trie.get(key2)).isEqualTo(Optional.of(value2)); + assertThat(trie.get(key3)).isEqualTo(Optional.of(value3)); + assertFalse(trie.get(Bytes.of(1, 4)).isPresent()); + assertFalse(trie.get(Bytes.of(2, 4)).isPresent()); + assertFalse(trie.get(Bytes.of(3)).isPresent()); + } + + @Test + public void splitBranchExtension() { + final Bytes key1 = Bytes.of(1, 5, 9); + final Bytes key2 = Bytes.of(1, 5, 2); + + final String value1 = "value1"; + trie.put(key1, value1); + + final String value2 = "value2"; + trie.put(key2, value2); + + final Bytes key3 = Bytes.of(1, 9, 1); + + final String value3 = "value3"; + trie.put(key3, value3); + + assertThat(trie.get(key1)).isEqualTo(Optional.of(value1)); + assertThat(trie.get(key2)).isEqualTo(Optional.of(value2)); + assertThat(trie.get(key3)).isEqualTo(Optional.of(value3)); + } + + @Test + public void replaceBranchChild() { + final Bytes key1 = Bytes.of(0); + final Bytes key2 = Bytes.of(1); + + final String value1 = "value1"; + trie.put(key1, value1); + final String value2 = "value2"; + trie.put(key2, value2); + + assertThat(trie.get(key1)).isEqualTo(Optional.of(value1)); + assertThat(trie.get(key2)).isEqualTo(Optional.of(value2)); + + final String value3 = "value3"; + trie.put(key1, value3); + + assertThat(trie.get(key1)).isEqualTo(Optional.of(value3)); + assertThat(trie.get(key2)).isEqualTo(Optional.of(value2)); + } + + @Test + public void inlineBranchInBranch() { + final Bytes key1 = Bytes.of(0); + final Bytes key2 = Bytes.of(1); + final Bytes key3 = Bytes.of(2); + final Bytes key4 = Bytes.of(0, 0); + final Bytes key5 = Bytes.of(0, 1); + + trie.put(key1, "value1"); + trie.put(key2, "value2"); + trie.put(key3, "value3"); + trie.put(key4, "value4"); + trie.put(key5, "value5"); + + trie.remove(key2); + trie.remove(key3); + + assertThat(trie.get(key1)).isEqualTo(Optional.of("value1")); + assertFalse(trie.get(key2).isPresent()); + assertFalse(trie.get(key3).isPresent()); + assertThat(trie.get(key4)).isEqualTo(Optional.of("value4")); + assertThat(trie.get(key5)).isEqualTo(Optional.of("value5")); + } + + @Test + public void removeNodeInBranchExtensionHasNoEffect() { + final Bytes key1 = Bytes.of(1, 5, 9); + final Bytes key2 = Bytes.of(1, 5, 2); + + final String value1 = "value1"; + trie.put(key1, value1); + + final String value2 = "value2"; + trie.put(key2, value2); + + final Bytes hash = trie.getRootHash(); + + trie.remove(Bytes.of(1, 4)); + assertThat(trie.getRootHash()).isEqualTo(hash); + } + + @Test + public void hashChangesWhenValueChanged() { + final Bytes key1 = Bytes.of(1, 5, 8, 9); + final Bytes key2 = Bytes.of(1, 6, 1, 2); + final Bytes key3 = Bytes.of(1, 6, 1, 3); + + final String value1 = "value1"; + trie.put(key1, value1); + final Bytes32 hash1 = trie.getRootHash(); + + final String value2 = "value2"; + trie.put(key2, value2); + final String value3 = "value3"; + trie.put(key3, value3); + final Bytes32 hash2 = trie.getRootHash(); + + assertThat(hash1).isNotEqualTo(hash2); + + final String value4 = "value4"; + trie.put(key1, value4); + final Bytes32 hash3 = trie.getRootHash(); + + assertThat(hash1).isNotEqualTo(hash3); + assertThat(hash2).isNotEqualTo(hash3); + + trie.put(key1, value1); + assertThat(trie.getRootHash()).isEqualTo(hash2); + + trie.remove(key2); + trie.remove(key3); + assertThat(trie.getRootHash()).isEqualTo(hash1); + } + + @Test + public void shouldRetrieveStoredExtensionWithInlinedChild() { + final KeyValueStorage keyValueStorage = new InMemoryKeyValueStorage(); + final MerkleStorage merkleStorage = new KeyValueMerkleStorage(keyValueStorage); + final StoredMerklePatriciaTrie trie = + new StoredMerklePatriciaTrie<>(merkleStorage::get, b -> b, b -> b); + + // Both of these can be inlined in its parent branch and the branch + // itself can be inlined into its parent extension. + trie.put(Bytes.fromHexString("0x0400"), Bytes.of(1)); + trie.put(Bytes.fromHexString("0x0800"), Bytes.of(2)); + trie.commit(merkleStorage::put); + + // Ensure the extension branch can be loaded correct with its inlined child. + final Bytes32 rootHash = trie.getRootHash(); + final StoredMerklePatriciaTrie newTrie = + new StoredMerklePatriciaTrie<>(merkleStorage::get, rootHash, b -> b, b -> b); + newTrie.get(Bytes.fromHexString("0x0401")); + } + + @Test + public void shouldInlineNodesInParentAcrossModifications() { + // Misuse of StorageNode allowed inlineable trie nodes to end + // up being stored as a hash in its parent, which this would fail for. + final KeyValueStorage keyValueStorage = new InMemoryKeyValueStorage(); + final MerkleStorage merkleStorage = new KeyValueMerkleStorage(keyValueStorage); + final StoredMerklePatriciaTrie trie = + new StoredMerklePatriciaTrie<>(merkleStorage::get, b -> b, b -> b); + + // Both of these can be inlined in its parent branch. + trie.put(Bytes.fromHexString("0x0400"), Bytes.of(1)); + trie.put(Bytes.fromHexString("0x0800"), Bytes.of(2)); + trie.commit(merkleStorage::put); + + final Bytes32 rootHash = trie.getRootHash(); + final StoredMerklePatriciaTrie newTrie = + new StoredMerklePatriciaTrie<>(merkleStorage::get, rootHash, b -> b, b -> b); + + newTrie.put(Bytes.fromHexString("0x0800"), Bytes.of(3)); + newTrie.get(Bytes.fromHexString("0x0401")); + trie.commit(merkleStorage::put); + + newTrie.get(Bytes.fromHexString("0x0401")); + } + + @Test + public void getValueWithProof_emptyTrie() { + final Bytes key1 = Bytes.of(0xfe, 1); + + Proof valueWithProof = trie.getValueWithProof(key1); + assertThat(valueWithProof.getValue()).isEmpty(); + assertThat(valueWithProof.getProofRelatedNodes()).hasSize(0); + } + + @Test + public void getValueWithProof_forExistingValues() { + final Bytes key1 = Bytes.of(0xfe, 1); + final Bytes key2 = Bytes.of(0xfe, 2); + final Bytes key3 = Bytes.of(0xfe, 3); + + final String value1 = "value1"; + trie.put(key1, value1); + + final String value2 = "value2"; + trie.put(key2, value2); + + final String value3 = "value3"; + trie.put(key3, value3); + + final Proof valueWithProof = trie.getValueWithProof(key1); + assertThat(valueWithProof.getProofRelatedNodes()).hasSize(2); + assertThat(valueWithProof.getValue()).contains(value1); + + final List> nodes = + TrieNodeDecoder.decodeNodes(null, valueWithProof.getProofRelatedNodes().get(1)); + + assertThat(new String(nodes.get(1).getValue().get().toArray(), UTF_8)).isEqualTo(value1); + assertThat(new String(nodes.get(2).getValue().get().toArray(), UTF_8)).isEqualTo(value2); + } + + @Test + public void getValueWithProof_forNonExistentValue() { + final Bytes key1 = Bytes.of(0xfe, 1); + final Bytes key2 = Bytes.of(0xfe, 2); + final Bytes key3 = Bytes.of(0xfe, 3); + final Bytes key4 = Bytes.of(0xfe, 4); + + final String value1 = "value1"; + trie.put(key1, value1); + + final String value2 = "value2"; + trie.put(key2, value2); + + final String value3 = "value3"; + trie.put(key3, value3); + + final Proof valueWithProof = trie.getValueWithProof(key4); + assertThat(valueWithProof.getValue()).isEmpty(); + assertThat(valueWithProof.getProofRelatedNodes()).hasSize(2); + } + + @Test + public void getValueWithProof_singleNodeTrie() { + final Bytes key1 = Bytes.of(0xfe, 1); + final String value1 = "1"; + trie.put(key1, value1); + + final Proof valueWithProof = trie.getValueWithProof(key1); + assertThat(valueWithProof.getValue()).contains(value1); + assertThat(valueWithProof.getProofRelatedNodes()).hasSize(1); + + final List> nodes = + TrieNodeDecoder.decodeNodes(null, valueWithProof.getProofRelatedNodes().get(0)); + + assertThat(nodes.size()).isEqualTo(1); + final String nodeValue = new String(nodes.get(0).getValue().get().toArray(), UTF_8); + assertThat(nodeValue).isEqualTo(value1); + } +} diff --git a/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/AllNodesVisitorTest.java b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/AllNodesVisitorTest.java new file mode 100644 index 00000000000..f8dfeac06fd --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/AllNodesVisitorTest.java @@ -0,0 +1,47 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.util.Collections; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class AllNodesVisitorTest { + + @Mock private StoredNode storedNode; + @Mock private ExtensionNode extensionNode; + @Mock private BranchNode branchNode; + + @Test + public void visitExtension() { + when(extensionNode.getChild()).thenReturn(storedNode); + new AllNodesVisitor(x -> {}).visit(extensionNode); + verify(storedNode).unload(); + } + + @Test + public void visitBranch() { + when(branchNode.getChildren()).thenReturn(Collections.singletonList(storedNode)); + new AllNodesVisitor(x -> {}).visit(branchNode); + verify(storedNode).unload(); + } +} diff --git a/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/CompactEncodingTest.java b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/CompactEncodingTest.java new file mode 100644 index 00000000000..a23973c77cd --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/CompactEncodingTest.java @@ -0,0 +1,68 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.apache.tuweni.units.bigints.UInt256; +import org.hyperledger.besu.crypto.Hash; +import org.junit.Test; + +import java.util.Random; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CompactEncodingTest { + + @Test + public void bytesToPath() { + final Bytes path = CompactEncoding.bytesToPath(Bytes.of(0xab, 0xcd, 0xff)); + assertThat(path).isEqualTo(Bytes.of(0xa, 0xb, 0xc, 0xd, 0xf, 0xf, 0x10)); + } + + @Test + public void shouldRoundTripFromBytesToPathAndBack() { + final Random random = new Random(282943948928429484L); + for (int i = 0; i < 1000; i++) { + final Bytes32 bytes = Hash.keccak256(UInt256.valueOf(random.nextInt(Integer.MAX_VALUE))); + final Bytes path = CompactEncoding.bytesToPath(bytes); + assertThat(CompactEncoding.pathToBytes(path)).isEqualTo(bytes); + } + } + + @Test + public void encodePath() { + assertThat(CompactEncoding.encode(Bytes.of(0x01, 0x02, 0x03, 0x04, 0x05))) + .isEqualTo(Bytes.of(0x11, 0x23, 0x45)); + assertThat(CompactEncoding.encode(Bytes.of(0x00, 0x01, 0x02, 0x03, 0x04, 0x05))) + .isEqualTo(Bytes.of(0x00, 0x01, 0x23, 0x45)); + assertThat(CompactEncoding.encode(Bytes.of(0x00, 0x0f, 0x01, 0x0c, 0x0b, 0x08, 0x10))) + .isEqualTo(Bytes.of(0x20, 0x0f, 0x1c, 0xb8)); + assertThat(CompactEncoding.encode(Bytes.of(0x0f, 0x01, 0x0c, 0x0b, 0x08, 0x10))) + .isEqualTo(Bytes.of(0x3f, 0x1c, 0xb8)); + } + + @Test + public void decode() { + assertThat(CompactEncoding.decode(Bytes.of(0x11, 0x23, 0x45))) + .isEqualTo(Bytes.of(0x01, 0x02, 0x03, 0x04, 0x05)); + assertThat(CompactEncoding.decode(Bytes.of(0x00, 0x01, 0x23, 0x45))) + .isEqualTo(Bytes.of(0x00, 0x01, 0x02, 0x03, 0x04, 0x05)); + assertThat(CompactEncoding.decode(Bytes.of(0x20, 0x0f, 0x1c, 0xb8))) + .isEqualTo(Bytes.of(0x00, 0x0f, 0x01, 0x0c, 0x0b, 0x08, 0x10)); + assertThat(CompactEncoding.decode(Bytes.of(0x3f, 0x1c, 0xb8))) + .isEqualTo(Bytes.of(0x0f, 0x01, 0x0c, 0x0b, 0x08, 0x10)); + } +} diff --git a/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/RocksDBKeyValueStorageTest.java b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/RocksDBKeyValueStorageTest.java new file mode 100644 index 00000000000..111d6157745 --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/RocksDBKeyValueStorageTest.java @@ -0,0 +1,39 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.hyperledger.besu.storage.KeyValueStorage; +import org.hyperledger.besu.storage.RocksDBConfiguration; +import org.hyperledger.besu.storage.RocksDBConfigurationBuilder; +import org.hyperledger.besu.storage.RocksDBKeyValueStorage; +import org.junit.Rule; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class RocksDBKeyValueStorageTest extends AbstractKeyValueStorageTest { + + @Rule public final TemporaryFolder folder = new TemporaryFolder(); + + @Override + protected KeyValueStorage createStore() throws Exception { + return new RocksDBKeyValueStorage(config()); + } + + private RocksDBConfiguration config() throws Exception { + return new RocksDBConfigurationBuilder().databaseDir(folder.newFolder().toPath()).build(); + } +} diff --git a/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/SimpleMerklePatriciaTrieTest.java b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/SimpleMerklePatriciaTrieTest.java new file mode 100644 index 00000000000..bcf4ad715b8 --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/SimpleMerklePatriciaTrieTest.java @@ -0,0 +1,27 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; + +import java.nio.charset.Charset; + +public class SimpleMerklePatriciaTrieTest extends AbstractMerklePatriciaTrieTest { + @Override + protected MerklePatriciaTrie createTrie() { + return new SimpleMerklePatriciaTrie<>( + value -> (value != null) ? Bytes.wrap(value.getBytes(Charset.forName("UTF-8"))) : null); + } +} diff --git a/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/StoredMerklePatriciaTrieTest.java b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/StoredMerklePatriciaTrieTest.java new file mode 100644 index 00000000000..b4a029a1d20 --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/StoredMerklePatriciaTrieTest.java @@ -0,0 +1,215 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.hyperledger.besu.storage.KeyValueStorage; +import org.hyperledger.besu.storage.RocksDBConfiguration; +import org.hyperledger.besu.storage.RocksDBConfigurationBuilder; +import org.hyperledger.besu.storage.RocksDBKeyValueStorage; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.Random; +import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatRuntimeException; + +public class StoredMerklePatriciaTrieTest extends AbstractMerklePatriciaTrieTest { + private KeyValueStorage keyValueStore; + private MerkleStorage merkleStorage; + private Function valueSerializer; + private Function valueDeserializer; + @Rule + public final TemporaryFolder folder = new TemporaryFolder(); + + protected KeyValueStorage createStore() { + try { + return new RocksDBKeyValueStorage(config()); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + private RocksDBConfiguration config() throws IOException { + return new RocksDBConfigurationBuilder().databaseDir(folder.newFolder().toPath()).build(); + } + + @Override + protected MerklePatriciaTrie createTrie() { + keyValueStore = createStore(); + merkleStorage = new KeyValueMerkleStorage(keyValueStore); + valueSerializer = + value -> (value != null) ? Bytes.wrap(value.getBytes(StandardCharsets.UTF_8)) : null; + valueDeserializer = bytes -> new String(bytes.toArrayUnsafe(), StandardCharsets.UTF_8); + return new StoredMerklePatriciaTrie<>(merkleStorage::get, valueSerializer, valueDeserializer); + } + + @Test + public void putEmpty() { + final Bytes key0 = Bytes.of(1, 9, 8, 9); + // Push some values into the trie and commit changes so nodes are persisted + final String value0 = ""; + trie.put(key0, value0); + // put data into pendingUpdates + trie.commit(merkleStorage::put); + assertThatRuntimeException().isThrownBy(() -> trie.get(key0)) + .withMessageContaining("leaf has null value"); + } + + @Test + public void canReloadTrieFromHash() { + final Bytes key1 = Bytes.of(1, 5, 8, 9); + final Bytes key2 = Bytes.of(1, 6, 1, 2); + final Bytes key3 = Bytes.of(1, 6, 1, 3); + + // Push some values into the trie and commit changes so nodes are persisted + final String value1 = "value1"; + trie.put(key1, value1); + final Bytes32 hash1 = trie.getRootHash(); + // put data into pendingUpdates + trie.commit(merkleStorage::put); + + final String value2 = "value2"; + trie.put(key2, value2); + final String value3 = "value3"; + trie.put(key3, value3); + final Bytes32 hash2 = trie.getRootHash(); + // put data into pendingUpdates + trie.commit(merkleStorage::put); + + final String value4 = "value4"; + trie.put(key1, value4); + final Bytes32 hash3 = trie.getRootHash(); + // put data into pendingUpdates + trie.commit(merkleStorage::put); + + // Check the root hashes for 3 tries are all distinct + assertThat(hash1).isNotEqualTo(hash2); + assertThat(hash1).isNotEqualTo(hash3); + assertThat(hash2).isNotEqualTo(hash3); + // And that we can retrieve the last value we set for key1 + assertThat(trie.get(key1)).isEqualTo(Optional.of("value4")); + + // Create new tries from root hashes and check that we find expected values + trie = + new StoredMerklePatriciaTrie<>( + merkleStorage::get, hash1, valueSerializer, valueDeserializer); + assertThat(trie.get(key1)).isEqualTo(Optional.of("value1")); + assertThat(trie.get(key2)).isEqualTo(Optional.empty()); + assertThat(trie.get(key3)).isEqualTo(Optional.empty()); + + trie = + new StoredMerklePatriciaTrie<>( + merkleStorage::get, hash2, valueSerializer, valueDeserializer); + assertThat(trie.get(key1)).isEqualTo(Optional.of("value1")); + assertThat(trie.get(key2)).isEqualTo(Optional.of("value2")); + assertThat(trie.get(key3)).isEqualTo(Optional.of("value3")); + + trie = + new StoredMerklePatriciaTrie<>( + merkleStorage::get, hash3, valueSerializer, valueDeserializer); + assertThat(trie.get(key1)).isEqualTo(Optional.of("value4")); + assertThat(trie.get(key2)).isEqualTo(Optional.of("value2")); + assertThat(trie.get(key3)).isEqualTo(Optional.of("value3")); + + // Commit changes to storage, and create new tries from roothash and new storage instance + merkleStorage.commit(); + final MerkleStorage newMerkleStorage = new KeyValueMerkleStorage(keyValueStore); + trie = + new StoredMerklePatriciaTrie<>( + newMerkleStorage::get, hash1, valueSerializer, valueDeserializer); + assertThat(trie.get(key1)).isEqualTo(Optional.of("value1")); + assertThat(trie.get(key2)).isEqualTo(Optional.empty()); + assertThat(trie.get(key3)).isEqualTo(Optional.empty()); + + trie = + new StoredMerklePatriciaTrie<>( + newMerkleStorage::get, hash2, valueSerializer, valueDeserializer); + assertThat(trie.get(key1)).isEqualTo(Optional.of("value1")); + assertThat(trie.get(key2)).isEqualTo(Optional.of("value2")); + assertThat(trie.get(key3)).isEqualTo(Optional.of("value3")); + + trie = + new StoredMerklePatriciaTrie<>( + newMerkleStorage::get, hash3, valueSerializer, valueDeserializer); + assertThat(trie.get(key1)).isEqualTo(Optional.of("value4")); + assertThat(trie.get(key2)).isEqualTo(Optional.of("value2")); + assertThat(trie.get(key3)).isEqualTo(Optional.of("value3")); + final Bytes key4 = Bytes.of(1,3,4,6,7,9); + final Bytes key5 = Bytes.of(1,3,4,6,3,9); + final Bytes key6 = Bytes.of(1,3,4,6,8,9); + final Bytes key7= Bytes.of(2); + final Bytes key8= Bytes32.random(); + final Bytes key9= Bytes.wrap(key8, key7); + trie.put(key4, "value5"); + trie.put(key5, "value6"); + trie.put(key6, "value7"); + trie.put(key5, "value8"); + trie.put(key7, "value9"); + trie.put(key8, "value10"); + trie.put(key9, "value11"); + Random r = new SecureRandom(); + List rl = new ArrayList<>(); + for (int i =1 ; i<= 1000; i++) { + byte[] array = new byte[i%256 + 8]; + r.nextBytes(array); + Bytes bytes = Bytes.wrap(array); + rl.add(bytes); + trie.put(bytes, UUID.randomUUID().toString()); + } + rl.addAll(Arrays.asList(key1,key2,key3,key4,key5,key6,key7, key8, key9)); + trie.commit(merkleStorage::put); + merkleStorage.commit(); + + List keys = new ArrayList<>(); + trie.visitAll((N) -> { + if (N instanceof BranchNode && N.getValue().isPresent()) { + Bytes k = CompactEncoding.pathToBytes( + Bytes.concatenate(N.getLocation().orElse(Bytes.EMPTY), + Bytes.of(CompactEncoding.LEAF_TERMINATOR))); + keys.add(k); + } + + if (N instanceof LeafNode) { + Bytes k = CompactEncoding.pathToBytes( + Bytes.concatenate(N.getLocation().orElse(Bytes.EMPTY), + N.getPath())); + keys.add(k); + } + }); + + Collections.sort(keys); + Collections.sort(rl); + rl = rl.stream().distinct().collect(Collectors.toList()); + assertThat(trie.get(key7)).isEqualTo(Optional.of("value9")); + assertThat(keys.size()).isEqualTo(rl.size()); + assertThat(keys).isEqualTo(rl); + } +} diff --git a/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/TrieIteratorTest.java b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/TrieIteratorTest.java new file mode 100644 index 00000000000..95bf8829bdd --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/TrieIteratorTest.java @@ -0,0 +1,143 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.apache.tuweni.units.bigints.UInt256; +import org.hyperledger.besu.crypto.Hash; +import org.hyperledger.besu.ethereum.trie.TrieIterator.LeafHandler; +import org.hyperledger.besu.ethereum.trie.TrieIterator.State; +import org.junit.Test; +import org.mockito.InOrder; + +import java.nio.charset.StandardCharsets; +import java.util.NavigableSet; +import java.util.Random; +import java.util.TreeSet; + +import static org.hyperledger.besu.ethereum.trie.CompactEncoding.bytesToPath; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +public class TrieIteratorTest { + + private static final Bytes32 KEY_HASH1 = + Bytes32.fromHexString("0x5555555555555555555555555555555555555555555555555555555555555555"); + private static final Bytes32 KEY_HASH2 = + Bytes32.fromHexString("0x5555555555555555555555555555555555555555555555555555555555555556"); + private static final Bytes PATH1 = bytesToPath(KEY_HASH1); + private static final Bytes PATH2 = bytesToPath(KEY_HASH2); + + @SuppressWarnings("unchecked") + private final LeafHandler leafHandler = mock(LeafHandler.class); + + private final DefaultNodeFactory nodeFactory = + new DefaultNodeFactory<>(this::valueSerializer); + private final TrieIterator iterator = new TrieIterator<>(leafHandler, false); + + private Bytes valueSerializer(final String value) { + return Bytes.wrap(value.getBytes(StandardCharsets.UTF_8)); + } + + @Test + public void shouldCallLeafHandlerWhenRootNodeIsALeaf() { + final Node leaf = nodeFactory.createLeaf(bytesToPath(KEY_HASH1), "Leaf"); + leaf.accept(iterator, PATH1); + + verify(leafHandler).onLeaf(KEY_HASH1, leaf); + } + + @Test + public void shouldNotNotifyLeafHandlerOfNullNodes() { + NullNode.instance().accept(iterator, PATH1); + + verifyNoInteractions(leafHandler); + } + + @Test + public void shouldConcatenatePathAndVisitChildOfExtensionNode() { + final Node leaf = nodeFactory.createLeaf(PATH1.slice(10), "Leaf"); + final Node extension = nodeFactory.createExtension(PATH1.slice(0, 10), leaf); + extension.accept(iterator, PATH1); + verify(leafHandler).onLeaf(KEY_HASH1, leaf); + } + + @Test + @SuppressWarnings("unchecked") + public void shouldVisitEachChildOfABranchNode() { + when(leafHandler.onLeaf(any(Bytes32.class), any(Node.class))).thenReturn(State.CONTINUE); + final Node root = + NullNode.instance() + .accept(new PutVisitor<>(nodeFactory, "Leaf 1"), PATH1) + .accept(new PutVisitor<>(nodeFactory, "Leaf 2"), PATH2); + root.accept(iterator, PATH1); + + final InOrder inOrder = inOrder(leafHandler); + inOrder.verify(leafHandler).onLeaf(eq(KEY_HASH1), any(Node.class)); + inOrder.verify(leafHandler).onLeaf(eq(KEY_HASH2), any(Node.class)); + verifyNoMoreInteractions(leafHandler); + } + + @Test + @SuppressWarnings("unchecked") + public void shouldStopIteratingChildrenOfBranchWhenLeafHandlerReturnsStop() { + when(leafHandler.onLeaf(any(Bytes32.class), any(Node.class))).thenReturn(State.STOP); + final Node root = + NullNode.instance() + .accept(new PutVisitor<>(nodeFactory, "Leaf 1"), PATH1) + .accept(new PutVisitor<>(nodeFactory, "Leaf 2"), PATH2); + root.accept(iterator, PATH1); + + verify(leafHandler).onLeaf(eq(KEY_HASH1), any(Node.class)); + verifyNoMoreInteractions(leafHandler); + } + + @Test + @SuppressWarnings({"unchecked", "MathAbsoluteRandom"}) + public void shouldIterateArbitraryStructureAccurately() { + Node root = NullNode.instance(); + final NavigableSet expectedKeyHashes = new TreeSet<>(); + final Random random = new Random(-5407159858935967790L); + Bytes32 startAtHash = Bytes32.ZERO; + Bytes32 stopAtHash = Bytes32.ZERO; + final int totalNodes = Math.abs(random.nextInt(1000)); + final int startNodeNumber = random.nextInt(Math.max(1, totalNodes - 1)); + final int stopNodeNumber = random.nextInt(Math.max(1, totalNodes - 1)); + for (int i = 0; i < totalNodes; i++) { + final Bytes32 keyHash = + Hash.keccak256(UInt256.valueOf(Math.abs(random.nextInt(Integer.MAX_VALUE)))); + root = root.accept(new PutVisitor<>(nodeFactory, "Value"), bytesToPath(keyHash)); + expectedKeyHashes.add(keyHash); + if (i == startNodeNumber) { + startAtHash = keyHash; + } else if (i == stopNodeNumber) { + stopAtHash = keyHash; + } + } + + final Bytes32 actualStopAtHash = + stopAtHash.compareTo(startAtHash) >= 0 ? stopAtHash : startAtHash; + when(leafHandler.onLeaf(any(Bytes32.class), any(Node.class))).thenReturn(State.CONTINUE); + when(leafHandler.onLeaf(eq(actualStopAtHash), any(Node.class))).thenReturn(State.STOP); + root.accept(iterator, bytesToPath(startAtHash)); + final InOrder inOrder = inOrder(leafHandler); + expectedKeyHashes + .subSet(startAtHash, true, actualStopAtHash, true) + .forEach(keyHash -> inOrder.verify(leafHandler).onLeaf(eq(keyHash), any(Node.class))); + verifyNoMoreInteractions(leafHandler); + } +} diff --git a/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/TrieNodeDecoderTest.java b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/TrieNodeDecoderTest.java new file mode 100644 index 00000000000..4f5521d3f36 --- /dev/null +++ b/state-trie-jdk8/src/test/java/org/hyperledger/besu/ethereum/trie/TrieNodeDecoderTest.java @@ -0,0 +1,245 @@ +/* + * Copyright ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.trie; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.hyperledger.besu.storage.InMemoryKeyValueStorage; +import org.hyperledger.besu.storage.KeyValueStorage; +import org.hyperledger.besu.storage.KeyValueStorageTransaction; +import org.junit.Test; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Random; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TrieNodeDecoderTest { + + @Test + public void decodeNodes() { + final InMemoryKeyValueStorage storage = new InMemoryKeyValueStorage(); + + // Build a small trie + final MerklePatriciaTrie trie = + new StoredMerklePatriciaTrie<>( + new BytesToByteNodeLoader(storage), Function.identity(), Function.identity()); + trie.put(Bytes.fromHexString("0x100000"), Bytes.of(1)); + trie.put(Bytes.fromHexString("0x200000"), Bytes.of(2)); + trie.put(Bytes.fromHexString("0x300000"), Bytes.of(3)); + + trie.put(Bytes.fromHexString("0x110000"), Bytes.of(10)); + trie.put(Bytes.fromHexString("0x210000"), Bytes.of(20)); + // Create large leaf node that will not be inlined + trie.put( + Bytes.fromHexString("0x310000"), + Bytes.fromHexString("0x11223344556677889900112233445566778899")); + + // Save nodes to storage + final KeyValueStorageTransaction tx = storage.startTransaction(); + trie.commit((location, key, value) -> tx.put(key.toArrayUnsafe(), value.toArrayUnsafe())); + tx.commit(); + + // Get and flatten root node + final Bytes rootNodeRlp = Bytes.wrap(storage.get(trie.getRootHash().toArrayUnsafe()).get()); + final List> nodes = TrieNodeDecoder.decodeNodes(null, rootNodeRlp); + // The full trie hold 10 nodes, the branch node starting with 0x3... holding 2 values will be a + // hash + // referenced node and so its 2 child nodes will be missing + assertThat(nodes.size()).isEqualTo(8); + + // Collect and check values + final List actualValues = + nodes.stream() + .filter(n -> !n.isReferencedByHash()) + .map(Node::getValue) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + assertThat(actualValues) + .containsExactlyInAnyOrder(Bytes.of(1), Bytes.of(10), Bytes.of(2), Bytes.of(20)); + } + + @Test + public void breadthFirstDecode_smallTrie() { + final InMemoryKeyValueStorage storage = new InMemoryKeyValueStorage(); + + // Build a small trie + final MerklePatriciaTrie trie = + new StoredMerklePatriciaTrie<>( + new BytesToByteNodeLoader(storage), Function.identity(), Function.identity()); + trie.put(Bytes.fromHexString("0x100000"), Bytes.of(1)); + trie.put(Bytes.fromHexString("0x200000"), Bytes.of(2)); + trie.put(Bytes.fromHexString("0x300000"), Bytes.of(3)); + + trie.put(Bytes.fromHexString("0x110000"), Bytes.of(10)); + trie.put(Bytes.fromHexString("0x210000"), Bytes.of(20)); + trie.put(Bytes.fromHexString("0x310000"), Bytes.of(30)); + + // Save nodes to storage + final KeyValueStorageTransaction tx = storage.startTransaction(); + trie.commit((location, key, value) -> tx.put(key.toArrayUnsafe(), value.toArrayUnsafe())); + tx.commit(); + + // First layer should just be the root node + final List> depth0Nodes = + TrieNodeDecoder.breadthFirstDecoder( + new BytesToByteNodeLoader(storage), trie.getRootHash(), 0) + .collect(Collectors.toList()); + + assertThat(depth0Nodes.size()).isEqualTo(1); + final Node rootNode = depth0Nodes.get(0); + assertThat(rootNode.getHash()).isEqualTo(trie.getRootHash()); + + // Decode first 2 levels + final List> depth0And1Nodes = + (TrieNodeDecoder.breadthFirstDecoder( + new BytesToByteNodeLoader(storage), trie.getRootHash(), 1) + .collect(Collectors.toList())); + final int secondLevelNodeCount = 3; + final int expectedNodeCount = secondLevelNodeCount + 1; + assertThat(depth0And1Nodes.size()).isEqualTo(expectedNodeCount); + // First node should be root node + assertThat(depth0And1Nodes.get(0).getHash()).isEqualTo(rootNode.getHash()); + // Subsequent nodes should be children of root node + final List expectedNodesHashes = + rootNode.getChildren().stream() + .filter(n -> !Objects.equals(n, NullNode.instance())) + .map(Node::getHash) + .collect(Collectors.toList()); + final List actualNodeHashes = + depth0And1Nodes.subList(1, expectedNodeCount).stream() + .map(Node::getHash) + .collect(Collectors.toList()); + assertThat(actualNodeHashes).isEqualTo(expectedNodesHashes); + + // Decode full trie + final List> allNodes = + TrieNodeDecoder.breadthFirstDecoder(new BytesToByteNodeLoader(storage), trie.getRootHash()) + .collect(Collectors.toList()); + assertThat(allNodes.size()).isEqualTo(10); + // Collect and check values + final List actualValues = + allNodes.stream() + .map(Node::getValue) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + assertThat(actualValues) + .containsExactly( + Bytes.of(1), Bytes.of(10), Bytes.of(2), Bytes.of(20), Bytes.of(3), Bytes.of(30)); + } + + @Test + public void breadthFirstDecode_partialTrie() { + final InMemoryKeyValueStorage fullStorage = new InMemoryKeyValueStorage(); + final InMemoryKeyValueStorage partialStorage = new InMemoryKeyValueStorage(); + + // Build a small trie + final MerklePatriciaTrie trie = + new StoredMerklePatriciaTrie<>( + new BytesToByteNodeLoader(fullStorage), Function.identity(), Function.identity()); + final Random random = new Random(1); + for (int i = 0; i < 30; i++) { + final byte[] key = new byte[4]; + final byte[] val = new byte[4]; + random.nextBytes(key); + random.nextBytes(val); + trie.put(Bytes.wrap(key), Bytes.wrap(val)); + } + final KeyValueStorageTransaction tx = fullStorage.startTransaction(); + trie.commit((location, key, value) -> tx.put(key.toArrayUnsafe(), value.toArrayUnsafe())); + tx.commit(); + + // Get root node + final Node rootNode = + TrieNodeDecoder.breadthFirstDecoder( + new BytesToByteNodeLoader(fullStorage), trie.getRootHash()) + .findFirst() + .get(); + + // Decode partially available trie + final KeyValueStorageTransaction partialTx = partialStorage.startTransaction(); + partialTx.put(trie.getRootHash().toArrayUnsafe(), rootNode.getRlp().toArrayUnsafe()); + partialTx.commit(); + final List> allDecodableNodes = + TrieNodeDecoder.breadthFirstDecoder( + new BytesToByteNodeLoader(partialStorage), trie.getRootHash()) + .collect(Collectors.toList()); + assertThat(allDecodableNodes.size()).isGreaterThanOrEqualTo(1); + assertThat(allDecodableNodes.get(0).getHash()).isEqualTo(rootNode.getHash()); + } + + @Test + public void breadthFirstDecode_emptyTrie() { + final List> result = + TrieNodeDecoder.breadthFirstDecoder( + (l, h) -> Optional.empty(), MerklePatriciaTrie.EMPTY_TRIE_NODE_HASH) + .collect(Collectors.toList()); + assertThat(result.size()).isEqualTo(0); + } + + @Test + public void breadthFirstDecode_singleNodeTrie() { + final InMemoryKeyValueStorage storage = new InMemoryKeyValueStorage(); + + final MerklePatriciaTrie trie = + new StoredMerklePatriciaTrie<>( + new BytesToByteNodeLoader(storage), Function.identity(), Function.identity()); + trie.put(Bytes.fromHexString("0x100000"), Bytes.of(1)); + + // Save nodes to storage + final KeyValueStorageTransaction tx = storage.startTransaction(); + trie.commit((location, key, value) -> tx.put(key.toArrayUnsafe(), value.toArrayUnsafe())); + tx.commit(); + + final List> result = + TrieNodeDecoder.breadthFirstDecoder(new BytesToByteNodeLoader(storage), trie.getRootHash()) + .collect(Collectors.toList()); + assertThat(result.size()).isEqualTo(1); + assertThat(result.get(0).getValue()).contains(Bytes.of(1)); + final Bytes actualPath = CompactEncoding.pathToBytes(result.get(0).getPath()); + assertThat(actualPath).isEqualTo(Bytes.fromHexString("0x100000")); + } + + @Test + public void breadthFirstDecode_unknownTrie() { + + final Bytes32 randomRootHash = Bytes32.fromHexStringLenient("0x12"); + final List> result = + TrieNodeDecoder.breadthFirstDecoder((l, h) -> Optional.empty(), randomRootHash) + .collect(Collectors.toList()); + assertThat(result.size()).isEqualTo(0); + } + + private static class BytesToByteNodeLoader implements NodeLoader { + + private final KeyValueStorage storage; + + private BytesToByteNodeLoader(final KeyValueStorage storage) { + this.storage = storage; + } + + @Override + public Optional getNode(final Bytes location, final Bytes32 hash) { + final byte[] value = storage.get(hash.toArrayUnsafe()).orElse(null); + return value == null ? Optional.empty() : Optional.of(Bytes.wrap(value)); + } + } +} From 42b60fbdf71273aba1054d932b3330324a9a2127 Mon Sep 17 00:00:00 2001 From: guoquanwu Date: Mon, 27 Feb 2023 17:30:11 +0800 Subject: [PATCH 02/34] feat(trie): add trie prune tool --- .../src/main/java/org/tron/core/state/TODO.md | 17 - plugins/README.md | 36 ++ plugins/build.gradle | 1 + .../main/java/org/tron/plugins/Constant.java | 14 + .../src/main/java/org/tron/plugins/Db.java | 3 +- .../main/java/org/tron/plugins/DbLite.java | 4 +- .../main/java/org/tron/plugins/Pruner.java | 552 ++++++++++++++++++ .../org/tron/plugins/utils/FileUtils.java | 18 + .../besu/ethereum/trie/AllNodesVisitor.java | 19 +- .../trie/StoredMerklePatriciaTrie.java | 3 +- 10 files changed, 645 insertions(+), 22 deletions(-) delete mode 100644 chainbase/src/main/java/org/tron/core/state/TODO.md create mode 100644 plugins/src/main/java/org/tron/plugins/Constant.java create mode 100644 plugins/src/main/java/org/tron/plugins/Pruner.java diff --git a/chainbase/src/main/java/org/tron/core/state/TODO.md b/chainbase/src/main/java/org/tron/core/state/TODO.md deleted file mode 100644 index a5a3f153c92..00000000000 --- a/chainbase/src/main/java/org/tron/core/state/TODO.md +++ /dev/null @@ -1,17 +0,0 @@ -This is the todo list: - -- filter the keys that are not the state data in `DynamicPropertiesStore`, method: `public void put(byte[] key, BytesCapsule item)` -- design the logic that decouple the asset10 from account struct, in `WorldStateCallBackUtils` -- design contract state query - - create another implementation of `Repositoty` - - create another implementation of `StorageFactory` -- add the state query interface -- make the world state tree switch as a config, e.g: `worldState = true` in `config.conf` -- make the trie prune as a config, e.g: `stateTriePrune = true` in `config.conf` -or -``` -worldstate { - open = true; - prune = false; -} -``` \ No newline at end of file diff --git a/plugins/README.md b/plugins/README.md index e2458b7e9a6..2db7c691d13 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -135,3 +135,39 @@ Execute move command. java -jar Toolkit.jar db mv -c main_net_config.conf -d /data/tron/output-directory ``` + +## DB Prune + +Prune tool is only used for pruning the MPT data for archive node. When a Fullnode sets `stateRoot.switch = true`, +it is a archive node and will store the history data in `stateGenesis.directory(default: output-directory/state-genesis/world-state-trie)`, +the data volume of this database grows fast and may reach terabyte levels in a few months. +But not all the archive node want to reserve the whole history data, some may only want to reserve recently history data like three month, +this tool can split the trie data and generate a new database which only contain the latest MPT as you specified. +When prune finished, you shoud replace the `state-genesis` by `state-directory-pruned`, +prune may take a long time depend on the number of MPT that you want reserved. + + + +### Available parameters: + +- `-c | --config`: config file, Default: config.conf. +- `-d | --output-directory`: src output directory, Default: output-directory. +- `-p | --state-directory-pruned`: pruned state directory, Default: state-genesis-pruned. +- `-n | --number-reserved`: the number of recent trie data should be reserved. +- `-k | --check`: the switch whether check the data correction after prune +- `-h | --help`: provide the help info + +### Examples: + +Execute move command. +```shell script +# full command + java -jar Toolkit.jar db prune [-hk] [-c=] -n= + [-p=] [-d=] +# 1. split and get pruned data + java -jar Toolkit.jar db prune -d ./output-directory -p ./state-genesis-pruned -c ./config.conf -n 1 -k +# 2. mv the prev state db away + mv ./output-directory/state-genesis /backup +# 3. replace and rename the pruned dir + mv ./state-genesis-pruned ./output-directory/state-genesis +``` diff --git a/plugins/build.gradle b/plugins/build.gradle index 457fb739058..23f7d6e6956 100644 --- a/plugins/build.gradle +++ b/plugins/build.gradle @@ -38,6 +38,7 @@ dependencies { compile 'io.github.tronprotocol:leveldbjni-all:1.18.2' compile 'io.github.tronprotocol:leveldb:1.18.2' compile project(":protocol") + compile project(":state-trie-jdk8") } check.dependsOn 'lint' diff --git a/plugins/src/main/java/org/tron/plugins/Constant.java b/plugins/src/main/java/org/tron/plugins/Constant.java new file mode 100644 index 00000000000..52e0c789f8b --- /dev/null +++ b/plugins/src/main/java/org/tron/plugins/Constant.java @@ -0,0 +1,14 @@ +package org.tron.plugins; + +public class Constant { + + public static final String PROPERTIES_CONFIG_KEY = "storage.properties"; + public static final String DB_DIRECTORY_CONFIG_KEY = "storage.db.directory"; + public static final String DEFAULT_DB_DIRECTORY = "database"; + + public static final String STATE_GENESIS_PATH_KEY = "storage.stateGenesis.directory"; + public static final String STATE_GENESIS_SWITCH_KEY = "storage.stateRoot.switch"; + public static final String STATE_GENESIS_META_FILE = "genesis.properties"; + public static final String STATE_TRIE_DB_NAME = "world-state-trie"; + +} diff --git a/plugins/src/main/java/org/tron/plugins/Db.java b/plugins/src/main/java/org/tron/plugins/Db.java index c67c838a3d6..d5b3e4a904b 100644 --- a/plugins/src/main/java/org/tron/plugins/Db.java +++ b/plugins/src/main/java/org/tron/plugins/Db.java @@ -11,7 +11,8 @@ DbArchive.class, DbConvert.class, DbLite.class, - DbCopy.class + DbCopy.class, + Pruner.class }, commandListHeading = "%nCommands:%n%nThe most commonly used db commands are:%n" ) diff --git a/plugins/src/main/java/org/tron/plugins/DbLite.java b/plugins/src/main/java/org/tron/plugins/DbLite.java index ef7e73ec6d6..7a11b186976 100644 --- a/plugins/src/main/java/org/tron/plugins/DbLite.java +++ b/plugins/src/main/java/org/tron/plugins/DbLite.java @@ -352,7 +352,7 @@ private void generateInfoProperties(String propertyfile, long num) } } - private long getLatestBlockHeaderNum(String databaseDir) throws IOException, RocksDBException { + public long getLatestBlockHeaderNum(String databaseDir) throws IOException, RocksDBException { // query latest_block_header_number from checkpoint first final String latestBlockHeaderNumber = "latest_block_header_number"; List cpList = getCheckpointV2List(databaseDir); @@ -661,7 +661,7 @@ private boolean isLite(String databaseDir) throws RocksDBException, IOException return getSecondBlock(databaseDir) > 1; } - private long getSecondBlock(String databaseDir) throws RocksDBException, IOException { + public long getSecondBlock(String databaseDir) throws RocksDBException, IOException { long num = 0; DBInterface sourceBlockIndexDb = DbTool.getDB(databaseDir, BLOCK_INDEX_DB_NAME); DBIterator iterator = sourceBlockIndexDb.iterator(); diff --git a/plugins/src/main/java/org/tron/plugins/Pruner.java b/plugins/src/main/java/org/tron/plugins/Pruner.java new file mode 100644 index 00000000000..a9504689bd5 --- /dev/null +++ b/plugins/src/main/java/org/tron/plugins/Pruner.java @@ -0,0 +1,552 @@ +package org.tron.plugins; + +import static org.tron.plugins.Constant.DB_DIRECTORY_CONFIG_KEY; +import static org.tron.plugins.Constant.PROPERTIES_CONFIG_KEY; +import static org.tron.plugins.Constant.STATE_GENESIS_META_FILE; +import static org.tron.plugins.Constant.STATE_GENESIS_PATH_KEY; +import static org.tron.plugins.Constant.STATE_TRIE_DB_NAME; + +import com.google.common.collect.Maps; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.typesafe.config.Config; +import com.typesafe.config.ConfigFactory; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.Function; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import me.tongfei.progressbar.ProgressBar; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.hyperledger.besu.ethereum.trie.KeyValueMerkleStorage; +import org.hyperledger.besu.ethereum.trie.MerklePatriciaTrie; +import org.hyperledger.besu.ethereum.trie.MerkleStorage; +import org.hyperledger.besu.ethereum.trie.StoredMerklePatriciaTrie; +import org.hyperledger.besu.storage.KeyValueStorage; +import org.hyperledger.besu.storage.KeyValueStorageTransaction; +import org.hyperledger.besu.storage.RocksDBConfigurationBuilder; +import org.hyperledger.besu.storage.RocksDBKeyValueStorage; +import org.rocksdb.RocksDB; +import org.rocksdb.RocksDBException; +import org.tron.plugins.utils.ByteArray; +import org.tron.plugins.utils.FileUtils; +import org.tron.plugins.utils.db.DBInterface; +import org.tron.plugins.utils.db.DbTool; +import org.tron.protos.Protocol; +import picocli.CommandLine; +import picocli.CommandLine.Option; + +@Slf4j(topic = "prune") +@CommandLine.Command(name = "prune", description = "A helper to prune the archive db.") +public class Pruner implements Callable { + + private static final byte[] IN_USE = Bytes.of(1).toArrayUnsafe(); + + private static final String BLOCK_DB_NAME = "block"; + private static final String BLOCK_INDEX_DB_NAME = "block-index"; + private static final String TRIE_DB_NAME = "world-state-trie"; + private static final String DEFAULT_STATE_GENESIS_DIRECTORY = "state-genesis"; + private static Path RESERVED_KEY_STORE_PATH; + + private final ReadWriteLock pendingMarksLock = new ReentrantReadWriteLock(); + private final Set pendingMarks = Collections.newSetFromMap(new ConcurrentHashMap<>()); + + private static final int DEFAULT_OPS_PER_TRANSACTION = 10_000; + + private MerkleStorage srcMerkleStorage; + private KeyValueStorage srcKvStorage; + private MerkleStorage destMerkleStorage; + private KeyValueStorage destKvStorage; + private RocksDB destDb; + private KeyValueStorage markedKeyStore; + + final ThreadPoolExecutor markingExecutorService = + new ThreadPoolExecutor( + 0, + Runtime.getRuntime().availableProcessors() * 2, + 5L, + TimeUnit.SECONDS, + new LinkedBlockingDeque<>(100), + new ThreadFactoryBuilder() + .setDaemon(true) + .setNameFormat(this.getClass().getSimpleName() + "-mark-%d") + .build(), + new ThreadPoolExecutor.CallerRunsPolicy() + ); + + final ThreadPoolExecutor checkExecutorService = + new ThreadPoolExecutor( + 0, + Runtime.getRuntime().availableProcessors() * 2, + 5L, + TimeUnit.SECONDS, + new LinkedBlockingDeque<>(100), + new ThreadFactoryBuilder() + .setDaemon(true) + // .setPriority(Thread.MIN_PRIORITY) + .setNameFormat(this.getClass().getSimpleName() + "-check-%d") + .build(), + new ThreadPoolExecutor.CallerRunsPolicy() + ); + + @CommandLine.Spec + CommandLine.Model.CommandSpec spec; + + @CommandLine.Option(names = {"-d", "--output-directory"}, + required = true, + defaultValue = "output-directory", + converter = DbMove.PathConverter.class, + order = 1, + description = "source output directory. Default: ${DEFAULT-VALUE}") + static Path srcDirectory; + + @Option(names = {"-p", "--state-directory-pruned"}, + required = true, + defaultValue = "state-genesis-pruned", + order = 2, + description = "pruned state directory. Default: ${DEFAULT-VALUE}") + private String prunedDir; + + @CommandLine.Option(names = {"-c", "--config"}, + required = true, + defaultValue = "config.conf", + converter = ConfigConverter.class, + order = 0, + description = "config file. Default: ${DEFAULT-VALUE}") + static Config config; + + @CommandLine.Option( + names = {"-n", "--number-reserved"}, + required = true, + order = 3, + description = "the number of block state data need to be reserved.") + private long reserveNumber; + + @CommandLine.Option( + names = {"-k", "--check"}, + order = 4, + description = "check trie data integrity") + private boolean check; + + @Option(names = {"-h", "--help"}) + static boolean help; + + + @Override + public Integer call() throws Exception { + if (help) { + spec.commandLine().usage(System.out); + return 0; + } + + if (!checkPrunedDir(prunedDir)) { + return 300; + } + + String msg; + Path databasePath = Paths.get(srcDirectory.toString(), + config.getString(DB_DIRECTORY_CONFIG_KEY)); + Path prunedPath = Paths.get(prunedDir); + Path statePath; + if (config.hasPath(STATE_GENESIS_PATH_KEY)) { + statePath = Paths.get(srcDirectory.toString(), config.getString(STATE_GENESIS_PATH_KEY)); + } else { + statePath = Paths.get(srcDirectory.toString(), DEFAULT_STATE_GENESIS_DIRECTORY); + } + + // check reserve number + Map result = checkAndGetBlockNumberRange( + databasePath.toString(), statePath.toString(), reserveNumber); + if (result == null || result.size() == 0) { + return 404; + } + + // init persistant storage, only for once + initKeyValueStorage(statePath.toString()); + initReservedKeyStore(prunedPath); + + // mark the trie data + long startIndex = result.get("end") - reserveNumber + 1; + long endIndex = result.get("end"); + print(String.format("Prune begin, start number: %d, end number: %d", + startIndex, endIndex), false); + long startTime = System.currentTimeMillis(); + for (long index = startIndex; index <= endIndex; index++) { + Bytes32 root = Bytes32.wrap( + getBlockByNumber(index).getBlockHeader().getArchiveRoot().toByteArray()); + MerklePatriciaTrie srcTrie = getTrie(srcMerkleStorage, root); + print("marking block number: " + index + ", root: " + root, false); + + srcTrie.visitAll((node) -> { + markNodes(node.getHash()); + }, markingExecutorService).join(); + } + + // wait markingExecutorService task finished + awaitTask(markingExecutorService); + + // flush the final task data + flushPendingMarks(); + print(String.format("mark trie finish, cost: %d ms", + System.currentTimeMillis() - startTime), false); + + // copy the marked data to dest merkle store + copy(); + + // check trie data correction + if (check) { + destMerkleStorage = new KeyValueMerkleStorage(getDestKvStorage(prunedDir)); + for (long index = startIndex; index <= endIndex; index++) { + Bytes32 root = Bytes32.wrap( + getBlockByNumber(index).getBlockHeader().getArchiveRoot().toByteArray()); + startTime = System.currentTimeMillis(); + MerklePatriciaTrie destTrie = getTrie( + destMerkleStorage, root); + destTrie.visitAll(node -> { + node.getHash(); + node.getValue(); + }, checkExecutorService).join(); + } + awaitTask(checkExecutorService); + msg = String.format("check trie data correction, cost: %d", + System.currentTimeMillis() - startTime); + print(msg, false); + destKvStorage.close(); + } + + // copy state genesis data + if (!copyStateGenesis(statePath, prunedPath)) { + return 501; + } + + // generate state meta file + Protocol.Block stateGenesisBlock = getBlockByNumber(startIndex); + if (!generateMetaFile(prunedPath, stateGenesisBlock)) { + return 501; + } + + // release resource + releaseResource(); + + msg = "prune success!"; + print(msg, false); + + return 0; + } + + private void copy() throws RocksDBException { + print("copy marked data start.", false); + // init destDb + initDestDb(prunedDir); + AtomicLong count = new AtomicLong(); + long start = System.currentTimeMillis(); + markedKeyStore.streamKeys().parallel().forEach(key -> { + Optional v = + Optional.ofNullable(srcKvStorage.get(key)).orElse(Optional.empty()); + try { + if (v.isPresent()) { + destDb.put(key, v.get()); + } + } catch (RocksDBException e) { + print(String.format("copy marked data failed, err: %s", e.getMessage()), true); + throw new RuntimeException(e); + } + count.incrementAndGet(); + }); + destDb.close(); + print(String.format("copy marked data finish, record number: %d, cost: %d", + count.get(), System.currentTimeMillis() - start), false); + } + + private void markNodes(final Bytes32 hash) { + markThenMaybeFlush(() -> pendingMarks.add(hash), 1); + } + + private void markThenMaybeFlush(final Runnable nodeMarker, final int numberOfNodes) { + // We use the read lock here because pendingMarks is threadsafe and we want to allow all the + // marking threads access simultaneously. + final Lock markLock = pendingMarksLock.readLock(); + markLock.lock(); + try { + nodeMarker.run(); + } finally { + markLock.unlock(); + } + + // However, when the size of pendingMarks grows too large, we want all the threads to stop + // adding because we're going to clear the set. + // Therefore, we need to take out a write lock. + if (pendingMarks.size() >= DEFAULT_OPS_PER_TRANSACTION) { + final Lock flushLock = pendingMarksLock.writeLock(); + flushLock.lock(); + try { + // Check once again that the condition holds. If it doesn't, that means another thread + // already flushed them. + if (pendingMarks.size() >= DEFAULT_OPS_PER_TRANSACTION) { + flushPendingMarks(); + } + } finally { + flushLock.unlock(); + } + } + } + + private void flushPendingMarks() { + final KeyValueStorageTransaction transaction = markedKeyStore.startTransaction(); + pendingMarks.forEach(node -> transaction.put(node.toArrayUnsafe(), IN_USE)); + transaction.commit(); + pendingMarks.clear(); + } + + private void awaitTask(ThreadPoolExecutor executor) throws InterruptedException { + Thread.sleep(10000); + while (executor.getActiveCount() > 0 || executor.getQueue().size() > 0) { + Thread.sleep(10000); + } + executor.shutdown(); + } + + private boolean copyStateGenesis(Path statePath, Path prunedPath) { + List services = new ArrayList<>(); + Arrays.stream(Objects.requireNonNull(statePath.toFile().listFiles())) + .filter(File::isDirectory) + .filter(f -> !STATE_TRIE_DB_NAME.equals(f.getName())) + .forEach(f -> services.add( + new DbCopy.DbCopier( + statePath.toFile().getPath(), prunedPath.toFile().getPath(), f.getName()))); + List fails = ProgressBar + .wrap(services.stream(), "copy task") + .parallel() + .map( + dbCopier -> { + try { + return dbCopier.doCopy() ? null : dbCopier.name(); + } catch (Exception e) { + print(String.format("copy state genesis failed, db: %s, err: %s", + dbCopier.name(), e.getMessage()), true); + return dbCopier.name(); + } + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + return fails.isEmpty(); + } + + private boolean generateMetaFile(Path prunedPath, Protocol.Block block) { + String propertyfile = Paths.get(prunedPath.toString(), + STATE_GENESIS_META_FILE).toString(); + if (!FileUtils.createFileIfNotExists(propertyfile)) { + print("Create properties file failed.", true); + return false; + } + + Map properties = new HashMap<>(); + properties.put("height", + String.valueOf(block.getBlockHeader().getRawData().getNumber())); + properties.put("hash", + Bytes32.wrap(block.getBlockHeader().getArchiveRoot().toByteArray()).toHexString()); + properties.put("time", + String.valueOf(block.getBlockHeader().getRawData().getTimestamp())); + + if (!FileUtils.writeProperties(propertyfile, properties)) { + print("Write properties file failed.", true); + return false; + } + return true; + } + + private void initKeyValueStorage(String stateDir) { + if (srcKvStorage == null) { + Path triePath = Paths.get(stateDir, TRIE_DB_NAME); + srcKvStorage = new RocksDBKeyValueStorage( + new RocksDBConfigurationBuilder() + .databaseDir(triePath) + .build()); + srcMerkleStorage = new KeyValueMerkleStorage(srcKvStorage); + } + } + + private RocksDB initDestDb(String prunedDirectory) throws RocksDBException { + Path triePath = Paths.get(prunedDirectory, TRIE_DB_NAME); + destDb = RocksDB.open(triePath.toString()); + return destDb; + } + + private KeyValueStorage getDestKvStorage(String prunedDirectory) { + Path triePath = Paths.get(prunedDirectory, TRIE_DB_NAME); + destKvStorage = new RocksDBKeyValueStorage( + new RocksDBConfigurationBuilder().databaseDir(triePath).build()); + return destKvStorage; + } + + private MerklePatriciaTrie getTrie( + MerkleStorage merkleStorage, Bytes32 root) { + return new StoredMerklePatriciaTrie<>( + merkleStorage::get, root, + Function.identity(), + Function.identity()); + } + + private Protocol.Block getBlockByNumber(long blockNumber) throws IOException { + try { + DBInterface blockDb = getDb(BLOCK_DB_NAME); + DBInterface blockIndexDb = getDb(BLOCK_INDEX_DB_NAME); + byte[] value = blockDb.get(blockIndexDb.get(ByteArray.fromLong(blockNumber))); + if (value == null || value.length == 0) { + throw new IOException("can not find block, number: " + blockNumber); + } + return Protocol.Block.parseFrom(value); + } catch (IOException | RocksDBException e) { + throw new IOException("get block number failed, " + e.getMessage()); + } + } + + /** + * get db object (can not get state db) + */ + private DBInterface getDb(String dbName) throws IOException, RocksDBException { + File dbDir = getAndCheckDbPath(srcDirectory.toString(), dbName, config).toFile(); + Path dbParentPath = dbDir.toPath().getParent(); + return DbTool.getDB(dbParentPath.toString(), dbName); + } + + private Path getDbPath(String outputDir, String dbName, Config config) { + String confPath = String.format("%s.%s", PROPERTIES_CONFIG_KEY, dbName); + if (config.hasPath(confPath)) { + return Paths.get(config.getString(confPath)); + } else { + return Paths.get(outputDir, config.getString(DB_DIRECTORY_CONFIG_KEY), dbName); + } + } + + private Path getAndCheckDbPath(String outputDir, String dbName, Config config) + throws IOException { + File file = getDbPath(outputDir, dbName, config).toFile(); + if (!file.exists() || !file.isDirectory()) { + String errMsg = String.format("%s database does not exist.", BLOCK_DB_NAME); + print(errMsg, true); + throw new IOException(errMsg); + } + return file.toPath(); + } + + private Map checkAndGetBlockNumberRange( + String databaseDir, String stateDir, long reserveNumber) { + Map result = Maps.newHashMap(); + String errMsg; + if (reserveNumber < 1) { + errMsg = "reserveNumber must bigger than 0"; + print(errMsg, true); + return null; + } + try { + long latestBlockNumber = new DbLite().getLatestBlockHeaderNum(databaseDir); + long stateInitNumber = getStateInitNumber(stateDir); + if (stateInitNumber == -1) { + return null; + } + if (reserveNumber > Math.subtractExact(latestBlockNumber, stateInitNumber)) { + errMsg = String.format("reserveNumber is bigger than the block gap. " + + "reserveNumber: %d, latestBlockNumber: %d, earliestBlockNumber: %d", + reserveNumber, latestBlockNumber, stateInitNumber); + print(errMsg, true); + return null; + } + result.put("start", stateInitNumber); + result.put("end", latestBlockNumber); + } catch (IOException | RocksDBException e) { + errMsg = String.format("checkReserveNumber failed, err: %s", e.getMessage()); + print(errMsg, true); + return null; + } + return result; + } + + private long getStateInitNumber(String stateDir) { + File f = Paths.get(stateDir, STATE_GENESIS_META_FILE).toFile(); + if (!f.exists()) { + String err = "state genesis meta file not exist."; + print(err, true); + return -1; + } + return Long.parseLong(FileUtils.readProperty(f.getPath(), "height")); + } + + private void initReservedKeyStore(Path path) { + RESERVED_KEY_STORE_PATH = Paths.get(path.toString(), + String.format(".reserved-keys-%s", System.currentTimeMillis())); + markedKeyStore = new RocksDBKeyValueStorage( + new RocksDBConfigurationBuilder().databaseDir(RESERVED_KEY_STORE_PATH).build()); + } + + private void destoryPrunedKeyStore() throws IOException { + markedKeyStore.close(); + FileUtils.deleteDir(RESERVED_KEY_STORE_PATH.toFile()); + } + + private void releaseResource() throws IOException { + DbTool.close(); + destoryPrunedKeyStore(); + srcKvStorage.close(); + destDb.close(); + } + + private void print(String msg, boolean err) { + if (err) { + spec.commandLine().getErr().println( + spec.commandLine().getColorScheme().errorText(msg)); + } else { + spec.commandLine().getOut().println(msg); + } + } + + private boolean checkPrunedDir(String prunedDir) { + File file = Paths.get(prunedDir).toFile(); + if (file.exists()) { + print("Pruned output path is already exist!", true); + return false; + } else if (!file.mkdirs()) { + print("Pruned output path create failed!", true); + return false; + } + return true; + } + + static class ConfigConverter implements CommandLine.ITypeConverter { + ConfigConverter() { + } + + public Config convert(String value) throws Exception { + if (help) { + return null; + } + File file = Paths.get(value).toFile(); + if (file.exists() && file.isFile()) { + return ConfigFactory.parseFile(Paths.get(value).toFile()); + } else { + throw new IOException("Parse Config [" + value + "] failed!"); + } + } + } + +} \ No newline at end of file diff --git a/plugins/src/main/java/org/tron/plugins/utils/FileUtils.java b/plugins/src/main/java/org/tron/plugins/utils/FileUtils.java index b07b4469dc3..ff3eb1971e0 100644 --- a/plugins/src/main/java/org/tron/plugins/utils/FileUtils.java +++ b/plugins/src/main/java/org/tron/plugins/utils/FileUtils.java @@ -19,6 +19,7 @@ import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.List; +import java.util.Map; import java.util.Properties; import lombok.extern.slf4j.Slf4j; @@ -66,6 +67,23 @@ public static boolean writeProperty(String file, String key, String value) { return true; } + public static boolean writeProperties(String file, Map kv) { + try (OutputStream o = new FileOutputStream(file); + FileInputStream f = new FileInputStream(file); + BufferedWriter w = new BufferedWriter(new OutputStreamWriter(o, StandardCharsets.UTF_8)); + BufferedReader r = new BufferedReader(new InputStreamReader(f, StandardCharsets.UTF_8)) + ) { + Properties properties = new Properties(); + properties.load(r); + kv.forEach(properties::setProperty); + properties.store(w, "Generated by the application. PLEASE DO NOT EDIT! "); + } catch (Exception e) { + logger.warn("writeProperty", e); + return false; + } + return true; + } + /** * delete directory. diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/AllNodesVisitor.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/AllNodesVisitor.java index 3c4d4f6b4b2..123abd4fabc 100644 --- a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/AllNodesVisitor.java +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/AllNodesVisitor.java @@ -14,16 +14,24 @@ */ package org.hyperledger.besu.ethereum.trie; +import java.util.concurrent.ExecutorService; import java.util.function.Consumer; public class AllNodesVisitor implements NodeVisitor { private final Consumer> handler; + private ExecutorService executorService; + AllNodesVisitor(final Consumer> handler) { this.handler = handler; } + AllNodesVisitor(final Consumer> handler, ExecutorService executorService) { + this.handler = handler; + this.executorService = executorService; + } + @Override public void visit(final ExtensionNode extensionNode) { handler.accept(extensionNode); @@ -33,7 +41,16 @@ public void visit(final ExtensionNode extensionNode) { @Override public void visit(final BranchNode branchNode) { handler.accept(branchNode); - branchNode.getChildren().forEach(this::acceptAndUnload); + if (executorService == null) { + branchNode.getChildren().forEach(this::acceptAndUnload); + } else { + branchNode.getChildren().forEach(child-> { + executorService.submit( () -> { + child.accept(this); + child.unload(); + }); + }); + } } @Override diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StoredMerklePatriciaTrie.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StoredMerklePatriciaTrie.java index 25d150e13b1..52b6ddad591 100644 --- a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StoredMerklePatriciaTrie.java +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/StoredMerklePatriciaTrie.java @@ -214,7 +214,8 @@ public CompletableFuture visitAll( .map( rootChild -> CompletableFuture.runAsync( - () -> rootChild.accept(new AllNodesVisitor<>(nodeConsumer)), + () -> rootChild.accept(new AllNodesVisitor<>(nodeConsumer, executorService)), + //() -> rootChild.accept(new AllNodesVisitor<>(nodeConsumer)), executorService))) .collect(Collectors.collectingAndThen( Collectors.toSet(), From 615331c778f64864a5e2cb0eb815c50347bc1210 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Fri, 10 Mar 2023 17:28:38 +0800 Subject: [PATCH 03/34] feat(trie): ignore some keys for properties db 1. key for helpers to mark something done 2. ignore configuration on effects --- framework/src/main/java/org/tron/core/db/Manager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/main/java/org/tron/core/db/Manager.java b/framework/src/main/java/org/tron/core/db/Manager.java index b16b561f5d1..0fa458ef938 100644 --- a/framework/src/main/java/org/tron/core/db/Manager.java +++ b/framework/src/main/java/org/tron/core/db/Manager.java @@ -474,6 +474,7 @@ public void init() { chainBaseManager.setMerkleContainer(getMerkleContainer()); chainBaseManager.setMortgageService(mortgageService); this.initGenesis(); + worldStateCallBack.setExecute(false); try { this.khaosDb.start(chainBaseManager.getBlockById( getDynamicPropertiesStore().getLatestBlockHeaderHash())); @@ -563,7 +564,6 @@ public void init() { } maxFlushCount = CommonParameter.getInstance().getStorage().getMaxFlushCount(); - worldStateCallBack.setExecute(false); } /** From b2dea18fe22c5606a753103d37bba4dd69357b2b Mon Sep 17 00:00:00 2001 From: guoquanwu Date: Fri, 10 Mar 2023 19:21:02 +0800 Subject: [PATCH 04/34] fix(rpc): keep json rpc return code compatible with prev version --- .../services/jsonrpc/TronJsonRpcImpl.java | 45 ++++++++++++++----- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index 8fddf024383..f46781b0108 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -138,6 +138,8 @@ public enum RequestSource { private static final String JSON_ERROR = "invalid json request"; private static final String BLOCK_NUM_ERROR = "invalid block number"; private static final String TAG_NOT_SUPPORT_ERROR = "TAG [earliest | pending] not supported"; + private static final String QUANTITY_NOT_SUPPORT_ERROR = + "QUANTITY not supported, just support TAG as latest"; private static final String NO_BLOCK_HEADER = "header not found"; private static final String NO_BLOCK_HEADER_BY_HASH = "header for hash not found"; @@ -150,6 +152,9 @@ public enum RequestSource { private final Wallet wallet; private final Manager manager; + private final boolean allowStateRoot = CommonParameter.getInstance().getStorage() + .isAllowStateRoot(); + public TronJsonRpcImpl(NodeInfoService nodeInfoService, Wallet wallet, Manager manager) { this.nodeInfoService = nodeInfoService; this.wallet = wallet; @@ -358,7 +363,11 @@ public String getTrxBalance(String address, String blockNumOrTag) } catch (Exception e) { throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR); } - reply = wallet.getAccount(addressData, blockNumber.longValue()); + if (allowStateRoot) { + reply = wallet.getAccount(addressData, blockNumber.longValue()); + } else { + throw new JsonRpcInvalidParamsException(QUANTITY_NOT_SUPPORT_ERROR); + } } long balance = 0; @@ -386,7 +395,11 @@ public Map getToken10(String address, String blockNumOrTag) } catch (Exception e) { throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR); } - reply = wallet.getAccountToken10(addressData, blockNumber.longValue()); + if (allowStateRoot) { + reply = wallet.getAccountToken10(addressData, blockNumber.longValue()); + } else { + throw new JsonRpcInvalidParamsException(QUANTITY_NOT_SUPPORT_ERROR); + } } Map token10s = new TreeMap<>(); @@ -537,8 +550,12 @@ public String getStorageAt(String address, String storageIdx, String blockNumOrT } catch (Exception e) { throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR); } - byte[] value = wallet.getStorageAt(addressByte, storageIdx, blockNumber.longValue()); - return ByteArray.toJsonHex(value == null ? new byte[32] : value); + if (allowStateRoot) { + byte[] value = wallet.getStorageAt(addressByte, storageIdx, blockNumber.longValue()); + return ByteArray.toJsonHex(value == null ? new byte[32] : value); + } else { + throw new JsonRpcInvalidParamsException(QUANTITY_NOT_SUPPORT_ERROR); + } } } @@ -567,8 +584,12 @@ public String getABIOfSmartContract(String contractAddress, String blockNumOrTag } catch (Exception e) { throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR); } - byte[] code = wallet.getCode(addressData, blockNumber.longValue()); - return code != null ? ByteArray.toJsonHex(code) : "0x"; + if (allowStateRoot) { + byte[] code = wallet.getCode(addressData, blockNumber.longValue()); + return code != null ? ByteArray.toJsonHex(code) : "0x"; + } else { + throw new JsonRpcInvalidParamsException(QUANTITY_NOT_SUPPORT_ERROR); + } } } @@ -861,11 +882,15 @@ public String getCall(CallArguments transactionCall, Object blockParamObj) } catch (Exception e) { throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR); } - byte[] addressData = addressCompatibleToByteArray(transactionCall.getFrom()); - byte[] contractAddressData = addressCompatibleToByteArray(transactionCall.getTo()); + if (allowStateRoot) { + byte[] addressData = addressCompatibleToByteArray(transactionCall.getFrom()); + byte[] contractAddressData = addressCompatibleToByteArray(transactionCall.getTo()); - return call(addressData, contractAddressData, transactionCall.parseValue(), - ByteArray.fromHexString(transactionCall.getData()), blockNumber); + return call(addressData, contractAddressData, transactionCall.parseValue(), + ByteArray.fromHexString(transactionCall.getData()), blockNumber); + } else { + throw new JsonRpcInvalidParamsException(QUANTITY_NOT_SUPPORT_ERROR); + } } } From 297fd5702291a3717f865d74f8dbe01136acb8b0 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Fri, 10 Mar 2023 19:15:37 +0800 Subject: [PATCH 05/34] fix(trie): force set netty version to 4.1.27.Final --- build.gradle | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 42c36101b44..82c7999d51e 100644 --- a/build.gradle +++ b/build.gradle @@ -67,8 +67,14 @@ subprojects { } configurations.all { - resolutionStrategy { - force group: 'com.google.guava', name: 'guava', version: '30.1-jre' + resolutionStrategy.eachDependency { details -> + if (details.requested.group == 'com.google.guava' && details.requested.name == 'guava') { + details.useVersion "30.1-jre" + } + // TODO if update grpc remove + if(details.requested.group == 'io.netty') { + details.useVersion "4.1.27.Final" + } } resolutionStrategy.eachDependency { details -> // TODO if update grpc remove From a65eb7e04ff5e28380ad46d92a7c5231e1c493ac Mon Sep 17 00:00:00 2001 From: guoquanwu Date: Mon, 13 Mar 2023 11:49:21 +0800 Subject: [PATCH 06/34] fix(json-rpc): fix compatibility of eth_call --- .../java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index f46781b0108..4396ae7d4ea 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -860,6 +860,9 @@ public String getCall(CallArguments transactionCall, Object blockParamObj) } else { throw new JsonRpcInvalidRequestException(JSON_ERROR); } + if (!allowStateRoot) { + blockNumOrTag = LATEST_STR; + } } else if (blockParamObj instanceof String) { blockNumOrTag = (String) blockParamObj; } else { From d8d76713a458905aeef78517dc89a7536c511ebd Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Wed, 15 Mar 2023 12:09:13 +0800 Subject: [PATCH 07/34] feat(trie): optimize token10 API for jsonrpc 1. add tron_getAssetById 2. make tron_getToken10 return list 3. rename from tron_getToken10 to tron_getAssets --- .../src/main/java/org/tron/core/Constant.java | 2 + .../src/main/java/org/tron/core/Wallet.java | 8 +- .../core/services/jsonrpc/TronJsonRpc.java | 30 ++- .../services/jsonrpc/TronJsonRpcImpl.java | 66 ++++- .../tron/core/state/WorldStateQueryTest.java | 238 ++++++++++++++++-- 5 files changed, 317 insertions(+), 27 deletions(-) diff --git a/common/src/main/java/org/tron/core/Constant.java b/common/src/main/java/org/tron/core/Constant.java index dea5a2534b9..54b2932018e 100644 --- a/common/src/main/java/org/tron/core/Constant.java +++ b/common/src/main/java/org/tron/core/Constant.java @@ -373,4 +373,6 @@ public class Constant { public static final String DYNAMIC_CONFIG_CHECK_INTERVAL = "node.dynamicConfig.checkInterval"; public static final String COMMITTEE_ALLOW_TVM_SHANGHAI = "committee.allowTvmShangHai"; + + public static final long TOKEN_NUM_START = 1000000L; } diff --git a/framework/src/main/java/org/tron/core/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java index e92738fe073..9be23034a4f 100755 --- a/framework/src/main/java/org/tron/core/Wallet.java +++ b/framework/src/main/java/org/tron/core/Wallet.java @@ -377,14 +377,18 @@ private void sortFrozenV2List(AccountCapsule accountCapsule) { } } - public Account getAccountToken10(byte[] address, long blockNumber) { + public Account getAccountToken10(byte[] address, long tokenId, long blockNumber) { Bytes32 rootHash = getRootHashByNumber(blockNumber); WorldStateQueryInstance worldStateQueryInstance = initWorldStateQueryInstance(rootHash); AccountCapsule accountCapsule = worldStateQueryInstance.getAccount(address); if (accountCapsule == null) { return null; } - accountCapsule.importAllAsset(); + if (tokenId == -1) { + accountCapsule.importAllAsset(); + } else { + accountCapsule.importAsset(String.valueOf(tokenId).getBytes()); + } return accountCapsule.getInstance(); } diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java index 0274e7fc560..7e8a1679b51 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java @@ -7,9 +7,9 @@ import com.googlecode.jsonrpc4j.JsonRpcMethod; import java.io.IOException; import java.util.List; -import java.util.Map; import java.util.concurrent.ExecutionException; import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -90,12 +90,19 @@ BlockResult ethGetBlockByNumber(String bnOrId, Boolean fullTransactionObjects) String getTrxBalance(String address, String blockNumOrTag) throws JsonRpcInvalidParamsException; - @JsonRpcMethod("tron_getToken10") + @JsonRpcMethod("tron_getAssets") @JsonRpcErrors({ @JsonRpcError(exception = JsonRpcInvalidParamsException.class, code = -32602, data = "{}"), }) - Map getToken10(String address, String blockNumOrTag) - throws JsonRpcInvalidParamsException; + List getToken10(String address, String blockNumOrTag) + throws JsonRpcInvalidParamsException; + + @JsonRpcMethod("tron_getAssetById") + @JsonRpcErrors({ + @JsonRpcError(exception = JsonRpcInvalidParamsException.class, code = -32602, data = "{}"), + }) + Token10Result getToken10ById(String address, String tokenId, String blockNumOrTag) + throws JsonRpcInvalidParamsException; @JsonRpcMethod("eth_getStorageAt") @JsonRpcErrors({ @@ -474,4 +481,19 @@ public LogFilterElement(String blockHash, Long blockNum, String txId, Integer tx this.removed = removed; } } + + @AllArgsConstructor + @JsonPropertyOrder + @EqualsAndHashCode + class Token10Result { + @Getter + private final String key; + @Getter + private final String value; + + @Override + public String toString() { + return JSONObject.toJSONString(this); + } + } } diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index 4396ae7d4ea..e065164ad32 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -15,13 +15,13 @@ import com.google.protobuf.GeneratedMessageV3; import java.math.BigInteger; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -33,6 +33,8 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.bouncycastle.util.encoders.Hex; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; import org.tron.api.GrpcAPI.BytesMessage; import org.tron.api.GrpcAPI.EstimateEnergyMessage; import org.tron.api.GrpcAPI.Return; @@ -46,6 +48,7 @@ import org.tron.common.runtime.vm.DataWord; import org.tron.common.utils.ByteArray; import org.tron.common.utils.ByteUtil; +import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.TransactionCapsule; @@ -94,6 +97,7 @@ import org.tron.protos.contract.SmartContractOuterClass.TriggerSmartContract; @Slf4j(topic = "API") +@Component public class TronJsonRpcImpl implements TronJsonRpc { public enum RequestSource { @@ -155,7 +159,8 @@ public enum RequestSource { private final boolean allowStateRoot = CommonParameter.getInstance().getStorage() .isAllowStateRoot(); - public TronJsonRpcImpl(NodeInfoService nodeInfoService, Wallet wallet, Manager manager) { + public TronJsonRpcImpl(@Autowired NodeInfoService nodeInfoService, + @Autowired Wallet wallet, @Autowired Manager manager) { this.nodeInfoService = nodeInfoService; this.wallet = wallet; this.manager = manager; @@ -378,7 +383,7 @@ public String getTrxBalance(String address, String blockNumOrTag) } @Override - public Map getToken10(String address, String blockNumOrTag) + public List getToken10(String address, String blockNumOrTag) throws JsonRpcInvalidParamsException { byte[] addressData = addressCompatibleToByteArray(address); Account reply; @@ -396,20 +401,67 @@ public Map getToken10(String address, String blockNumOrTag) throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR); } if (allowStateRoot) { - reply = wallet.getAccountToken10(addressData, blockNumber.longValue()); + reply = wallet.getAccountToken10(addressData, -1, blockNumber.longValue()); } else { throw new JsonRpcInvalidParamsException(QUANTITY_NOT_SUPPORT_ERROR); } } - Map token10s = new TreeMap<>(); + List token10s = new ArrayList<>(); if (reply != null) { - reply.getAssetV2Map().forEach((k, v) -> token10s.put(ByteArray.toJsonHex(k), - ByteArray.toJsonHex(v))); + reply.getAssetV2Map().entrySet().stream().filter(e -> e.getValue() > 0).map(e -> + new Token10Result(ByteArray.toJsonHex(Long.parseUnsignedLong(e.getKey())), + ByteArray.toJsonHex(e.getValue()))).forEach(token10s::add); } return token10s; } + @Override + public Token10Result getToken10ById(String address, String tokenId, String blockNumOrTag) + throws JsonRpcInvalidParamsException { + + long tokenNum; + String tokenStr; + try { + tokenNum = ByteArray.hexToBigInteger(tokenId).longValue(); + if (tokenNum < Constant.TOKEN_NUM_START + || tokenNum > manager.getDynamicPropertiesStore().getTokenIdNum()) { + throw new JsonRpcInvalidParamsException("invalid token id"); + } + tokenStr = Long.toString(tokenNum); + } catch (Exception e) { + throw new JsonRpcInvalidParamsException("invalid token id"); + } + + byte[] addressData = addressCompatibleToByteArray(address); + Account reply; + if (EARLIEST_STR.equalsIgnoreCase(blockNumOrTag) + || PENDING_STR.equalsIgnoreCase(blockNumOrTag)) { + throw new JsonRpcInvalidParamsException(TAG_NOT_SUPPORT_ERROR); + } else if (LATEST_STR.equalsIgnoreCase(blockNumOrTag)) { + Account account = Account.newBuilder().setAddress(ByteString.copyFrom(addressData)).build(); + reply = wallet.getAccount(account); + } else { + BigInteger blockNumber; + try { + blockNumber = ByteArray.hexToBigInteger(blockNumOrTag); + } catch (Exception e) { + throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR); + } + if (allowStateRoot) { + reply = wallet.getAccountToken10(addressData, tokenNum, blockNumber.longValue()); + } else { + throw new JsonRpcInvalidParamsException(QUANTITY_NOT_SUPPORT_ERROR); + } + } + + long amt = 0; + if (reply != null) { + amt = reply.getAssetV2Map().getOrDefault(tokenStr, 0L); + } + return new Token10Result(tokenId, ByteArray.toJsonHex(amt)); + } + private void callTriggerConstantContract(byte[] ownerAddressByte, byte[] contractAddressByte, long value, byte[] data, TransactionExtention.Builder trxExtBuilder, Return.Builder retBuilder, long blockNumber) diff --git a/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java b/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java index c4560c8dea0..12694ae1875 100644 --- a/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java +++ b/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java @@ -3,7 +3,10 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.apache.tuweni.bytes.Bytes32; import org.junit.AfterClass; import org.junit.Assert; @@ -23,17 +26,22 @@ import org.tron.common.utils.WalletUtil; import org.tron.core.ChainBaseManager; import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.AssetIssueCapsule; import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.ContractCapsule; import org.tron.core.capsule.TransactionCapsule; import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; import org.tron.core.db.Manager; -import org.tron.core.services.RpcApiService; -import org.tron.core.services.interfaceOnSolidity.RpcApiServiceOnSolidity; +import org.tron.core.exception.JsonRpcInternalException; +import org.tron.core.exception.JsonRpcInvalidParamsException; +import org.tron.core.exception.JsonRpcInvalidRequestException; +import org.tron.core.services.jsonrpc.TronJsonRpc; +import org.tron.core.services.jsonrpc.types.CallArguments; import org.tron.core.vm.program.Storage; import org.tron.protos.Protocol; import org.tron.protos.Protocol.Transaction.Contract.ContractType; +import org.tron.protos.contract.AssetIssueContractOuterClass; import org.tron.protos.contract.BalanceContract; public class WorldStateQueryTest { @@ -43,6 +51,9 @@ public class WorldStateQueryTest { private static Manager manager; private static String dbPath = "output-directory-state"; + private static TronJsonRpc tronJsonRpc; + private static final long TOKEN_ID1 = 1000001L; + private static final long TOKEN_ID2 = 1000002L; private ECKey account1Prikey = ECKey.fromPrivate(ByteArray.fromHexString( "D95611A9AF2A2A45359106222ED1AFED48853D9A44DEFF8DC7913F5CBA727366")); @@ -56,6 +67,9 @@ public class WorldStateQueryTest { */ @BeforeClass public static void init() { + if (FileUtil.isExists(dbPath)) { + FileUtil.deleteDir(new File(dbPath)); + } Args.setParam(new String[]{"-d", dbPath}, "config-localtest.conf"); // allow account root Args.getInstance().setAllowAccountStateRoot(1); @@ -63,24 +77,71 @@ public static void init() { Args.getInstance().dbBackupConfig = DbBackupConfig.getInstance(); context = new TronApplicationContext(DefaultConfig.class); appTest = ApplicationFactory.create(context); - appTest.addService(context.getBean(RpcApiService.class)); - appTest.addService(context.getBean(RpcApiServiceOnSolidity.class)); appTest.initServices(Args.getInstance()); appTest.startServices(); appTest.startup(); chainBaseManager = context.getBean(ChainBaseManager.class); manager = context.getBean(Manager.class); + tronJsonRpc = context.getBean(TronJsonRpc.class); } @AfterClass - public static void destory() { + public static void destroy() { appTest.shutdown(); Args.clearParam(); FileUtil.deleteDir(new File(dbPath)); } + public void createAsset() { + Assert.assertEquals(TOKEN_ID1,manager.getDynamicPropertiesStore().getTokenIdNum() + 1); + manager.getDynamicPropertiesStore().saveTokenIdNum(TOKEN_ID1); + AssetIssueContractOuterClass.AssetIssueContract assetIssueContract = + AssetIssueContractOuterClass.AssetIssueContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(account1Prikey.getAddress())) + .setName(ByteString.copyFrom(ByteArray.fromString("token1"))) + .setId(Long.toString(TOKEN_ID1)) + .setTotalSupply(10) + .setTrxNum(10) + .setNum(1) + .setStartTime(1) + .setEndTime(2) + .setVoteScore(2) + .setDescription(ByteString.copyFrom(ByteArray.fromString("token1"))) + .setUrl(ByteString.copyFrom(ByteArray.fromString("https://tron.network"))) + .build(); + AssetIssueCapsule assetIssueCapsule = new AssetIssueCapsule(assetIssueContract); + manager.getAssetIssueV2Store() + .put(assetIssueCapsule.createDbV2Key(), assetIssueCapsule); + + Assert.assertEquals(TOKEN_ID2,manager.getDynamicPropertiesStore().getTokenIdNum() + 1); + manager.getDynamicPropertiesStore().saveTokenIdNum(TOKEN_ID2); + AssetIssueContractOuterClass.AssetIssueContract assetIssueContract2 = + AssetIssueContractOuterClass.AssetIssueContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(account1Prikey.getAddress())) + .setName(ByteString.copyFrom(ByteArray.fromString("token2"))) + .setId(Long.toString(TOKEN_ID2)) + .setTotalSupply(10) + .setTrxNum(10) + .setNum(1) + .setStartTime(1) + .setEndTime(2) + .setVoteScore(2) + .setDescription(ByteString.copyFrom(ByteArray.fromString("token2"))) + .setUrl(ByteString.copyFrom(ByteArray.fromString("https://tron.network"))) + .build(); + AssetIssueCapsule assetIssueCapsule2 = new AssetIssueCapsule(assetIssueContract2); + manager.getAssetIssueV2Store() + .put(assetIssueCapsule2.createDbV2Key(), assetIssueCapsule2); + AccountCapsule ownerCapsule = manager.getAccountStore() + .get(account1Prikey.getAddress()); + ownerCapsule.addAssetV2(Long.toString(TOKEN_ID1).getBytes(), 1000); + ownerCapsule.addAssetV2(Long.toString(TOKEN_ID2).getBytes(), 5000); + manager.getAccountStore().put(ownerCapsule.getAddress().toByteArray(), ownerCapsule); + + } + @Test - public void testTransfer() throws InterruptedException { + public void testTransfer() throws InterruptedException, JsonRpcInvalidParamsException { manager.initGenesis(); List blockCapsules = chainBaseManager .getBlockStore().getBlockByLatestNum(1); @@ -95,7 +156,7 @@ public void testTransfer() throws InterruptedException { blockCapsule = blockCapsules.get(0); Bytes32 rootHash = blockCapsule.getArchiveRoot(); WorldStateQueryInstance worldStateQueryInstance = ChainBaseManager.fetch(rootHash); - checkAccount(worldStateQueryInstance); + checkAccount(worldStateQueryInstance, blockCapsule.getNum()); try { manager.pushBlock(buildTransferBlock(blockCapsule)); @@ -108,11 +169,45 @@ public void testTransfer() throws InterruptedException { blockCapsule = blockCapsules.get(0); rootHash = blockCapsule.getArchiveRoot(); worldStateQueryInstance = ChainBaseManager.fetch(rootHash); - checkAccount(worldStateQueryInstance); + checkAccount(worldStateQueryInstance, blockCapsule.getNum()); + } + + @Test + public void testTransferAsset() throws InterruptedException, JsonRpcInvalidParamsException { + createAsset(); + manager.initGenesis(); + List blockCapsules = chainBaseManager + .getBlockStore().getBlockByLatestNum(1); + BlockCapsule blockCapsule = blockCapsules.get(0); + try { + manager.pushBlock(buildTransferAssetBlock(blockCapsule)); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + Thread.sleep(3000); + blockCapsules = chainBaseManager.getBlockStore().getBlockByLatestNum(1); + blockCapsule = blockCapsules.get(0); + Bytes32 rootHash = blockCapsule.getArchiveRoot(); + WorldStateQueryInstance worldStateQueryInstance = ChainBaseManager.fetch(rootHash); + checkAccount(worldStateQueryInstance, blockCapsule.getNum()); + + try { + manager.pushBlock(buildTransferAssetBlock(blockCapsule)); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + Thread.sleep(3000); + + blockCapsules = chainBaseManager.getBlockStore().getBlockByLatestNum(1); + blockCapsule = blockCapsules.get(0); + rootHash = blockCapsule.getArchiveRoot(); + worldStateQueryInstance = ChainBaseManager.fetch(rootHash); + checkAccount(worldStateQueryInstance, blockCapsule.getNum()); } @Test - public void testContract() throws InterruptedException { + public void testContract() throws InterruptedException, JsonRpcInvalidParamsException, + JsonRpcInvalidRequestException, JsonRpcInternalException { manager.initGenesis(); List blockCapsules = chainBaseManager .getBlockStore().getBlockByLatestNum(1); @@ -129,7 +224,7 @@ public void testContract() throws InterruptedException { WorldStateQueryInstance worldStateQueryInstance = ChainBaseManager.fetch(rootHash); Assert.assertArrayEquals(chainBaseManager.getContractStore().get(contractAddress).getData(), worldStateQueryInstance.getContract(contractAddress).getData()); - checkAccount(worldStateQueryInstance); + checkAccount(worldStateQueryInstance, blockCapsule.getNum()); try { manager.pushBlock(buildTriggerBlock(blockCapsule)); @@ -151,22 +246,104 @@ public void testContract() throws InterruptedException { DataWord value2 = storage.getValue(new DataWord(ByteArray.fromHexString("0"))); Assert.assertArrayEquals(value1.getData(), value2.getData()); - checkAccount(worldStateQueryInstance); + checkAccount(worldStateQueryInstance, blockCapsule.getNum()); + Assert.assertEquals(tronJsonRpc.getABIOfSmartContract(ByteArray.toHexString(contractAddress), + ByteArray.toJsonHex(blockCapsule.getNum())), + tronJsonRpc.getABIOfSmartContract(ByteArray.toHexString(contractAddress), + "latest")); + + Assert.assertEquals(tronJsonRpc.getStorageAt(ByteArray.toHexString(contractAddress), + "0x0", ByteArray.toJsonHex(blockCapsule.getNum())), + tronJsonRpc.getStorageAt(ByteArray.toHexString(contractAddress), + "0x0", "latest")); + + byte[] triggerData = TvmTestUtils.parseAbi("increment()", null); + CallArguments callArguments = new CallArguments(); + callArguments.setFrom(ByteArray.toHexString(account1Prikey.getAddress())); + callArguments.setTo(ByteArray.toHexString(contractAddress)); + callArguments.setGas("0x0"); + callArguments.setGasPrice("0x0"); + callArguments.setValue("0x0"); + callArguments.setData(ByteArray.toHexString(triggerData)); + + Assert.assertEquals(tronJsonRpc.getCall(callArguments, ByteArray.toJsonHex( + blockCapsule.getNum())), tronJsonRpc.getCall(callArguments, "latest")); + + } - private void checkAccount(WorldStateQueryInstance worldStateQueryInstance) { + private void checkAccount(WorldStateQueryInstance worldStateQueryInstance, long blockNum) + throws JsonRpcInvalidParamsException { AccountCapsule account1Capsule = chainBaseManager.getAccountStore() .get(account1Prikey.getAddress()); - account1Capsule.clearAsset(); AccountCapsule account2Capsule = chainBaseManager.getAccountStore() .get(account2Prikey.getAddress()); - account2Capsule.clearAsset(); Assert.assertArrayEquals(account1Capsule.getInstance().toByteArray(), worldStateQueryInstance.getAccount(account1Prikey.getAddress()) .getInstance().toByteArray()); Assert.assertArrayEquals(account2Capsule.getInstance().toByteArray(), worldStateQueryInstance.getAccount(account2Prikey.getAddress()) .getInstance().toByteArray()); + Assert.assertEquals(tronJsonRpc.getTrxBalance( + ByteArray.toHexString(account1Prikey.getAddress()), + ByteArray.toJsonHex(blockNum)), + tronJsonRpc.getTrxBalance( + ByteArray.toHexString(account1Prikey.getAddress()), "latest")); + + Assert.assertEquals(tronJsonRpc.getToken10( + ByteArray.toHexString(account1Prikey.getAddress()), + ByteArray.toJsonHex(blockNum)), + tronJsonRpc.getToken10( + ByteArray.toHexString(account1Prikey.getAddress()), "latest")); + + Assert.assertEquals(tronJsonRpc.getToken10( + ByteArray.toHexString(account2Prikey.getAddress()), + ByteArray.toJsonHex(blockNum)), + tronJsonRpc.getToken10( + ByteArray.toHexString(account2Prikey.getAddress()), "latest")); + + Map asset = new HashMap<>(); + for (TronJsonRpc.Token10Result t : tronJsonRpc.getToken10( + ByteArray.toHexString(account2Prikey.getAddress()), "latest")) { + asset.put(Long.toString(ByteArray.jsonHexToLong(t.getKey())), + ByteArray.jsonHexToLong(t.getValue())); + } + Assert.assertEquals(account2Capsule.getAssetMapV2(), asset); + + Assert.assertEquals(tronJsonRpc.getToken10( + ByteArray.toHexString(account1Prikey.getAddress()), "latest"), + tronJsonRpc.getToken10( + ByteArray.toHexString(account1Prikey.getAddress()), ByteArray.toJsonHex(blockNum))); + + Assert.assertEquals(tronJsonRpc.getToken10ById(ByteArray.toHexString( + account2Prikey.getAddress()), ByteArray.toJsonHex(TOKEN_ID1), + ByteArray.toJsonHex(blockNum)), + tronJsonRpc.getToken10ById(ByteArray.toHexString( + account2Prikey.getAddress()), ByteArray.toJsonHex(TOKEN_ID1), + "latest")); + + Assert.assertEquals(tronJsonRpc.getToken10ById(ByteArray.toHexString( + account2Prikey.getAddress()), ByteArray.toJsonHex(TOKEN_ID2), + ByteArray.toJsonHex(blockNum)), + tronJsonRpc.getToken10ById(ByteArray.toHexString( + account2Prikey.getAddress()), ByteArray.toJsonHex(TOKEN_ID2), + "latest")); + + Assert.assertEquals(account2Capsule.getAssetV2(Long.toString(TOKEN_ID2)), + ByteArray.jsonHexToLong(tronJsonRpc.getToken10ById(ByteArray.toHexString( + account2Prikey.getAddress()), ByteArray.toJsonHex(TOKEN_ID2), + ByteArray.toJsonHex(blockNum)).getValue())); + + List list = new ArrayList<>(); + list.add(tronJsonRpc.getToken10ById(ByteArray.toHexString( + account1Prikey.getAddress()), ByteArray.toJsonHex(TOKEN_ID1), + ByteArray.toJsonHex(blockNum))); + list.add(tronJsonRpc.getToken10ById(ByteArray.toHexString( + account1Prikey.getAddress()), ByteArray.toJsonHex(TOKEN_ID2), + ByteArray.toJsonHex(blockNum))); + + Assert.assertEquals(list, tronJsonRpc.getToken10( + ByteArray.toHexString(account1Prikey.getAddress()), ByteArray.toJsonHex(blockNum))); } private BlockCapsule buildTransferBlock(BlockCapsule parentBlock) { @@ -203,6 +380,39 @@ private BlockCapsule buildTransferBlock(BlockCapsule parentBlock) { return blockCapsule; } + private BlockCapsule buildTransferAssetBlock(BlockCapsule parentBlock) { + TransactionCapsule transactionCapsule = buildTransferAsset(TOKEN_ID1, 5, parentBlock); + TransactionCapsule transactionCapsule2 = buildTransferAsset(TOKEN_ID2, 10, parentBlock); + BlockCapsule blockCapsule = new BlockCapsule(parentBlock.getNum() + 1, + Sha256Hash.wrap(parentBlock.getBlockId().getByteString()), System.currentTimeMillis(), + ByteString.copyFrom(ECKey.fromPrivate(ByteArray.fromHexString( + Args.getLocalWitnesses().getPrivateKey())).getAddress())); + blockCapsule.addTransaction(transactionCapsule); + blockCapsule.addTransaction(transactionCapsule2); + blockCapsule.setMerkleRoot(); + blockCapsule.sign(ByteArray.fromHexString(Args.getLocalWitnesses().getPrivateKey())); + return blockCapsule; + } + + private TransactionCapsule buildTransferAsset(long token, long amt, BlockCapsule parentBlock) { + AssetIssueContractOuterClass.TransferAssetContract transferAssetContract = + AssetIssueContractOuterClass.TransferAssetContract.newBuilder() + .setAssetName(ByteString.copyFrom(Long.toString(token).getBytes())) + .setOwnerAddress(ByteString.copyFrom(account1Prikey.getAddress())) + .setToAddress(ByteString.copyFrom(account2Prikey.getAddress())) + .setAmount(amt) + .build(); + + Protocol.Transaction.raw.Builder transactionBuilder = Protocol.Transaction.raw.newBuilder() + .addContract(Protocol.Transaction.Contract.newBuilder() + .setType(ContractType.TransferAssetContract) + .setParameter(Any.pack(transferAssetContract)) + .build()); + Protocol.Transaction transaction = Protocol.Transaction.newBuilder() + .setRawData(transactionBuilder.build()).build(); + return setAndSignTx(transaction, parentBlock, account1Prikey); + } + private BlockCapsule buildContractBlock(BlockCapsule parentBlock) { long value = 0L; long feeLimit = 1_000_000_000L; From c2fd11ed4b4f9a952070d66d3e5094c3b3df0dac Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Wed, 15 Mar 2023 22:23:30 +0800 Subject: [PATCH 08/34] fix(trie): fix token10 API for jsonrpc 1. fix range queries for tron_getAssets when not exist in state trie 2. fix query from worldStateGenesis for tron_getAssetById 3. fix test error 4. add test --- .../core/state/WorldStateQueryInstance.java | 4 +- .../org/tron/core/state/trie/TrieImpl2.java | 15 ++- .../state/WorldStateQueryInstanceTest.java | 32 ++++- .../java/org/tron/core/tire/Trie2Test.java | 116 +++++++++++++++--- 4 files changed, 147 insertions(+), 20 deletions(-) diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java b/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java index 30577b5b2e4..d2db9f568ca 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java @@ -86,7 +86,9 @@ public Long getAccountAsset(byte[] address, long tokenId) { } return value.toLong(); } - byte[] v = worldStateGenesis.get(StateType.AccountAsset, key); + byte[] v = worldStateGenesis.get(StateType.AccountAsset, + com.google.common.primitives.Bytes.concat(address, + Long.toString(tokenId).getBytes())); return Objects.nonNull(v) ? Longs.fromByteArray(v) : null; } diff --git a/chainbase/src/main/java/org/tron/core/state/trie/TrieImpl2.java b/chainbase/src/main/java/org/tron/core/state/trie/TrieImpl2.java index 426f420a63a..4cc33be5e7e 100644 --- a/chainbase/src/main/java/org/tron/core/state/trie/TrieImpl2.java +++ b/chainbase/src/main/java/org/tron/core/state/trie/TrieImpl2.java @@ -142,13 +142,24 @@ public void clear() { throw new RuntimeException("Not implemented yet"); } + /** + * NOTE: This is an exact range query. + * + * @see RangeStorageEntriesCollector#onLeaf(Bytes32, Node) + * @code {eth/protocols/snap/handler.go:283} + * @link https://github.com/hyperledger/besu/issues/5222 + * @param startKeyHash start,include + * @param endKeyHash end,include + * @return exact range query. + */ public TreeMap entriesFrom(Bytes32 startKeyHash, Bytes32 endKeyHash) { final RangeStorageEntriesCollector collector = RangeStorageEntriesCollector.createCollector( startKeyHash, endKeyHash, Integer.MAX_VALUE, Integer.MAX_VALUE); final TrieIterator visitor = RangeStorageEntriesCollector.createVisitor(collector); - return (TreeMap) - this.entriesFrom(root -> RangeStorageEntriesCollector.collectEntries(collector, visitor, + final TreeMap origin = (TreeMap) + this.entriesFrom(root -> RangeStorageEntriesCollector.collectEntries(collector, visitor, root, startKeyHash)); + return new TreeMap<>(origin.subMap(startKeyHash, true, endKeyHash, true)); } public Map entriesFrom(final Function, Map> handler) { diff --git a/framework/src/test/java/org/tron/core/state/WorldStateQueryInstanceTest.java b/framework/src/test/java/org/tron/core/state/WorldStateQueryInstanceTest.java index 251e46e70f5..b02d360cf14 100644 --- a/framework/src/test/java/org/tron/core/state/WorldStateQueryInstanceTest.java +++ b/framework/src/test/java/org/tron/core/state/WorldStateQueryInstanceTest.java @@ -9,6 +9,7 @@ import org.apache.commons.lang3.RandomStringUtils; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; +import org.apache.tuweni.units.bigints.UInt256; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -32,6 +33,7 @@ import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; import org.tron.core.state.trie.TrieImpl2; +import org.tron.protos.Protocol; import org.tron.protos.contract.SmartContractOuterClass; public class WorldStateQueryInstanceTest { @@ -98,8 +100,25 @@ private void testGetAccountAsset() { trieImpl2.flush(); byte[] root = trieImpl2.getRootHash(); worldStateQueryInstance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); - Assert.assertEquals(amount, - worldStateQueryInstance.getAccountAsset(address, tokenId).longValue()); + Assert.assertEquals(amount, worldStateQueryInstance.getAccountAsset( + Protocol.Account.newBuilder().setAddress(ByteString.copyFrom(address)).build(), + tokenId)); + Assert.assertEquals(worldStateQueryInstance.getRootHash(),trieImpl2.getRootHashByte32()); + trieImpl2.put( + fix32(StateType.encodeKey(StateType.AccountAsset, + com.google.common.primitives.Bytes.concat(address, Longs.toByteArray(tokenId)))), + UInt256.ZERO); + trieImpl2.commit(); + trieImpl2.flush(); + worldStateQueryInstance = new WorldStateQueryInstance(trieImpl2.getRootHashByte32(), + chainBaseManager); + Assert.assertEquals(0, worldStateQueryInstance.getAccountAsset( + Protocol.Account.newBuilder().setAddress(ByteString.copyFrom(address)).build(), + tokenId)); + Assert.assertFalse(worldStateQueryInstance.hasAssetV2( + Protocol.Account.newBuilder().setAddress(ByteString.copyFrom(address)).build(), + tokenId)); + } private void testGetContractState() { @@ -149,7 +168,8 @@ private void testGetAssetIssue() { } private void testGetWitness() { - byte[] value = new WitnessCapsule(ByteString.copyFrom(ecKey.getPubKey()), "http://").getData(); + byte[] value = new WitnessCapsule(ByteString.copyFrom(ecKey.getPubKey()), "http://") + .getData(); trieImpl2.put(StateType.encodeKey(StateType.Witness, address), Bytes.wrap(value)); trieImpl2.commit(); trieImpl2.flush(); @@ -211,6 +231,12 @@ private void testGetDynamicProperty() { byte[] root = trieImpl2.getRootHash(); worldStateQueryInstance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); Assert.assertArrayEquals(value, worldStateQueryInstance.getDynamicProperty(key).getData()); + try { + worldStateQueryInstance.getDynamicProperty("not-key".getBytes()); + Assert.fail(); + } catch (Exception e) { + Assert.assertTrue(e instanceof IllegalArgumentException); + } } private void testGetDynamicPropertyLong() { diff --git a/framework/src/test/java/org/tron/core/tire/Trie2Test.java b/framework/src/test/java/org/tron/core/tire/Trie2Test.java index 4398e7e2f4c..bed61c25ace 100644 --- a/framework/src/test/java/org/tron/core/tire/Trie2Test.java +++ b/framework/src/test/java/org/tron/core/tire/Trie2Test.java @@ -460,37 +460,112 @@ public void testRange2() { trie.put(Bytes.fromHexString("0x0531303030303031"), Bytes32.ZERO); trie.put(Bytes.fromHexString("0x14414c4c4f575f54564d5f5452414e534645525f5452433130"), Bytes32.ZERO); + trie.put(Bytes.fromHexString("0x14414c4c4f575f41535345545f4f5054494d495a4154494f4e"), + Bytes.fromHexString("0x0000000000000001")); + trie.put(Bytes.fromHexString( "0x02a0abd4b9367799eaa3197fecb144eb71de1e049abc00000000000f42410000"), Bytes.fromHexString("0x0000000005f5e09c")); - trie.put(Bytes.fromHexString("0x14414c4c4f575f41535345545f4f5054494d495a4154494f4e"), - Bytes.fromHexString("0x0000000000000001")); + trie.put(Bytes.fromHexString( + "0x02a0abd4b9367799eaa3197fecb144eb71de1e049abc00000000000f42420000"), + Bytes.fromHexString("0x000000000000009c")); trie.put(Bytes.fromHexString( "0x02a0f9490505f11ffb8d7e3df9789e63ab8709cf457200000000000f42410000"), Bytes.fromHexString("0x0000000000000063")); + trie.put(Bytes.fromHexString( + "0x02a0f9490505f11ffb8d7e3df9789e63ab8709cf457200000000000f42510000"), + Bytes.fromHexString("0x0000000000000049")); trie.put(Bytes.fromHexString( "0x02a0548794500882809695a8a687866e76d4271a1abc00000000000f42410000"), Bytes.fromHexString("0x0000000000000009")); trie.put(Bytes.fromHexString( "0x02a0abd4b9367799eaa3197fecb144eb71de1e049abc00000000000f42410000"), Bytes.fromHexString("0x0000000005f5e094")); + trie.put(Bytes.fromHexString( + "0x02a03c612889142e98bb2f4bc40af2d2b77730baff7a00000000000f55780000"), + Bytes.fromHexString("0x01")); - long tokenId = Bytes.fromHexString("0x00000000000f4241").toLong(); - + Map assets = new HashMap<>(); + // 1. address is before head, not exit Bytes32 min = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), - Bytes.fromHexString("0xa0548794500882809695a8a687866e76d4271a1abc"), + Bytes.fromHexString("413c6120b82a61d0e0bb0c4d4ebfae56cb664ba5a6"), Bytes.ofUnsignedLong(0))); Bytes32 max = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), + Bytes.fromHexString("413c6120b82a61d0e0bb0c4d4ebfae56cb664ba5a6"), + Bytes.ofUnsignedLong(Long.MAX_VALUE))); + + trie.entriesFrom(min, max).forEach((k, v) -> assets.put( + k.slice(Byte.BYTES + ADDRESS_SIZE, Long.BYTES).toLong(), + v.toLong())); + Assert.assertTrue(assets.isEmpty()); + + // 2. address is head + min = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), + Bytes.fromHexString("0xa03c612889142e98bb2f4bc40af2d2b77730baff7a"), + Bytes.ofUnsignedLong(0))); + + max = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), + Bytes.fromHexString("0xa03c612889142e98bb2f4bc40af2d2b77730baff7a"), + Bytes.ofUnsignedLong(Long.MAX_VALUE))); + trie.entriesFrom(min, max).forEach((k, v) -> assets.put( + k.slice(Byte.BYTES + ADDRESS_SIZE, Long.BYTES).toLong(), + v.toLong())); + Assert.assertEquals(Bytes.fromHexString("0x01").toLong(), + assets.get(Bytes.fromHexString("0x00000000000f5578").toLong()).longValue()); + Assert.assertEquals(1, assets.size()); + assets.clear(); + + // 3. address is second + min = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), + Bytes.fromHexString("0xa0548794500882809695a8a687866e76d4271a1abc"), + Bytes.ofUnsignedLong(0))); + + max = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), Bytes.fromHexString("0xa0548794500882809695a8a687866e76d4271a1abc"), Bytes.ofUnsignedLong(Long.MAX_VALUE))); - Map assets = new HashMap<>(); trie.entriesFrom(min, max).forEach((k, v) -> assets.put( k.slice(Byte.BYTES + ADDRESS_SIZE, Long.BYTES).toLong(), v.toLong())); Assert.assertEquals(Bytes.fromHexString("0x0000000000000009").toLong(), - assets.get(tokenId).longValue()); + assets.get(Bytes.fromHexString("0x00000000000f4241").toLong()).longValue()); + Assert.assertEquals(1, assets.size()); + assets.clear(); + + // 4. address is inside, not exit + + min = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), + Bytes.fromHexString("0xa08c6120b82a61d0e0bb0c4d4ebfae56cb664ba5a8"), + Bytes.ofUnsignedLong(0))); + + max = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), + Bytes.fromHexString("0xa08c6120b82a61d0e0bb0c4d4ebfae56cb664ba5a8"), + Bytes.ofUnsignedLong(Long.MAX_VALUE))); + trie.entriesFrom(min, max).forEach((k, v) -> assets.put( + k.slice(Byte.BYTES + ADDRESS_SIZE, Long.BYTES).toLong(), + v.toLong())); + Assert.assertTrue(assets.isEmpty()); + + // 5. address is third + + min = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), + Bytes.fromHexString("0xa0abd4b9367799eaa3197fecb144eb71de1e049abc"), + Bytes.ofUnsignedLong(0))); + + max = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), + Bytes.fromHexString("0xa0abd4b9367799eaa3197fecb144eb71de1e049abc"), + Bytes.ofUnsignedLong(Long.MAX_VALUE))); + trie.entriesFrom(min, max).forEach((k, v) -> assets.put( + k.slice(Byte.BYTES + ADDRESS_SIZE, Long.BYTES).toLong(), + v.toLong())); + Assert.assertEquals(Bytes.fromHexString("0x0000000005f5e094").toLong(), + assets.get(Bytes.fromHexString("0x00000000000f4241").toLong()).longValue()); + Assert.assertEquals(Bytes.fromHexString("0x000000000000009c").toLong(), + assets.get(Bytes.fromHexString("0x00000000000f4242").toLong()).longValue()); + Assert.assertEquals(2, assets.size()); + assets.clear(); + // 6. address is last min = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), Bytes.fromHexString("0xa0f9490505f11ffb8d7e3df9789e63ab8709cf4572"), Bytes.ofUnsignedLong(0))); @@ -498,26 +573,39 @@ public void testRange2() { max = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), Bytes.fromHexString("0xa0f9490505f11ffb8d7e3df9789e63ab8709cf4572"), Bytes.ofUnsignedLong(Long.MAX_VALUE))); - assets.clear(); trie.entriesFrom(min, max).forEach((k, v) -> assets.put( k.slice(Byte.BYTES + ADDRESS_SIZE, Long.BYTES).toLong(), v.toLong())); Assert.assertEquals(Bytes.fromHexString("0x0000000000000063").toLong(), - assets.get(tokenId).longValue()); + assets.get(Bytes.fromHexString("0x00000000000f4241").toLong()).longValue()); + Assert.assertEquals(Bytes.fromHexString("0x0000000000000049").toLong(), + assets.get(Bytes.fromHexString("0x00000000000f4251").toLong()).longValue()); + Assert.assertEquals(2, assets.size()); + assets.clear(); + // 7. address is after last, not exit min = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), - Bytes.fromHexString("a0abd4b9367799eaa3197fecb144eb71de1e049abc"), + Bytes.fromHexString("0xa1f9490505f11ffb8d7e3df9789e63ab8709cf4572"), Bytes.ofUnsignedLong(0))); max = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), - Bytes.fromHexString("a0abd4b9367799eaa3197fecb144eb71de1e049abc"), + Bytes.fromHexString("0xa1f9490505f11ffb8d7e3df9789e63ab8709cf4572"), Bytes.ofUnsignedLong(Long.MAX_VALUE))); - assets.clear(); trie.entriesFrom(min, max).forEach((k, v) -> assets.put( k.slice(Byte.BYTES + ADDRESS_SIZE, Long.BYTES).toLong(), v.toLong())); - Assert.assertEquals(Bytes.fromHexString("0x0000000005f5e094").toLong(), - assets.get(tokenId).longValue()); + Assert.assertTrue(assets.isEmpty()); + + // 8. not fix32,should not error + min = fix32(Bytes.wrap(Bytes.of(StateType.Witness.value()), + Bytes.fromHexString("0xa0"))); + + max = fix32(Bytes.wrap(Bytes.of(StateType.Witness.value()), + Bytes.fromHexString("0xa1"))); + trie.entriesFrom(min, max).forEach((k, v) -> assets.put( + k.slice(Byte.BYTES + ADDRESS_SIZE, Long.BYTES).toLong(), + v.toLong())); + Assert.assertTrue(assets.isEmpty()); } @Test From 1783ff4d1ee1cd6dae7ceaa41279751440d856f7 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Thu, 16 Mar 2023 17:02:14 +0800 Subject: [PATCH 09/34] feat(trie): small improvements for trie and jsonrpc 1. make worldStateTrieStore conditional autowired 2. keep results in order for tron_getAssets --- .../main/java/org/tron/core/ChainBaseManager.java | 2 +- .../tron/core/state/WorldStateQueryInstance.java | 7 +++---- .../org/tron/core/state/WorldStateTrieStore.java | 3 +++ .../NeedWorldStateTrieStoreCondition.java | 13 +++++++++++++ 4 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 chainbase/src/main/java/org/tron/core/state/annotation/NeedWorldStateTrieStoreCondition.java diff --git a/chainbase/src/main/java/org/tron/core/ChainBaseManager.java b/chainbase/src/main/java/org/tron/core/ChainBaseManager.java index b7bf6d78769..6cbfcdf200d 100644 --- a/chainbase/src/main/java/org/tron/core/ChainBaseManager.java +++ b/chainbase/src/main/java/org/tron/core/ChainBaseManager.java @@ -245,7 +245,7 @@ public class ChainBaseManager { @Getter private SectionBloomStore sectionBloomStore; - @Autowired + @Autowired(required = false) @Getter private WorldStateTrieStore worldStateTrieStore; diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java b/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java index d2db9f568ca..99a3fbd11ff 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java @@ -102,7 +102,7 @@ public boolean hasAssetV2(Protocol.Account account, long tokenId) { } public Map importAllAsset(Protocol.Account account) { - Map assets = new HashMap<>(); + Map assets = new TreeMap<>(); Map genesis = worldStateGenesis.prefixQuery(StateType.AccountAsset, account.getAddress().toByteArray()); genesis.forEach((k, v) -> assets.put( @@ -121,9 +121,8 @@ public Map importAllAsset(Protocol.Account account) { v.toLong()) ); // remove asset = 0 - return assets.entrySet().stream().filter(e -> e.getValue() > 0) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - + assets.entrySet().removeIf(e -> e.getValue() <= 0); + return assets; } // contract diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java b/chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java index 41137c9082f..4a279977d5b 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java @@ -7,13 +7,16 @@ import org.hyperledger.besu.storage.RocksDBKeyValueStorage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Conditional; import org.springframework.stereotype.Component; import org.tron.common.parameter.CommonParameter; import org.tron.common.utils.FileUtil; +import org.tron.core.state.annotation.NeedWorldStateTrieStoreCondition; @Slf4j(topic = "State") @Component +@Conditional(NeedWorldStateTrieStoreCondition.class) public class WorldStateTrieStore extends RocksDBKeyValueStorage { @Autowired diff --git a/chainbase/src/main/java/org/tron/core/state/annotation/NeedWorldStateTrieStoreCondition.java b/chainbase/src/main/java/org/tron/core/state/annotation/NeedWorldStateTrieStoreCondition.java new file mode 100644 index 00000000000..acdd7ff762a --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/annotation/NeedWorldStateTrieStoreCondition.java @@ -0,0 +1,13 @@ +package org.tron.core.state.annotation; + +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.type.AnnotatedTypeMetadata; +import org.tron.common.parameter.CommonParameter; + +public class NeedWorldStateTrieStoreCondition implements Condition { + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + return CommonParameter.getInstance().getStorage().isAllowStateRoot(); + } +} From 2de5ad71cdb911668bac852c44857fa2c44487ec Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Sat, 18 Mar 2023 23:03:06 +0800 Subject: [PATCH 10/34] feat(trie): return assets in order --- .../java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index e065164ad32..764c894e422 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -17,6 +17,7 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; +import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -413,6 +414,7 @@ public List getToken10(String address, String blockNumOrTag) new Token10Result(ByteArray.toJsonHex(Long.parseUnsignedLong(e.getKey())), ByteArray.toJsonHex(e.getValue()))).forEach(token10s::add); } + token10s.sort(Comparator.comparing(Token10Result::getKey)); return token10s; } From aeb8c2c521f19aa2f7de756027ae087f0b81fcf1 Mon Sep 17 00:00:00 2001 From: guoquanwu Date: Wed, 22 Mar 2023 11:46:49 +0800 Subject: [PATCH 11/34] feature(trie): reset root when launching a new archive node --- .../tron/core/state/WorldStateGenesis.java | 27 +++++- .../state/WorldStateGenesisRocksDBTest.java | 63 ++++++++++++++ .../core/state/WorldStateGenesisTest.java | 84 +++++++++++++++++++ 3 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 framework/src/test/java/org/tron/core/state/WorldStateGenesisRocksDBTest.java create mode 100644 framework/src/test/java/org/tron/core/state/WorldStateGenesisTest.java diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateGenesis.java b/chainbase/src/main/java/org/tron/core/state/WorldStateGenesis.java index 388cc0cc5f9..1edafb40254 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateGenesis.java +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateGenesis.java @@ -17,6 +17,7 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; import org.rocksdb.BlockBasedTableConfig; import org.rocksdb.BloomFilter; import org.rocksdb.ComparatorOptions; @@ -32,6 +33,8 @@ import org.tron.common.utils.PropUtil; import org.tron.core.ChainBaseManager; import org.tron.core.capsule.BlockCapsule; +import org.tron.core.db.BlockStore; +import org.tron.core.exception.HeaderNotFound; @Component("worldStateGenesis") @Slf4j(topic = "DB") @@ -145,10 +148,32 @@ private void tryInitGenesis() { } // copy state db initGenesis(); + // reset root + resetArchiveRoot(); // init genesis properties initGenesisProperties(); } + public void resetArchiveRoot() { + BlockStore blockStore = chainBaseManager.getBlockStore(); + BlockCapsule blockCapsule = null; + try { + blockCapsule = chainBaseManager.getHead(); + if (blockCapsule.getNum() == genesisHeight) { + logger.debug("skip reset archive root in case of the head is 0"); + return; + } + } catch (HeaderNotFound e) { + logger.error("reset archive root failed, err: {}", e.getMessage()); + System.exit(1); + } + logger.info("reset archive root, number: {}, prev root: {}", + blockCapsule.getNum(), + blockCapsule.getArchiveRoot()); + blockCapsule.setArchiveRoot(Bytes32.ZERO.toArray()); + blockStore.put(blockCapsule.getBlockId().getBytes(), blockCapsule); + } + private void initGenesisDBs() { if (this.stateGenesisHeight == genesisHeight) { return; @@ -279,7 +304,7 @@ private org.rocksdb.RocksDB newRocksDbReadOnly(Path db) throws RocksDBException if (MARKET_PAIR_PRICE_TO_ORDER.equalsIgnoreCase(db.getFileName().toString())) { options.setComparator(new MarketOrderPriceComparatorForRockDB(new ComparatorOptions())); } - return org.rocksdb.RocksDB.openReadOnly(options, db.toString()); + return org.rocksdb.RocksDB.openReadOnly(options, db.toString()); } } diff --git a/framework/src/test/java/org/tron/core/state/WorldStateGenesisRocksDBTest.java b/framework/src/test/java/org/tron/core/state/WorldStateGenesisRocksDBTest.java new file mode 100644 index 00000000000..16ad3176f1f --- /dev/null +++ b/framework/src/test/java/org/tron/core/state/WorldStateGenesisRocksDBTest.java @@ -0,0 +1,63 @@ +package org.tron.core.state; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Map; +import org.apache.tuweni.bytes.Bytes; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.rocksdb.Options; +import org.rocksdb.RocksDB; +import org.rocksdb.RocksDBException; +import org.tron.common.utils.FileUtil; + +public class WorldStateGenesisRocksDBTest { + + @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Test + public void testPrefixQuery() throws IOException { + Path parentPath = temporaryFolder.newFolder().toPath(); + String dbName = "test_prefix"; + Path dbPath = Paths.get(parentPath.toString(), dbName); + + try { + Options options = new Options(); + options.setCreateIfMissing(true); + RocksDB rocksDB = RocksDB.open(options, dbPath.toString()); + Bytes key1 = Bytes.wrap("a1".getBytes()); + Bytes key2 = Bytes.wrap("b1".getBytes()); + Bytes key3 = Bytes.wrap("c1".getBytes()); + Bytes key4 = Bytes.wrap("b2".getBytes()); + Bytes key5 = Bytes.wrap("b3".getBytes()); + Bytes value1 = Bytes.wrap("value1".getBytes()); + Bytes value2 = Bytes.wrap("value2".getBytes()); + Bytes value3 = Bytes.wrap("value3".getBytes()); + Bytes value4 = Bytes.wrap("value4".getBytes()); + Bytes value5 = Bytes.wrap("value5".getBytes()); + rocksDB.put(key1.toArray(), value1.toArray()); + rocksDB.put(key2.toArray(), value2.toArray()); + rocksDB.put(key3.toArray(), value3.toArray()); + rocksDB.put(key4.toArray(), value4.toArray()); + rocksDB.put(key5.toArray(), value5.toArray()); + options.close(); + rocksDB.close(); + + WorldStateGenesis.RocksDB db = + new WorldStateGenesis.RocksDB(parentPath, dbName); + Map result = db.prefixQuery("b".getBytes()); + Assert.assertEquals(3, result.size()); + Assert.assertEquals(value2, result.get(key2)); + Assert.assertEquals(value4, result.get(key4)); + Assert.assertEquals(value5, result.get(key5)); + db.close(); + } catch (RocksDBException | IOException e) { + Assert.fail(); + } finally { + FileUtil.deleteDir(parentPath.toFile()); + } + } +} diff --git a/framework/src/test/java/org/tron/core/state/WorldStateGenesisTest.java b/framework/src/test/java/org/tron/core/state/WorldStateGenesisTest.java new file mode 100644 index 00000000000..644c2c4f2ff --- /dev/null +++ b/framework/src/test/java/org/tron/core/state/WorldStateGenesisTest.java @@ -0,0 +1,84 @@ +package org.tron.core.state; + +import com.google.protobuf.ByteString; +import java.io.File; +import org.apache.tuweni.bytes.Bytes32; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.application.Application; +import org.tron.common.application.ApplicationFactory; +import org.tron.common.application.TronApplicationContext; +import org.tron.common.config.DbBackupConfig; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.FileUtil; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.ChainBaseManager; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.exception.HeaderNotFound; + +public class WorldStateGenesisTest { + private static TronApplicationContext context; + private static Application appTest; + private static ChainBaseManager chainBaseManager; + private static WorldStateGenesis worldStateGenesis; + + private static String dbPath = "output-directory-state-genesis"; + + /** + * init logic. + */ + @Before + public void init() { + if (FileUtil.isExists(dbPath)) { + FileUtil.deleteDir(new File(dbPath)); + } + Args.setParam(new String[]{"-d", dbPath}, "config-localtest.conf"); + // allow account root + Args.getInstance().setAllowAccountStateRoot(1); + // init dbBackupConfig to avoid NPE + Args.getInstance().dbBackupConfig = DbBackupConfig.getInstance(); + context = new TronApplicationContext(DefaultConfig.class); + appTest = ApplicationFactory.create(context); + appTest.startup(); + chainBaseManager = context.getBean(ChainBaseManager.class); + worldStateGenesis = context.getBean(WorldStateGenesis.class); + } + + @After + public void destroy() { + appTest.shutdown(); + Args.clearParam(); + FileUtil.deleteDir(new File(dbPath)); + } + + @Test + public void testResetArchiveRoot() throws HeaderNotFound { + // test ignore genesis reset + worldStateGenesis.resetArchiveRoot(); + Assert.assertNotEquals(Bytes32.ZERO, chainBaseManager.getHead().getArchiveRoot()); + + // test reset + BlockCapsule parentBlock = chainBaseManager.getHead(); + BlockCapsule blockCapsule = + new BlockCapsule( + parentBlock.getNum() + 1, + Sha256Hash.wrap(parentBlock.getBlockId().getByteString()), + System.currentTimeMillis(), + ByteString.copyFrom( + ECKey.fromPrivate( + org.tron.common.utils.ByteArray.fromHexString( + Args.getLocalWitnesses().getPrivateKey())) + .getAddress())); + blockCapsule.setMerkleRoot(); + blockCapsule.setArchiveRoot(Bytes32.random().toArray()); + chainBaseManager.getBlockStore().put(blockCapsule.getBlockId().getBytes(), blockCapsule); + + worldStateGenesis.resetArchiveRoot(); + Assert.assertEquals(Bytes32.ZERO, chainBaseManager.getHead().getArchiveRoot()); + } + +} From 33c0e0a8aa9f023a0625cbae9e7de97fc0bf399d Mon Sep 17 00:00:00 2001 From: guoquanwu Date: Wed, 29 Mar 2023 17:57:20 +0800 Subject: [PATCH 12/34] fix(trie): reset archive root on khaosdb --- framework/src/main/java/org/tron/core/db/Manager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/src/main/java/org/tron/core/db/Manager.java b/framework/src/main/java/org/tron/core/db/Manager.java index 0fa458ef938..c1376075822 100644 --- a/framework/src/main/java/org/tron/core/db/Manager.java +++ b/framework/src/main/java/org/tron/core/db/Manager.java @@ -475,6 +475,8 @@ public void init() { chainBaseManager.setMortgageService(mortgageService); this.initGenesis(); worldStateCallBack.setExecute(false); + // worldState init, before khasoDb init + worldStateGenesis.init(chainBaseManager); try { this.khaosDb.start(chainBaseManager.getBlockById( getDynamicPropertiesStore().getLatestBlockHeaderHash())); @@ -521,8 +523,6 @@ public void init() { // init liteFullNode initLiteNode(); - // init worldState - worldStateGenesis.init(chainBaseManager); long headNum = chainBaseManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber(); logger.info("Current headNum is: {}.", headNum); boolean isLite = chainBaseManager.isLiteNode(); From fce0f8905cef0add51e8abce692a2285b0a1f243 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Mon, 3 Apr 2023 22:44:52 +0800 Subject: [PATCH 13/34] refactor(trie): optimize code, remove unused code --- .../tron/core/capsule/utils/AssetUtil.java | 7 +- .../tron/core/db/TronStoreWithRevoking.java | 8 +- .../tron/core/state/WorldStateCallBack.java | 87 ++++++++++- .../core/state/WorldStateCallBackUtils.java | 142 ------------------ .../tron/core/state/WorldStateGenesis.java | 12 +- .../core/state/WorldStateQueryInstance.java | 15 +- .../core/state/store/AccountStateStore.java | 2 + .../state/store/AssetIssueV2StateStore.java | 2 + .../state/store/DelegationStateStore.java | 2 + .../store/DynamicPropertiesStateStore.java | 2 + .../core/store/DynamicPropertiesStore.java | 6 +- .../main/java/org/tron/core/db/Manager.java | 2 +- .../runtime/vm/TransferToAccountTest.java | 6 + .../actuator/UnfreezeBalanceActuatorTest.java | 9 +- .../db2/RevokingDbWithCacheNewValueTest.java | 2 +- .../state/WorldStateQueryInstanceTest.java | 15 +- .../java/org/tron/core/tire/Trie2Test.java | 2 +- 17 files changed, 124 insertions(+), 197 deletions(-) delete mode 100644 chainbase/src/main/java/org/tron/core/state/WorldStateCallBackUtils.java diff --git a/chainbase/src/main/java/org/tron/core/capsule/utils/AssetUtil.java b/chainbase/src/main/java/org/tron/core/capsule/utils/AssetUtil.java index 033debaedda..f554d412c19 100644 --- a/chainbase/src/main/java/org/tron/core/capsule/utils/AssetUtil.java +++ b/chainbase/src/main/java/org/tron/core/capsule/utils/AssetUtil.java @@ -6,6 +6,7 @@ import org.apache.tuweni.bytes.Bytes32; import org.tron.common.utils.ByteArray; import org.tron.core.ChainBaseManager; +import org.tron.core.state.store.DynamicPropertiesStateStore; import org.tron.core.store.AccountAssetStore; import org.tron.core.store.DynamicPropertiesStore; import org.tron.protos.Protocol.Account; @@ -89,8 +90,10 @@ public static boolean isAllowAssetOptimization(Bytes32 root) { if (Bytes32.ZERO.equals(root)) { return dynamicPropertiesStore.supportAllowAssetOptimization(); } - return ChainBaseManager.fetch(root).supportAllowAssetOptimization(); - + try (DynamicPropertiesStateStore store = new DynamicPropertiesStateStore()) { + store.init(ChainBaseManager.fetch(root)); + return store.supportAllowAssetOptimization(); + } } } diff --git a/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java b/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java index 3b671cb1bc4..0b599f416a6 100644 --- a/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java +++ b/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java @@ -37,7 +37,7 @@ import org.tron.core.exception.BadItemException; import org.tron.core.exception.ItemNotFoundException; import org.tron.core.state.StateType; -import org.tron.core.state.WorldStateCallBackUtils; +import org.tron.core.state.WorldStateCallBack; @Slf4j(topic = "DB") @@ -60,7 +60,7 @@ public abstract class TronStoreWithRevoking implements I private StateType type; @Autowired - protected WorldStateCallBackUtils worldStateCallBackUtils; + protected WorldStateCallBack worldStateCallBack; protected TronStoreWithRevoking(String dbName) { String dbEngine = CommonParameter.getInstance().getStorage().getDbEngine(); @@ -121,12 +121,12 @@ public void put(byte[] key, T item) { } byte[] value = item.getData(); revokingDB.put(key, value); - worldStateCallBackUtils.callBack(type, key, value, Value.Operator.PUT); + worldStateCallBack.callBack(type, key, value, Value.Operator.PUT); } @Override public void delete(byte[] key) { - worldStateCallBackUtils.callBack(type, key, + worldStateCallBack.callBack(type, key, StateType.Account == type ? revokingDB.getUnchecked(key) : null, Value.Operator.DELETE); revokingDB.delete(key); diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java b/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java index 4f131779752..41a4e78e4ff 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java @@ -1,18 +1,34 @@ package org.tron.core.state; import com.google.common.annotations.VisibleForTesting; +import com.google.common.primitives.Longs; +import java.util.HashMap; +import java.util.Map; import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.hyperledger.besu.ethereum.trie.MerkleTrieException; import org.springframework.stereotype.Component; import org.tron.common.parameter.CommonParameter; +import org.tron.core.ChainBaseManager; +import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.BlockCapsule; +import org.tron.core.db2.common.Value; import org.tron.core.state.trie.TrieImpl2; @Slf4j(topic = "State") @Component -public class WorldStateCallBack extends WorldStateCallBackUtils { +public class WorldStateCallBack { + + @Setter + protected volatile boolean execute; + protected volatile boolean allowGenerateRoot; + protected Map trieEntryList = new HashMap<>(); + @Setter + protected ChainBaseManager chainBaseManager; private BlockCapsule blockCapsule; @@ -25,6 +41,75 @@ public WorldStateCallBack() { this.allowGenerateRoot = CommonParameter.getInstance().getStorage().isAllowStateRoot(); } + public void callBack(StateType type, byte[] key, byte[] value, Value.Operator op) { + if (!exe() || type == StateType.UNDEFINED) { + return; + } + if (op == Value.Operator.DELETE || ArrayUtils.isEmpty(value)) { + if (type == StateType.Account) { + // @see org.tron.core.db2.core.SnapshotRoot#remove(byte[] key) + AccountCapsule accountCapsule = new AccountCapsule(value); + if (accountCapsule.getAssetOptimized()) { + accountCapsule.getAssetMapV2().keySet().forEach(tokenId -> addFix32( + StateType.AccountAsset, com.google.common.primitives.Bytes.concat(key, + Longs.toByteArray(Long.parseLong(tokenId))), + WorldStateQueryInstance.DELETE)); + } + } + add(type, key, WorldStateQueryInstance.DELETE); + return; + } + if (type == StateType.Account && chainBaseManager.getDynamicPropertiesStore() + .getAllowAccountAssetOptimizationFromRoot() == 1) { + // @see org.tron.core.db2.core.SnapshotRoot#put(byte[] key, byte[] value) + AccountCapsule accountCapsule = new AccountCapsule(value); + if (accountCapsule.getAssetOptimized()) { + accountCapsule.getInstance().getAssetV2Map().forEach((tokenId, amount) -> addFix32( + StateType.AccountAsset, com.google.common.primitives.Bytes.concat(key, + Longs.toByteArray(Long.parseLong(tokenId))), + Longs.toByteArray(amount))); + } else { + accountCapsule.getAssetMapV2().forEach((tokenId, amount) -> addFix32( + StateType.AccountAsset, com.google.common.primitives.Bytes.concat(key, + Longs.toByteArray(Long.parseLong(tokenId))), + Longs.toByteArray(amount))); + accountCapsule.setAssetOptimized(true); + } + value = accountCapsule.getInstance().toBuilder() + .clearAsset() + .clearAssetV2() + .build().toByteArray(); + + } + add(type, key, value); + } + + private void add(StateType type, byte[] key, byte[] value) { + trieEntryList.put(Bytes.of(StateType.encodeKey(type, key)), Bytes.of(value)); + } + + private void addFix32(StateType type, byte[] key, byte[] value) { + trieEntryList.put(fix32(StateType.encodeKey(type, key)), Bytes.of(value)); + } + + public static Bytes32 fix32(byte[] key) { + return Bytes32.rightPad(Bytes.wrap(key)); + } + + public static Bytes32 fix32(Bytes key) { + return Bytes32.rightPad(key); + } + + + protected boolean exe() { + if (!allowGenerateRoot || !execute) { + //Agreement same block high to generate archive root + execute = false; + return false; + } + return true; + } + @VisibleForTesting public void clear() { if (!exe()) { diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateCallBackUtils.java b/chainbase/src/main/java/org/tron/core/state/WorldStateCallBackUtils.java deleted file mode 100644 index c498cbd48b4..00000000000 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateCallBackUtils.java +++ /dev/null @@ -1,142 +0,0 @@ -package org.tron.core.state; - -import com.google.common.base.Objects; -import com.google.common.primitives.Longs; -import java.util.HashMap; -import java.util.Map; - -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.tron.core.ChainBaseManager; -import org.tron.core.capsule.AccountCapsule; -import org.tron.core.db2.common.Value; - -@Slf4j(topic = "DB") -public class WorldStateCallBackUtils { - - @Setter - protected volatile boolean execute = false; - protected volatile boolean allowGenerateRoot = false; - protected Map trieEntryList = new HashMap<>(); - @Setter - protected ChainBaseManager chainBaseManager; - - public void callBack(StateType type, byte[] key, byte[] value, Value.Operator op) { - if (!exe() || type == StateType.UNDEFINED) { - return; - } - if (op == Value.Operator.DELETE || ArrayUtils.isEmpty(value)) { - if (type == StateType.Account) { - // @see org.tron.core.db2.core.SnapshotRoot#remove(byte[] key) - AccountCapsule accountCapsule = new AccountCapsule(value); - if (accountCapsule.getAssetOptimized()) { - accountCapsule.getAssetMapV2().keySet().forEach(tokenId -> addFix32( - StateType.AccountAsset, com.google.common.primitives.Bytes.concat(key, - Longs.toByteArray(Long.parseLong(tokenId))), - WorldStateQueryInstance.DELETE)); - } - } - add(type, key, WorldStateQueryInstance.DELETE); - return; - } - if (type == StateType.Account && chainBaseManager.getDynamicPropertiesStore() - .getAllowAccountAssetOptimizationFromRoot() == 1) { - // @see org.tron.core.db2.core.SnapshotRoot#put(byte[] key, byte[] value) - AccountCapsule accountCapsule = new AccountCapsule(value); - if (accountCapsule.getAssetOptimized()) { - accountCapsule.getInstance().getAssetV2Map().forEach((tokenId, amount) -> addFix32( - StateType.AccountAsset, com.google.common.primitives.Bytes.concat(key, - Longs.toByteArray(Long.parseLong(tokenId))), - Longs.toByteArray(amount))); - } else { - accountCapsule.getAssetMapV2().forEach((tokenId, amount) -> addFix32( - StateType.AccountAsset, com.google.common.primitives.Bytes.concat(key, - Longs.toByteArray(Long.parseLong(tokenId))), - Longs.toByteArray(amount))); - accountCapsule.setAssetOptimized(true); - } - value = accountCapsule.getInstance().toBuilder() - .clearAsset() - .clearAssetV2() - .build().toByteArray(); - - } - add(type, key, value); - } - - private void add(StateType type, byte[] key, byte[] value) { - trieEntryList.put(Bytes.of(StateType.encodeKey(type, key)), Bytes.of(value)); - } - - private void addFix32(StateType type, byte[] key, byte[] value) { - trieEntryList.put(fix32(StateType.encodeKey(type, key)), Bytes.of(value)); - } - - public static Bytes32 fix32(byte[] key) { - return Bytes32.rightPad(Bytes.wrap(key)); - } - - public static Bytes32 fix32(Bytes key) { - return Bytes32.rightPad(key); - } - - - protected boolean exe() { - if (!execute || !allowGenerateRoot) { - //Agreement same block high to generate archive root - execute = false; - return false; - } - return true; - } - - public static class TrieEntry { - - private Bytes key; - private Bytes data; - - public static TrieEntry build(Bytes key, Bytes data) { - TrieEntry trieEntry = new TrieEntry(); - return trieEntry.setKey(key).setData(data); - } - - public org.apache.tuweni.bytes.Bytes getKey() { - return key; - } - - public TrieEntry setKey(Bytes key) { - this.key = key; - return this; - } - - public Bytes getData() { - return data; - } - - public TrieEntry setData(Bytes data) { - this.data = data; - return this; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - TrieEntry trieEntry = (TrieEntry) o; - return Objects.equal(key, trieEntry.key); - } - - @Override - public int hashCode() { - return Objects.hashCode(key); - } - } - -} diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateGenesis.java b/chainbase/src/main/java/org/tron/core/state/WorldStateGenesis.java index 1edafb40254..77df5480415 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateGenesis.java +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateGenesis.java @@ -16,6 +16,7 @@ import javax.annotation.PreDestroy; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.rocksdb.BlockBasedTableConfig; @@ -56,8 +57,6 @@ public class WorldStateGenesis { private static final String STATE_GENESIS_PROPERTIES = "genesis.properties"; private static final String STATE_GENESIS_HEIGHT = "height"; - private static final String STATE_GENESIS_HASH = "hash"; - private static final String STATE_GENESIS_TIME = "time"; private final Map genesisDBs = Maps.newConcurrentMap(); @@ -67,9 +66,6 @@ public synchronized void init(ChainBaseManager chainBaseManager) { if (!allowStateRoot) { return; } - if (inited) { - return; - } this.chainBaseManager = chainBaseManager; genesisHeight = chainBaseManager.getGenesisBlockId().getNum(); tryInitGenesis(); @@ -221,12 +217,8 @@ private void initGenesis() { private void initGenesisProperties() { logger.info("State genesis properties init start"); long height = chainBaseManager.getHeadBlockNum(); - long time = chainBaseManager.getHeadBlockTimeStamp(); - BlockCapsule.BlockId hash = chainBaseManager.getHeadBlockId(); Map properties = new HashMap<>(); properties.put(STATE_GENESIS_HEIGHT, String.valueOf(height)); - properties.put(STATE_GENESIS_TIME, String.valueOf(time)); - properties.put(STATE_GENESIS_HASH, hash.toString()); String genesisFile = new File(stateGenesisPath.toString(), STATE_GENESIS_PROPERTIES).toString(); PropUtil.writeProperties(genesisFile, properties); this.stateGenesisHeight = height; @@ -242,7 +234,7 @@ private long tryFindStateGenesisHeight() { } String height = PropUtil.readProperty(genesisFile.toString(), STATE_GENESIS_HEIGHT); - if (height.isEmpty()) { + if (StringUtils.isEmpty(height)) { return -1; } long header = Long.parseLong(height); diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java b/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java index 99a3fbd11ff..f8c162968e4 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java @@ -1,14 +1,11 @@ package org.tron.core.state; -import static org.tron.core.state.WorldStateCallBackUtils.fix32; +import static org.tron.core.state.WorldStateCallBack.fix32; import com.google.common.primitives.Longs; -import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.TreeMap; -import java.util.stream.Collectors; - import lombok.Getter; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; @@ -41,8 +38,6 @@ public class WorldStateQueryInstance { public static final int ADDRESS_SIZE = DecodeUtil.ADDRESS_SIZE >> 1; public static final Bytes MAX_ASSET_ID = Bytes.ofUnsignedLong(Long.MAX_VALUE); public static final Bytes MIN_ASSET_ID = Bytes.ofUnsignedLong(0); - private static final byte[] ALLOW_ASSET_OPTIMIZATION = - "ALLOW_ASSET_OPTIMIZATION".getBytes(); private final WorldStateGenesis worldStateGenesis; @@ -203,12 +198,4 @@ public BytesCapsule getUncheckedDynamicProperty(byte[] key) { } return null; } - - public long getDynamicPropertyLong(byte[] key) { - return ByteArray.toLong(getDynamicProperty(key).getData()); - } - - public boolean supportAllowAssetOptimization() { - return getDynamicPropertyLong(ALLOW_ASSET_OPTIMIZATION) == 1L; - } } diff --git a/chainbase/src/main/java/org/tron/core/state/store/AccountStateStore.java b/chainbase/src/main/java/org/tron/core/state/store/AccountStateStore.java index 2a058d79466..54e992617a0 100644 --- a/chainbase/src/main/java/org/tron/core/state/store/AccountStateStore.java +++ b/chainbase/src/main/java/org/tron/core/state/store/AccountStateStore.java @@ -55,6 +55,8 @@ public boolean has(byte[] key) { @Override public void close() { + this.worldStateQueryInstance = null; + init = false; } @Override diff --git a/chainbase/src/main/java/org/tron/core/state/store/AssetIssueV2StateStore.java b/chainbase/src/main/java/org/tron/core/state/store/AssetIssueV2StateStore.java index 84b266e8f1e..2cd563b8e77 100644 --- a/chainbase/src/main/java/org/tron/core/state/store/AssetIssueV2StateStore.java +++ b/chainbase/src/main/java/org/tron/core/state/store/AssetIssueV2StateStore.java @@ -58,6 +58,8 @@ public boolean has(byte[] key) { @Override public void close() { + this.worldStateQueryInstance = null; + init = false; } @Override diff --git a/chainbase/src/main/java/org/tron/core/state/store/DelegationStateStore.java b/chainbase/src/main/java/org/tron/core/state/store/DelegationStateStore.java index cfa9da54eaf..b20ff8814d9 100644 --- a/chainbase/src/main/java/org/tron/core/state/store/DelegationStateStore.java +++ b/chainbase/src/main/java/org/tron/core/state/store/DelegationStateStore.java @@ -55,6 +55,8 @@ public boolean has(byte[] key) { @Override public void close() { + this.worldStateQueryInstance = null; + init = false; } @Override diff --git a/chainbase/src/main/java/org/tron/core/state/store/DynamicPropertiesStateStore.java b/chainbase/src/main/java/org/tron/core/state/store/DynamicPropertiesStateStore.java index 6c64d53d949..1ec14d58109 100644 --- a/chainbase/src/main/java/org/tron/core/state/store/DynamicPropertiesStateStore.java +++ b/chainbase/src/main/java/org/tron/core/state/store/DynamicPropertiesStateStore.java @@ -56,6 +56,8 @@ public boolean has(byte[] key) { @Override public void close() { + this.worldStateQueryInstance = null; + init = false; } @Override diff --git a/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java b/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java index eea9a0c423d..809c2060951 100644 --- a/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java +++ b/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java @@ -20,7 +20,7 @@ import org.tron.core.db.TronStoreWithRevoking; import org.tron.core.exception.BadItemException; import org.tron.core.exception.ItemNotFoundException; -import org.tron.core.state.WorldStateCallBackUtils; +import org.tron.core.state.WorldStateCallBack; @Slf4j(topic = "DB") @Component @@ -219,9 +219,9 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking @Autowired private DynamicPropertiesStore(@Value("properties") String dbName, - @Autowired WorldStateCallBackUtils worldStateCallBackUtils) { + @Autowired WorldStateCallBack worldStateCallBack) { super(dbName); - this.worldStateCallBackUtils = worldStateCallBackUtils; + this.worldStateCallBack = worldStateCallBack; try { this.getTotalSignNum(); diff --git a/framework/src/main/java/org/tron/core/db/Manager.java b/framework/src/main/java/org/tron/core/db/Manager.java index c1376075822..846a6c7590c 100644 --- a/framework/src/main/java/org/tron/core/db/Manager.java +++ b/framework/src/main/java/org/tron/core/db/Manager.java @@ -475,7 +475,7 @@ public void init() { chainBaseManager.setMortgageService(mortgageService); this.initGenesis(); worldStateCallBack.setExecute(false); - // worldState init, before khasoDb init + // worldState init, before khaosDb init worldStateGenesis.init(chainBaseManager); try { this.khaosDb.start(chainBaseManager.getBlockById( diff --git a/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java b/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java index fda82e2c801..2560ef839f1 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java @@ -32,6 +32,7 @@ import org.tron.core.exception.VMIllegalException; import org.tron.core.state.WorldStateCallBack; import org.tron.core.state.WorldStateQueryInstance; +import org.tron.core.state.store.AccountStateStore; import org.tron.core.state.trie.TrieImpl2; import org.tron.core.store.StoreFactory; import org.tron.core.vm.EnergyCost; @@ -141,6 +142,11 @@ public void TransferTokenTest() Assert.assertEquals(100, worldStateQueryInstance.getAccount(contractAddress) .getAssetV2MapForTest().get(String.valueOf(id)).longValue()); + try (AccountStateStore store = new AccountStateStore()) { + store.init(worldStateQueryInstance); + Assert.assertEquals(100, + store.get(contractAddress).getAssetV2MapForTest().get(String.valueOf(id)).longValue()); + } Assert.assertEquals(1000, chainBaseManager.getAccountStore().get(contractAddress).getBalance()); Assert.assertEquals(1000, diff --git a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java index 1d0bc192aa8..a574760e2a7 100644 --- a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java @@ -164,10 +164,11 @@ public void testUnfreezeBalanceForBandwidth() { Assert.assertEquals(totalNetWeightBefore, totalNetWeightAfter + frozenBalance / 1000_000L); - DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(); - stateStore.init(queryInstance); - Assert.assertEquals(totalNetWeightBefore, - stateStore.getTotalNetWeight() + frozenBalance / 1000_000L); + try (DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore()) { + stateStore.init(queryInstance); + Assert.assertEquals(totalNetWeightBefore, + stateStore.getTotalNetWeight() + frozenBalance / 1000_000L); + } } catch (ContractValidateException e) { Assert.assertFalse(e instanceof ContractValidateException); diff --git a/framework/src/test/java/org/tron/core/db2/RevokingDbWithCacheNewValueTest.java b/framework/src/test/java/org/tron/core/db2/RevokingDbWithCacheNewValueTest.java index de4b79e07e6..92945698480 100644 --- a/framework/src/test/java/org/tron/core/db2/RevokingDbWithCacheNewValueTest.java +++ b/framework/src/test/java/org/tron/core/db2/RevokingDbWithCacheNewValueTest.java @@ -473,7 +473,7 @@ public static class TestRevokingTronStore extends TronStoreWithRevoking Date: Tue, 11 Apr 2023 14:25:23 +0800 Subject: [PATCH 14/34] feat(trie): make trie db configurable --- .../tron/core/state/WorldStateTrieStore.java | 10 +++---- common/build.gradle | 1 + .../org/tron/core/config/args/Storage.java | 29 ++++++++++++++++--- .../java/org/tron/core/config/args/Args.java | 3 +- .../src/main/resources/config-localtest.conf | 8 ++++- framework/src/main/resources/config.conf | 6 ++++ .../src/test/resources/config-localtest.conf | 7 +++++ framework/src/test/resources/config-test.conf | 8 +++++ .../besu/storage/RocksDBConfiguration.java | 9 +++++- .../storage/RocksDBConfigurationBuilder.java | 13 +++++++-- .../storage/RocksDBFactoryConfiguration.java | 9 +++++- .../besu/storage/RocksDBKeyValueStorage.java | 7 ++++- 12 files changed, 93 insertions(+), 17 deletions(-) diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java b/chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java index 4a279977d5b..f77d4b75ac4 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java @@ -3,7 +3,7 @@ import java.nio.file.Paths; import javax.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; -import org.hyperledger.besu.storage.RocksDBConfigurationBuilder; +import org.hyperledger.besu.storage.RocksDBConfiguration; import org.hyperledger.besu.storage.RocksDBKeyValueStorage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -21,8 +21,7 @@ public class WorldStateTrieStore extends RocksDBKeyValueStorage { @Autowired private WorldStateTrieStore(@Value("world-state-trie") String dbName) { - super(new RocksDBConfigurationBuilder().databaseDir(Paths.get(calDbParentPath(), - dbName)).build()); + super(buildConf(dbName)); } @PreDestroy @@ -35,7 +34,7 @@ public void clearUp() { } - private static String calDbParentPath() { + private static RocksDBConfiguration buildConf(String dbName) { String stateGenesis = CommonParameter.getInstance().getStorage() .getStateGenesisDirectory(); if (!Paths.get(stateGenesis).isAbsolute()) { @@ -43,7 +42,8 @@ private static String calDbParentPath() { stateGenesis).toString(); } FileUtil.createDirIfNotExists(stateGenesis); - return stateGenesis; + return CommonParameter.getInstance().getStorage().getStateDbConf() + .databaseDir(Paths.get(stateGenesis, dbName)).build(); } } diff --git a/common/build.gradle b/common/build.gradle index 0ed13763a1e..cd973304a0e 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -60,6 +60,7 @@ dependencies { exclude group: 'com.google.protobuf', module: 'protobuf-java' exclude group: 'com.google.protobuf', module: 'protobuf-java-util' } + compile project(":state-trie-jdk8") compile project(":protocol") } diff --git a/common/src/main/java/org/tron/core/config/args/Storage.java b/common/src/main/java/org/tron/core/config/args/Storage.java index ba02c391e5d..479565ed0a1 100644 --- a/common/src/main/java/org/tron/core/config/args/Storage.java +++ b/common/src/main/java/org/tron/core/config/args/Storage.java @@ -25,6 +25,7 @@ import lombok.Getter; import lombok.Setter; import org.apache.commons.lang3.StringUtils; +import org.hyperledger.besu.storage.RocksDBConfigurationBuilder; import org.iq80.leveldb.CompressionType; import org.iq80.leveldb.Options; import org.tron.common.cache.CacheStrategies; @@ -79,6 +80,12 @@ public class Storage { private static final String CACHE_STRATEGIES = "storage.cache.strategies"; private static final String STATE_ROOT_SWITCH_KEY = "storage.stateRoot.switch"; + private static final String STATE_DB_MAX_OPEN_FILES_KEY = "storage.stateRoot.db.maxOpenFiles"; + private static final String STATE_DB_WRITE_BUFFER_SIZE_KEY = + "storage.stateRoot.db.writeBufferSize"; + private static final String STATE_DB_CACHE_CAPACITY_KEY = "storage.stateRoot.db.cacheCapacity"; + private static final String STATE_DB_CACHE_INDEX_AND_FILTER_KEY = + "storage.stateRoot.db.cacheIndexAndFilter"; private static final String STATE_GENESIS_DIRECTORY_KEY = "storage.stateGenesis.directory"; /** @@ -162,6 +169,10 @@ public class Storage { @Getter private String stateGenesisDirectory = DEFAULT_STATE_GENESIS_DIRECTORY; + @Getter + private final RocksDBConfigurationBuilder stateDbConf = new RocksDBConfigurationBuilder(); + + /** * Key: dbName, Value: Property object of that database */ @@ -258,16 +269,26 @@ public String getCacheStrategy(CacheType dbName) { return this.cacheStrategies.getOrDefault(dbName, CacheStrategies.getCacheStrategy(dbName)); } - public void setAllowStateRoot(final Config config) { + public void setStateConfig(final Config config) { if (config.hasPath(STATE_ROOT_SWITCH_KEY)) { this.allowStateRoot = config.getBoolean(STATE_ROOT_SWITCH_KEY); } - } - - public void setStateGenesisDirectory(final Config config) { if (config.hasPath(STATE_GENESIS_DIRECTORY_KEY)) { this.stateGenesisDirectory = config.getString(STATE_GENESIS_DIRECTORY_KEY); } + if (config.hasPath(STATE_DB_MAX_OPEN_FILES_KEY)) { + this.stateDbConf.maxOpenFiles(config.getInt(STATE_DB_MAX_OPEN_FILES_KEY)); + } + if (config.hasPath(STATE_DB_CACHE_CAPACITY_KEY)) { + this.stateDbConf.cacheCapacity(config.getLong(STATE_DB_CACHE_CAPACITY_KEY)); + } + if (config.hasPath(STATE_DB_WRITE_BUFFER_SIZE_KEY)) { + this.stateDbConf.writeBufferSize(config.getLong(STATE_DB_WRITE_BUFFER_SIZE_KEY)); + } + if (config.hasPath(STATE_DB_CACHE_INDEX_AND_FILTER_KEY)) { + this.stateDbConf.isCacheIndexAndFilter( + config.getBoolean(STATE_DB_CACHE_INDEX_AND_FILTER_KEY)); + } } private Property createProperty(final ConfigObject conf) { diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java index 3851a48d003..cbc933d42c6 100644 --- a/framework/src/main/java/org/tron/core/config/args/Args.java +++ b/framework/src/main/java/org/tron/core/config/args/Args.java @@ -531,8 +531,7 @@ public static void setParam(final String[] args, final String confFileName) { PARAMETER.storage.setPropertyMapFromConfig(config); PARAMETER.storage.setCacheStrategies(config); - PARAMETER.storage.setAllowStateRoot(config); - PARAMETER.storage.setStateGenesisDirectory(config); + PARAMETER.storage.setStateConfig(config); PARAMETER.seedNode = new SeedNode(); PARAMETER.seedNode.setAddressList(loadSeeds(config)); diff --git a/framework/src/main/resources/config-localtest.conf b/framework/src/main/resources/config-localtest.conf index 1898ea53087..62ae0725d6a 100644 --- a/framework/src/main/resources/config-localtest.conf +++ b/framework/src/main/resources/config-localtest.conf @@ -54,7 +54,13 @@ storage { checkpoint.sync = true stateRoot.switch = true -# stateGenesis.directory = state-genesis + stateGenesis.directory = "state-genesis" + stateRoot.db = { + maxOpenFiles = 5000 + writeBufferSize = 10485760 // 10 MB = 10 * 1024 * 1024 B + cacheCapacity = 10485760 // 10 MB = 10 * 1024 * 1024 B + cacheIndexAndFilter = true + } } node.discovery = { diff --git a/framework/src/main/resources/config.conf b/framework/src/main/resources/config.conf index 55beb71a7e5..7eb5c0ca212 100644 --- a/framework/src/main/resources/config.conf +++ b/framework/src/main/resources/config.conf @@ -99,6 +99,12 @@ storage { # world state # stateRoot.switch = false # stateGenesis.directory = "state-genesis" + # stateRoot.db = { + # maxOpenFiles = 5000 + # writeBufferSize = 10485760 // 10 MB = 10 * 1024 * 1024 B + # cacheCapacity = 10485760 // 10 MB = 10 * 1024 * 1024 B + # cacheIndexAndFilter = false + # } } node.discovery = { diff --git a/framework/src/test/resources/config-localtest.conf b/framework/src/test/resources/config-localtest.conf index 58a45bc33a9..084fda8a284 100644 --- a/framework/src/test/resources/config-localtest.conf +++ b/framework/src/test/resources/config-localtest.conf @@ -53,6 +53,13 @@ storage { ] stateRoot.switch = true + stateGenesis.directory = "state-genesis" + stateRoot.db = { + maxOpenFiles = 5000 + writeBufferSize = 10485760 // 10 MB = 10 * 1024 * 1024 B + cacheCapacity = 10485760 // 10 MB = 10 * 1024 * 1024 B + cacheIndexAndFilter = true + } } diff --git a/framework/src/test/resources/config-test.conf b/framework/src/test/resources/config-test.conf index 5ab997277d2..40c175f53a9 100644 --- a/framework/src/test/resources/config-test.conf +++ b/framework/src/test/resources/config-test.conf @@ -67,6 +67,14 @@ storage { # so the total number of cached transactions is 65536 * txCache.estimatedTransactions txCache.estimatedTransactions = 50 stateRoot.switch = true + stateGenesis.directory = "state-genesis" + stateRoot.db = { + maxOpenFiles = 5000 + writeBufferSize = 10485760 // 10 MB = 10 * 1024 * 1024 B + cacheCapacity = 10485760 // 10 MB = 10 * 1024 * 1024 B + cacheIndexAndFilter = true + } + } diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBConfiguration.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBConfiguration.java index fdbba6cf9a9..0588cc185a5 100644 --- a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBConfiguration.java +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBConfiguration.java @@ -26,6 +26,7 @@ public class RocksDBConfiguration { private final long cacheCapacity; private final long writeBufferSize; private final boolean isHighSpec; + private final boolean cacheIndexAndFilter; public RocksDBConfiguration( final Path databaseDir, @@ -35,7 +36,8 @@ public RocksDBConfiguration( final long cacheCapacity, final long writeBufferSize, final String label, - final boolean isHighSpec) { + final boolean isHighSpec, + final boolean cacheIndexAndFilter) { this.maxBackgroundCompactions = maxBackgroundCompactions; this.backgroundThreadCount = backgroundThreadCount; this.databaseDir = databaseDir; @@ -44,6 +46,7 @@ public RocksDBConfiguration( this.writeBufferSize = writeBufferSize; this.label = label; this.isHighSpec = isHighSpec; + this.cacheIndexAndFilter = cacheIndexAndFilter; } public Path getDatabaseDir() { @@ -77,4 +80,8 @@ public String getLabel() { public boolean isHighSpec() { return isHighSpec; } + + public boolean isCacheIndexAndFilter() { + return cacheIndexAndFilter; + } } diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBConfigurationBuilder.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBConfigurationBuilder.java index f830bc56906..13010d9f7d6 100644 --- a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBConfigurationBuilder.java +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBConfigurationBuilder.java @@ -23,6 +23,7 @@ public class RocksDBConfigurationBuilder { public static final int DEFAULT_MAX_BACKGROUND_COMPACTIONS = Runtime.getRuntime().availableProcessors(); public static final int DEFAULT_BACKGROUND_THREAD_COUNT = 4; public static final boolean DEFAULT_IS_HIGH_SPEC = false; + public static final boolean DEFAULT_IS_CACHE_INDEX_AND_FILTER = false; private Path databaseDir; private String label = "blockchain"; private int maxOpenFiles = DEFAULT_MAX_OPEN_FILES; @@ -31,6 +32,7 @@ public class RocksDBConfigurationBuilder { private int maxBackgroundCompactions = DEFAULT_MAX_BACKGROUND_COMPACTIONS; private int backgroundThreadCount = DEFAULT_BACKGROUND_THREAD_COUNT; private boolean isHighSpec = DEFAULT_IS_HIGH_SPEC; + private boolean cacheIndexAndFilter = DEFAULT_IS_CACHE_INDEX_AND_FILTER; public RocksDBConfigurationBuilder databaseDir(final Path databaseDir) { this.databaseDir = databaseDir; @@ -72,6 +74,11 @@ public RocksDBConfigurationBuilder isHighSpec(final boolean isHighSpec) { return this; } + public RocksDBConfigurationBuilder isCacheIndexAndFilter(final boolean cacheIndexAndFilter) { + this.cacheIndexAndFilter = cacheIndexAndFilter; + return this; + } + public static RocksDBConfigurationBuilder from(final RocksDBFactoryConfiguration configuration) { return new RocksDBConfigurationBuilder() .backgroundThreadCount(configuration.getBackgroundThreadCount()) @@ -79,7 +86,8 @@ public static RocksDBConfigurationBuilder from(final RocksDBFactoryConfiguration .writeBufferSize(configuration.getWriteBufferSize()) .maxBackgroundCompactions(configuration.getMaxBackgroundCompactions()) .maxOpenFiles(configuration.getMaxOpenFiles()) - .isHighSpec(configuration.isHighSpec()); + .isHighSpec(configuration.isHighSpec()) + .isCacheIndexAndFilter(configuration.isCacheIndexAndFilter()); } public RocksDBConfiguration build() { @@ -91,6 +99,7 @@ public RocksDBConfiguration build() { cacheCapacity, writeBufferSize, label, - isHighSpec); + isHighSpec, + cacheIndexAndFilter); } } diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBFactoryConfiguration.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBFactoryConfiguration.java index 1b4419656a9..2929ecc4a64 100644 --- a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBFactoryConfiguration.java +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBFactoryConfiguration.java @@ -22,6 +22,7 @@ public class RocksDBFactoryConfiguration { private final long cacheCapacity; private final long writeBufferSize; private final boolean isHighSpec; + private final boolean isCacheIndexAndFilter; public RocksDBFactoryConfiguration( final int maxOpenFiles, @@ -29,13 +30,15 @@ public RocksDBFactoryConfiguration( final int backgroundThreadCount, final long cacheCapacity, final long writeBufferSize, - final boolean isHighSpec) { + final boolean isHighSpec, + final boolean isCacheIndexAndFilter) { this.maxBackgroundCompactions = maxBackgroundCompactions; this.backgroundThreadCount = backgroundThreadCount; this.maxOpenFiles = maxOpenFiles; this.cacheCapacity = cacheCapacity; this.writeBufferSize = writeBufferSize; this.isHighSpec = isHighSpec; + this.isCacheIndexAndFilter = isCacheIndexAndFilter; } public int getMaxOpenFiles() { @@ -61,4 +64,8 @@ public long getWriteBufferSize() { public boolean isHighSpec() { return isHighSpec; } + + public boolean isCacheIndexAndFilter() { + return isCacheIndexAndFilter; + } } diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBKeyValueStorage.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBKeyValueStorage.java index c00b23502db..dfdb4a38501 100644 --- a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBKeyValueStorage.java +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBKeyValueStorage.java @@ -164,7 +164,12 @@ public void close() { private BlockBasedTableConfig createBlockBasedTableConfig(final RocksDBConfiguration config) { final LRUCache cache = new LRUCache(config.getCacheCapacity()); - return new BlockBasedTableConfig().setBlockCache(cache); + final BlockBasedTableConfig tableCfg = new BlockBasedTableConfig(); + tableCfg.setBlockCache(cache); + tableCfg.setCacheIndexAndFilterBlocks(config.isCacheIndexAndFilter()); + tableCfg.setPinL0FilterAndIndexBlocksInCache(config.isCacheIndexAndFilter()); + tableCfg.setFilter(new BloomFilter(10, false)); + return tableCfg; } private void throwIfClosed() { From 8c3d94930d6d3a565615cbcabbb0f0472547f821 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Fri, 14 Apr 2023 11:30:13 +0800 Subject: [PATCH 15/34] feat(trie): fix 10token read and write --- .../org/tron/core/capsule/AccountCapsule.java | 28 ++++++- .../tron/core/capsule/utils/AssetUtil.java | 72 +++++------------ .../tron/core/state/WorldStateCallBack.java | 14 ++-- .../core/state/WorldStateQueryInstance.java | 11 ++- .../tron/core/state/utils/AssetStateUtil.java | 67 ++++++++++++++++ .../src/main/java/org/tron/core/Wallet.java | 17 ---- .../tron/core/state/WorldStateQueryTest.java | 80 +++++++++++++++++-- 7 files changed, 200 insertions(+), 89 deletions(-) create mode 100644 chainbase/src/main/java/org/tron/core/state/utils/AssetStateUtil.java diff --git a/chainbase/src/main/java/org/tron/core/capsule/AccountCapsule.java b/chainbase/src/main/java/org/tron/core/capsule/AccountCapsule.java index 4473f3e32b4..3edf76e99b4 100644 --- a/chainbase/src/main/java/org/tron/core/capsule/AccountCapsule.java +++ b/chainbase/src/main/java/org/tron/core/capsule/AccountCapsule.java @@ -25,6 +25,7 @@ import org.apache.tuweni.bytes.Bytes32; import org.tron.common.utils.ByteArray; import org.tron.core.capsule.utils.AssetUtil; +import org.tron.core.state.utils.AssetStateUtil; import org.tron.core.store.AssetIssueStore; import org.tron.core.store.DynamicPropertiesStore; import org.tron.protos.Protocol.Account; @@ -834,7 +835,7 @@ public boolean addAsset(byte[] key, long value) { } public boolean addAssetV2(byte[] key, long value) { - if (AssetUtil.hasAssetV2(this.account, key, root)) { + if (hasAssetV2(key)) { return false; } @@ -1335,12 +1336,12 @@ public void clearDelegatedResource() { } public void importAsset(byte[] key) { - this.account = AssetUtil.importAssetV2(this.account, key, root); + this.account = importAssetV2(key); } public void importAllAsset() { if (!flag) { - this.account = AssetUtil.importAllAsset(this.account, root); + this.account = importAllAssetV2(); flag = true; } } @@ -1459,4 +1460,25 @@ public void setNewWindowSizeV2( ResourceCode resourceCode, long newWindowSize) { } } + private boolean hasAssetV2(byte[] key) { + if (Bytes32.ZERO.equals(this.root)) { + return AssetUtil.hasAssetV2(this.account, key); + } + return AssetStateUtil.hasAssetV2(this.account, key, this.root); + } + + private Account importAssetV2(byte[] key) { + if (Bytes32.ZERO.equals(this.root)) { + return AssetUtil.importAsset(this.account, key); + } + return AssetStateUtil.importAssetV2(this.account, key , this.root); + } + + private Account importAllAssetV2() { + if (Bytes32.ZERO.equals(root)) { + return AssetUtil.importAllAsset(this.account); + } + return AssetStateUtil.importAllAsset(this.account, this.root); + } + } diff --git a/chainbase/src/main/java/org/tron/core/capsule/utils/AssetUtil.java b/chainbase/src/main/java/org/tron/core/capsule/utils/AssetUtil.java index f554d412c19..abdb8098643 100644 --- a/chainbase/src/main/java/org/tron/core/capsule/utils/AssetUtil.java +++ b/chainbase/src/main/java/org/tron/core/capsule/utils/AssetUtil.java @@ -3,10 +3,7 @@ import com.google.common.primitives.Bytes; import java.util.HashMap; import java.util.Map; -import org.apache.tuweni.bytes.Bytes32; import org.tron.common.utils.ByteArray; -import org.tron.core.ChainBaseManager; -import org.tron.core.state.store.DynamicPropertiesStateStore; import org.tron.core.store.AccountAssetStore; import org.tron.core.store.DynamicPropertiesStore; import org.tron.protos.Protocol.Account; @@ -17,63 +14,40 @@ public class AssetUtil { private static DynamicPropertiesStore dynamicPropertiesStore; - public static boolean hasAssetV2(Account account, byte[] key, Bytes32 root) { - if (account.getAssetV2Map().containsKey(ByteArray.toStr(key))) { + public static boolean hasAssetV2(Account account, byte[] key) { + if (!account.getAssetV2Map().isEmpty() + && account.getAssetV2Map().containsKey(ByteArray.toStr(key))) { return true; } - if (!isAllowAssetOptimization(root)) { + if (!isAllowAssetOptimization()) { return false; } - if (!account.getAssetOptimized()) { - return false; - } - if (Bytes32.ZERO.equals(root)) { - byte[] dbKey = Bytes.concat(account.getAddress().toByteArray(), key); - return accountAssetStore.get(dbKey) != null; - } - return ChainBaseManager.fetch(root).hasAssetV2(account, - Long.valueOf(ByteArray.toStr(key))); + byte[] dbKey = Bytes.concat(account.getAddress().toByteArray(), key); + return accountAssetStore.get(dbKey) != null; } - public static Account importAssetV2(Account account, byte[] key, Bytes32 root) { - String tokenId = ByteArray.toStr(key); - if (account.getAssetV2Map().containsKey(tokenId)) { - return account; - } - if (!isAllowAssetOptimization(root)) { - return account; - } - if (!account.getAssetOptimized()) { + public static Account importAsset(Account account, byte[] key) { + if (!isAllowAssetOptimization()) { return account; } - long balance; - if (Bytes32.ZERO.equals(root)) { - balance = accountAssetStore.getBalance(account, key); - } else { - balance = ChainBaseManager.fetch(root).getAccountAsset(account, - Long.valueOf(ByteArray.toStr(key))); + String sKey = ByteArray.toStr(key); + if (account.getAssetV2Map().containsKey(sKey)) { + return account; } - Map map = new HashMap<>(account.getAssetV2Map()); - map.put(tokenId, balance); + long balance = accountAssetStore.getBalance(account, key); + Map map = new HashMap<>(); + map.putAll(account.getAssetV2Map()); + map.put(sKey, balance); return account.toBuilder().clearAssetV2().putAllAssetV2(map).build(); } - public static Account importAllAsset(Account account, Bytes32 root) { - if (!isAllowAssetOptimization(root)) { - return account; - } - - if (!account.getAssetOptimized()) { + public static Account importAllAsset(Account account) { + if (!isAllowAssetOptimization()) { return account; } - Map map; - if (Bytes32.ZERO.equals(root)) { - map = accountAssetStore.getAllAssets(account); - } else { - map = ChainBaseManager.fetch(root).importAllAsset(account); - } + Map map = accountAssetStore.getAllAssets(account); return account.toBuilder().clearAssetV2().putAllAssetV2(map).build(); } @@ -86,14 +60,8 @@ public static void setDynamicPropertiesStore(DynamicPropertiesStore dynamicPrope AssetUtil.dynamicPropertiesStore = dynamicPropertiesStore; } - public static boolean isAllowAssetOptimization(Bytes32 root) { - if (Bytes32.ZERO.equals(root)) { - return dynamicPropertiesStore.supportAllowAssetOptimization(); - } - try (DynamicPropertiesStateStore store = new DynamicPropertiesStateStore()) { - store.init(ChainBaseManager.fetch(root)); - return store.supportAllowAssetOptimization(); - } + public static boolean isAllowAssetOptimization() { + return dynamicPropertiesStore.supportAllowAssetOptimization(); } } diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java b/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java index 41a4e78e4ff..0f3895f556f 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java @@ -46,15 +46,15 @@ public void callBack(StateType type, byte[] key, byte[] value, Value.Operator op return; } if (op == Value.Operator.DELETE || ArrayUtils.isEmpty(value)) { - if (type == StateType.Account) { + if (type == StateType.Account && chainBaseManager.getDynamicPropertiesStore() + .getAllowAccountAssetOptimizationFromRoot() == 1) { // @see org.tron.core.db2.core.SnapshotRoot#remove(byte[] key) + // @see org.tron.core.db2.core.SnapshotRoot#put(byte[] key, byte[] value) AccountCapsule accountCapsule = new AccountCapsule(value); - if (accountCapsule.getAssetOptimized()) { - accountCapsule.getAssetMapV2().keySet().forEach(tokenId -> addFix32( - StateType.AccountAsset, com.google.common.primitives.Bytes.concat(key, - Longs.toByteArray(Long.parseLong(tokenId))), - WorldStateQueryInstance.DELETE)); - } + accountCapsule.getAssetMapV2().keySet().forEach(tokenId -> addFix32( + StateType.AccountAsset, com.google.common.primitives.Bytes.concat(key, + Longs.toByteArray(Long.parseLong(tokenId))), + WorldStateQueryInstance.DELETE)); } add(type, key, WorldStateQueryInstance.DELETE); return; diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java b/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java index f8c162968e4..05751e3ebd0 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java @@ -111,10 +111,13 @@ public Map importAllAsset(Protocol.Account account) { Bytes32 max = fix32(Bytes.wrap(Bytes.of(StateType.AccountAsset.value()), address, MAX_ASSET_ID)); TreeMap state = trieImpl.entriesFrom(min, max); - state.forEach((k, v) -> assets.put( - String.valueOf(k.slice(Byte.BYTES + ADDRESS_SIZE, Long.BYTES).toLong()), - v.toLong()) - ); + // remove asset is deleted + state.entrySet().stream() + .filter(e -> !Objects.equals(e.getValue(), UInt256.ZERO)) + .forEach(e -> assets.put( + String.valueOf( + e.getKey().slice(Byte.BYTES + ADDRESS_SIZE, Long.BYTES).toLong()), + e.getValue().toLong())); // remove asset = 0 assets.entrySet().removeIf(e -> e.getValue() <= 0); return assets; diff --git a/chainbase/src/main/java/org/tron/core/state/utils/AssetStateUtil.java b/chainbase/src/main/java/org/tron/core/state/utils/AssetStateUtil.java new file mode 100644 index 00000000000..05fcdf7dafa --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/utils/AssetStateUtil.java @@ -0,0 +1,67 @@ +package org.tron.core.state.utils; + +import org.apache.tuweni.bytes.Bytes32; +import org.tron.common.utils.ByteArray; +import org.tron.core.ChainBaseManager; +import org.tron.core.state.store.DynamicPropertiesStateStore; +import org.tron.protos.Protocol.Account; + +import java.util.HashMap; +import java.util.Map; + +public class AssetStateUtil { + + + public static boolean hasAssetV2(Account account, byte[] key, Bytes32 root) { + if (account.getAssetV2Map().containsKey(ByteArray.toStr(key))) { + return true; + } + if (!isAllowAssetOptimization(root)) { + return false; + } + if (!account.getAssetOptimized()) { + return false; + } + return ChainBaseManager.fetch(root).hasAssetV2(account, Long.valueOf(ByteArray.toStr(key))); + } + + public static Account importAssetV2(Account account, byte[] key, Bytes32 root) { + String tokenId = ByteArray.toStr(key); + if (account.getAssetV2Map().containsKey(tokenId)) { + return account; + } + if (!isAllowAssetOptimization(root)) { + return account; + } + if (!account.getAssetOptimized()) { + return account; + } + + long balance = ChainBaseManager.fetch(root).getAccountAsset(account, + Long.valueOf(ByteArray.toStr(key))); + + Map map = new HashMap<>(account.getAssetV2Map()); + map.put(tokenId, balance); + return account.toBuilder().clearAssetV2().putAllAssetV2(map).build(); + } + + public static Account importAllAsset(Account account, Bytes32 root) { + if (!isAllowAssetOptimization(root)) { + return account; + } + + if (!account.getAssetOptimized()) { + return account; + } + Map map = ChainBaseManager.fetch(root).importAllAsset(account); + return account.toBuilder().clearAssetV2().putAllAssetV2(map).build(); + } + + public static boolean isAllowAssetOptimization(Bytes32 root) { + try (DynamicPropertiesStateStore store = new DynamicPropertiesStateStore()) { + store.init(ChainBaseManager.fetch(root)); + return store.supportAllowAssetOptimization(); + } + } + +} diff --git a/framework/src/main/java/org/tron/core/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java index 9be23034a4f..98ab25d8696 100755 --- a/framework/src/main/java/org/tron/core/Wallet.java +++ b/framework/src/main/java/org/tron/core/Wallet.java @@ -3146,23 +3146,6 @@ public SmartContract getContract(GrpcAPI.BytesMessage bytesMessage) { return null; } - public SmartContract getContract(byte[] address, long blockNumber) { - Bytes32 rootHash = getRootHashByNumber(blockNumber); - WorldStateQueryInstance worldStateQueryInstance = initWorldStateQueryInstance(rootHash); - AccountCapsule accountCapsule = worldStateQueryInstance.getAccount(address); - if (accountCapsule == null) { - logger.error( - "Get contract failed, the account does not exist or the account " - + "does not have a code hash!"); - return null; - } - ContractCapsule contractCapsule = worldStateQueryInstance.getContract(address); - if (contractCapsule == null) { - return null; - } - return contractCapsule.getInstance(); - } - /** * Add a wrapper for smart contract. Current additional information including runtime code for a * smart contract. diff --git a/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java b/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java index 12694ae1875..f13eb4624ff 100644 --- a/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java +++ b/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java @@ -3,6 +3,7 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; import java.io.File; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -33,6 +34,7 @@ import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; import org.tron.core.db.Manager; +import org.tron.core.db2.ISession; import org.tron.core.exception.JsonRpcInternalException; import org.tron.core.exception.JsonRpcInvalidParamsException; import org.tron.core.exception.JsonRpcInvalidRequestException; @@ -61,6 +63,7 @@ public class WorldStateQueryTest { "cba92a516ea09f620a16ff7ee95ce0df1d56550a8babe9964981a7144c8a784a")); byte[] contractAddress; + private static WorldStateCallBack worldStateCallBack; /** * init logic. @@ -71,6 +74,8 @@ public static void init() { FileUtil.deleteDir(new File(dbPath)); } Args.setParam(new String[]{"-d", dbPath}, "config-localtest.conf"); + // disable p2p + Args.getInstance().setP2pDisable(true); // allow account root Args.getInstance().setAllowAccountStateRoot(1); // init dbBackupConfig to avoid NPE @@ -81,6 +86,11 @@ public static void init() { appTest.startServices(); appTest.startup(); chainBaseManager = context.getBean(ChainBaseManager.class); + // open account asset optimize + worldStateCallBack = context.getBean(WorldStateCallBack.class); + worldStateCallBack.setExecute(true); + chainBaseManager.getDynamicPropertiesStore().setAllowAssetOptimization(1); + worldStateCallBack.setExecute(false); manager = context.getBean(Manager.class); tronJsonRpc = context.getBean(TronJsonRpc.class); } @@ -278,12 +288,14 @@ private void checkAccount(WorldStateQueryInstance worldStateQueryInstance, long .get(account1Prikey.getAddress()); AccountCapsule account2Capsule = chainBaseManager.getAccountStore() .get(account2Prikey.getAddress()); - Assert.assertArrayEquals(account1Capsule.getInstance().toByteArray(), - worldStateQueryInstance.getAccount(account1Prikey.getAddress()) - .getInstance().toByteArray()); - Assert.assertArrayEquals(account2Capsule.getInstance().toByteArray(), - worldStateQueryInstance.getAccount(account2Prikey.getAddress()) - .getInstance().toByteArray()); + Assert.assertEquals(account1Capsule.getBalance(), + worldStateQueryInstance.getAccount(account1Prikey.getAddress()).getBalance()); + Assert.assertEquals(account2Capsule.getBalance(), + worldStateQueryInstance.getAccount(account2Prikey.getAddress()).getBalance()); + Assert.assertEquals(account1Capsule.getAssetMapV2(), + worldStateQueryInstance.getAccount(account1Prikey.getAddress()).getAssetMapV2()); + Assert.assertEquals(account2Capsule.getAssetMapV2(), + worldStateQueryInstance.getAccount(account2Prikey.getAddress()).getAssetMapV2()); Assert.assertEquals(tronJsonRpc.getTrxBalance( ByteArray.toHexString(account1Prikey.getAddress()), ByteArray.toJsonHex(blockNum)), @@ -497,4 +509,60 @@ private TransactionCapsule setAndSignTx(Protocol.Transaction transaction, transactionCapsule.getInstance())); } + @Test + public void mockSuicide() { + worldStateCallBack.setExecute(true); + byte[] address = ByteArray.fromHexString("41B68F8AEC4279E8527D678A52BFDFD23B1AA69729"); + Protocol.Account.Builder builder = Protocol.Account.newBuilder(); + builder.setAddress(ByteString.copyFrom(address)); + builder.setBalance(100L); + builder.putAssetV2("1000001", 10); + builder.putAssetV2("1000002", 20); + + AccountCapsule capsule = new AccountCapsule(builder.build()); + try (ISession tmpSession = manager.getRevokingStore().buildSession()) { + chainBaseManager.getAccountStore().put(capsule.createDbKey(), capsule); + tmpSession.commit(); + } + + try (ISession tmpSession = manager.getRevokingStore().buildSession()) { + chainBaseManager.getAccountStore().delete(capsule.createDbKey()); + tmpSession.commit(); + } + + builder = Protocol.Account.newBuilder(); + builder.setAddress(ByteString.copyFrom(address)); + builder.setBalance(200L); + builder.putAssetV2("1000003", 30); + + capsule = new AccountCapsule(builder.build()); + try (ISession tmpSession = manager.getRevokingStore().buildSession()) { + chainBaseManager.getAccountStore().put(capsule.createDbKey(), capsule); + tmpSession.commit(); + } + + WorldStateQueryInstance instance = getQueryInstance(); + AccountCapsule fromState = instance.getAccount(address); + AccountCapsule fromDb = chainBaseManager.getAccountStore().get(address); + Assert.assertEquals(fromState.getBalance(), 200L); + Assert.assertEquals(fromState.getBalance(), fromDb.getBalance()); + + Map assetV2 = new HashMap<>(); + assetV2.put("1000003", 30L); + + Assert.assertEquals(assetV2, fromDb.getAssetV2MapForTest()); + + Assert.assertEquals(assetV2, fromState.getAssetV2MapForTest()); + worldStateCallBack.setExecute(false); + } + + private WorldStateQueryInstance getQueryInstance() { + Assert.assertNotNull(worldStateCallBack.getTrie()); + worldStateCallBack.clear(); + worldStateCallBack.getTrie().commit(); + worldStateCallBack.getTrie().flush(); + return new WorldStateQueryInstance(worldStateCallBack.getTrie().getRootHashByte32(), + chainBaseManager); + } + } From 7f3e4eb5f6dd98d3cb3934c82901141caaac06c2 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Mon, 17 Apr 2023 16:37:41 +0800 Subject: [PATCH 16/34] feat(trie): add stat for trie db --- .../common/storage/metric/DbStatService.java | 12 +---- .../org/tron/common/storage/metric/Stat.java | 6 +++ .../tron/core/db/common/DbSourceInter.java | 5 +-- .../java/org/tron/core/db2/common/DB.java | 6 +-- .../tron/core/state/WorldStateTrieStore.java | 45 +++++++++++++++++-- .../besu/storage/RocksDBKeyValueStorage.java | 4 +- 6 files changed, 57 insertions(+), 21 deletions(-) create mode 100644 chainbase/src/main/java/org/tron/common/storage/metric/Stat.java diff --git a/chainbase/src/main/java/org/tron/common/storage/metric/DbStatService.java b/chainbase/src/main/java/org/tron/common/storage/metric/DbStatService.java index 402ab087808..46dbe149070 100644 --- a/chainbase/src/main/java/org/tron/common/storage/metric/DbStatService.java +++ b/chainbase/src/main/java/org/tron/common/storage/metric/DbStatService.java @@ -7,8 +7,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.tron.common.prometheus.Metrics; -import org.tron.core.db.common.DbSourceInter; -import org.tron.core.db2.common.DB; @Slf4j(topic = "metrics") @Component @@ -18,15 +16,9 @@ public class DbStatService { new ThreadFactoryBuilder().setNameFormat("db-stats-thread-%d").build()); - public void register(DB db) { + public void register(Stat stat) { if (Metrics.enabled()) { - statExecutor.scheduleWithFixedDelay(db::stat, 0, 6, TimeUnit.HOURS); - } - } - - public void register(DbSourceInter db) { - if (Metrics.enabled()) { - statExecutor.scheduleWithFixedDelay(db::stat, 0, 6, TimeUnit.HOURS); + statExecutor.scheduleWithFixedDelay(stat::stat, 0, 6, TimeUnit.HOURS); } } diff --git a/chainbase/src/main/java/org/tron/common/storage/metric/Stat.java b/chainbase/src/main/java/org/tron/common/storage/metric/Stat.java new file mode 100644 index 00000000000..94366498d41 --- /dev/null +++ b/chainbase/src/main/java/org/tron/common/storage/metric/Stat.java @@ -0,0 +1,6 @@ +package org.tron.common.storage.metric; + +public interface Stat { + + void stat(); +} diff --git a/chainbase/src/main/java/org/tron/core/db/common/DbSourceInter.java b/chainbase/src/main/java/org/tron/core/db/common/DbSourceInter.java index 0823b7a7cf4..a265f3c4b15 100755 --- a/chainbase/src/main/java/org/tron/core/db/common/DbSourceInter.java +++ b/chainbase/src/main/java/org/tron/core/db/common/DbSourceInter.java @@ -17,6 +17,7 @@ */ package org.tron.core.db.common; +import org.tron.common.storage.metric.Stat; import org.tron.core.db2.common.WrappedByteArray; import java.util.Map; @@ -24,7 +25,7 @@ public interface DbSourceInter extends BatchSourceInter, - Iterable> { + Iterable>, Stat { String getDBName(); @@ -44,8 +45,6 @@ public interface DbSourceInter extends BatchSourceInter, long getTotal() throws RuntimeException; - void stat(); - Map prefixQuery(byte[] key); } diff --git a/chainbase/src/main/java/org/tron/core/db2/common/DB.java b/chainbase/src/main/java/org/tron/core/db2/common/DB.java index eae529c5ca9..2858ac06f4d 100644 --- a/chainbase/src/main/java/org/tron/core/db2/common/DB.java +++ b/chainbase/src/main/java/org/tron/core/db2/common/DB.java @@ -1,9 +1,11 @@ package org.tron.core.db2.common; +import org.tron.common.storage.metric.Stat; + import java.util.Iterator; import java.util.Map; -public interface DB extends Iterable>, Instance> { +public interface DB extends Iterable>, Instance>, Stat { V get(K k); @@ -20,6 +22,4 @@ public interface DB extends Iterable>, Instance> void close(); String getDbName(); - - void stat(); } diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java b/chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java index f77d4b75ac4..32a1ab283f1 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java @@ -1,6 +1,9 @@ package org.tron.core.state; import java.nio.file.Paths; +import java.util.Arrays; +import java.util.stream.Collectors; +import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; import org.hyperledger.besu.storage.RocksDBConfiguration; @@ -10,6 +13,10 @@ import org.springframework.context.annotation.Conditional; import org.springframework.stereotype.Component; import org.tron.common.parameter.CommonParameter; +import org.tron.common.prometheus.MetricKeys; +import org.tron.common.prometheus.Metrics; +import org.tron.common.storage.metric.DbStatService; +import org.tron.common.storage.metric.Stat; import org.tron.common.utils.FileUtil; import org.tron.core.state.annotation.NeedWorldStateTrieStoreCondition; @@ -17,15 +24,26 @@ @Slf4j(topic = "State") @Component @Conditional(NeedWorldStateTrieStoreCondition.class) -public class WorldStateTrieStore extends RocksDBKeyValueStorage { +public class WorldStateTrieStore extends RocksDBKeyValueStorage implements Stat { + + private static final String NAME = "world-state-trie"; + private static final String ROCKSDB = "ROCKSDB"; + + @Autowired + private DbStatService dbStatService; @Autowired - private WorldStateTrieStore(@Value("world-state-trie") String dbName) { + private WorldStateTrieStore(@Value(NAME) String dbName) { super(buildConf(dbName)); } + @PostConstruct + private void init() { + dbStatService.register(this); + } + @PreDestroy - public void clearUp() { + private void clearUp() { try { this.close(); } catch (Exception e) { @@ -46,4 +64,25 @@ private static RocksDBConfiguration buildConf(String dbName) { .databaseDir(Paths.get(stateGenesis, dbName)).build(); } + @Override + public void stat() { + if (closed.get()) { + return; + } + try { + String[] stats = db.getProperty("rocksdb.levelstats").split("\n"); + Arrays.stream(stats).skip(2).collect(Collectors.toList()).forEach(stat -> { + String[] tmp = stat.trim().replaceAll(" +", ",").split(","); + String level = tmp[0]; + double files = Double.parseDouble(tmp[1]); + double size = Double.parseDouble(tmp[2]) * 1048576.0; + Metrics.gaugeSet(MetricKeys.Gauge.DB_SST_LEVEL, files, ROCKSDB, NAME, level); + Metrics.gaugeSet(MetricKeys.Gauge.DB_SIZE_BYTES, size, ROCKSDB, NAME, level); + logger.info("DB {}, level:{},files:{},size:{} M", + NAME, level, files, size / 1048576.0); + }); + } catch (Exception e) { + logger.warn("DB {} stats error", NAME, e); + } + } } diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBKeyValueStorage.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBKeyValueStorage.java index dfdb4a38501..2684d0c5a72 100644 --- a/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBKeyValueStorage.java +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/storage/RocksDBKeyValueStorage.java @@ -36,8 +36,8 @@ public class RocksDBKeyValueStorage implements KeyValueStorage { private static final Logger LOG = LoggerFactory.getLogger(RocksDBKeyValueStorage.class); private final Options options; - private final OptimisticTransactionDB db; - private final AtomicBoolean closed = new AtomicBoolean(false); + protected final OptimisticTransactionDB db; + protected final AtomicBoolean closed = new AtomicBoolean(false); private final WriteOptions tryDeleteOptions = new WriteOptions().setNoSlowdown(true).setIgnoreMissingColumnFamilies(true); From f1d22ba9a56ddce1d7bd9155bdc297917f599851 Mon Sep 17 00:00:00 2001 From: guoquanwu Date: Mon, 17 Apr 2023 16:24:05 +0800 Subject: [PATCH 17/34] feat(trie): fix `getStorageAt` logic for `create2` contracts --- .../src/main/java/org/tron/core/Wallet.java | 1 + .../tron/common/runtime/VmStateTestUtil.java | 7 +++++-- .../tron/common/runtime/vm/Create2Test.java | 21 +++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/framework/src/main/java/org/tron/core/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java index 98ab25d8696..caade28ecce 100755 --- a/framework/src/main/java/org/tron/core/Wallet.java +++ b/framework/src/main/java/org/tron/core/Wallet.java @@ -4517,6 +4517,7 @@ public byte[] getStorageAt(byte[] address, String storageIdx, long blockNumber) } Storage storage = new Storage(address, worldStateQueryInstance); storage.setContractVersion(contractCapsule.getInstance().getVersion()); + storage.generateAddrHash(contractCapsule.getTrxHash()); DataWord value = storage.getValue(new DataWord(ByteArray.fromHexString(storageIdx))); return value == null ? new byte[32] : value.getData(); } diff --git a/framework/src/test/java/org/tron/common/runtime/VmStateTestUtil.java b/framework/src/test/java/org/tron/common/runtime/VmStateTestUtil.java index 9ed42139457..66d7c54c805 100644 --- a/framework/src/test/java/org/tron/common/runtime/VmStateTestUtil.java +++ b/framework/src/test/java/org/tron/common/runtime/VmStateTestUtil.java @@ -37,12 +37,13 @@ public static ProgramResult runConstantCall( public static BlockCapsule mockBlock(ChainBaseManager chainBaseManager, WorldStateCallBack worldStateCallBack) { - chainBaseManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(1000); + long mockNumber = 1000; + chainBaseManager.getDynamicPropertiesStore().saveLatestBlockHeaderNumber(mockNumber); TrieImpl2 trie = flushTrie(worldStateCallBack); BlockCapsule blockCap = new BlockCapsule(Protocol.Block.newBuilder().build()); Protocol.BlockHeader.raw blockHeaderRaw = blockCap.getInstance().getBlockHeader().getRawData().toBuilder() - .setNumber(100) + .setNumber(mockNumber) .setTimestamp(System.currentTimeMillis()) .setWitnessAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) .build(); @@ -53,6 +54,8 @@ public static BlockCapsule mockBlock(ChainBaseManager chainBaseManager, blockCap = new BlockCapsule( blockCap.getInstance().toBuilder().setBlockHeader(blockHeader).build()); blockCap.generatedByMyself = true; + chainBaseManager.getBlockStore().put(blockCap.getBlockId().getBytes(), blockCap); + chainBaseManager.getBlockIndexStore().put(blockCap.getBlockId()); return blockCap; } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/Create2Test.java b/framework/src/test/java/org/tron/common/runtime/vm/Create2Test.java index 8f9ea5c059a..90bd07c605a 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/Create2Test.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/Create2Test.java @@ -5,17 +5,20 @@ import java.util.Arrays; import java.util.Collections; + import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; import org.junit.Test; import org.testng.Assert; import org.tron.common.runtime.TVMTestResult; import org.tron.common.runtime.TvmTestUtils; +import org.tron.common.runtime.VmStateTestUtil; import org.tron.common.utils.ByteArray; import org.tron.common.utils.WalletUtil; import org.tron.common.utils.client.utils.AbiUtil; import org.tron.common.utils.client.utils.DataWord; import org.tron.core.Wallet; +import org.tron.core.capsule.BlockCapsule; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; import org.tron.core.exception.JsonRpcInvalidParamsException; @@ -23,6 +26,7 @@ import org.tron.core.exception.VMIllegalException; import org.tron.core.services.NodeInfoService; import org.tron.core.services.jsonrpc.TronJsonRpcImpl; +import org.tron.core.state.WorldStateCallBack; import org.tron.protos.Protocol.Transaction; @@ -103,10 +107,15 @@ triggercontract Txxxxxxxxxxx deploy(bytes,uint256) bytes,uint256 false 100000000 */ + private WorldStateCallBack worldStateCallBack; + @Test public void testCreate2() throws ContractExeException, ReceiptCheckErrException, VMIllegalException, ContractValidateException { + worldStateCallBack = context.getBean(WorldStateCallBack.class); + worldStateCallBack.setExecute(true); + manager.getDynamicPropertiesStore().saveAllowTvmTransferTrc10(1); manager.getDynamicPropertiesStore().saveAllowTvmConstantinople(1); manager.getDynamicPropertiesStore().saveAllowTvmIstanbul(0); @@ -202,6 +211,18 @@ private void testJsonRpc(byte[] actualContract, long loop) { } catch (JsonRpcInvalidParamsException e) { Assert.fail(); } + + // test for archive node + BlockCapsule blockCapsule = + VmStateTestUtil.mockBlock(manager.getChainBaseManager(), worldStateCallBack); + try { + String res = + tronJsonRpc.getStorageAt(ByteArray.toHexString(actualContract), "0", + "0x" + Long.toHexString(blockCapsule.getNum())); + Assert.assertEquals(loop, ByteArray.jsonHexToLong(res)); + } catch (JsonRpcInvalidParamsException e) { + Assert.fail(); + } } /* From 53a2b193a8bf353049dee2e006a9d9e39263e034 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Thu, 20 Apr 2023 15:14:52 +0800 Subject: [PATCH 18/34] refactor(trie): optimize code for TVM --- .../org/tron/core/actuator/VMActuator.java | 22 +- .../org/tron/core/vm/program/Storage.java | 17 +- .../vm/repository/RepositoryStateImpl.java | 45 ++-- .../core/state/WorldStateQueryInstance.java | 26 +- .../core/state/store/AccountStateStore.java | 14 +- .../state/store/AssetIssueV2StateStore.java | 15 +- .../state/store/DelegationStateStore.java | 14 +- .../store/DynamicPropertiesStateStore.java | 20 +- .../org/tron/core/state/store/StateStore.java | 11 - .../state/store/StorageRowStateStore.java | 113 ++++++++ .../tron/core/state/utils/AssetStateUtil.java | 4 +- .../org/tron/core/store/StorageRowStore.java | 4 + .../src/main/java/org/tron/core/Wallet.java | 14 +- .../tron/common/runtime/vm/FreezeV2Test.java | 18 +- .../common/runtime/vm/RewardBalanceTest.java | 18 +- .../runtime/vm/TransferToAccountTest.java | 5 +- .../DelegateResourceActuatorTest.java | 3 +- .../actuator/FreezeBalanceActuatorTest.java | 3 +- .../actuator/UnfreezeBalanceActuatorTest.java | 21 +- .../UnfreezeBalanceV2ActuatorTest.java | 14 +- .../state/WorldStateQueryInstanceTest.java | 252 +++++++++++++----- .../tron/core/state/WorldStateQueryTest.java | 20 +- 22 files changed, 433 insertions(+), 240 deletions(-) create mode 100644 chainbase/src/main/java/org/tron/core/state/store/StorageRowStateStore.java diff --git a/actuator/src/main/java/org/tron/core/actuator/VMActuator.java b/actuator/src/main/java/org/tron/core/actuator/VMActuator.java index 25098d17a68..a6157f9e6e2 100644 --- a/actuator/src/main/java/org/tron/core/actuator/VMActuator.java +++ b/actuator/src/main/java/org/tron/core/actuator/VMActuator.java @@ -34,6 +34,7 @@ import org.tron.core.db.TransactionContext; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; +import org.tron.core.exception.HeaderNotFound; import org.tron.core.utils.TransactionUtil; import org.tron.core.vm.EnergyCost; import org.tron.core.vm.LogInfoTriggerParser; @@ -94,6 +95,9 @@ public class VMActuator implements Actuator2 { private LogInfoTriggerParser logInfoTriggerParser; + private static final boolean isAllowStateRoot = CommonParameter.getInstance().getStorage() + .isAllowStateRoot(); + public VMActuator(boolean isConstantCall) { this.isConstantCall = isConstantCall; this.maxEnergyLimit = CommonParameter.getInstance().maxEnergyLimitForConstant; @@ -120,16 +124,20 @@ public void validate(Object object) throws ContractValidateException { trx = context.getTrxCap().getInstance(); // check whether is state query - boolean stateQuery = context.getBlockCap() != null - && context.getBlockCap().getNum() < context.getStoreFactory() - .getChainBaseManager().getDynamicPropertiesStore().getLatestBlockHeaderNumber(); + boolean stateQuery = isAllowStateRoot && isConstantCall; + stateQuery = stateQuery && context.getBlockCap() != null; + try { + stateQuery = stateQuery && context.getBlockCap().getNum() < context.getStoreFactory() + .getChainBaseManager().getHead().getNum(); + } catch (HeaderNotFound e) { + throw new ContractValidateException(e.getMessage()); + } //Prepare Repository - if (!stateQuery) { - rootRepository = RepositoryImpl.createRoot(context.getStoreFactory()); + if (stateQuery) { + rootRepository = RepositoryStateImpl.createRoot(context.getBlockCap().getArchiveRoot()); } else { - rootRepository = RepositoryStateImpl.createRoot(context.getStoreFactory(), - context.getBlockCap().getArchiveRoot()); + rootRepository = RepositoryImpl.createRoot(context.getStoreFactory()); } // Load Config ConfigLoader.load(rootRepository); diff --git a/actuator/src/main/java/org/tron/core/vm/program/Storage.java b/actuator/src/main/java/org/tron/core/vm/program/Storage.java index 82d53b4d1bb..572af048081 100644 --- a/actuator/src/main/java/org/tron/core/vm/program/Storage.java +++ b/actuator/src/main/java/org/tron/core/vm/program/Storage.java @@ -10,7 +10,6 @@ import org.tron.common.runtime.vm.DataWord; import org.tron.common.utils.ByteUtil; import org.tron.core.capsule.StorageRowCapsule; -import org.tron.core.state.WorldStateQueryInstance; import org.tron.core.store.StorageRowStore; public class Storage { @@ -20,19 +19,13 @@ public class Storage { private final Map rowCache = new HashMap<>(); @Getter private byte[] addrHash; + @Getter private StorageRowStore store; - private WorldStateQueryInstance worldStateQueryInstance; @Getter private byte[] address; @Setter private int contractVersion; - public Storage(byte[] address, WorldStateQueryInstance worldStateQueryInstance) { - addrHash = addrHash(address); - this.address = address; - this.worldStateQueryInstance = worldStateQueryInstance; - } - public Storage(byte[] address, StorageRowStore store) { addrHash = addrHash(address); this.address = address; @@ -43,7 +36,6 @@ public Storage(Storage storage) { this.addrHash = storage.addrHash.clone(); this.address = storage.getAddress().clone(); this.store = storage.store; - this.worldStateQueryInstance = storage.worldStateQueryInstance; this.contractVersion = storage.contractVersion; storage.getRowCache().forEach((DataWord rowKey, StorageRowCapsule row) -> { StorageRowCapsule newRow = new StorageRowCapsule(row); @@ -82,9 +74,7 @@ public DataWord getValue(DataWord key) { if (rowCache.containsKey(key)) { return new DataWord(rowCache.get(key).getValue()); } else { - byte[] rowKey = compose(key.getData(), addrHash); - StorageRowCapsule row = worldStateQueryInstance == null - ? store.get(rowKey) : worldStateQueryInstance.getStorageRow(rowKey); + StorageRowCapsule row = store.get(compose(key.getData(), addrHash)); if (row == null || row.getInstance() == null) { return null; } @@ -104,9 +94,6 @@ public void put(DataWord key, DataWord value) { } public void commit() { - if (store == null) { - throw new UnsupportedOperationException(); - } rowCache.forEach((DataWord rowKey, StorageRowCapsule row) -> { if (row.isDirty()) { if (new DataWord(row.getValue()).isZero()) { diff --git a/actuator/src/main/java/org/tron/core/vm/repository/RepositoryStateImpl.java b/actuator/src/main/java/org/tron/core/vm/repository/RepositoryStateImpl.java index c7b12de9b80..cb537877e98 100644 --- a/actuator/src/main/java/org/tron/core/vm/repository/RepositoryStateImpl.java +++ b/actuator/src/main/java/org/tron/core/vm/repository/RepositoryStateImpl.java @@ -42,12 +42,13 @@ import org.tron.core.state.store.AssetIssueV2StateStore; import org.tron.core.state.store.DelegationStateStore; import org.tron.core.state.store.DynamicPropertiesStateStore; +import org.tron.core.state.store.StorageRowStateStore; import org.tron.core.store.AccountStore; import org.tron.core.store.AssetIssueStore; import org.tron.core.store.AssetIssueV2Store; import org.tron.core.store.DelegationStore; import org.tron.core.store.DynamicPropertiesStore; -import org.tron.core.store.StoreFactory; +import org.tron.core.store.StorageRowStore; import org.tron.core.vm.config.VMConfig; import org.tron.core.vm.program.Program; import org.tron.core.vm.program.Storage; @@ -71,7 +72,6 @@ public class RepositoryStateImpl implements Repository { private static final byte[] TOTAL_TRON_POWER_WEIGHT = "TOTAL_TRON_POWER_WEIGHT".getBytes(); private final Bytes32 rootHash; - private StoreFactory storeFactory; @Getter private final WorldStateQueryInstance worldStateQueryInstance; @@ -80,6 +80,7 @@ public class RepositoryStateImpl implements Repository { private final AssetIssueV2StateStore assetIssueV2StateStore; private final DelegationStateStore delegationStateStore; private final DynamicPropertiesStateStore dynamicPropertiesStateStore; + private final StorageRowStateStore storageRowStateStore; private Repository parent = null; @@ -98,36 +99,24 @@ public class RepositoryStateImpl implements Repository { private final HashMap> delegatedResourceAccountIndexCache = new HashMap<>(); - public RepositoryStateImpl(StoreFactory storeFactory, RepositoryStateImpl repository, - Bytes32 rootHash) { + public RepositoryStateImpl(Bytes32 rootHash, RepositoryStateImpl repository) { this.rootHash = rootHash; + this.parent = repository; this.worldStateQueryInstance = ChainBaseManager.fetch(rootHash); - this.accountStateStore = new AccountStateStore(); - this.assetIssueV2StateStore = new AssetIssueV2StateStore(); - this.delegationStateStore = new DelegationStateStore(); - this.dynamicPropertiesStateStore = new DynamicPropertiesStateStore(); - - init(storeFactory, repository); - } - - public static RepositoryStateImpl createRoot(StoreFactory storeFactory, Bytes32 rootHash) { - return new RepositoryStateImpl(storeFactory, null, rootHash); + this.accountStateStore = new AccountStateStore(worldStateQueryInstance); + this.assetIssueV2StateStore = new AssetIssueV2StateStore(worldStateQueryInstance); + this.delegationStateStore = new DelegationStateStore(worldStateQueryInstance); + this.dynamicPropertiesStateStore = new DynamicPropertiesStateStore(worldStateQueryInstance); + this.storageRowStateStore = new StorageRowStateStore(worldStateQueryInstance); } - protected void init(StoreFactory storeFactory, RepositoryStateImpl parent) { - if (storeFactory != null) { - this.storeFactory = storeFactory; - } - this.parent = parent; - accountStateStore.init(this.worldStateQueryInstance); - assetIssueV2StateStore.init(this.worldStateQueryInstance); - delegationStateStore.init(this.worldStateQueryInstance); - dynamicPropertiesStateStore.init(this.worldStateQueryInstance); + public static RepositoryStateImpl createRoot(Bytes32 rootHash) { + return new RepositoryStateImpl(rootHash, null); } @Override public Repository newRepositoryChild() { - return new RepositoryStateImpl(storeFactory, this, this.rootHash); + return new RepositoryStateImpl(this.rootHash, this); } @Override @@ -248,6 +237,10 @@ public DelegationStore getDelegationStore() { return delegationStateStore; } + public StorageRowStore getStorageRowStore() { + return storageRowStateStore; + } + @Override public AccountCapsule createAccount(byte[] address, Protocol.AccountType type) { Key key = new Key(address); @@ -624,7 +617,7 @@ public Storage getStorage(byte[] address) { storage = parentStorage; } } else { - storage = new Storage(address, worldStateQueryInstance); + storage = new Storage(address, getStorageRowStore()); } ContractCapsule contract = getContract(address); if (contract != null) { @@ -794,7 +787,7 @@ public byte[] getBlackHoleAddress() { @Override public BlockCapsule getBlockByNum(long num) { try { - return ChainBaseManager.getInstance().getBlockByNum(num); + return worldStateQueryInstance.getBlockByNum(num); } catch (StoreException e) { throw new Program.IllegalOperationException("cannot find block num"); } diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java b/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java index 05751e3ebd0..1e00133340c 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java @@ -15,6 +15,7 @@ import org.tron.core.ChainBaseManager; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.AssetIssueCapsule; +import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.BytesCapsule; import org.tron.core.capsule.CodeCapsule; import org.tron.core.capsule.ContractCapsule; @@ -24,6 +25,8 @@ import org.tron.core.capsule.StorageRowCapsule; import org.tron.core.capsule.VotesCapsule; import org.tron.core.capsule.WitnessCapsule; +import org.tron.core.exception.ItemNotFoundException; +import org.tron.core.exception.StoreException; import org.tron.core.state.trie.TrieImpl2; import org.tron.protos.Protocol; @@ -40,11 +43,13 @@ public class WorldStateQueryInstance { public static final Bytes MIN_ASSET_ID = Bytes.ofUnsignedLong(0); private final WorldStateGenesis worldStateGenesis; + private final ChainBaseManager chainBaseManager; public WorldStateQueryInstance(Bytes32 rootHash, ChainBaseManager chainBaseManager) { this.rootHash = rootHash; this.trieImpl = new TrieImpl2(chainBaseManager.getWorldStateTrieStore(), rootHash); this.worldStateGenesis = chainBaseManager.getWorldStateGenesis(); + this.chainBaseManager = chainBaseManager; } private byte[] get(StateType type, byte[] key) { @@ -139,14 +144,13 @@ public CodeCapsule getCode(byte[] address) { return Objects.nonNull(value) ? new CodeCapsule(value) : null; } + + // never return null public StorageRowCapsule getStorageRow(byte[] key) { byte[] value = get(StateType.StorageRow, key); - if (Objects.nonNull(value)) { - StorageRowCapsule storageRowCapsule = new StorageRowCapsule(value); - storageRowCapsule.setRowKey(key); - return storageRowCapsule; - } - return null; + StorageRowCapsule storageRowCapsule = new StorageRowCapsule(value); + storageRowCapsule.setRowKey(key); + return storageRowCapsule; } // asset @@ -185,12 +189,12 @@ public VotesCapsule getVotes(byte[] address) { } // properties - public BytesCapsule getDynamicProperty(byte[] key) { + public BytesCapsule getDynamicProperty(byte[] key) throws ItemNotFoundException { BytesCapsule value = getUncheckedDynamicProperty(key); if (Objects.nonNull(value)) { return value; } else { - throw new IllegalArgumentException("not found: " + ByteArray.toStr(key)); + throw new ItemNotFoundException(); } } @@ -201,4 +205,10 @@ public BytesCapsule getUncheckedDynamicProperty(byte[] key) { } return null; } + + // getBlockByNum + public BlockCapsule getBlockByNum(long num) throws StoreException { + return chainBaseManager.getBlockByNum(num); + } + } diff --git a/chainbase/src/main/java/org/tron/core/state/store/AccountStateStore.java b/chainbase/src/main/java/org/tron/core/state/store/AccountStateStore.java index 54e992617a0..224fa68765c 100644 --- a/chainbase/src/main/java/org/tron/core/state/store/AccountStateStore.java +++ b/chainbase/src/main/java/org/tron/core/state/store/AccountStateStore.java @@ -1,11 +1,9 @@ package org.tron.core.state.store; -import lombok.Getter; import org.rocksdb.DirectComparator; import org.tron.core.capsule.AccountCapsule; import org.tron.core.db2.common.WrappedByteArray; import org.tron.core.db2.core.Chainbase; -import org.tron.core.exception.BadItemException; import org.tron.core.state.WorldStateQueryInstance; import org.tron.core.store.AccountStore; @@ -15,13 +13,9 @@ public class AccountStateStore extends AccountStore implements StateStore { private WorldStateQueryInstance worldStateQueryInstance; - @Getter - private boolean init; - @Override - public void init(WorldStateQueryInstance worldStateQueryInstance) { + public AccountStateStore(WorldStateQueryInstance worldStateQueryInstance) { this.worldStateQueryInstance = worldStateQueryInstance; - this.init = true; } //**** Override Operation For StateDB @@ -44,19 +38,17 @@ public AccountCapsule getFromRoot(byte[] key) { @Override public AccountCapsule getUnchecked(byte[] key) { - throwIfNotInit(); return worldStateQueryInstance.getAccount(key); } @Override public boolean has(byte[] key) { - return get(key) != null; + return getUnchecked(key) != null; } @Override public void close() { this.worldStateQueryInstance = null; - init = false; } @Override @@ -90,7 +82,7 @@ public void delete(byte[] key) { } @Override - public AccountCapsule of(byte[] value) throws BadItemException { + public AccountCapsule of(byte[] value) { throwIfError(); return null; } diff --git a/chainbase/src/main/java/org/tron/core/state/store/AssetIssueV2StateStore.java b/chainbase/src/main/java/org/tron/core/state/store/AssetIssueV2StateStore.java index 2cd563b8e77..fc76137ac2c 100644 --- a/chainbase/src/main/java/org/tron/core/state/store/AssetIssueV2StateStore.java +++ b/chainbase/src/main/java/org/tron/core/state/store/AssetIssueV2StateStore.java @@ -1,12 +1,10 @@ package org.tron.core.state.store; -import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.rocksdb.DirectComparator; import org.tron.core.capsule.AssetIssueCapsule; import org.tron.core.db2.common.WrappedByteArray; import org.tron.core.db2.core.Chainbase; -import org.tron.core.exception.BadItemException; import org.tron.core.state.WorldStateQueryInstance; import org.tron.core.store.AssetIssueV2Store; @@ -18,13 +16,10 @@ public class AssetIssueV2StateStore extends AssetIssueV2Store implements StateStore { private WorldStateQueryInstance worldStateQueryInstance; - @Getter - private boolean init; - @Override - public void init(WorldStateQueryInstance worldStateQueryInstance) { + + public AssetIssueV2StateStore(WorldStateQueryInstance worldStateQueryInstance) { this.worldStateQueryInstance = worldStateQueryInstance; - this.init = true; } //**** Override Operation For StateDB @@ -47,19 +42,17 @@ public AssetIssueCapsule getFromRoot(byte[] key) { @Override public AssetIssueCapsule getUnchecked(byte[] key) { - throwIfNotInit(); return worldStateQueryInstance.getAssetIssue(key); } @Override public boolean has(byte[] key) { - return get(key) != null; + return getUnchecked(key) != null; } @Override public void close() { this.worldStateQueryInstance = null; - init = false; } @Override @@ -89,7 +82,7 @@ public void delete(byte[] key) { } @Override - public AssetIssueCapsule of(byte[] value) throws BadItemException { + public AssetIssueCapsule of(byte[] value) { throwIfError(); return null; } diff --git a/chainbase/src/main/java/org/tron/core/state/store/DelegationStateStore.java b/chainbase/src/main/java/org/tron/core/state/store/DelegationStateStore.java index b20ff8814d9..bad3fed0745 100644 --- a/chainbase/src/main/java/org/tron/core/state/store/DelegationStateStore.java +++ b/chainbase/src/main/java/org/tron/core/state/store/DelegationStateStore.java @@ -1,11 +1,9 @@ package org.tron.core.state.store; -import lombok.Getter; import org.rocksdb.DirectComparator; import org.tron.core.capsule.BytesCapsule; import org.tron.core.db2.common.WrappedByteArray; import org.tron.core.db2.core.Chainbase; -import org.tron.core.exception.BadItemException; import org.tron.core.state.WorldStateQueryInstance; import org.tron.core.store.DelegationStore; @@ -15,13 +13,9 @@ public class DelegationStateStore extends DelegationStore implements StateStore { private WorldStateQueryInstance worldStateQueryInstance; - @Getter - private boolean init; - @Override - public void init(WorldStateQueryInstance worldStateQueryInstance) { + public DelegationStateStore(WorldStateQueryInstance worldStateQueryInstance) { this.worldStateQueryInstance = worldStateQueryInstance; - this.init = true; } //**** Override Operation For StateDB @@ -44,19 +38,17 @@ public BytesCapsule getFromRoot(byte[] key) { @Override public BytesCapsule getUnchecked(byte[] key) { - throwIfNotInit(); return worldStateQueryInstance.getDelegation(key); } @Override public boolean has(byte[] key) { - return get(key) != null; + return getUnchecked(key) != null; } @Override public void close() { this.worldStateQueryInstance = null; - init = false; } @Override @@ -86,7 +78,7 @@ public void delete(byte[] key) { } @Override - public BytesCapsule of(byte[] value) throws BadItemException { + public BytesCapsule of(byte[] value) { throwIfError(); return null; } diff --git a/chainbase/src/main/java/org/tron/core/state/store/DynamicPropertiesStateStore.java b/chainbase/src/main/java/org/tron/core/state/store/DynamicPropertiesStateStore.java index 1ec14d58109..cc0ad1b3897 100644 --- a/chainbase/src/main/java/org/tron/core/state/store/DynamicPropertiesStateStore.java +++ b/chainbase/src/main/java/org/tron/core/state/store/DynamicPropertiesStateStore.java @@ -1,11 +1,10 @@ package org.tron.core.state.store; -import lombok.Getter; import org.rocksdb.DirectComparator; import org.tron.core.capsule.BytesCapsule; import org.tron.core.db2.common.WrappedByteArray; import org.tron.core.db2.core.Chainbase; -import org.tron.core.exception.BadItemException; +import org.tron.core.exception.ItemNotFoundException; import org.tron.core.state.WorldStateQueryInstance; import org.tron.core.store.DynamicPropertiesStore; @@ -15,13 +14,9 @@ public class DynamicPropertiesStateStore extends DynamicPropertiesStore implements StateStore { private WorldStateQueryInstance worldStateQueryInstance; - @Getter - private boolean init; - @Override - public void init(WorldStateQueryInstance worldStateQueryInstance) { + public DynamicPropertiesStateStore(WorldStateQueryInstance worldStateQueryInstance) { this.worldStateQueryInstance = worldStateQueryInstance; - init = true; } //**** Override Operation For StateDB @@ -32,32 +27,29 @@ public String getDbName() { } @Override - public BytesCapsule get(byte[] key) { + public BytesCapsule get(byte[] key) throws ItemNotFoundException { return getFromRoot(key); } @Override - public BytesCapsule getFromRoot(byte[] key) { - throwIfNotInit(); + public BytesCapsule getFromRoot(byte[] key) throws ItemNotFoundException { return worldStateQueryInstance.getDynamicProperty(key); } @Override public BytesCapsule getUnchecked(byte[] key) { - throwIfNotInit(); return worldStateQueryInstance.getUncheckedDynamicProperty(key); } @Override public boolean has(byte[] key) { - return get(key) != null; + return getUnchecked(key) != null; } @Override public void close() { this.worldStateQueryInstance = null; - init = false; } @Override @@ -87,7 +79,7 @@ public void delete(byte[] key) { } @Override - public BytesCapsule of(byte[] value) throws BadItemException { + public BytesCapsule of(byte[] value) { throwIfError(); return null; } diff --git a/chainbase/src/main/java/org/tron/core/state/store/StateStore.java b/chainbase/src/main/java/org/tron/core/state/store/StateStore.java index 27900b2848d..cb5612ca89d 100644 --- a/chainbase/src/main/java/org/tron/core/state/store/StateStore.java +++ b/chainbase/src/main/java/org/tron/core/state/store/StateStore.java @@ -1,20 +1,9 @@ package org.tron.core.state.store; -import org.tron.core.state.WorldStateQueryInstance; public interface StateStore { - void init(WorldStateQueryInstance worldStateQueryInstance); - - boolean isInit(); - default void throwIfError() { throw new UnsupportedOperationException(); } - - default void throwIfNotInit() { - if (!isInit()) { - throw new IllegalStateException(); - } - } } diff --git a/chainbase/src/main/java/org/tron/core/state/store/StorageRowStateStore.java b/chainbase/src/main/java/org/tron/core/state/store/StorageRowStateStore.java new file mode 100644 index 00000000000..b2b4f455b88 --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/store/StorageRowStateStore.java @@ -0,0 +1,113 @@ +package org.tron.core.state.store; + +import org.rocksdb.DirectComparator; +import org.tron.core.capsule.StorageRowCapsule; +import org.tron.core.db2.common.WrappedByteArray; +import org.tron.core.db2.core.Chainbase; +import org.tron.core.state.WorldStateQueryInstance; +import org.tron.core.store.StorageRowStore; + +import java.util.Iterator; +import java.util.Map; + +public class StorageRowStateStore extends StorageRowStore implements StateStore { + + private WorldStateQueryInstance worldStateQueryInstance; + + public StorageRowStateStore(WorldStateQueryInstance worldStateQueryInstance) { + this.worldStateQueryInstance = worldStateQueryInstance; + } + + //**** Override Operation For StateDB + + @Override + public String getDbName() { + return worldStateQueryInstance.getRootHash().toHexString(); + } + + @Override + public StorageRowCapsule get(byte[] key) { + return getFromRoot(key); + } + + @Override + public StorageRowCapsule getFromRoot(byte[] key) { + return getUnchecked(key); + + } + + @Override + public StorageRowCapsule getUnchecked(byte[] key) { + return worldStateQueryInstance.getStorageRow(key); + } + + @Override + public boolean has(byte[] key) { + return getUnchecked(key).getData() != null; + } + + @Override + public void close() { + this.worldStateQueryInstance = null; + } + + @Override + public void reset() { + } + + //**** Override Operation For StateDB + + //**** Unsupported Operation For StateDB + + protected org.iq80.leveldb.Options getOptionsByDbNameForLevelDB(String dbName) { + throw new UnsupportedOperationException(); + } + + protected DirectComparator getDirectComparator() { + throw new UnsupportedOperationException(); + } + + @Override + public void put(byte[] key, StorageRowCapsule item) { + throwIfError(); + } + + @Override + public void delete(byte[] key) { + throwIfError(); + } + + @Override + public StorageRowCapsule of(byte[] value) { + throwIfError(); + return null; + } + + @Override + public boolean isNotEmpty() { + throwIfError(); + return false; + } + + @Override + public Iterator> iterator() { + throwIfError(); + return null; + } + + public long size() { + throwIfError(); + return 0; + } + + public void setCursor(Chainbase.Cursor cursor) { + throwIfError(); + } + + public Map prefixQuery(byte[] key) { + throwIfError(); + return null; + } + + //**** Unsupported Operation For StateDB +} diff --git a/chainbase/src/main/java/org/tron/core/state/utils/AssetStateUtil.java b/chainbase/src/main/java/org/tron/core/state/utils/AssetStateUtil.java index 05fcdf7dafa..f346ef2527f 100644 --- a/chainbase/src/main/java/org/tron/core/state/utils/AssetStateUtil.java +++ b/chainbase/src/main/java/org/tron/core/state/utils/AssetStateUtil.java @@ -58,8 +58,8 @@ public static Account importAllAsset(Account account, Bytes32 root) { } public static boolean isAllowAssetOptimization(Bytes32 root) { - try (DynamicPropertiesStateStore store = new DynamicPropertiesStateStore()) { - store.init(ChainBaseManager.fetch(root)); + try (DynamicPropertiesStateStore store = + new DynamicPropertiesStateStore(ChainBaseManager.fetch(root))) { return store.supportAllowAssetOptimization(); } } diff --git a/chainbase/src/main/java/org/tron/core/store/StorageRowStore.java b/chainbase/src/main/java/org/tron/core/store/StorageRowStore.java index d5c6b6d73ac..a2c1e064a45 100644 --- a/chainbase/src/main/java/org/tron/core/store/StorageRowStore.java +++ b/chainbase/src/main/java/org/tron/core/store/StorageRowStore.java @@ -16,6 +16,10 @@ private StorageRowStore(@Value("storage-row") String dbName) { super(dbName); } + protected StorageRowStore() { + super(); + } + @Override public StorageRowCapsule get(byte[] key) { StorageRowCapsule row = getUnchecked(key); diff --git a/framework/src/main/java/org/tron/core/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java index caade28ecce..3f26f9b398b 100755 --- a/framework/src/main/java/org/tron/core/Wallet.java +++ b/framework/src/main/java/org/tron/core/Wallet.java @@ -184,6 +184,7 @@ import org.tron.core.net.TronNetService; import org.tron.core.net.message.adv.TransactionMessage; import org.tron.core.state.WorldStateQueryInstance; +import org.tron.core.state.store.StorageRowStateStore; import org.tron.core.store.AccountIdIndexStore; import org.tron.core.store.AccountStore; import org.tron.core.store.AccountTraceStore; @@ -4515,11 +4516,14 @@ public byte[] getStorageAt(byte[] address, String storageIdx, long blockNumber) if (contractCapsule == null) { return null; } - Storage storage = new Storage(address, worldStateQueryInstance); - storage.setContractVersion(contractCapsule.getInstance().getVersion()); - storage.generateAddrHash(contractCapsule.getTrxHash()); - DataWord value = storage.getValue(new DataWord(ByteArray.fromHexString(storageIdx))); - return value == null ? new byte[32] : value.getData(); + + try (StorageRowStateStore store = new StorageRowStateStore(worldStateQueryInstance)) { + Storage storage = new Storage(address, store); + storage.setContractVersion(contractCapsule.getInstance().getVersion()); + storage.generateAddrHash(contractCapsule.getTrxHash()); + DataWord value = storage.getValue(new DataWord(ByteArray.fromHexString(storageIdx))); + return value == null ? new byte[32] : value.getData(); + } } private Bytes32 getRootHashByNumber(long blockNumber) { diff --git a/framework/src/test/java/org/tron/common/runtime/vm/FreezeV2Test.java b/framework/src/test/java/org/tron/common/runtime/vm/FreezeV2Test.java index ba4e1233c59..49ea2a390c8 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/FreezeV2Test.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/FreezeV2Test.java @@ -573,7 +573,7 @@ public void testSuicideToOtherAccount() throws Exception { cancelAllUnfreezeV2(owner, contract, 0); AccountCapsule contractCapsule = manager.getAccountStore().get(contract); - contractCapsule.setLatestConsumeTimeForEnergy(ChainBaseManager.getInstance().getHeadSlot()); + contractCapsule.setLatestConsumeTimeForEnergy(chainBaseManager.getHeadSlot()); contractCapsule.setNewWindowSize(ENERGY, WINDOW_SIZE_MS / BLOCK_PRODUCED_INTERVAL); contractCapsule.setEnergyUsage(frozenBalance); manager.getAccountStore().put(contract, contractCapsule); @@ -912,15 +912,13 @@ private TVMTestResult unDelegateResource( Assert.assertEquals( oldReceiver.getNetUsage() - transferUsage, newReceiver.getNetUsage()); - Assert.assertEquals( - ChainBaseManager.getInstance().getHeadSlot(), + Assert.assertEquals(chainBaseManager.getHeadSlot(), newReceiver.getLastConsumeTime(BANDWIDTH)); } else { Assert.assertEquals( oldReceiver.getEnergyUsage() + transferUsage, newReceiver.getEnergyUsage()); - Assert.assertEquals( - ChainBaseManager.getInstance().getHeadSlot(), + Assert.assertEquals(chainBaseManager.getHeadSlot(), newReceiver.getLastConsumeTime(ENERGY)); } } else { @@ -974,12 +972,12 @@ private TVMTestResult suicide(byte[] callerAddr, byte[] contractAddr, byte[] inh oldInheritorBandwidthUsage = oldInheritor.getUsage(BANDWIDTH); oldInheritorEnergyUsage = oldInheritor.getUsage(ENERGY); } - BandwidthProcessor bandwidthProcessor = new BandwidthProcessor(ChainBaseManager.getInstance()); + BandwidthProcessor bandwidthProcessor = new BandwidthProcessor(chainBaseManager); bandwidthProcessor.updateUsage(oldContract); oldContract.setLatestConsumeTime(now); EnergyProcessor energyProcessor = new EnergyProcessor( - manager.getDynamicPropertiesStore(), ChainBaseManager.getInstance().getAccountStore()); + manager.getDynamicPropertiesStore(), chainBaseManager.getAccountStore()); energyProcessor.updateUsage(oldContract); oldContract.setLatestConsumeTimeForEnergy(now); @@ -1020,8 +1018,7 @@ private TVMTestResult suicide(byte[] callerAddr, byte[] contractAddr, byte[] inh now); Assert.assertEquals( expectedNewNetUsage, newInheritor.getNetUsage() - oldInheritorBandwidthUsage); - Assert.assertEquals( - ChainBaseManager.getInstance().getHeadSlot(), newInheritor.getLatestConsumeTime()); + Assert.assertEquals(chainBaseManager.getHeadSlot(), newInheritor.getLatestConsumeTime()); } if (oldContract.getEnergyUsage() > 0) { long expectedNewEnergyUsage = @@ -1033,8 +1030,7 @@ private TVMTestResult suicide(byte[] callerAddr, byte[] contractAddr, byte[] inh now); Assert.assertEquals( expectedNewEnergyUsage, newInheritor.getEnergyUsage() - oldInheritorEnergyUsage); - Assert.assertEquals( - ChainBaseManager.getInstance().getHeadSlot(), + Assert.assertEquals(chainBaseManager.getHeadSlot(), newInheritor.getLatestConsumeTimeForEnergy()); } } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/RewardBalanceTest.java b/framework/src/test/java/org/tron/common/runtime/vm/RewardBalanceTest.java index 6a504b9f857..3b1021885e7 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/RewardBalanceTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/RewardBalanceTest.java @@ -187,7 +187,7 @@ public void testRewardBalance() repository.commit(); // test state query - testStateQuery(trie, storeFactory, blockCap, + testStateQuery(trie, blockCap, new DataWord(Base58.decode(nonexistentAccount)), rootInternalTransaction, trx); // trigger deployed contract @@ -209,7 +209,7 @@ public void testRewardBalance() repository.commit(); // test state query - testStateQuery(trie, storeFactory, blockCap, + testStateQuery(trie, blockCap, new DataWord(Base58.decode(factoryAddressStr)), rootInternalTransaction, trx); // trigger deployed contract @@ -232,8 +232,8 @@ public void testRewardBalance() repository.commit(); // test state query - testStateQuery(trie, storeFactory, blockCap, - new DataWord(Base58.decode(witnessAccount)), rootInternalTransaction, trx); + testStateQuery(trie, blockCap, + new DataWord(Base58.decode(witnessAccount)), rootInternalTransaction, trx); // Trigger contract method: nullAddressTest(address) methodByAddr = "nullAddressTest()"; @@ -255,8 +255,7 @@ public void testRewardBalance() repository.commit(); // test state query - testStateQuery(trie, storeFactory, blockCap, - DataWord.ZERO(), rootInternalTransaction, trx); + testStateQuery(trie, blockCap, DataWord.ZERO(), rootInternalTransaction, trx); // Trigger contract method: localContractAddrTest() methodByAddr = "localContractAddrTest()"; @@ -278,15 +277,14 @@ public void testRewardBalance() repository.commit(); // test state query - testStateQuery(trie, storeFactory, blockCap, + testStateQuery(trie, blockCap, new DataWord(Base58.decode(factoryAddressStr)), rootInternalTransaction, trx); ConfigLoader.disable = false; } - private void testStateQuery(TrieImpl2 trie, StoreFactory storeFactory, - BlockCapsule blockCap, DataWord address, + private void testStateQuery(TrieImpl2 trie, BlockCapsule blockCap, DataWord address, InternalTransaction rootInternalTransaction, Transaction trx) throws ContractValidateException { @@ -294,7 +292,7 @@ private void testStateQuery(TrieImpl2 trie, StoreFactory storeFactory, trie.commit(); trie.flush(); byte[] root = trie.getRootHash(); - Repository repositoryState = RepositoryStateImpl.createRoot(storeFactory, Bytes32.wrap(root)); + Repository repositoryState = RepositoryStateImpl.createRoot(Bytes32.wrap(root)); ProgramInvoke programInvoke = ProgramInvokeFactory .createProgramInvoke(InternalTransaction.TrxType.TRX_CONTRACT_CALL_TYPE, InternalTransaction.ExecutorType.ET_PRE_TYPE, trx, diff --git a/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java b/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java index 2560ef839f1..2198db7ef76 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java @@ -37,7 +37,6 @@ import org.tron.core.store.StoreFactory; import org.tron.core.vm.EnergyCost; import org.tron.core.vm.repository.RepositoryImpl; -import org.tron.core.vm.repository.RepositoryStateImpl; import org.tron.protos.Protocol.AccountType; import org.tron.protos.Protocol.Transaction; import org.tron.protos.contract.AssetIssueContractOuterClass.AssetIssueContract; @@ -57,7 +56,6 @@ public class TransferToAccountTest extends BaseTest { private static final String URL = "https://tron.network"; private static Runtime runtime; private static RepositoryImpl repository; - private static RepositoryStateImpl repositoryState; private static AccountCapsule ownerCapsule; private static WorldStateCallBack worldStateCallBack; @@ -142,8 +140,7 @@ public void TransferTokenTest() Assert.assertEquals(100, worldStateQueryInstance.getAccount(contractAddress) .getAssetV2MapForTest().get(String.valueOf(id)).longValue()); - try (AccountStateStore store = new AccountStateStore()) { - store.init(worldStateQueryInstance); + try (AccountStateStore store = new AccountStateStore(worldStateQueryInstance)) { Assert.assertEquals(100, store.get(contractAddress).getAssetV2MapForTest().get(String.valueOf(id)).longValue()); } diff --git a/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java index 0391e34caba..19741611f42 100644 --- a/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java @@ -384,8 +384,7 @@ public void testDelegateResourceForBandwidth() { long totalNetWeightAfter = dbManager.getDynamicPropertiesStore().getTotalNetWeight(); Assert.assertEquals(totalNetWeightBefore, totalNetWeightAfter); - DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(); - stateStore.init(queryInstance); + DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(queryInstance); Assert.assertEquals(totalNetWeightBefore, stateStore.getTotalNetWeight()); diff --git a/framework/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java index bbfc2c1f9f9..5e3ce901731 100644 --- a/framework/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java @@ -303,8 +303,7 @@ public void testFreezeDelegatedBalanceForBandwidth() { long totalNetWeightAfter = dbManager.getDynamicPropertiesStore().getTotalNetWeight(); Assert.assertEquals(totalNetWeightBefore + frozenBalance / 1000_000L, totalNetWeightAfter); - DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(); - stateStore.init(queryInstance); + DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(queryInstance); Assert.assertEquals(totalNetWeightBefore + frozenBalance / 1000_000L, stateStore.getTotalNetWeight()); diff --git a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java index a574760e2a7..f2fd25a3e60 100644 --- a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java @@ -151,21 +151,20 @@ public void testUnfreezeBalanceForBandwidth() { Assert.assertEquals(owner.getBalance(), initBalance + frozenBalance); Assert.assertEquals(owner.getFrozenBalance(), 0); Assert.assertEquals(owner.getTronPower(), 0L); - WorldStateQueryInstance queryInstance = getQueryInstance(); + WorldStateQueryInstance instance = getQueryInstance(); Assert.assertEquals(owner.getBalance(), - queryInstance.getAccount(owner.createDbKey()).getBalance()); + instance.getAccount(owner.createDbKey()).getBalance()); Assert.assertEquals(owner.getFrozenBalance(), - queryInstance.getAccount(owner.createDbKey()).getFrozenBalance()); + instance.getAccount(owner.createDbKey()).getFrozenBalance()); Assert.assertEquals(owner.getTronPower(), - queryInstance.getAccount(owner.createDbKey()).getTronPower()); + instance.getAccount(owner.createDbKey()).getTronPower()); long totalNetWeightAfter = dbManager.getDynamicPropertiesStore().getTotalNetWeight(); Assert.assertEquals(totalNetWeightBefore, totalNetWeightAfter + frozenBalance / 1000_000L); - try (DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore()) { - stateStore.init(queryInstance); + try (DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(instance)) { Assert.assertEquals(totalNetWeightBefore, stateStore.getTotalNetWeight() + frozenBalance / 1000_000L); } @@ -237,9 +236,8 @@ public void testUnfreezeSelfAndOthersForBandwidth() { actuator1.validate(); actuator1.execute(ret1); long afterWeight1 = dbManager.getDynamicPropertiesStore().getTotalNetWeight(); - WorldStateQueryInstance queryInstance = getQueryInstance(); - DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(); - stateStore.init(queryInstance); + WorldStateQueryInstance instance = getQueryInstance(); + DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(instance); Assert.assertEquals(1, stateStore.getTotalNetWeight()); Assert.assertEquals(1, afterWeight1); Assert.assertEquals(ret1.getInstance().getRet(), code.SUCESS); @@ -259,9 +257,8 @@ public void testUnfreezeSelfAndOthersForBandwidth() { actuator.validate(); actuator.execute(ret); long afterWeight = dbManager.getDynamicPropertiesStore().getTotalNetWeight(); - WorldStateQueryInstance queryInstance = getQueryInstance(); - DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(); - stateStore.init(queryInstance); + WorldStateQueryInstance instance = getQueryInstance(); + DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(instance); Assert.assertEquals(0, stateStore.getTotalNetWeight()); Assert.assertEquals(0, afterWeight); Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); diff --git a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceV2ActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceV2ActuatorTest.java index 57f99d8be1f..a3bfd85ac19 100644 --- a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceV2ActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceV2ActuatorTest.java @@ -175,16 +175,15 @@ public void testUnfreezeBalanceForBandwidth() { Assert.assertEquals(100, owner.getFrozenV2BalanceForBandwidth()); Assert.assertEquals(100L, owner.getTronPower()); - WorldStateQueryInstance queryInstance = getQueryInstance(); - owner = queryInstance.getAccount(ByteArray.fromHexString(OWNER_ADDRESS)); + WorldStateQueryInstance instance = getQueryInstance(); + owner = instance.getAccount(ByteArray.fromHexString(OWNER_ADDRESS)); Assert.assertEquals(100, owner.getFrozenV2BalanceForBandwidth()); Assert.assertEquals(100L, owner.getTronPower()); long totalNetWeightAfter = dbManager.getDynamicPropertiesStore().getTotalNetWeight(); Assert.assertEquals(totalNetWeightBefore - 1000, totalNetWeightAfter); - DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(); - stateStore.init(queryInstance); + DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(instance); Assert.assertEquals(totalNetWeightAfter, stateStore.getTotalNetWeight()); } catch (Exception e) { @@ -225,16 +224,15 @@ public void testUnfreezeBalanceForEnergy() { Assert.assertEquals(100, owner.getAllFrozenBalanceForEnergy()); Assert.assertEquals(100, owner.getTronPower()); - WorldStateQueryInstance queryInstance = getQueryInstance(); - owner = queryInstance.getAccount(ByteArray.fromHexString(OWNER_ADDRESS)); + WorldStateQueryInstance instance = getQueryInstance(); + owner = instance.getAccount(ByteArray.fromHexString(OWNER_ADDRESS)); Assert.assertEquals(100, owner.getAllFrozenBalanceForEnergy()); Assert.assertEquals(100, owner.getTronPower()); long totalEnergyWeightAfter = dbManager.getDynamicPropertiesStore().getTotalEnergyWeight(); Assert.assertEquals(totalEnergyWeightBefore - 1000, totalEnergyWeightAfter); - DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(); - stateStore.init(queryInstance); + DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(instance); Assert.assertEquals(totalEnergyWeightAfter, stateStore.getTotalEnergyWeight()); } catch (Exception e) { diff --git a/framework/src/test/java/org/tron/core/state/WorldStateQueryInstanceTest.java b/framework/src/test/java/org/tron/core/state/WorldStateQueryInstanceTest.java index ce0ffbcb110..95a2fb3e8e4 100644 --- a/framework/src/test/java/org/tron/core/state/WorldStateQueryInstanceTest.java +++ b/framework/src/test/java/org/tron/core/state/WorldStateQueryInstanceTest.java @@ -5,21 +5,22 @@ import com.beust.jcommander.internal.Lists; import com.google.common.primitives.Longs; import com.google.protobuf.ByteString; -import java.io.File; -import org.apache.commons.lang3.RandomStringUtils; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; -import org.tron.common.application.Application; -import org.tron.common.application.ApplicationFactory; +import org.junit.rules.TemporaryFolder; import org.tron.common.application.TronApplicationContext; import org.tron.common.config.DbBackupConfig; import org.tron.common.crypto.ECKey; -import org.tron.common.utils.FileUtil; +import org.tron.common.runtime.vm.DataWord; import org.tron.common.utils.Utils; import org.tron.core.ChainBaseManager; import org.tron.core.capsule.AssetIssueCapsule; @@ -32,49 +33,59 @@ import org.tron.core.capsule.WitnessCapsule; import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; +import org.tron.core.db.TronStoreWithRevoking; +import org.tron.core.db2.core.Chainbase; +import org.tron.core.exception.BadItemException; +import org.tron.core.exception.ItemNotFoundException; +import org.tron.core.state.store.AccountStateStore; +import org.tron.core.state.store.AssetIssueV2StateStore; +import org.tron.core.state.store.DelegationStateStore; +import org.tron.core.state.store.DynamicPropertiesStateStore; +import org.tron.core.state.store.StorageRowStateStore; import org.tron.core.state.trie.TrieImpl2; +import org.tron.core.vm.program.Storage; import org.tron.protos.Protocol; import org.tron.protos.contract.SmartContractOuterClass; public class WorldStateQueryInstanceTest { - private WorldStateQueryInstance worldStateQueryInstance; + private WorldStateQueryInstance instance; private TrieImpl2 trieImpl2; private static TronApplicationContext context; - private static Application appTest; private static ChainBaseManager chainBaseManager; private static WorldStateTrieStore worldStateTrieStore; - private static ECKey ecKey = new ECKey(Utils.getRandom()); - private static byte[] address = ecKey.getAddress(); + private static final ECKey ecKey = new ECKey(Utils.getRandom()); + private static final byte[] address = ecKey.getAddress(); - public static String DB_PATH = "trie-query-" + RandomStringUtils.randomAlphanumeric(5); + @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder(); @Before - public void init() { - Args.setParam(new String[]{"-d", DB_PATH}, "config-localtest.conf"); + public void init() throws IOException { + Args.setParam(new String[]{"-d", temporaryFolder.newFolder().toString(), + "--p2p-disable", "true"}, "config-localtest.conf"); // allow account root Args.getInstance().setAllowAccountStateRoot(1); // init dbBackupConfig to avoid NPE Args.getInstance().dbBackupConfig = DbBackupConfig.getInstance(); context = new TronApplicationContext(DefaultConfig.class); - appTest = ApplicationFactory.create(context); - appTest.startup(); + Path parentPath = temporaryFolder.newFolder().toPath(); + Path dbPath = Paths.get(parentPath.toString()); chainBaseManager = context.getBean(ChainBaseManager.class); worldStateTrieStore = chainBaseManager.getWorldStateTrieStore(); } @After - public void destory() { - appTest.shutdown(); + public void destroy() { + context.destroy(); Args.clearParam(); - FileUtil.deleteDir(new File(DB_PATH)); } @Test public void testGet() { trieImpl2 = new TrieImpl2(worldStateTrieStore); + testGetAccount(); testGetAccountAsset(); testGetContractState(); testGetContract(); @@ -86,35 +97,52 @@ public void testGet() { testGetDelegatedResourceAccountIndex(); testGetVotes(); testGetDynamicProperty(); + testGetStorageRow(); + } + + private void testGetAccount() { + byte[] key = address; + byte[] value = Protocol.Account.newBuilder().setAddress(ByteString.copyFrom(address)).build() + .toByteArray(); + trieImpl2.put(StateType.encodeKey(StateType.Account, key), Bytes.wrap(value)); + trieImpl2.commit(); + trieImpl2.flush(); + byte[] root = trieImpl2.getRootHash(); + instance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); + try (AccountStateStore store = new AccountStateStore(instance)) { + Assert.assertArrayEquals(value, store.get(key).getData()); + testUnsupportedOperation(store, key); + Assert.assertEquals(store.getDbName(),(Bytes32.wrap(root).toHexString())); + } } private void testGetAccountAsset() { long tokenId = 1000001; long amount = 100; trieImpl2.put( - fix32(StateType.encodeKey(StateType.AccountAsset, - com.google.common.primitives.Bytes.concat(address, Longs.toByteArray(tokenId)))), - Bytes.of(Longs.toByteArray(amount))); + fix32(StateType.encodeKey(StateType.AccountAsset, + com.google.common.primitives.Bytes.concat(address, + Longs.toByteArray(tokenId)))), Bytes.of(Longs.toByteArray(amount))); trieImpl2.commit(); trieImpl2.flush(); byte[] root = trieImpl2.getRootHash(); - worldStateQueryInstance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); - Assert.assertEquals(amount, worldStateQueryInstance.getAccountAsset( + instance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); + Assert.assertEquals(amount, instance.getAccountAsset( Protocol.Account.newBuilder().setAddress(ByteString.copyFrom(address)).build(), tokenId)); - Assert.assertEquals(worldStateQueryInstance.getRootHash(),trieImpl2.getRootHashByte32()); + Assert.assertEquals(instance.getRootHash(),trieImpl2.getRootHashByte32()); trieImpl2.put( - fix32(StateType.encodeKey(StateType.AccountAsset, - com.google.common.primitives.Bytes.concat(address, Longs.toByteArray(tokenId)))), - UInt256.ZERO); + fix32(StateType.encodeKey(StateType.AccountAsset, + com.google.common.primitives.Bytes.concat( + address, Longs.toByteArray(tokenId)))), UInt256.ZERO); trieImpl2.commit(); trieImpl2.flush(); - worldStateQueryInstance = new WorldStateQueryInstance(trieImpl2.getRootHashByte32(), + instance = new WorldStateQueryInstance(trieImpl2.getRootHashByte32(), chainBaseManager); - Assert.assertEquals(0, worldStateQueryInstance.getAccountAsset( + Assert.assertEquals(0, instance.getAccountAsset( Protocol.Account.newBuilder().setAddress(ByteString.copyFrom(address)).build(), tokenId)); - Assert.assertFalse(worldStateQueryInstance.hasAssetV2( + Assert.assertFalse(instance.hasAssetV2( Protocol.Account.newBuilder().setAddress(ByteString.copyFrom(address)).build(), tokenId)); @@ -126,21 +154,19 @@ private void testGetContractState() { trieImpl2.commit(); trieImpl2.flush(); byte[] root = trieImpl2.getRootHash(); - worldStateQueryInstance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); - Assert.assertArrayEquals(value, - worldStateQueryInstance.getContractState(address).getData()); + instance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); + Assert.assertArrayEquals(value, instance.getContractState(address).getData()); } private void testGetContract() { - byte[] value = new ContractCapsule( - SmartContractOuterClass.SmartContract.newBuilder() + byte[] value = new ContractCapsule(SmartContractOuterClass.SmartContract.newBuilder() .setContractAddress(ByteString.copyFrom(address)).build()).getData(); trieImpl2.put(StateType.encodeKey(StateType.Contract, address), Bytes.wrap(value)); trieImpl2.commit(); trieImpl2.flush(); byte[] root = trieImpl2.getRootHash(); - worldStateQueryInstance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); - Assert.assertArrayEquals(value, worldStateQueryInstance.getContract(address).getData()); + instance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); + Assert.assertArrayEquals(value, instance.getContract(address).getData()); } private void testGetCode() { @@ -149,66 +175,71 @@ private void testGetCode() { trieImpl2.commit(); trieImpl2.flush(); byte[] root = trieImpl2.getRootHash(); - worldStateQueryInstance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); - Assert.assertArrayEquals(value, worldStateQueryInstance.getCode(address).getData()); + instance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); + Assert.assertArrayEquals(value, instance.getCode(address).getData()); } private void testGetAssetIssue() { String tokenId = "100001"; - byte[] value = new AssetIssueCapsule( - address, tokenId, "token1", "test", 100, 100).getData(); + byte[] value = new AssetIssueCapsule(address, tokenId, "token1", "test", 100, 100).getData(); trieImpl2.put(StateType.encodeKey(StateType.AssetIssue, tokenId.getBytes()), Bytes.wrap(value)); trieImpl2.commit(); trieImpl2.flush(); byte[] root = trieImpl2.getRootHash(); - worldStateQueryInstance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); - Assert.assertArrayEquals(value, - worldStateQueryInstance.getAssetIssue(tokenId.getBytes()).getData()); + instance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); + try (AssetIssueV2StateStore store = new AssetIssueV2StateStore(instance)) { + Assert.assertArrayEquals(value, store.get(tokenId.getBytes()).getData()); + testUnsupportedOperation(store, tokenId.getBytes()); + Assert.assertEquals(store.getDbName(),(Bytes32.wrap(root).toHexString())); + } } private void testGetWitness() { - byte[] value = new WitnessCapsule(ByteString.copyFrom(ecKey.getPubKey()), "http://") - .getData(); + byte[] value = new WitnessCapsule(ByteString.copyFrom(ecKey.getPubKey()), "http://").getData(); trieImpl2.put(StateType.encodeKey(StateType.Witness, address), Bytes.wrap(value)); trieImpl2.commit(); trieImpl2.flush(); byte[] root = trieImpl2.getRootHash(); - worldStateQueryInstance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); - Assert.assertArrayEquals(value, worldStateQueryInstance.getWitness(address).getData()); + instance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); + Assert.assertArrayEquals(value, instance.getWitness(address).getData()); } private void testGetDelegatedResource() { byte[] value = new DelegatedResourceCapsule(ByteString.copyFrom(address), - ByteString.copyFrom(address)).getData(); + ByteString.copyFrom(address)).getData(); byte[] key = DelegatedResourceCapsule.createDbKey(address, address); trieImpl2.put(StateType.encodeKey(StateType.DelegatedResource, key), Bytes.wrap(value)); trieImpl2.commit(); trieImpl2.flush(); byte[] root = trieImpl2.getRootHash(); - worldStateQueryInstance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); - Assert.assertArrayEquals(value, worldStateQueryInstance.getDelegatedResource(key).getData()); + instance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); + Assert.assertArrayEquals(value, instance.getDelegatedResource(key).getData()); } private void testGetDelegation() { byte[] value = "test".getBytes(); + byte[] key = address; trieImpl2.put(StateType.encodeKey(StateType.Delegation, address), Bytes.wrap(value)); trieImpl2.commit(); trieImpl2.flush(); byte[] root = trieImpl2.getRootHash(); - worldStateQueryInstance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); - Assert.assertArrayEquals(value, worldStateQueryInstance.getDelegation(address).getData()); + instance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); + try (DelegationStateStore store = new DelegationStateStore(instance)) { + Assert.assertArrayEquals(value, store.get(key).getData()); + testUnsupportedOperation(store, key); + Assert.assertEquals(store.getDbName(),(Bytes32.wrap(root).toHexString())); + } } private void testGetDelegatedResourceAccountIndex() { byte[] value = new DelegatedResourceAccountIndexCapsule(ByteString.copyFrom(address)).getData(); - trieImpl2.put( - StateType.encodeKey(StateType.DelegatedResourceAccountIndex, address), Bytes.wrap(value)); + trieImpl2.put(StateType.encodeKey(StateType.DelegatedResourceAccountIndex, address), + Bytes.wrap(value)); trieImpl2.commit(); trieImpl2.flush(); byte[] root = trieImpl2.getRootHash(); - worldStateQueryInstance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); - Assert.assertArrayEquals(value, - worldStateQueryInstance.getDelegatedResourceAccountIndex(address).getData()); + instance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); + Assert.assertArrayEquals(value, instance.getDelegatedResourceAccountIndex(address).getData()); } private void testGetVotes() { @@ -217,8 +248,8 @@ private void testGetVotes() { trieImpl2.commit(); trieImpl2.flush(); byte[] root = trieImpl2.getRootHash(); - worldStateQueryInstance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); - Assert.assertArrayEquals(value, worldStateQueryInstance.getVotes(address).getData()); + instance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); + Assert.assertArrayEquals(value, instance.getVotes(address).getData()); } private void testGetDynamicProperty() { @@ -228,13 +259,106 @@ private void testGetDynamicProperty() { trieImpl2.commit(); trieImpl2.flush(); byte[] root = trieImpl2.getRootHash(); - worldStateQueryInstance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); - Assert.assertArrayEquals(value, worldStateQueryInstance.getDynamicProperty(key).getData()); + instance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); + try (DynamicPropertiesStateStore store = new DynamicPropertiesStateStore(instance)) { + try { + Assert.assertArrayEquals(value, store.get(key).getData()); + } catch (ItemNotFoundException e) { + Assert.fail(); + } + try { + Assert.assertArrayEquals(value, store.get("not-key".getBytes()).getData()); + Assert.fail(); + } catch (ItemNotFoundException e) { + Assert.assertTrue(true); + } + + testUnsupportedOperation(store, key); + Assert.assertEquals(store.getDbName(), Bytes32.wrap(root).toHexString()); + } + } + + private void testGetStorageRow() { + trieImpl2 = new TrieImpl2(worldStateTrieStore); + byte[] key = address; + byte[] value = "test".getBytes(); + trieImpl2.put(StateType.encodeKey(StateType.StorageRow, key), Bytes.wrap(value)); + trieImpl2.commit(); + trieImpl2.flush(); + byte[] root = trieImpl2.getRootHash(); + instance = new WorldStateQueryInstance(Bytes32.wrap(root), chainBaseManager); + try (StorageRowStateStore store = new StorageRowStateStore(instance)) { + Assert.assertArrayEquals(value, store.get(key).getData()); + testUnsupportedOperation(store, key); + Assert.assertEquals(store.getDbName(), Bytes32.wrap(root).toHexString()); + try { + Storage storage = new Storage(address, store); + storage.put(new DataWord(0), new DataWord(0)); + storage.commit(); + Assert.fail(); + } catch (UnsupportedOperationException e) { + Assert.assertTrue(true); + } + } + } + + private void testUnsupportedOperation(TronStoreWithRevoking store, byte[] key) { + try { + store.put(key, null); + Assert.fail(); + } catch (UnsupportedOperationException e) { + Assert.assertTrue(true); + } + Assert.assertFalse(store.has("not-key".getBytes())); + + try { + store.delete(key); + Assert.fail(); + } catch (UnsupportedOperationException e) { + Assert.assertTrue(true); + } + + try { + store.setCursor(Chainbase.Cursor.HEAD); + Assert.fail(); + } catch (UnsupportedOperationException e) { + Assert.assertTrue(true); + } + + try { + store.iterator(); + Assert.fail(); + } catch (UnsupportedOperationException e) { + Assert.assertTrue(true); + } + + try { + store.prefixQuery(key); + Assert.fail(); + } catch (UnsupportedOperationException e) { + Assert.assertTrue(true); + } + + try { + store.size(); + Assert.fail(); + } catch (UnsupportedOperationException e) { + Assert.assertTrue(true); + } + + try { + store.isNotEmpty(); + Assert.fail(); + } catch (UnsupportedOperationException e) { + Assert.assertTrue(true); + } + try { - worldStateQueryInstance.getDynamicProperty("not-key".getBytes()); + store.of(null); + } catch (UnsupportedOperationException e) { + Assert.assertTrue(true); + } catch (BadItemException e) { Assert.fail(); - } catch (Exception e) { - Assert.assertTrue(e instanceof IllegalArgumentException); } } diff --git a/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java b/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java index f13eb4624ff..37c3499ba81 100644 --- a/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java +++ b/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java @@ -38,8 +38,10 @@ import org.tron.core.exception.JsonRpcInternalException; import org.tron.core.exception.JsonRpcInvalidParamsException; import org.tron.core.exception.JsonRpcInvalidRequestException; +import org.tron.core.exception.StoreException; import org.tron.core.services.jsonrpc.TronJsonRpc; import org.tron.core.services.jsonrpc.types.CallArguments; +import org.tron.core.state.store.StorageRowStateStore; import org.tron.core.vm.program.Storage; import org.tron.protos.Protocol; import org.tron.protos.Protocol.Transaction.Contract.ContractType; @@ -248,14 +250,15 @@ public void testContract() throws InterruptedException, JsonRpcInvalidParamsExce rootHash = blockCapsule.getArchiveRoot(); worldStateQueryInstance = ChainBaseManager.fetch(rootHash); ContractCapsule contractCapsule = worldStateQueryInstance.getContract(contractAddress); + try (StorageRowStateStore store = new StorageRowStateStore(worldStateQueryInstance)) { + Storage storage = new Storage(contractAddress, store); + storage.setContractVersion(contractCapsule.getInstance().getVersion()); - Storage storage = new Storage(contractAddress, worldStateQueryInstance); - storage.setContractVersion(contractCapsule.getInstance().getVersion()); + DataWord value1 = storage.getValue(new DataWord(ByteArray.fromHexString("0"))); - DataWord value1 = storage.getValue(new DataWord(ByteArray.fromHexString("0"))); - - DataWord value2 = storage.getValue(new DataWord(ByteArray.fromHexString("0"))); - Assert.assertArrayEquals(value1.getData(), value2.getData()); + DataWord value2 = storage.getValue(new DataWord(ByteArray.fromHexString("0"))); + Assert.assertArrayEquals(value1.getData(), value2.getData()); + } checkAccount(worldStateQueryInstance, blockCapsule.getNum()); Assert.assertEquals(tronJsonRpc.getABIOfSmartContract(ByteArray.toHexString(contractAddress), ByteArray.toJsonHex(blockCapsule.getNum())), @@ -356,6 +359,11 @@ private void checkAccount(WorldStateQueryInstance worldStateQueryInstance, long Assert.assertEquals(list, tronJsonRpc.getToken10( ByteArray.toHexString(account1Prikey.getAddress()), ByteArray.toJsonHex(blockNum))); + try { + Assert.assertNotNull(worldStateQueryInstance.getBlockByNum(blockNum)); + } catch (StoreException e) { + Assert.fail(); + } } private BlockCapsule buildTransferBlock(BlockCapsule parentBlock) { From 36373b979ebf4d9a41a6d0ca0e8bd792faf35e64 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Sat, 6 May 2023 19:29:35 +0800 Subject: [PATCH 19/34] refactor(trie): add switch to turn off services 1. rpc 2. http 3. jsonrpc --- build.gradle | 2 + .../common/parameter/CommonParameter.java | 12 +++++ .../src/main/java/org/tron/core/Constant.java | 4 ++ .../java/org/tron/core/config/args/Args.java | 20 ++++++++ .../org/tron/core/services/RpcApiService.java | 7 ++- .../interfaceOnPBFT/RpcApiServiceOnPBFT.java | 7 ++- .../RpcApiServiceOnSolidity.java | 7 ++- .../main/java/org/tron/program/FullNode.java | 41 +++++++++------ framework/src/main/resources/config.conf | 7 +++ .../core/state/WorldStateGenesisTest.java | 27 ++++++---- .../state/WorldStateQueryInstanceTest.java | 11 ++-- .../tron/core/state/WorldStateQueryTest.java | 50 +++++++++++++------ .../src/test/resources/config-localtest.conf | 11 +++- 13 files changed, 156 insertions(+), 50 deletions(-) diff --git a/build.gradle b/build.gradle index 82c7999d51e..58cfab2667f 100644 --- a/build.gradle +++ b/build.gradle @@ -48,6 +48,8 @@ subprojects { compile "com.google.code.findbugs:jsr305:3.0.0" compile group: 'org.springframework', name: 'spring-context', version: '5.3.18' compile group: 'org.springframework', name: 'spring-tx', version: '5.3.18' + testImplementation group: 'org.springframework', name: 'spring-test', version: '5.3.18' + testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.9.1' compile "org.apache.commons:commons-lang3:3.12.0" compile group: 'org.apache.commons', name: 'commons-math', version: '2.2' compile "org.apache.commons:commons-collections4:4.1" diff --git a/common/src/main/java/org/tron/common/parameter/CommonParameter.java b/common/src/main/java/org/tron/common/parameter/CommonParameter.java index 0c8e6f74ee3..4e07f601003 100644 --- a/common/src/main/java/org/tron/common/parameter/CommonParameter.java +++ b/common/src/main/java/org/tron/common/parameter/CommonParameter.java @@ -459,12 +459,24 @@ public class CommonParameter { public String cryptoEngine = Constant.ECKey_ENGINE; @Getter @Setter + public boolean fullNodeRpcEnable = true; + @Getter + @Setter + public boolean solidityNodeRpcEnable = true; + @Getter + @Setter + public boolean PBFTNodeRpcEnable = true; + @Getter + @Setter public boolean fullNodeHttpEnable = true; @Getter @Setter public boolean solidityNodeHttpEnable = true; @Getter @Setter + public boolean PBFTNodeHttpEnable = true; + @Getter + @Setter public boolean jsonRpcHttpFullNodeEnable = false; @Getter @Setter diff --git a/common/src/main/java/org/tron/core/Constant.java b/common/src/main/java/org/tron/core/Constant.java index 54b2932018e..b063132db69 100644 --- a/common/src/main/java/org/tron/core/Constant.java +++ b/common/src/main/java/org/tron/core/Constant.java @@ -122,6 +122,9 @@ public class Constant { public static final String NODE_DNS_AWS_REGION = "node.dns.awsRegion"; public static final String NODE_DNS_AWS_HOST_ZONE_ID = "node.dns.awsHostZoneId"; + public static final String NODE_RPC_FULLNODE_ENABLE = "node.rpc.fullNodeEnable"; + public static final String NODE_RPC_SOLIDITY_ENABLE = "node.rpc.solidityEnable"; + public static final String NODE_RPC_PBFT_ENABLE = "node.rpc.PBFTEnable"; public static final String NODE_RPC_PORT = "node.rpc.port"; public static final String NODE_RPC_SOLIDITY_PORT = "node.rpc.solidityPort"; public static final String NODE_RPC_PBFT_PORT = "node.rpc.PBFTPort"; @@ -129,6 +132,7 @@ public class Constant { public static final String NODE_HTTP_SOLIDITY_PORT = "node.http.solidityPort"; public static final String NODE_HTTP_FULLNODE_ENABLE = "node.http.fullNodeEnable"; public static final String NODE_HTTP_SOLIDITY_ENABLE = "node.http.solidityEnable"; + public static final String NODE_HTTP_PBFT_ENABLE = "node.http.PBFTEnable"; public static final String NODE_HTTP_PBFT_PORT = "node.http.PBFTPort"; public static final String NODE_JSONRPC_HTTP_FULLNODE_ENABLE = "node.jsonrpc.httpFullNodeEnable"; diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java index cbc933d42c6..15dfeb5d799 100644 --- a/framework/src/main/java/org/tron/core/config/args/Args.java +++ b/framework/src/main/java/org/tron/core/config/args/Args.java @@ -195,8 +195,12 @@ public static void clearParam() { PARAMETER.validContractProtoThreadNum = 1; PARAMETER.shieldedTransInPendingMaxCounts = 10; PARAMETER.changedDelegation = 0; + PARAMETER.fullNodeRpcEnable = true; + PARAMETER.solidityNodeRpcEnable = true; + PARAMETER.PBFTNodeRpcEnable = true; PARAMETER.fullNodeHttpEnable = true; PARAMETER.solidityNodeHttpEnable = true; + PARAMETER.PBFTNodeHttpEnable = true; PARAMETER.jsonRpcHttpFullNodeEnable = false; PARAMETER.jsonRpcHttpSolidityNodeEnable = false; PARAMETER.jsonRpcHttpPBFTNodeEnable = false; @@ -449,6 +453,18 @@ public static void setParam(final String[] args, final String confFileName) { PARAMETER.lruCacheSize = config.getInt(Constant.VM_LRU_CACHE_SIZE); } + if (config.hasPath(Constant.NODE_RPC_FULLNODE_ENABLE)) { + PARAMETER.fullNodeRpcEnable = config.getBoolean(Constant.NODE_RPC_FULLNODE_ENABLE); + } + + if (config.hasPath(Constant.NODE_RPC_SOLIDITY_ENABLE)) { + PARAMETER.solidityNodeRpcEnable = config.getBoolean(Constant.NODE_RPC_SOLIDITY_ENABLE); + } + + if (config.hasPath(Constant.NODE_RPC_PBFT_ENABLE)) { + PARAMETER.PBFTNodeRpcEnable = config.getBoolean(Constant.NODE_RPC_PBFT_ENABLE); + } + if (config.hasPath(Constant.NODE_HTTP_FULLNODE_ENABLE)) { PARAMETER.fullNodeHttpEnable = config.getBoolean(Constant.NODE_HTTP_FULLNODE_ENABLE); } @@ -457,6 +473,10 @@ public static void setParam(final String[] args, final String confFileName) { PARAMETER.solidityNodeHttpEnable = config.getBoolean(Constant.NODE_HTTP_SOLIDITY_ENABLE); } + if (config.hasPath(Constant.NODE_HTTP_PBFT_ENABLE)) { + PARAMETER.PBFTNodeHttpEnable = config.getBoolean(Constant.NODE_HTTP_PBFT_ENABLE); + } + if (config.hasPath(Constant.NODE_JSONRPC_HTTP_FULLNODE_ENABLE)) { PARAMETER.jsonRpcHttpFullNodeEnable = config.getBoolean(Constant.NODE_JSONRPC_HTTP_FULLNODE_ENABLE); diff --git a/framework/src/main/java/org/tron/core/services/RpcApiService.java b/framework/src/main/java/org/tron/core/services/RpcApiService.java index 2a4ebca95b4..ee12db817d3 100755 --- a/framework/src/main/java/org/tron/core/services/RpcApiService.java +++ b/framework/src/main/java/org/tron/core/services/RpcApiService.java @@ -371,7 +371,12 @@ private void checkSupportShieldedTRC20Transaction() throws ZksnarkException { @Override public void stop() { if (apiServer != null) { - apiServer.shutdown(); + try { + apiServer.shutdown().awaitTermination(); + } catch (InterruptedException e) { + logger.warn("{}", e); + Thread.currentThread().interrupt(); + } } } diff --git a/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/RpcApiServiceOnPBFT.java b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/RpcApiServiceOnPBFT.java index c003f9d3994..937decd7b57 100755 --- a/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/RpcApiServiceOnPBFT.java +++ b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/RpcApiServiceOnPBFT.java @@ -148,7 +148,12 @@ public void start() { @Override public void stop() { if (apiServer != null) { - apiServer.shutdown(); + try { + apiServer.shutdown().awaitTermination(); + } catch (InterruptedException e) { + logger.warn("{}", e); + Thread.currentThread().interrupt(); + } } } diff --git a/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/RpcApiServiceOnSolidity.java b/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/RpcApiServiceOnSolidity.java index 3f4bfeda731..19755d744db 100755 --- a/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/RpcApiServiceOnSolidity.java +++ b/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/RpcApiServiceOnSolidity.java @@ -177,7 +177,12 @@ private BlockExtention block2Extention(Block block) { @Override public void stop() { if (apiServer != null) { - apiServer.shutdown(); + try { + apiServer.shutdown().awaitTermination(); + } catch (InterruptedException e) { + logger.warn("{}", e); + Thread.currentThread().interrupt(); + } } } diff --git a/framework/src/main/java/org/tron/program/FullNode.java b/framework/src/main/java/org/tron/program/FullNode.java index 62732dd5e60..8ca16b7db83 100644 --- a/framework/src/main/java/org/tron/program/FullNode.java +++ b/framework/src/main/java/org/tron/program/FullNode.java @@ -84,12 +84,14 @@ public static void main(String[] args) { shutdown(appT); // grpc api server - RpcApiService rpcApiService = context.getBean(RpcApiService.class); - appT.addService(rpcApiService); + if (CommonParameter.getInstance().fullNodeRpcEnable) { + RpcApiService rpcApiService = context.getBean(RpcApiService.class); + appT.addService(rpcApiService); + } // http api server - FullNodeHttpApiService httpApiService = context.getBean(FullNodeHttpApiService.class); if (CommonParameter.getInstance().fullNodeHttpEnable) { + FullNodeHttpApiService httpApiService = context.getBean(FullNodeHttpApiService.class); appT.addService(httpApiService); } @@ -102,12 +104,15 @@ public static void main(String[] args) { // full node and solidity node fuse together // provide solidity rpc and http server on the full node. - RpcApiServiceOnSolidity rpcApiServiceOnSolidity = context - .getBean(RpcApiServiceOnSolidity.class); - appT.addService(rpcApiServiceOnSolidity); - HttpApiOnSolidityService httpApiOnSolidityService = context - .getBean(HttpApiOnSolidityService.class); + if (CommonParameter.getInstance().solidityNodeRpcEnable) { + RpcApiServiceOnSolidity rpcApiServiceOnSolidity = context + .getBean(RpcApiServiceOnSolidity.class); + appT.addService(rpcApiServiceOnSolidity); + } + if (CommonParameter.getInstance().solidityNodeHttpEnable) { + HttpApiOnSolidityService httpApiOnSolidityService = context + .getBean(HttpApiOnSolidityService.class); appT.addService(httpApiOnSolidityService); } @@ -119,12 +124,18 @@ public static void main(String[] args) { } // PBFT API (HTTP and GRPC) - RpcApiServiceOnPBFT rpcApiServiceOnPBFT = context - .getBean(RpcApiServiceOnPBFT.class); - appT.addService(rpcApiServiceOnPBFT); - HttpApiOnPBFTService httpApiOnPBFTService = context - .getBean(HttpApiOnPBFTService.class); - appT.addService(httpApiOnPBFTService); + if (CommonParameter.getInstance().PBFTNodeRpcEnable) { + RpcApiServiceOnPBFT rpcApiServiceOnPBFT = context + .getBean(RpcApiServiceOnPBFT.class); + appT.addService(rpcApiServiceOnPBFT); + } + + if (CommonParameter.getInstance().PBFTNodeHttpEnable) { + HttpApiOnPBFTService httpApiOnPBFTService = context + .getBean(HttpApiOnPBFTService.class); + appT.addService(httpApiOnPBFTService); + } + // JSON-RPC on PBFT if (CommonParameter.getInstance().jsonRpcHttpPBFTNodeEnable) { @@ -135,8 +146,6 @@ public static void main(String[] args) { appT.initServices(parameter); appT.startServices(); appT.startup(); - - rpcApiService.blockUntilShutdown(); } public static void shutdown(final Application app) { diff --git a/framework/src/main/resources/config.conf b/framework/src/main/resources/config.conf index 7eb5c0ca212..e1d25a63934 100644 --- a/framework/src/main/resources/config.conf +++ b/framework/src/main/resources/config.conf @@ -210,6 +210,8 @@ node { fullNodePort = 8090 solidityEnable = true solidityPort = 8091 + PBFTEnable = true + PBFTPort = 8092 } # use your ipv6 address for node discovery and tcp connection, default false @@ -228,6 +230,11 @@ node { rpc { port = 50051 #solidityPort = 50061 + #PBFTPort = 50071 + fullNodeEnable = true + solidityEnable = true + PBFTEnable = true + # Number of gRPC thread, default availableProcessors / 2 # thread = 16 diff --git a/framework/src/test/java/org/tron/core/state/WorldStateGenesisTest.java b/framework/src/test/java/org/tron/core/state/WorldStateGenesisTest.java index 644c2c4f2ff..214a7c2170e 100644 --- a/framework/src/test/java/org/tron/core/state/WorldStateGenesisTest.java +++ b/framework/src/test/java/org/tron/core/state/WorldStateGenesisTest.java @@ -1,18 +1,23 @@ package org.tron.core.state; import com.google.protobuf.ByteString; -import java.io.File; +import java.io.IOException; import org.apache.tuweni.bytes.Bytes32; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.rules.TemporaryFolder; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.application.TronApplicationContext; import org.tron.common.config.DbBackupConfig; import org.tron.common.crypto.ECKey; -import org.tron.common.utils.FileUtil; import org.tron.common.utils.Sha256Hash; import org.tron.core.ChainBaseManager; import org.tron.core.capsule.BlockCapsule; @@ -20,23 +25,26 @@ import org.tron.core.config.args.Args; import org.tron.core.exception.HeaderNotFound; +@ExtendWith(SpringExtension.class) +@ContextConfiguration +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) public class WorldStateGenesisTest { private static TronApplicationContext context; private static Application appTest; private static ChainBaseManager chainBaseManager; private static WorldStateGenesis worldStateGenesis; - private static String dbPath = "output-directory-state-genesis"; + @Rule + public final TemporaryFolder temporaryFolder = new TemporaryFolder(); /** * init logic. */ @Before - public void init() { - if (FileUtil.isExists(dbPath)) { - FileUtil.deleteDir(new File(dbPath)); - } - Args.setParam(new String[]{"-d", dbPath}, "config-localtest.conf"); + public void init() throws IOException { + + Args.setParam(new String[]{"-d", temporaryFolder.newFolder().toString()}, + "config-localtest.conf"); // allow account root Args.getInstance().setAllowAccountStateRoot(1); // init dbBackupConfig to avoid NPE @@ -50,9 +58,8 @@ public void init() { @After public void destroy() { - appTest.shutdown(); + context.destroy(); Args.clearParam(); - FileUtil.deleteDir(new File(dbPath)); } @Test diff --git a/framework/src/test/java/org/tron/core/state/WorldStateQueryInstanceTest.java b/framework/src/test/java/org/tron/core/state/WorldStateQueryInstanceTest.java index 95a2fb3e8e4..154cf1c4e35 100644 --- a/framework/src/test/java/org/tron/core/state/WorldStateQueryInstanceTest.java +++ b/framework/src/test/java/org/tron/core/state/WorldStateQueryInstanceTest.java @@ -6,8 +6,6 @@ import com.google.common.primitives.Longs; import com.google.protobuf.ByteString; import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; @@ -16,7 +14,11 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.junit.rules.TemporaryFolder; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import org.tron.common.application.TronApplicationContext; import org.tron.common.config.DbBackupConfig; import org.tron.common.crypto.ECKey; @@ -47,6 +49,9 @@ import org.tron.protos.Protocol; import org.tron.protos.contract.SmartContractOuterClass; +@ExtendWith(SpringExtension.class) +@ContextConfiguration +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) public class WorldStateQueryInstanceTest { private WorldStateQueryInstance instance; @@ -70,8 +75,6 @@ public void init() throws IOException { // init dbBackupConfig to avoid NPE Args.getInstance().dbBackupConfig = DbBackupConfig.getInstance(); context = new TronApplicationContext(DefaultConfig.class); - Path parentPath = temporaryFolder.newFolder().toPath(); - Path dbPath = Paths.get(parentPath.toString()); chainBaseManager = context.getBean(ChainBaseManager.class); worldStateTrieStore = chainBaseManager.getWorldStateTrieStore(); } diff --git a/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java b/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java index 37c3499ba81..ccc7cba3a46 100644 --- a/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java +++ b/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java @@ -2,17 +2,23 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; -import java.io.File; -import java.nio.charset.StandardCharsets; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import org.apache.tuweni.bytes.Bytes32; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; +import org.junit.ClassRule; import org.junit.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.rules.TemporaryFolder; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.application.TronApplicationContext; @@ -21,7 +27,6 @@ import org.tron.common.runtime.TvmTestUtils; import org.tron.common.runtime.vm.DataWord; import org.tron.common.utils.ByteArray; -import org.tron.common.utils.FileUtil; import org.tron.common.utils.PublicMethod; import org.tron.common.utils.Sha256Hash; import org.tron.common.utils.WalletUtil; @@ -48,34 +53,36 @@ import org.tron.protos.contract.AssetIssueContractOuterClass; import org.tron.protos.contract.BalanceContract; +@ExtendWith(SpringExtension.class) +@ContextConfiguration +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) public class WorldStateQueryTest { private static TronApplicationContext context; private static Application appTest; private static ChainBaseManager chainBaseManager; private static Manager manager; - private static String dbPath = "output-directory-state"; private static TronJsonRpc tronJsonRpc; private static final long TOKEN_ID1 = 1000001L; private static final long TOKEN_ID2 = 1000002L; - private ECKey account1Prikey = ECKey.fromPrivate(ByteArray.fromHexString( - "D95611A9AF2A2A45359106222ED1AFED48853D9A44DEFF8DC7913F5CBA727366")); - private ECKey account2Prikey = ECKey.fromPrivate(ByteArray.fromHexString( - "cba92a516ea09f620a16ff7ee95ce0df1d56550a8babe9964981a7144c8a784a")); + private static ECKey account1Prikey = new ECKey(); + private static ECKey account2Prikey = new ECKey(); byte[] contractAddress; private static WorldStateCallBack worldStateCallBack; + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); + /** * init logic. */ @BeforeClass - public static void init() { - if (FileUtil.isExists(dbPath)) { - FileUtil.deleteDir(new File(dbPath)); - } - Args.setParam(new String[]{"-d", dbPath}, "config-localtest.conf"); + public static void init() throws IOException { + + Args.setParam(new String[]{"-d", temporaryFolder.newFolder().toString()}, + "config-localtest.conf"); // disable p2p Args.getInstance().setP2pDisable(true); // allow account root @@ -95,13 +102,26 @@ public static void init() { worldStateCallBack.setExecute(false); manager = context.getBean(Manager.class); tronJsonRpc = context.getBean(TronJsonRpc.class); + + Protocol.Account acc = Protocol.Account.newBuilder() + .setAccountName(ByteString.copyFrom(Objects.requireNonNull(ByteArray.fromString("acc")))) + .setAddress(ByteString.copyFrom(account1Prikey.getAddress())) + .setType(Protocol.AccountType.AssetIssue) + .setBalance(10000000000000000L).build(); + Protocol.Account sun = Protocol.Account.newBuilder() + .setAccountName(ByteString.copyFrom(Objects.requireNonNull(ByteArray.fromString("sun")))) + .setAddress(ByteString.copyFrom(account2Prikey.getAddress())) + .setType(Protocol.AccountType.AssetIssue) + .setBalance(10000000000000000L).build(); + chainBaseManager.getAccountStore().put(account1Prikey.getAddress(), new AccountCapsule(acc)); + chainBaseManager.getAccountStore().put(account2Prikey.getAddress(), new AccountCapsule(sun)); + } @AfterClass public static void destroy() { - appTest.shutdown(); + context.destroy(); Args.clearParam(); - FileUtil.deleteDir(new File(dbPath)); } public void createAsset() { diff --git a/framework/src/test/resources/config-localtest.conf b/framework/src/test/resources/config-localtest.conf index 084fda8a284..7c99a735259 100644 --- a/framework/src/test/resources/config-localtest.conf +++ b/framework/src/test/resources/config-localtest.conf @@ -126,14 +126,21 @@ node { ] http { + fullNodeEnable = true fullNodePort = 8090 + solidityEnable = true solidityPort = 8091 + PBFTEnable = true + PBFTPort = 8092 } rpc { port = 50051 - # default value is 50061 - # solidityPort = 50061 + #solidityPort = 50061 + #PBFTPort = 50071 + fullNodeEnable = true + solidityEnable = true + PBFTEnable = true # Number of gRPC thread, default availableProcessors / 2 # thread = 16 From 21ec94b7657bc5516b491d933106a0f5ac6681eb Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Wed, 10 May 2023 15:20:33 +0800 Subject: [PATCH 20/34] feat(trie): fix Zksnark init --- .../services/http/FullNodeHttpApiService.java | 1 - .../solidity/SolidityNodeHttpApiService.java | 1 - .../java/org/tron/core/zen/ZksnarkService.java | 16 ++++++++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 framework/src/main/java/org/tron/core/zen/ZksnarkService.java diff --git a/framework/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java b/framework/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java index 082307fe629..135f98627a1 100644 --- a/framework/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java +++ b/framework/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java @@ -349,7 +349,6 @@ public void init() { @Override public void init(CommonParameter args) { - librustzcashInitZksnarkParams(); } @Override diff --git a/framework/src/main/java/org/tron/core/services/http/solidity/SolidityNodeHttpApiService.java b/framework/src/main/java/org/tron/core/services/http/solidity/SolidityNodeHttpApiService.java index 534bc504c82..bc3cd667e2c 100644 --- a/framework/src/main/java/org/tron/core/services/http/solidity/SolidityNodeHttpApiService.java +++ b/framework/src/main/java/org/tron/core/services/http/solidity/SolidityNodeHttpApiService.java @@ -176,7 +176,6 @@ public void init() { @Override public void init(CommonParameter args) { - FullNodeHttpApiService.librustzcashInitZksnarkParams(); } @Override diff --git a/framework/src/main/java/org/tron/core/zen/ZksnarkService.java b/framework/src/main/java/org/tron/core/zen/ZksnarkService.java new file mode 100644 index 00000000000..b9a0485a2d6 --- /dev/null +++ b/framework/src/main/java/org/tron/core/zen/ZksnarkService.java @@ -0,0 +1,16 @@ +package org.tron.core.zen; + +import javax.annotation.PostConstruct; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.tron.core.services.http.FullNodeHttpApiService; + +@Slf4j(topic = "API") +@Component +public class ZksnarkService { + + @PostConstruct + private void init() { + FullNodeHttpApiService.librustzcashInitZksnarkParams(); + } +} From a06d40c295d366ccba77af5e2137c5dc5fb2c449 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Mon, 22 May 2023 16:40:07 +0800 Subject: [PATCH 21/34] feat(trie): set writable false when p2p is disabled for state trie --- .../src/main/java/org/tron/core/state/WorldStateCallBack.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java b/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java index 0f3895f556f..36e5e48bc32 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java @@ -37,7 +37,8 @@ public class WorldStateCallBack { private volatile TrieImpl2 trie; public WorldStateCallBack() { - this.execute = true; + // set false when p2p is disabled + this.execute = !CommonParameter.getInstance().isP2pDisable(); this.allowGenerateRoot = CommonParameter.getInstance().getStorage().isAllowStateRoot(); } From 76506420e34daf33a907032d0c52b189bdf6e001 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Wed, 10 May 2023 19:33:33 +0800 Subject: [PATCH 22/34] feat(trie): rocksdb update 7.7.3 --- chainbase/build.gradle | 2 +- .../rocksdb/RocksDbDataSourceImpl.java | 7 +- .../MarketOrderPriceComparatorForRockDB.java | 19 ++-- .../java/org/tron/core/db/TronDatabase.java | 4 +- .../tron/core/db/TronStoreWithRevoking.java | 4 +- .../tron/core/state/WorldStateGenesis.java | 102 +++++++++++++++++- .../core/state/store/AccountStateStore.java | 4 +- .../state/store/AssetIssueV2StateStore.java | 4 +- .../state/store/DelegationStateStore.java | 4 +- .../store/DynamicPropertiesStateStore.java | 4 +- .../state/store/StorageRowStateStore.java | 4 +- .../store/MarketPairPriceToOrderStore.java | 4 +- common/build.gradle | 2 +- plugins/README.md | 3 +- plugins/build.gradle | 2 +- .../main/java/org/tron/plugins/DbConvert.java | 9 +- .../MarketOrderPriceComparatorForRockDB.java | 19 ++-- state-trie-jdk8/build.gradle | 2 +- 18 files changed, 144 insertions(+), 55 deletions(-) diff --git a/chainbase/build.gradle b/chainbase/build.gradle index 0a42c83fd9f..5c9a874227e 100644 --- a/chainbase/build.gradle +++ b/chainbase/build.gradle @@ -37,7 +37,7 @@ dependencies { compile group: leveldbGroup, name: leveldbName, version: leveldbVersion compile "org.fusesource.jansi:jansi:$jansiVersion" - compile group: 'org.rocksdb', name: 'rocksdbjni', version: '5.15.10' + compile group: 'org.rocksdb', name: 'rocksdbjni', version: '7.7.3' compile group: 'com.typesafe', name: 'config', version: '1.3.2' compile 'io.github.tronprotocol:zksnark-java-sdk:1.0.0' compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.8.5' diff --git a/chainbase/src/main/java/org/tron/common/storage/rocksdb/RocksDbDataSourceImpl.java b/chainbase/src/main/java/org/tron/common/storage/rocksdb/RocksDbDataSourceImpl.java index a561ed1fa11..15a93425292 100644 --- a/chainbase/src/main/java/org/tron/common/storage/rocksdb/RocksDbDataSourceImpl.java +++ b/chainbase/src/main/java/org/tron/common/storage/rocksdb/RocksDbDataSourceImpl.java @@ -23,7 +23,7 @@ import org.rocksdb.BlockBasedTableConfig; import org.rocksdb.BloomFilter; import org.rocksdb.Checkpoint; -import org.rocksdb.DirectComparator; +import org.rocksdb.AbstractComparator; import org.rocksdb.InfoLogLevel; import org.rocksdb.Logger; import org.rocksdb.Options; @@ -59,11 +59,11 @@ public class RocksDbDataSourceImpl extends DbStat implements DbSourceInter genesisHeight) { try { return genesisDBs.get(type).get(key); - } catch (RocksDBException e) { + } catch (RocksDBException | DBException e) { throw new RuntimeException(type.getName(), e); } } else { @@ -177,13 +187,26 @@ private void initGenesisDBs() { Arrays.stream(StateType.values()).filter(type -> type != StateType.UNDEFINED) .parallel().forEach(type -> { try { - genesisDBs.put(type, new RocksDB(stateGenesisPath, type.getName())); - } catch (RocksDBException e) { + genesisDBs.put(type, getDb(stateGenesisPath, type.getName())); + } catch (RocksDBException | IOException e) { throw new RuntimeException(e); } }); } + private DB getDb(Path sourceDir, String dbName) throws RocksDBException, IOException { + File engineFile = Paths.get(sourceDir.toString(), dbName, ENGINE_FILE).toFile(); + if (!engineFile.exists()) { + return new LevelDB(sourceDir, dbName); + } + String engine = PropUtil.readProperty(engineFile.toString(), KEY_ENGINE); + if (engine.equalsIgnoreCase(ROCKSDB)) { + return new RocksDB(sourceDir, dbName); + } else { + return new LevelDB(sourceDir, dbName); + } + } + private void initGenesis() { logger.info("State genesis init start"); FileUtil.createDirIfNotExists(stateGenesisPath.toString()); @@ -272,8 +295,8 @@ public byte[] get(byte[] key) throws RocksDBException { @Override public Map prefixQuery(byte[] key) { - try (ReadOptions readOptions = new ReadOptions().setFillCache(false)) { - RocksIterator iterator = this.rocksDB.newIterator(readOptions); + try (ReadOptions readOptions = new ReadOptions().setFillCache(false); + RocksIterator iterator = this.rocksDB.newIterator(readOptions)) { Map result = new HashMap<>(); for (iterator.seek(key); iterator.isValid(); iterator.next()) { if (com.google.common.primitives.Bytes.indexOf(iterator.key(), key) == 0) { @@ -328,5 +351,74 @@ public void close() throws IOException { } } + static class LevelDB implements DB { + + private final org.iq80.leveldb.DB levelDB; + private final String name; + + private static final String MARKET_PAIR_PRICE_TO_ORDER = "market_pair_price_to_order"; + + public LevelDB(Path path, String name) throws IOException { + this.name = name; + this.levelDB = newLevelDb(Paths.get(path.toString(), name)); + } + + @Override + public byte[] get(byte[] key) throws DBException { + return this.levelDB.get(key); + } + + @Override + public Map prefixQuery(byte[] key) { + try (DBIterator iterator = this.levelDB.iterator( + new org.iq80.leveldb.ReadOptions().fillCache(false))) { + Map result = new HashMap<>(); + for (iterator.seek(key); iterator.hasNext(); iterator.next()) { + Map.Entry entry = iterator.peekNext(); + if (com.google.common.primitives.Bytes.indexOf(entry.getKey(), key) == 0) { + result.put(Bytes.wrap(entry.getKey()), Bytes.wrap(entry.getValue())); + } else { + return result; + } + } + return result; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public String name() { + return this.name; + } + + private org.iq80.leveldb.DB newLevelDb(Path db) throws IOException { + org.iq80.leveldb.Options options = createDefaultDbOptions(); + if (MARKET_PAIR_PRICE_TO_ORDER.equalsIgnoreCase(db.getFileName().toString())) { + options.comparator(new MarketOrderPriceComparatorForLevelDB()); + } + return factory.open(db.toFile(), options); + } + + private org.iq80.leveldb.Options createDefaultDbOptions() { + org.iq80.leveldb.Options options = new org.iq80.leveldb.Options(); + options.createIfMissing(false); + options.paranoidChecks(true); + options.verifyChecksums(true); + + options.compressionType(DbOptionalsUtils.DEFAULT_COMPRESSION_TYPE); + options.blockSize(DbOptionalsUtils.DEFAULT_BLOCK_SIZE); + options.writeBufferSize(DbOptionalsUtils.DEFAULT_WRITE_BUFFER_SIZE); + options.cacheSize(DbOptionalsUtils.DEFAULT_CACHE_SIZE); + options.maxOpenFiles(DbOptionalsUtils.DEFAULT_MAX_OPEN_FILES); + return options; + } + + @Override + public void close() throws IOException { + this.levelDB.close(); + } + } + } diff --git a/chainbase/src/main/java/org/tron/core/state/store/AccountStateStore.java b/chainbase/src/main/java/org/tron/core/state/store/AccountStateStore.java index 224fa68765c..2612099d363 100644 --- a/chainbase/src/main/java/org/tron/core/state/store/AccountStateStore.java +++ b/chainbase/src/main/java/org/tron/core/state/store/AccountStateStore.java @@ -1,6 +1,6 @@ package org.tron.core.state.store; -import org.rocksdb.DirectComparator; +import org.rocksdb.AbstractComparator; import org.tron.core.capsule.AccountCapsule; import org.tron.core.db2.common.WrappedByteArray; import org.tron.core.db2.core.Chainbase; @@ -67,7 +67,7 @@ protected org.iq80.leveldb.Options getOptionsByDbNameForLevelDB(String dbName) { throw new UnsupportedOperationException(); } - protected DirectComparator getDirectComparator() { + protected AbstractComparator getDirectComparator() { throw new UnsupportedOperationException(); } diff --git a/chainbase/src/main/java/org/tron/core/state/store/AssetIssueV2StateStore.java b/chainbase/src/main/java/org/tron/core/state/store/AssetIssueV2StateStore.java index fc76137ac2c..736444ecaf9 100644 --- a/chainbase/src/main/java/org/tron/core/state/store/AssetIssueV2StateStore.java +++ b/chainbase/src/main/java/org/tron/core/state/store/AssetIssueV2StateStore.java @@ -1,7 +1,7 @@ package org.tron.core.state.store; import lombok.extern.slf4j.Slf4j; -import org.rocksdb.DirectComparator; +import org.rocksdb.AbstractComparator; import org.tron.core.capsule.AssetIssueCapsule; import org.tron.core.db2.common.WrappedByteArray; import org.tron.core.db2.core.Chainbase; @@ -67,7 +67,7 @@ protected org.iq80.leveldb.Options getOptionsByDbNameForLevelDB(String dbName) { throw new UnsupportedOperationException(); } - protected DirectComparator getDirectComparator() { + protected AbstractComparator getDirectComparator() { throw new UnsupportedOperationException(); } diff --git a/chainbase/src/main/java/org/tron/core/state/store/DelegationStateStore.java b/chainbase/src/main/java/org/tron/core/state/store/DelegationStateStore.java index bad3fed0745..1da81908ac7 100644 --- a/chainbase/src/main/java/org/tron/core/state/store/DelegationStateStore.java +++ b/chainbase/src/main/java/org/tron/core/state/store/DelegationStateStore.java @@ -1,6 +1,6 @@ package org.tron.core.state.store; -import org.rocksdb.DirectComparator; +import org.rocksdb.AbstractComparator; import org.tron.core.capsule.BytesCapsule; import org.tron.core.db2.common.WrappedByteArray; import org.tron.core.db2.core.Chainbase; @@ -63,7 +63,7 @@ protected org.iq80.leveldb.Options getOptionsByDbNameForLevelDB(String dbName) { throw new UnsupportedOperationException(); } - protected DirectComparator getDirectComparator() { + protected AbstractComparator getDirectComparator() { throw new UnsupportedOperationException(); } diff --git a/chainbase/src/main/java/org/tron/core/state/store/DynamicPropertiesStateStore.java b/chainbase/src/main/java/org/tron/core/state/store/DynamicPropertiesStateStore.java index cc0ad1b3897..116ecae1361 100644 --- a/chainbase/src/main/java/org/tron/core/state/store/DynamicPropertiesStateStore.java +++ b/chainbase/src/main/java/org/tron/core/state/store/DynamicPropertiesStateStore.java @@ -1,6 +1,6 @@ package org.tron.core.state.store; -import org.rocksdb.DirectComparator; +import org.rocksdb.AbstractComparator; import org.tron.core.capsule.BytesCapsule; import org.tron.core.db2.common.WrappedByteArray; import org.tron.core.db2.core.Chainbase; @@ -64,7 +64,7 @@ protected org.iq80.leveldb.Options getOptionsByDbNameForLevelDB(String dbName) { throw new UnsupportedOperationException(); } - protected DirectComparator getDirectComparator() { + protected AbstractComparator getDirectComparator() { throw new UnsupportedOperationException(); } diff --git a/chainbase/src/main/java/org/tron/core/state/store/StorageRowStateStore.java b/chainbase/src/main/java/org/tron/core/state/store/StorageRowStateStore.java index b2b4f455b88..847eeba10e6 100644 --- a/chainbase/src/main/java/org/tron/core/state/store/StorageRowStateStore.java +++ b/chainbase/src/main/java/org/tron/core/state/store/StorageRowStateStore.java @@ -1,6 +1,6 @@ package org.tron.core.state.store; -import org.rocksdb.DirectComparator; +import org.rocksdb.AbstractComparator; import org.tron.core.capsule.StorageRowCapsule; import org.tron.core.db2.common.WrappedByteArray; import org.tron.core.db2.core.Chainbase; @@ -63,7 +63,7 @@ protected org.iq80.leveldb.Options getOptionsByDbNameForLevelDB(String dbName) { throw new UnsupportedOperationException(); } - protected DirectComparator getDirectComparator() { + protected AbstractComparator getDirectComparator() { throw new UnsupportedOperationException(); } diff --git a/chainbase/src/main/java/org/tron/core/store/MarketPairPriceToOrderStore.java b/chainbase/src/main/java/org/tron/core/store/MarketPairPriceToOrderStore.java index 605952328ed..35931f10bba 100644 --- a/chainbase/src/main/java/org/tron/core/store/MarketPairPriceToOrderStore.java +++ b/chainbase/src/main/java/org/tron/core/store/MarketPairPriceToOrderStore.java @@ -5,7 +5,7 @@ import java.util.List; import org.iq80.leveldb.Options; import org.rocksdb.ComparatorOptions; -import org.rocksdb.DirectComparator; +import org.rocksdb.AbstractComparator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -35,7 +35,7 @@ protected Options getOptionsByDbNameForLevelDB(String dbName) { //todo: to test later @Override - protected DirectComparator getDirectComparator() { + protected AbstractComparator getDirectComparator() { ComparatorOptions comparatorOptions = new ComparatorOptions(); return new MarketOrderPriceComparatorForRockDB(comparatorOptions); } diff --git a/common/build.gradle b/common/build.gradle index cd973304a0e..e00528d7a94 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -44,7 +44,7 @@ dependencies { compile group: 'com.beust', name: 'jcommander', version: '1.72' compile group: 'com.typesafe', name: 'config', version: '1.3.2' compile group: leveldbGroup, name: leveldbName, version: leveldbVersion - compile group: 'org.rocksdb', name: 'rocksdbjni', version: '5.15.10' + compile group: 'org.rocksdb', name: 'rocksdbjni', version: '7.7.3' // https://mvnrepository.com/artifact/org.quartz-scheduler/quartz compile group: 'org.quartz-scheduler', name: 'quartz', version: '2.3.2' compile group: 'io.prometheus', name: 'simpleclient', version: '0.15.0' diff --git a/plugins/README.md b/plugins/README.md index 2db7c691d13..17f3f81f04d 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -34,8 +34,7 @@ DB convert provides a helper which can convert LevelDB data to RocksDB data, par - ``: Input path for leveldb, default: output-directory/database. - ``: Output path for rocksdb, default: output-directory-dst/database. -- `--safe`: In safe mode, read data from leveldb then put into rocksdb, it's a very time-consuming procedure. If not, just change engine.properties from leveldb to rocksdb, rocksdb - is compatible with leveldb for the current version. This may not be the case in the future, default: false. +- `--safe`: It is deprecated, now must is in the safe mode. - `-h | --help`: Provide the help info. ### Examples: diff --git a/plugins/build.gradle b/plugins/build.gradle index 23f7d6e6956..c769f7b163f 100644 --- a/plugins/build.gradle +++ b/plugins/build.gradle @@ -34,7 +34,7 @@ dependencies { compile group: 'com.typesafe', name: 'config', version: '1.3.2' compile group: 'me.tongfei', name: 'progressbar', version: '0.9.3' compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.69' - compile group: 'org.rocksdb', name: 'rocksdbjni', version: '5.15.10' + compile group: 'org.rocksdb', name: 'rocksdbjni', version: '7.7.3' compile 'io.github.tronprotocol:leveldbjni-all:1.18.2' compile 'io.github.tronprotocol:leveldb:1.18.2' compile project(":protocol") diff --git a/plugins/src/main/java/org/tron/plugins/DbConvert.java b/plugins/src/main/java/org/tron/plugins/DbConvert.java index a75b235bbcf..66f9207fa6c 100644 --- a/plugins/src/main/java/org/tron/plugins/DbConvert.java +++ b/plugins/src/main/java/org/tron/plugins/DbConvert.java @@ -50,12 +50,13 @@ public class DbConvert implements Callable { private File dest; @CommandLine.Option(names = {"--safe"}, + defaultValue = "true", description = "In safe mode, read data from leveldb then put rocksdb." + "If not, just change engine.properties from leveldb to rocksdb," + "rocksdb is compatible with leveldb for current version." + "This may not be the case in the future." + "Default: ${DEFAULT-VALUE}") - private boolean safe; + private boolean safe = true; @CommandLine.Option(names = {"-h", "--help"}) private boolean help; @@ -94,6 +95,12 @@ public Integer call() throws Exception { } final long time = System.currentTimeMillis(); List services = new ArrayList<>(); + if (!safe) { + logger.info("set safe mode in rocksdb version {}", RocksDB.rocksdbVersion()); + spec.commandLine().getOut().format("set safe mode in rocksdb version %s", + RocksDB.rocksdbVersion()).println(); + safe = true; + } files.forEach(f -> services.add( new DbConverter(src.getPath(), dest.getPath(), f.getName(), safe))); cpList.forEach(f -> services.add( diff --git a/plugins/src/main/java/org/tron/plugins/comparator/MarketOrderPriceComparatorForRockDB.java b/plugins/src/main/java/org/tron/plugins/comparator/MarketOrderPriceComparatorForRockDB.java index cd718bdd2d7..388711f99c6 100644 --- a/plugins/src/main/java/org/tron/plugins/comparator/MarketOrderPriceComparatorForRockDB.java +++ b/plugins/src/main/java/org/tron/plugins/comparator/MarketOrderPriceComparatorForRockDB.java @@ -1,11 +1,11 @@ package org.tron.plugins.comparator; +import java.nio.ByteBuffer; +import org.rocksdb.AbstractComparator; import org.rocksdb.ComparatorOptions; -import org.rocksdb.DirectSlice; -import org.rocksdb.util.DirectBytewiseComparator; import org.tron.plugins.utils.MarketUtils; -public class MarketOrderPriceComparatorForRockDB extends DirectBytewiseComparator { +public class MarketOrderPriceComparatorForRockDB extends AbstractComparator { public MarketOrderPriceComparatorForRockDB(final ComparatorOptions copt) { super(copt); @@ -17,21 +17,16 @@ public String name() { } @Override - public int compare(final DirectSlice a, final DirectSlice b) { + public int compare(final ByteBuffer a, final ByteBuffer b) { return MarketUtils.comparePriceKey(convertDataToBytes(a), convertDataToBytes(b)); } /** * DirectSlice.data().array will throw UnsupportedOperationException. * */ - public byte[] convertDataToBytes(DirectSlice directSlice) { - int capacity = directSlice.data().capacity(); - byte[] bytes = new byte[capacity]; - - for (int i = 0; i < capacity; i++) { - bytes[i] = directSlice.get(i); - } - + public byte[] convertDataToBytes(ByteBuffer buf) { + byte[] bytes = new byte[buf.remaining()]; + buf.get(bytes); return bytes; } diff --git a/state-trie-jdk8/build.gradle b/state-trie-jdk8/build.gradle index 4022c6c595e..5ca8eafc88e 100644 --- a/state-trie-jdk8/build.gradle +++ b/state-trie-jdk8/build.gradle @@ -28,7 +28,7 @@ dependencies { compile group: 'io.vertx', name: 'vertx-core', version: '4.3.7' compile group: 'org.immutables', name: 'value', version: '2.9.3' compile group: 'org.immutables', name: 'value-annotations', version: '2.9.3' - compile group: 'org.rocksdb', name: 'rocksdbjni', version: '5.15.10' + compile group: 'org.rocksdb', name: 'rocksdbjni', version: '7.7.3' testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.9.1' From deb0b823fe45233ebd052610e1c1b40ebf6e896a Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Mon, 29 May 2023 15:46:24 +0800 Subject: [PATCH 23/34] feat(trie): add cache for tire db --- .../java/org/tron/core/ChainBaseManager.java | 6 +- .../java/org/tron/core/state/StateType.java | 7 +- .../tron/core/state/WorldStateCallBack.java | 4 +- .../core/state/WorldStateQueryInstance.java | 2 +- .../store/KeyValueMerkleCacheStorage.java | 99 +++++++++++++++++++ .../{ => store}/WorldStateTrieStore.java | 2 +- .../org/tron/common/cache/CacheManager.java | 19 +++- .../tron/common/cache/CacheStrategies.java | 8 ++ .../java/org/tron/common/cache/CacheType.java | 10 +- .../java/org/tron/common/cache/TronCache.java | 8 +- .../state/WorldStateQueryInstanceTest.java | 9 +- .../java/org/tron/core/tire/Trie2Test.java | 20 ++++ .../ethereum/trie/KeyValueMerkleStorage.java | 4 +- 13 files changed, 177 insertions(+), 21 deletions(-) create mode 100644 chainbase/src/main/java/org/tron/core/state/store/KeyValueMerkleCacheStorage.java rename chainbase/src/main/java/org/tron/core/state/{ => store}/WorldStateTrieStore.java (98%) diff --git a/chainbase/src/main/java/org/tron/core/ChainBaseManager.java b/chainbase/src/main/java/org/tron/core/ChainBaseManager.java index 6cbfcdf200d..3418d6c15ef 100644 --- a/chainbase/src/main/java/org/tron/core/ChainBaseManager.java +++ b/chainbase/src/main/java/org/tron/core/ChainBaseManager.java @@ -5,13 +5,14 @@ import com.google.common.cache.CacheLoader; import com.google.protobuf.ByteString; import java.util.List; -import javax.annotation.PostConstruct; import java.util.concurrent.ExecutionException; +import javax.annotation.PostConstruct; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.tuweni.bytes.Bytes32; +import org.hyperledger.besu.ethereum.trie.MerkleStorage; import org.hyperledger.besu.ethereum.trie.MerkleTrieException; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; @@ -44,7 +45,6 @@ import org.tron.core.service.MortgageService; import org.tron.core.state.WorldStateGenesis; import org.tron.core.state.WorldStateQueryInstance; -import org.tron.core.state.WorldStateTrieStore; import org.tron.core.store.AbiStore; import org.tron.core.store.AccountAssetStore; import org.tron.core.store.AccountIdIndexStore; @@ -247,7 +247,7 @@ public class ChainBaseManager { @Autowired(required = false) @Getter - private WorldStateTrieStore worldStateTrieStore; + private MerkleStorage merkleStorage; @Autowired @Getter diff --git a/chainbase/src/main/java/org/tron/core/state/StateType.java b/chainbase/src/main/java/org/tron/core/state/StateType.java index 356b2664576..38e744374f5 100644 --- a/chainbase/src/main/java/org/tron/core/state/StateType.java +++ b/chainbase/src/main/java/org/tron/core/state/StateType.java @@ -53,6 +53,11 @@ public static StateType get(String name) { .findFirst().orElse(UNDEFINED); } + public static StateType get(byte value) { + return Arrays.stream(StateType.values()).filter(type -> type.value == value) + .findFirst().orElse(UNDEFINED); + } + public static byte[] encodeKey(StateType type, byte[] key) { byte[] p = new byte[]{type.value}; return Bytes.concat(p, key); @@ -62,4 +67,4 @@ public static byte[] decodeKey(byte[] key) { return Arrays.copyOfRange(key, 1, key.length); } -} \ No newline at end of file +} diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java b/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java index 36e5e48bc32..3b905da48fc 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java @@ -138,7 +138,7 @@ public void preExecute(BlockCapsule blockCapsule) { BlockCapsule parentBlockCapsule = chainBaseManager.getBlockById(blockCapsule.getParentBlockId()); Bytes32 rootHash = parentBlockCapsule.getArchiveRoot(); - trie = new TrieImpl2(chainBaseManager.getWorldStateTrieStore(), rootHash); + trie = new TrieImpl2(chainBaseManager.getMerkleStorage(), rootHash); } catch (Exception e) { throw new MerkleTrieException(e.getMessage()); } @@ -160,7 +160,7 @@ public void initGenesis(BlockCapsule blockCapsule) { if (!exe()) { return; } - trie = new TrieImpl2(chainBaseManager.getWorldStateTrieStore()); + trie = new TrieImpl2(chainBaseManager.getMerkleStorage()); clear(); trie.commit(); trie.flush(); diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java b/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java index 1e00133340c..0e5a86c9fd7 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateQueryInstance.java @@ -47,7 +47,7 @@ public class WorldStateQueryInstance { public WorldStateQueryInstance(Bytes32 rootHash, ChainBaseManager chainBaseManager) { this.rootHash = rootHash; - this.trieImpl = new TrieImpl2(chainBaseManager.getWorldStateTrieStore(), rootHash); + this.trieImpl = new TrieImpl2(chainBaseManager.getMerkleStorage(), rootHash); this.worldStateGenesis = chainBaseManager.getWorldStateGenesis(); this.chainBaseManager = chainBaseManager; } diff --git a/chainbase/src/main/java/org/tron/core/state/store/KeyValueMerkleCacheStorage.java b/chainbase/src/main/java/org/tron/core/state/store/KeyValueMerkleCacheStorage.java new file mode 100644 index 00000000000..1251d09693a --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/state/store/KeyValueMerkleCacheStorage.java @@ -0,0 +1,99 @@ +package org.tron.core.state.store; + +import com.google.common.cache.CacheLoader; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; +import org.hyperledger.besu.ethereum.trie.KeyValueMerkleStorage; +import org.hyperledger.besu.ethereum.trie.MerkleTrieException; +import org.hyperledger.besu.storage.KeyValueStorage; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; +import org.tron.common.cache.CacheManager; +import org.tron.common.cache.CacheType; +import org.tron.common.cache.TronCache; +import org.tron.core.state.StateType; +import org.tron.core.state.annotation.NeedWorldStateTrieStoreCondition; + +@Component +@Conditional(NeedWorldStateTrieStoreCondition.class) +public class KeyValueMerkleCacheStorage extends KeyValueMerkleStorage { + + private final Map>> cache; + + private final List cacheTypes = Arrays.asList( + StateType.DelegatedResource, StateType.DelegatedResourceAccountIndex, + StateType.StorageRow, StateType.Account, + StateType.Votes, + StateType.Code, StateType.Contract); + + @Autowired + public KeyValueMerkleCacheStorage(@Autowired KeyValueStorage keyValueStorage) { + super(keyValueStorage); + cache = Collections.synchronizedMap(new HashMap<>()); + for (StateType stateType : cacheTypes) { + cache.put(stateType, CacheManager.allocate(CacheType.findByType( + CacheType.worldStateTrie.type + '.' + stateType.getName()), + new CacheLoader>() { + @Override + public Optional load(@NotNull Bytes32 key) { + return get(key); + } + }, (key, value) -> Bytes32.SIZE + value.orElse(Bytes.EMPTY).size())); + } + } + + @Override + public Optional get(final Bytes location, final Bytes32 hash) { + try { + StateType stateType = parse(location); + if (stateType != StateType.UNDEFINED) { + return cache.get(stateType).get(hash); + } + return get(hash); + } catch (ExecutionException e) { + throw new MerkleTrieException(e.getMessage(), hash, location); + } + } + + + private Optional get(final Bytes32 hash) { + return super.get(null, hash); + } + + @Override + public void put(final Bytes location, final Bytes32 hash, final Bytes value) { + super.put(location, hash, value); + StateType stateType = parse(location); + if (stateType != StateType.UNDEFINED) { + cache.get(stateType).put(hash, Optional.of(value)); + } + } + + private StateType parse(final Bytes location) { + byte stateTypeLen = Byte.BYTES << 1; + if (location.size() < stateTypeLen) { + return StateType.UNDEFINED; + } + byte high = location.get(0); + byte low = location.get(1); + if ((high & 0xf0) != 0 || (low & 0xf0) != 0) { + throw new IllegalArgumentException("Invalid path: contains elements larger than a nibble"); + } + + byte type = (byte) (high << 4 | low); + StateType s = StateType.get(type); + if (cacheTypes.contains(s)) { + return s; + } + return StateType.UNDEFINED; + } +} diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java b/chainbase/src/main/java/org/tron/core/state/store/WorldStateTrieStore.java similarity index 98% rename from chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java rename to chainbase/src/main/java/org/tron/core/state/store/WorldStateTrieStore.java index 32a1ab283f1..e2946f050f4 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateTrieStore.java +++ b/chainbase/src/main/java/org/tron/core/state/store/WorldStateTrieStore.java @@ -1,4 +1,4 @@ -package org.tron.core.state; +package org.tron.core.state.store; import java.nio.file.Paths; import java.util.Arrays; diff --git a/common/src/main/java/org/tron/common/cache/CacheManager.java b/common/src/main/java/org/tron/common/cache/CacheManager.java index 3ffb224a84b..2b647019cd8 100644 --- a/common/src/main/java/org/tron/common/cache/CacheManager.java +++ b/common/src/main/java/org/tron/common/cache/CacheManager.java @@ -2,6 +2,7 @@ import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheStats; +import com.google.common.cache.Weigher; import com.google.common.collect.Maps; import java.util.Map; import java.util.stream.Collectors; @@ -18,22 +19,30 @@ public static TronCache allocate(CacheType name) { return cache; } - public static TronCache allocate(CacheType name, String strategy) { + public static TronCache allocate(CacheType name, String strategy) { TronCache cache = new TronCache<>(name, strategy); CACHES.put(name, cache); return cache; } - public static TronCache allocate(CacheType name, - CacheLoader loader) { + public static TronCache allocate(CacheType name, + CacheLoader loader) { TronCache cache = new TronCache<>(name, CommonParameter.getInstance() .getStorage().getCacheStrategy(name), loader); CACHES.put(name, cache); return cache; } - public static TronCache allocate(CacheType name, String strategy, - CacheLoader loader) { + public static TronCache allocate(CacheType name, CacheLoader loader, + Weigher weigher) { + TronCache cache = new TronCache<>(name, CommonParameter.getInstance() + .getStorage().getCacheStrategy(name), loader, weigher); + CACHES.put(name, cache); + return cache; + } + + public static TronCache allocate(CacheType name, String strategy, + CacheLoader loader) { TronCache cache = new TronCache<>(name, strategy, loader); CACHES.put(name, cache); return cache; diff --git a/common/src/main/java/org/tron/common/cache/CacheStrategies.java b/common/src/main/java/org/tron/common/cache/CacheStrategies.java index 6cf0bb98935..97f63514366 100644 --- a/common/src/main/java/org/tron/common/cache/CacheStrategies.java +++ b/common/src/main/java/org/tron/common/cache/CacheStrategies.java @@ -45,6 +45,11 @@ public class CacheStrategies { String.format(PATTERNS, 10000, 10000, "30s", CPUS); private static final String CACHE_STRATEGY_HUGE_DEFAULT = String.format(PATTERNS, 20000, 20000, "30s", CPUS); + + // for world state trie cache 512M + private static final String CACHE_STRATEGY_WORLD_STATE_TRIE_DEFAULT = + "maximumWeight=536870912,expireAfterAccess=7d,recordStats"; + private static final List CACHE_HUGE_DBS = Arrays.asList(storageRow, account); public static final List CACHE_DBS = Stream.of(CACHE_SMALL_DBS, CACHE_NORMAL_DBS, @@ -66,6 +71,9 @@ public static String getCacheStrategy(CacheType dbName) { if (CACHE_HUGE_DBS.contains(dbName)) { defaultStrategy = CACHE_STRATEGY_HUGE_DEFAULT; } + if (dbName.type.contains(CacheType.worldStateTrie.type)) { + defaultStrategy = CACHE_STRATEGY_WORLD_STATE_TRIE_DEFAULT; + } return defaultStrategy; } } diff --git a/common/src/main/java/org/tron/common/cache/CacheType.java b/common/src/main/java/org/tron/common/cache/CacheType.java index a959a07b3d8..d20acbe3f98 100644 --- a/common/src/main/java/org/tron/common/cache/CacheType.java +++ b/common/src/main/java/org/tron/common/cache/CacheType.java @@ -23,7 +23,15 @@ public enum CacheType { // for leveldb or rocksdb cache // archive node - worldStateQueryInstance("worldStateQueryInstance"); + worldStateQueryInstance("worldStateQueryInstance"), + worldStateTrie("world-state-trie"), + worldStateTrieDelegatedResource("world-state-trie.DelegatedResource"), + worldStateTrieDelegatedResourceAccountIndex("world-state-trie.DelegatedResourceAccountIndex"), + worldStateTrieVotes("world-state-trie.votes"), + worldStateTrieStorageRow("world-state-trie.storage-row"), + worldStateTrieAccount("world-state-trie.account"), + worldStateTrieCode("world-state-trie.code"), + worldStateTrieContract("world-state-trie.contract"); public final String type; diff --git a/common/src/main/java/org/tron/common/cache/TronCache.java b/common/src/main/java/org/tron/common/cache/TronCache.java index 44ffb9ffec0..3d5bde12821 100644 --- a/common/src/main/java/org/tron/common/cache/TronCache.java +++ b/common/src/main/java/org/tron/common/cache/TronCache.java @@ -6,9 +6,10 @@ import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheStats; import com.google.common.cache.LoadingCache; -import lombok.Getter; +import com.google.common.cache.Weigher; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; +import lombok.Getter; public class TronCache { @@ -26,6 +27,11 @@ public class TronCache { this.cache = CacheBuilder.from(strategy).build(loader); } + TronCache(CacheType name, String strategy, CacheLoader loader, Weigher weigher) { + this.name = name; + this.cache = CacheBuilder.from(strategy).weigher(weigher).build(loader); + } + public void put(K k, V v) { this.cache.put(k, v); } diff --git a/framework/src/test/java/org/tron/core/state/WorldStateQueryInstanceTest.java b/framework/src/test/java/org/tron/core/state/WorldStateQueryInstanceTest.java index 154cf1c4e35..ae15cbb6e5b 100644 --- a/framework/src/test/java/org/tron/core/state/WorldStateQueryInstanceTest.java +++ b/framework/src/test/java/org/tron/core/state/WorldStateQueryInstanceTest.java @@ -9,6 +9,7 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; +import org.hyperledger.besu.ethereum.trie.MerkleStorage; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -59,7 +60,7 @@ public class WorldStateQueryInstanceTest { private static TronApplicationContext context; private static ChainBaseManager chainBaseManager; - private static WorldStateTrieStore worldStateTrieStore; + private static MerkleStorage merkleStorage; private static final ECKey ecKey = new ECKey(Utils.getRandom()); private static final byte[] address = ecKey.getAddress(); @@ -76,7 +77,7 @@ public void init() throws IOException { Args.getInstance().dbBackupConfig = DbBackupConfig.getInstance(); context = new TronApplicationContext(DefaultConfig.class); chainBaseManager = context.getBean(ChainBaseManager.class); - worldStateTrieStore = chainBaseManager.getWorldStateTrieStore(); + merkleStorage = context.getBean(MerkleStorage.class); } @After @@ -87,7 +88,7 @@ public void destroy() { @Test public void testGet() { - trieImpl2 = new TrieImpl2(worldStateTrieStore); + trieImpl2 = new TrieImpl2(merkleStorage); testGetAccount(); testGetAccountAsset(); testGetContractState(); @@ -282,7 +283,7 @@ private void testGetDynamicProperty() { } private void testGetStorageRow() { - trieImpl2 = new TrieImpl2(worldStateTrieStore); + trieImpl2 = new TrieImpl2(merkleStorage); byte[] key = address; byte[] value = "test".getBytes(); trieImpl2.put(StateType.encodeKey(StateType.StorageRow, key), Bytes.wrap(value)); diff --git a/framework/src/test/java/org/tron/core/tire/Trie2Test.java b/framework/src/test/java/org/tron/core/tire/Trie2Test.java index 9ed4e99608e..cc852b2a8c2 100644 --- a/framework/src/test/java/org/tron/core/tire/Trie2Test.java +++ b/framework/src/test/java/org/tron/core/tire/Trie2Test.java @@ -628,4 +628,24 @@ public void testEqual() throws IOException { Assert.assertEquals(trie3, trie); } + @Test + public void testRootHash() throws IOException { + TrieImpl2 trie = new TrieImpl2(folder.newFolder().toPath().toString()); + Bytes k1 = Bytes.fromHexString("41548794500882809695a8a687866e76d4271a1abc"); + Bytes v1 = Bytes.wrap(new byte[]{0}); + Bytes v2 = Bytes.wrap(new byte[]{0}); + trie.put(k1, v1); + trie.commit(); + Bytes32 hash1 = trie.getRootHashByte32(); + trie.put(k1, v2); + trie.commit(); + Bytes32 hash2 = trie.getRootHashByte32(); + Assert.assertEquals(hash1, hash2); + trie.put(k1, Bytes.ofUnsignedLong(0)); + trie.commit(); + Bytes32 hash3 = trie.getRootHashByte32(); + Assert.assertNotEquals(hash1, hash3); + + } + } diff --git a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/KeyValueMerkleStorage.java b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/KeyValueMerkleStorage.java index 7c04f18cc0c..d5a06130c6f 100644 --- a/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/KeyValueMerkleStorage.java +++ b/state-trie-jdk8/src/main/java/org/hyperledger/besu/ethereum/trie/KeyValueMerkleStorage.java @@ -25,8 +25,8 @@ public class KeyValueMerkleStorage implements MerkleStorage { - private final KeyValueStorage keyValueStorage; - private final Map pendingUpdates = new HashMap<>(); + protected final KeyValueStorage keyValueStorage; + protected final Map pendingUpdates = new HashMap<>(); public KeyValueMerkleStorage(final KeyValueStorage keyValueStorage) { this.keyValueStorage = keyValueStorage; From 3af2c7362c508e2081df3a4525bbdb613f08c805 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Tue, 30 May 2023 14:46:19 +0800 Subject: [PATCH 24/34] feat(db): skip unnecessary check and init --- .../src/main/java/org/tron/core/db/Manager.java | 12 ++++++++---- .../main/java/org/tron/core/net/TronNetDelegate.java | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/framework/src/main/java/org/tron/core/db/Manager.java b/framework/src/main/java/org/tron/core/db/Manager.java index 846a6c7590c..ec5b92cfc34 100644 --- a/framework/src/main/java/org/tron/core/db/Manager.java +++ b/framework/src/main/java/org/tron/core/db/Manager.java @@ -1423,8 +1423,11 @@ public TransactionInfo processTransaction(final TransactionCapsule trxCap, Block chainBaseManager.getBalanceTraceStore().initCurrentTransactionBalanceTrace(trxCap); } - validateTapos(trxCap); - validateCommon(trxCap); + if (Objects.isNull(blockCap) || !blockCap.generatedByMyself) { + validateTapos(trxCap); + validateCommon(trxCap); + validateDup(trxCap); + } if (trxCap.getInstance().getRawData().getContractList().size() != 1) { throw new ContractSizeNotEqualToOneException( @@ -1433,8 +1436,6 @@ public TransactionInfo processTransaction(final TransactionCapsule trxCap, Block txId, trxCap.getInstance().getRawData().getContractList().size())); } - validateDup(trxCap); - if (!trxCap.validateSignature(chainBaseManager.getAccountStore(), chainBaseManager.getDynamicPropertiesStore())) { throw new ValidateSignatureException( @@ -2383,6 +2384,9 @@ private void initLiteNode() { // When using bloom filter for transaction de-duplication, // it is possible to use trans for secondary confirmation. // Init trans db for liteNode if needed. + if (CommonParameter.getInstance().isP2pDisable()) { + return; + } long headNum = chainBaseManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber(); long recentBlockCount = chainBaseManager.getRecentBlockStore().size(); long recentBlockStart = headNum - recentBlockCount + 1; diff --git a/framework/src/main/java/org/tron/core/net/TronNetDelegate.java b/framework/src/main/java/org/tron/core/net/TronNetDelegate.java index 4d22f98d680..1eba8e5ea59 100644 --- a/framework/src/main/java/org/tron/core/net/TronNetDelegate.java +++ b/framework/src/main/java/org/tron/core/net/TronNetDelegate.java @@ -257,6 +257,8 @@ public void processBlock(BlockCapsule block, boolean isSync) throws P2pException MetricKeys.Histogram.LOCK_ACQUIRE_LATENCY, MetricLabels.BLOCK)); Histogram.Timer timer = Metrics.histogramStartTimer( MetricKeys.Histogram.BLOCK_PROCESS_LATENCY, String.valueOf(isSync)); + // skip sign + block.generatedByMyself = true; dbManager.pushBlock(block); Metrics.histogramObserve(timer); freshBlockId.put(blockId, System.currentTimeMillis()); From c298d15c19fd96f8b2bfc575e075def11d441823 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Tue, 30 May 2023 14:46:49 +0800 Subject: [PATCH 25/34] feat(db): add metrics --- .../main/java/org/tron/core/state/StateType.java | 4 ++++ .../org/tron/core/state/WorldStateCallBack.java | 13 ++++++++++++- .../java/org/tron/core/state/trie/TrieImpl2.java | 9 +++++++++ .../java/org/tron/common/prometheus/MetricKeys.java | 7 +++++++ .../org/tron/common/prometheus/MetricsGauge.java | 1 + .../tron/common/prometheus/MetricsHistogram.java | 6 ++++++ .../src/main/java/org/tron/core/db/Manager.java | 1 + 7 files changed, 40 insertions(+), 1 deletion(-) diff --git a/chainbase/src/main/java/org/tron/core/state/StateType.java b/chainbase/src/main/java/org/tron/core/state/StateType.java index 38e744374f5..ab5e73de983 100644 --- a/chainbase/src/main/java/org/tron/core/state/StateType.java +++ b/chainbase/src/main/java/org/tron/core/state/StateType.java @@ -67,4 +67,8 @@ public static byte[] decodeKey(byte[] key) { return Arrays.copyOfRange(key, 1, key.length); } + public static StateType decodeType(org.apache.tuweni.bytes.Bytes key) { + return StateType.get(key.get(0)); + } + } diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java b/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java index 3b905da48fc..34ebeb7a9d3 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java @@ -2,6 +2,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.primitives.Longs; +import io.prometheus.client.Histogram; import java.util.HashMap; import java.util.Map; import lombok.Getter; @@ -13,6 +14,8 @@ import org.hyperledger.besu.ethereum.trie.MerkleTrieException; import org.springframework.stereotype.Component; import org.tron.common.parameter.CommonParameter; +import org.tron.common.prometheus.MetricKeys; +import org.tron.common.prometheus.Metrics; import org.tron.core.ChainBaseManager; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.BlockCapsule; @@ -116,8 +119,16 @@ public void clear() { if (!exe()) { return; } - trieEntryList.forEach(trie::put); + Histogram.Timer timer = trieEntryList.isEmpty() ? null : Metrics.histogramStartTimer( + MetricKeys.Histogram.TRON_STATE_PUT_PER_TRANS_LATENCY); + trieEntryList.forEach((key, value) -> { + Histogram.Timer t = Metrics.histogramStartTimer( + MetricKeys.Histogram.TRON_STATE_PUT_LATENCY, StateType.decodeType(key).getName()); + trie.put(key, value); + Metrics.histogramObserve(t); + }); trieEntryList.clear(); + Metrics.histogramObserve(timer); } public void preExeTrans() { diff --git a/chainbase/src/main/java/org/tron/core/state/trie/TrieImpl2.java b/chainbase/src/main/java/org/tron/core/state/trie/TrieImpl2.java index 4cc33be5e7e..de407274008 100644 --- a/chainbase/src/main/java/org/tron/core/state/trie/TrieImpl2.java +++ b/chainbase/src/main/java/org/tron/core/state/trie/TrieImpl2.java @@ -9,6 +9,7 @@ import java.util.TreeMap; import java.util.function.Consumer; import java.util.function.Function; +import io.prometheus.client.Histogram; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.apache.tuweni.bytes.Bytes; @@ -25,6 +26,8 @@ import org.hyperledger.besu.storage.RocksDBConfiguration; import org.hyperledger.besu.storage.RocksDBConfigurationBuilder; import org.hyperledger.besu.storage.RocksDBKeyValueStorage; +import org.tron.common.prometheus.MetricKeys; +import org.tron.common.prometheus.Metrics; /** * @@ -120,7 +123,10 @@ public void delete(byte[] key) { @Override public void commit() { + Histogram.Timer timer = Metrics.histogramStartTimer( + MetricKeys.Histogram.STATE_PUSH_BLOCK_FINISH_LATENCY, "commit"); trie.commit(merkleStorage::put); + Metrics.histogramObserve(timer); } @Override @@ -168,7 +174,10 @@ public Map entriesFrom(final Function, Map Date: Sun, 9 Jul 2023 17:57:57 +0800 Subject: [PATCH 26/34] feat(trie): skip tran-cache init when p2p is disabled --- .../src/main/java/org/tron/core/db2/common/TxCacheDB.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/chainbase/src/main/java/org/tron/core/db2/common/TxCacheDB.java b/chainbase/src/main/java/org/tron/core/db2/common/TxCacheDB.java index 71cf361b06a..4ea53469941 100644 --- a/chainbase/src/main/java/org/tron/core/db2/common/TxCacheDB.java +++ b/chainbase/src/main/java/org/tron/core/db2/common/TxCacheDB.java @@ -110,6 +110,9 @@ private void initCache() { } public void init() { + if (CommonParameter.getInstance().isP2pDisable()) { + return; + } long size = recentTransactionStore.size(); if (size != MAX_BLOCK_SIZE) { // 0. load from persistentStore From d064f99ec2a48c1ab18429fb3959491fa4863d15 Mon Sep 17 00:00:00 2001 From: halibobo1205 <82020050+halibobo1205@users.noreply.github.com> Date: Sun, 9 Jul 2023 19:14:49 +0800 Subject: [PATCH 27/34] feat(trie): add logs for jsonrpc --- .../tron/core/services/jsonrpc/FullNodeJsonRpcHttpService.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/FullNodeJsonRpcHttpService.java b/framework/src/main/java/org/tron/core/services/jsonrpc/FullNodeJsonRpcHttpService.java index c38b9b198c0..3b6f0ac4b71 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/FullNodeJsonRpcHttpService.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/FullNodeJsonRpcHttpService.java @@ -58,6 +58,8 @@ public void start() { server.start(); + logger.info("JsonRpcHttpService start at {}, success", port); + } catch (Exception e) { logger.debug("IOException: {}", e.getMessage()); } From 73185830560b58cece1eba704ab52ce693468418 Mon Sep 17 00:00:00 2001 From: halibobo1205 Date: Mon, 10 Jul 2023 14:24:12 +0800 Subject: [PATCH 28/34] feat(trie): merge master --- .../java/org/tron/core/db/TronStoreWithRevoking.java | 1 + .../tron/core/services/jsonrpc/TronJsonRpcImpl.java | 2 +- .../common/runtime/vm/TransferToAccountTest.java | 7 ++++--- .../core/actuator/DelegateResourceActuatorTest.java | 12 +++--------- .../core/actuator/FreezeBalanceActuatorTest.java | 11 ++++------- .../core/actuator/FreezeBalanceV2ActuatorTest.java | 11 +++-------- .../org/tron/core/actuator/TransferActuatorTest.java | 12 +++--------- .../core/actuator/TransferAssetActuatorTest.java | 12 +++--------- .../core/actuator/UnfreezeAssetActuatorTest.java | 11 +++-------- .../core/actuator/UnfreezeBalanceActuatorTest.java | 12 +++--------- .../core/actuator/UnfreezeBalanceV2ActuatorTest.java | 12 +++--------- .../java/org/tron/core/zksnark/NoteEncDecryTest.java | 2 +- 12 files changed, 32 insertions(+), 73 deletions(-) diff --git a/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java b/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java index 078a73e2924..cd333b7c0f7 100644 --- a/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java +++ b/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java @@ -87,6 +87,7 @@ protected TronStoreWithRevoking(String dbName) { } protected TronStoreWithRevoking() { + this.db = null; } protected org.iq80.leveldb.Options getOptionsByDbNameForLevelDB(String dbName) { diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index 764c894e422..751cd2c79bd 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -481,7 +481,7 @@ private void callTriggerConstantContract(byte[] ownerAddressByte, byte[] contrac TransactionCapsule trxCap = wallet.createTransactionCapsule(triggerContract, ContractType.TriggerSmartContract); Transaction trx = wallet.triggerConstantContract( - triggerContract, trxCap, trxExtBuilder, retBuilder, blockNumber); + triggerContract, trxCap, trxExtBuilder, retBuilder, false, blockNumber); trxExtBuilder.setTransaction(trx); trxExtBuilder.setTxid(trxCap.getTransactionId().getByteString()); diff --git a/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java b/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java index 2198db7ef76..24255f26aed 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java @@ -1,6 +1,7 @@ package org.tron.common.runtime.vm; import com.google.protobuf.ByteString; +import javax.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; import org.junit.Assert; @@ -16,7 +17,6 @@ import org.tron.common.utils.StringUtil; import org.tron.common.utils.Utils; import org.tron.common.utils.client.utils.AbiUtil; -import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.actuator.VMActuator; @@ -57,7 +57,8 @@ public class TransferToAccountTest extends BaseTest { private static Runtime runtime; private static RepositoryImpl repository; private static AccountCapsule ownerCapsule; - private static WorldStateCallBack worldStateCallBack; + @Resource + private WorldStateCallBack worldStateCallBack; static { dbPath = "output_TransferToAccountTest"; @@ -79,7 +80,6 @@ public void before() { AccountType.AssetIssue); ownerCapsule.setBalance(1000_1000_1000L); - worldStateCallBack = context.getBean(WorldStateCallBack.class); } private long createAsset(String tokenName) { @@ -354,6 +354,7 @@ private byte[] deployTransferContract(long id) .deployContractWholeProcessReturnContractAddress(contractName, address, ABI, code, value, feeLimit, consumeUserResourcePercent, null, tokenValue, tokenId, repository, null); + return contractAddress; } private WorldStateQueryInstance flushTrieAndGetQueryInstance() { diff --git a/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java index 19741611f42..b71f67ccbed 100644 --- a/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java @@ -13,15 +13,13 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; import lombok.extern.slf4j.Slf4j; +import javax.annotation.Resource; import org.junit.After; -import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.tron.common.BaseTest; import org.tron.common.utils.ByteArray; -import org.tron.common.utils.FileUtil; -import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; @@ -49,10 +47,8 @@ public class DelegateResourceActuatorTest extends BaseTest { private static final String OWNER_ADDRESS_INVALID = "aaaa"; private static final String OWNER_ACCOUNT_INVALID; private static final long initBalance = 10_000_000_000L; - private static Manager dbManager; - private static final TronApplicationContext context; - private static final WorldStateCallBack worldStateCallBack; - private static final ChainBaseManager chainBaseManager; + @Resource + private WorldStateCallBack worldStateCallBack; static { dbPath = "output_delegate_resource_test"; @@ -61,8 +57,6 @@ public class DelegateResourceActuatorTest extends BaseTest { RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; - worldStateCallBack = context.getBean(WorldStateCallBack.class); - chainBaseManager = context.getBean(ChainBaseManager.class); } /** diff --git a/framework/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java index 5e3ce901731..64e741d3f9d 100644 --- a/framework/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java @@ -6,9 +6,9 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; import java.util.List; +import javax.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.junit.After; -import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -25,6 +25,7 @@ import org.tron.core.capsule.TransactionResultCapsule; import org.tron.core.config.Parameter.ChainConstant; import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; import org.tron.core.state.WorldStateCallBack; @@ -44,10 +45,8 @@ public class FreezeBalanceActuatorTest extends BaseTest { private static final String OWNER_ADDRESS_INVALID = "aaaa"; private static final String OWNER_ACCOUNT_INVALID; private static final long initBalance = 10_000_000_000L; - private static Manager dbManager; - private static TronApplicationContext context; - private static WorldStateCallBack worldStateCallBack; - private static ChainBaseManager chainBaseManager; + @Resource + private WorldStateCallBack worldStateCallBack; static { dbPath = "output_freeze_balance_test"; @@ -56,8 +55,6 @@ public class FreezeBalanceActuatorTest extends BaseTest { RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; - worldStateCallBack = context.getBean(WorldStateCallBack.class); - chainBaseManager = context.getBean(ChainBaseManager.class); } /** diff --git a/framework/src/test/java/org/tron/core/actuator/FreezeBalanceV2ActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/FreezeBalanceV2ActuatorTest.java index 9fb6833ccd1..57241b17900 100644 --- a/framework/src/test/java/org/tron/core/actuator/FreezeBalanceV2ActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/FreezeBalanceV2ActuatorTest.java @@ -5,9 +5,9 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; +import javax.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.junit.After; -import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -38,10 +38,8 @@ public class FreezeBalanceV2ActuatorTest extends BaseTest { private static final String OWNER_ADDRESS_INVALID = "aaaa"; private static final String OWNER_ACCOUNT_INVALID; private static final long initBalance = 10_000_000_000L; - private static Manager dbManager; - private static TronApplicationContext context; - private static final WorldStateCallBack worldStateCallBack; - private static final ChainBaseManager chainBaseManager; + @Resource + private WorldStateCallBack worldStateCallBack; static { dbPath = "output_freeze_balance_v2_test"; @@ -50,9 +48,6 @@ public class FreezeBalanceV2ActuatorTest extends BaseTest { RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; - worldStateCallBack = context.getBean(WorldStateCallBack.class); - chainBaseManager = context.getBean(ChainBaseManager.class); - Assert.assertNotNull(worldStateCallBack.getTrie()); } /** diff --git a/framework/src/test/java/org/tron/core/actuator/TransferActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/TransferActuatorTest.java index 3839b81a5cf..91ba02a62f9 100644 --- a/framework/src/test/java/org/tron/core/actuator/TransferActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/TransferActuatorTest.java @@ -6,18 +6,16 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; import java.util.Date; +import javax.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; import org.junit.After; -import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.tron.common.BaseTest; import org.tron.common.runtime.TvmTestUtils; import org.tron.common.utils.ByteArray; -import org.tron.common.utils.FileUtil; -import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; @@ -50,10 +48,8 @@ public class TransferActuatorTest extends BaseTest { private static final String OWNER_ACCOUNT_INVALID; private static final String OWNER_NO_BALANCE; private static final String To_ACCOUNT_INVALID; - private static Manager dbManager; - private static TronApplicationContext context; - private static final WorldStateCallBack worldStateCallBack; - private static final ChainBaseManager chainBaseManager; + @Resource + private WorldStateCallBack worldStateCallBack; static { dbPath = "output_transfer_test"; @@ -65,8 +61,6 @@ public class TransferActuatorTest extends BaseTest { OWNER_NO_BALANCE = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3433"; To_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3422"; - worldStateCallBack = context.getBean(WorldStateCallBack.class); - chainBaseManager = context.getBean(ChainBaseManager.class); } /** diff --git a/framework/src/test/java/org/tron/core/actuator/TransferAssetActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/TransferAssetActuatorTest.java index 88e987ef79f..992b630f989 100755 --- a/framework/src/test/java/org/tron/core/actuator/TransferAssetActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/TransferAssetActuatorTest.java @@ -20,18 +20,16 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; +import javax.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; import org.junit.After; -import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.tron.common.BaseTest; import org.tron.common.runtime.TvmTestUtils; import org.tron.common.utils.ByteArray; -import org.tron.common.utils.FileUtil; -import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; @@ -76,11 +74,9 @@ public class TransferAssetActuatorTest extends BaseTest { private static final int VOTE_SCORE = 2; private static final String DESCRIPTION = "TRX"; private static final String URL = "https://tron.network"; - private static TronApplicationContext context; - private static Manager dbManager; private static Any contract; - private static final WorldStateCallBack worldStateCallBack; - private static final ChainBaseManager chainBaseManager; + @Resource + private WorldStateCallBack worldStateCallBack; static { dbPath = "output_transferasset_test"; @@ -92,8 +88,6 @@ public class TransferAssetActuatorTest extends BaseTest { + "B56446E617E924805E4D6CA021D341FEF6E21234"; ownerAsset_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049010"; - worldStateCallBack = context.getBean(WorldStateCallBack.class); - chainBaseManager = context.getBean(ChainBaseManager.class); } /** diff --git a/framework/src/test/java/org/tron/core/actuator/UnfreezeAssetActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UnfreezeAssetActuatorTest.java index b943f325040..37480713ebc 100644 --- a/framework/src/test/java/org/tron/core/actuator/UnfreezeAssetActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UnfreezeAssetActuatorTest.java @@ -2,16 +2,15 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; +import javax.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.junit.After; -import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.tron.common.BaseTest; import org.tron.common.utils.ByteArray; import org.tron.common.utils.StringUtil; -import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; @@ -40,10 +39,8 @@ public class UnfreezeAssetActuatorTest extends BaseTest { private static final long frozenBalance = 1_000_000_000L; private static final String assetName = "testCoin"; private static final String assetID = "123456"; - private static Manager dbManager; - private static TronApplicationContext context; - private static final WorldStateCallBack worldStateCallBack; - private static final ChainBaseManager chainBaseManager; + @Resource + private WorldStateCallBack worldStateCallBack; static { dbPath = "output_unfreeze_asset_test"; @@ -51,8 +48,6 @@ public class UnfreezeAssetActuatorTest extends BaseTest { OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; - worldStateCallBack = context.getBean(WorldStateCallBack.class); - chainBaseManager = context.getBean(ChainBaseManager.class); } /** diff --git a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java index f2fd25a3e60..734c37dbe05 100644 --- a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java @@ -6,16 +6,14 @@ import com.google.protobuf.ByteString; import java.util.ArrayList; import java.util.List; +import javax.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.junit.After; -import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.tron.common.BaseTest; import org.tron.common.utils.ByteArray; -import org.tron.common.utils.FileUtil; -import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; @@ -46,10 +44,8 @@ public class UnfreezeBalanceActuatorTest extends BaseTest { private static final long initBalance = 10_000_000_000L; private static final long frozenBalance = 1_000_000_000L; private static final long smallTatalResource = 100L; - private static Manager dbManager; - private static TronApplicationContext context; - private static final WorldStateCallBack worldStateCallBack; - private static final ChainBaseManager chainBaseManager; + @Resource + private WorldStateCallBack worldStateCallBack; static { dbPath = "output_unfreeze_balance_test"; @@ -58,8 +54,6 @@ public class UnfreezeBalanceActuatorTest extends BaseTest { RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; - worldStateCallBack = context.getBean(WorldStateCallBack.class); - chainBaseManager = context.getBean(ChainBaseManager.class); } /** diff --git a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceV2ActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceV2ActuatorTest.java index a3bfd85ac19..0355d310e58 100644 --- a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceV2ActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceV2ActuatorTest.java @@ -6,16 +6,14 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; +import javax.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.junit.After; -import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.tron.common.BaseTest; import org.tron.common.utils.ByteArray; -import org.tron.common.utils.FileUtil; -import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; @@ -43,10 +41,8 @@ public class UnfreezeBalanceV2ActuatorTest extends BaseTest { private static final String OWNER_ACCOUNT_INVALID; private static final long initBalance = 10_000_000_000L; private static final long frozenBalance = 1_000_000_000L; - private static Manager dbManager; - private static final TronApplicationContext context; - private static final WorldStateCallBack worldStateCallBack; - private static final ChainBaseManager chainBaseManager; + @Resource + private WorldStateCallBack worldStateCallBack; static { dbPath = "output_unfreeze_balance_v2_test"; @@ -55,8 +51,6 @@ public class UnfreezeBalanceV2ActuatorTest extends BaseTest { RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; - worldStateCallBack = context.getBean(WorldStateCallBack.class); - chainBaseManager = context.getBean(ChainBaseManager.class); } /** diff --git a/framework/src/test/java/org/tron/core/zksnark/NoteEncDecryTest.java b/framework/src/test/java/org/tron/core/zksnark/NoteEncDecryTest.java index e2b8ef43306..fb054747fe6 100644 --- a/framework/src/test/java/org/tron/core/zksnark/NoteEncDecryTest.java +++ b/framework/src/test/java/org/tron/core/zksnark/NoteEncDecryTest.java @@ -22,7 +22,6 @@ @Slf4j public class NoteEncDecryTest extends BaseTest { - private static final String dbPath = "note_encdec_test"; private static final String FROM_ADDRESS; private static final String ADDRESS_ONE_PRIVATE_KEY; private static final long OWNER_BALANCE = 100_000_000; @@ -41,6 +40,7 @@ public class NoteEncDecryTest extends BaseTest { private Wallet wallet; static { + dbPath = "note_encdec_test"; Args.setParam(new String[]{"--output-directory", dbPath}, "config-localtest.conf"); FROM_ADDRESS = Wallet.getAddressPreFixString() + "a7d8a35b260395c14aa456297662092ba3b76fc0"; ADDRESS_ONE_PRIVATE_KEY = "7f7f701e94d4f1dd60ee5205e7ea8ee31121427210417b608a6b2e96433549a7"; From 457075b58cb7fd832081c60ad6f9833557fef730 Mon Sep 17 00:00:00 2001 From: halibobo1205 <82020050+halibobo1205@users.noreply.github.com> Date: Mon, 1 Apr 2024 11:12:27 +0800 Subject: [PATCH 29/34] merge 4.7.3.1 (#17) --- .github/ISSUE_TEMPLATE/ask-a-question.md | 22 +- .github/ISSUE_TEMPLATE/report-a-bug.md | 2 +- .github/ISSUE_TEMPLATE/request-a-feature.md | 2 +- .github/workflows/codeql.yml | 64 + .gitignore | 1 + README.md | 21 +- SECURITY.md | 7 + actuator/build.gradle | 23 +- .../actuator/CancelAllUnfreezeV2Actuator.java | 5 + .../actuator/DelegateResourceActuator.java | 58 +- .../core/actuator/FreezeBalanceActuator.java | 4 +- .../actuator/FreezeBalanceV2Actuator.java | 6 +- .../actuator/UnDelegateResourceActuator.java | 12 +- .../actuator/UnfreezeBalanceV2Actuator.java | 16 +- .../WithdrawExpireUnfreezeActuator.java | 4 +- .../org/tron/core/utils/ProposalUtil.java | 6 +- .../org/tron/core/utils/TransactionUtil.java | 57 +- .../tron/core/vm/PrecompiledContracts.java | 12 +- .../DelegateResourceProcessor.java | 28 +- .../FreezeBalanceProcessor.java | 4 +- .../FreezeBalanceV2Processor.java | 5 +- .../UnDelegateResourceProcessor.java | 16 +- .../WithdrawExpireUnfreezeProcessor.java | 4 +- .../org/tron/core/vm/program/Program.java | 44 +- .../org/tron/core/vm/utils/FreezeV2Util.java | 40 +- build.gradle | 6 - chainbase/build.gradle | 23 +- .../leveldb/LevelDbDataSourceImpl.java | 21 +- .../common/storage/metric/DbStatService.java | 16 +- .../rocksdb/RocksDbDataSourceImpl.java | 10 +- .../java/org/tron/core/ChainBaseManager.java | 57 +- .../org/tron/core/capsule/AccountCapsule.java | 16 + .../org/tron/core/capsule/BlockCapsule.java | 3 +- .../tron/core/capsule/TransactionCapsule.java | 11 +- .../org/tron/core/db/ResourceProcessor.java | 25 +- .../org/tron/core/db/TransactionCache.java | 8 +- .../java/org/tron/core/db/TronDatabase.java | 9 +- .../tron/core/db/TronStoreWithRevoking.java | 9 +- .../org/tron/core/db2/common/TxCacheDB.java | 239 +- .../tron/core/db2/core/AbstractSnapshot.java | 7 + .../java/org/tron/core/db2/core/Snapshot.java | 4 + .../org/tron/core/db2/core/SnapshotImpl.java | 23 + .../tron/core/db2/core/SnapshotManager.java | 47 +- .../org/tron/core/db2/core/SnapshotRoot.java | 4 + .../tron/core/store/CheckPointV2Store.java | 17 + .../core/store/DynamicPropertiesStore.java | 6 +- .../org/tron/core/store/WitnessStore.java | 22 +- common/build.gradle | 4 +- .../common/es/ExecutorServiceManager.java | 83 + .../trigger/TransactionLogTrigger.java | 6 + .../common/parameter/CommonParameter.java | 20 +- .../src/main/java/org/tron/core/Constant.java | 8 +- .../java/org/tron/core/config/Parameter.java | 1 + .../org/tron/core/config/args/Storage.java | 10 + consensus/build.gradle | 22 +- .../org/tron/consensus/ConsensusDelegate.java | 4 - .../org/tron/consensus/dpos/DposTask.java | 20 +- .../consensus/dpos/MaintenanceManager.java | 4 +- .../org/tron/consensus/pbft/PbftManager.java | 14 +- crypto/build.gradle | 13 + .../org/tron/common/crypto/SignUtils.java | 10 +- docker/docker.md | 2 +- framework/build.gradle | 10 +- .../tron/common/application/Application.java | 4 + .../common/application/ApplicationImpl.java | 41 +- .../tron/common/application/HttpService.java | 81 + .../tron/common/application/RpcService.java | 85 + .../org/tron/common/application/Service.java | 7 + .../common/application/ServiceContainer.java | 33 +- .../application/TronApplicationContext.java | 24 +- .../org/tron/common/backup/BackupManager.java | 11 +- .../common/backup/socket/BackupServer.java | 16 +- .../tron/common/cache/CacheManagerTest.java | 14 + .../capsule/TransactionLogTriggerCapsule.java | 91 + .../src/main/java/org/tron/core/Wallet.java | 83 +- .../org/tron/core/config/DefaultConfig.java | 9 +- .../tron/core/config/TronLogShutdownHook.java | 9 +- .../java/org/tron/core/config/args/Args.java | 68 +- .../tron/core/config/args/DynamicArgs.java | 16 +- .../main/java/org/tron/core/db/Manager.java | 67 +- .../tron/core/net/P2pEventHandlerImpl.java | 4 +- .../org/tron/core/net/TronNetDelegate.java | 8 + .../org/tron/core/net/TronNetService.java | 2 +- .../message/sync/ChainInventoryMessage.java | 1 + .../messagehandler/PbftDataSyncHandler.java | 16 +- .../net/messagehandler/PbftMsgHandler.java | 17 + .../SyncBlockChainMsgHandler.java | 30 +- .../TransactionsMsgHandler.java | 26 +- .../tron/core/net/peer/PeerConnection.java | 4 + .../org/tron/core/net/peer/PeerManager.java | 11 +- .../tron/core/net/peer/PeerStatusCheck.java | 10 +- .../tron/core/net/service/adv/AdvService.java | 42 +- .../effective/EffectiveCheckService.java | 16 +- .../service/fetchblock/FetchBlockService.java | 12 +- .../nodepersist/NodePersistService.java | 30 +- .../core/net/service/relay/RelayService.java | 10 +- .../service/statistics/TronStatsManager.java | 13 +- .../core/net/service/sync/SyncService.java | 15 +- .../org/tron/core/services/RpcApiService.java | 117 +- .../services/filter/HttpApiAccessFilter.java | 2 +- .../core/services/filter/HttpInterceptor.java | 76 +- .../services/http/FullNodeHttpApiService.java | 74 +- .../http/GetAssetIssueListServlet.java | 3 +- .../GetAvailableUnfreezeCountServlet.java | 3 + .../http/GetBandwidthPricesServlet.java | 15 +- .../services/http/GetBlockByNumServlet.java | 9 +- .../http/GetCanDelegatedMaxSizeServlet.java | 8 +- .../GetCanWithdrawUnfreezeAmountServlet.java | 14 +- .../services/http/GetEnergyPricesServlet.java | 15 +- .../http/GetMemoFeePricesServlet.java | 15 +- .../services/http/GetNowBlockServlet.java | 3 +- .../core/services/http/ListNodesServlet.java | 3 +- .../services/http/ListProposalsServlet.java | 3 +- .../tron/core/services/http/PostParams.java | 6 + .../services/http/RateLimiterServlet.java | 19 +- .../org/tron/core/services/http/Util.java | 97 +- .../solidity/SolidityNodeHttpApiService.java | 43 +- .../JsonRpcServiceOnPBFT.java | 26 +- .../JsonRpcServiceOnSolidity.java | 27 +- .../interfaceOnPBFT/RpcApiServiceOnPBFT.java | 62 +- .../http/GetBandwidthPricesOnPBFTServlet.java | 27 + .../http/GetEnergyPricesOnPBFTServlet.java | 3 +- .../http/PBFT/HttpApiOnPBFTService.java | 32 +- .../RpcApiServiceOnSolidity.java | 61 +- .../GetBandwidthPricesOnSolidityServlet.java | 28 + .../GetEnergyPricesOnSolidityServlet.java | 3 +- .../solidity/HttpApiOnSolidityService.java | 32 +- .../jsonrpc/FullNodeJsonRpcHttpService.java | 26 +- .../core/services/jsonrpc/JsonRpcServlet.java | 9 +- .../services/jsonrpc/TronJsonRpcImpl.java | 15 +- .../ratelimiter/RateLimiterInterceptor.java | 7 +- .../adapter/GlobalPreemptibleAdapter.java | 1 - .../ratelimiter/strategy/QpsStrategy.java | 5 +- .../java/org/tron/core/trie/TrieImpl.java | 6 +- .../org/tron/core/zen/ZksnarkInitService.java | 65 + .../org/tron/core/zen/ZksnarkService.java | 16 - .../java/org/tron/keystore/Credentials.java | 6 +- .../main/java/org/tron/program/FullNode.java | 52 +- .../java/org/tron/program/SolidityNode.java | 13 +- .../main/java/org/tron/program/Version.java | 6 +- .../tool/litefullnode/LiteFullNodeTool.java | 3 + framework/src/main/resources/config.conf | 39 +- .../test/java/org/tron/common/BaseTest.java | 39 +- .../java/org/tron/common/ComparatorTest.java | 2 +- .../tron/common/backup/BackupServerTest.java | 44 + .../common/backup/KeepAliveMessageTest.java | 6 +- .../common/backup/UdpMessageTypeEnumTest.java | 2 +- .../org/tron/common/config/args/ArgsTest.java | 36 +- .../tron/common/crypto/BouncyCastleTest.java | 18 + .../logsfilter/EventParserJsonTest.java | 2 +- .../common/logsfilter/EventParserTest.java | 4 +- .../TransactionLogTriggerCapsuleTest.java | 178 ++ .../tron/common/runtime/InheritanceTest.java | 5 +- .../InternalTransactionComplexTest.java | 5 +- .../common/runtime/ProgramResultTest.java | 52 +- .../tron/common/runtime/RuntimeImplTest.java | 5 +- .../runtime/RuntimeTransferComplexTest.java | 5 +- .../runtime/vm/AllowTvmCompatibleEvmTest.java | 8 +- .../common/runtime/vm/AllowTvmLondonTest.java | 4 +- .../vm/BandWidthRuntimeOutOfTimeTest.java | 3 +- ...andWidthRuntimeOutOfTimeWithCheckTest.java | 3 +- .../runtime/vm/BandWidthRuntimeTest.java | 3 +- .../vm/BandWidthRuntimeWithCheckTest.java | 3 +- .../tron/common/runtime/vm/BatchSendTest.java | 3 +- .../vm/BatchValidateSignContractTest.java | 6 +- .../tron/common/runtime/vm/ChargeTest.java | 5 +- .../tron/common/runtime/vm/Create2Test.java | 7 +- .../runtime/vm/CreateContractSuicideTest.java | 2 +- .../runtime/vm/EnergyWhenAssertStyleTest.java | 5 +- .../vm/EnergyWhenRequireStyleTest.java | 5 +- .../vm/EnergyWhenSendAndTransferTest.java | 5 +- .../vm/EnergyWhenTimeoutStyleTest.java | 5 +- .../common/runtime/vm/ExtCodeHashTest.java | 2 +- .../tron/common/runtime/vm/FreezeTest.java | 16 +- .../tron/common/runtime/vm/FreezeV2Test.java | 52 +- .../vm/InternalTransactionCallTest.java | 21 +- .../common/runtime/vm/IsContractTest.java | 2 +- .../common/runtime/vm/IsSRCandidateTest.java | 2 +- .../tron/common/runtime/vm/IstanbulTest.java | 2 +- .../tron/common/runtime/vm/MemoryTest.java | 2 +- .../common/runtime/vm/OperationsTest.java | 6 +- .../runtime/vm/PrecompiledContractsTest.java | 3 +- .../PrecompiledContractsVerifyProofTest.java | 7 +- .../common/runtime/vm/RepositoryTest.java | 31 +- .../common/runtime/vm/RewardBalanceTest.java | 2 +- .../tron/common/runtime/vm/StorageTest.java | 2 +- .../common/runtime/vm/TimeBenchmarkTest.java | 5 +- .../runtime/vm/TransferFailedEnergyTest.java | 10 +- .../runtime/vm/TransferToAccountTest.java | 3 +- .../common/runtime/vm/TransferTokenTest.java | 7 +- .../common/runtime/vm/VMContractTestBase.java | 20 +- .../tron/common/runtime/vm/VMTestBase.java | 21 +- .../vm/ValidateMultiSignContractTest.java | 15 +- .../org/tron/common/runtime/vm/VoteTest.java | 14 +- .../leveldb/LevelDbDataSourceImplTest.java | 53 +- .../leveldb/RocksDbDataSourceImplTest.java | 60 +- .../common/utils/client/utils/HttpMethed.java | 10 +- .../org/tron/core/BandwidthProcessorTest.java | 3 +- .../org/tron/core/EnergyProcessorTest.java | 3 +- .../org/tron/core/ForkControllerTest.java | 15 +- .../java/org/tron/core/ShieldWalletTest.java | 383 +++ .../tron/core/ShieldedTRC20BuilderTest.java | 7 +- .../java/org/tron/core/StorageMarketTest.java | 3 +- .../test/java/org/tron/core/WalletTest.java | 178 +- .../AccountPermissionUpdateActuatorTest.java | 7 +- .../core/actuator/ActuatorConstantTest.java | 3 +- .../core/actuator/AssetIssueActuatorTest.java | 5 +- .../CancelAllUnfreezeV2ActuatorTest.java | 3 +- .../ClearABIContractActuatorTest.java | 3 +- .../actuator/CreateAccountActuatorTest.java | 5 +- .../DelegateResourceActuatorTest.java | 89 +- .../actuator/ExchangeCreateActuatorTest.java | 5 +- .../actuator/ExchangeInjectActuatorTest.java | 5 +- .../ExchangeTransactionActuatorTest.java | 5 +- .../ExchangeWithdrawActuatorTest.java | 5 +- .../actuator/FreezeBalanceActuatorTest.java | 132 +- .../actuator/FreezeBalanceV2ActuatorTest.java | 77 +- .../MarketCancelOrderActuatorTest.java | 19 +- .../actuator/MarketSellAssetActuatorTest.java | 5 +- .../ParticipateAssetIssueActuatorTest.java | 3 +- .../actuator/ProposalApproveActuatorTest.java | 3 +- .../actuator/ProposalCreateActuatorTest.java | 3 +- .../actuator/ProposalDeleteActuatorTest.java | 3 +- .../actuator/SetAccountIdActuatorTest.java | 3 +- .../ShieldedTransferActuatorTest.java | 7 +- .../core/actuator/TransferActuatorTest.java | 3 +- .../actuator/TransferAssetActuatorTest.java | 3 +- .../UnDelegateResourceActuatorTest.java | 3 +- .../actuator/UnfreezeAssetActuatorTest.java | 3 +- .../actuator/UnfreezeBalanceActuatorTest.java | 190 +- .../UnfreezeBalanceV2ActuatorTest.java | 6 +- .../actuator/UpdateAccountActuatorTest.java | 3 +- .../actuator/UpdateAssetActuatorTest.java | 3 +- .../actuator/UpdateBrokerageActuatorTest.java | 3 +- ...UpdateEnergyLimitContractActuatorTest.java | 3 +- .../UpdateSettingContractActuatorTest.java | 3 +- .../actuator/VoteWitnessActuatorTest.java | 3 +- .../actuator/WithdrawBalanceActuatorTest.java | 3 +- .../WithdrawExpireUnfreezeActuatorTest.java | 3 +- .../actuator/WitnessCreateActuatorTest.java | 3 +- .../actuator/WitnessUpdateActuatorTest.java | 3 +- .../core/actuator/utils/ProposalUtilTest.java | 3 +- .../actuator/utils/TransactionUtilTest.java | 280 ++- .../actuator/vm/ProgramTraceListenerTest.java | 14 +- .../core/actuator/vm/ProgramTraceTest.java | 15 +- .../tron/core/capsule/AccountCapsuleTest.java | 3 +- .../tron/core/capsule/BlockCapsuleTest.java | 32 +- .../core/capsule/ExchangeCapsuleTest.java | 3 +- .../core/capsule/TransactionCapsuleTest.java | 5 +- .../tron/core/capsule/VotesCapsuleTest.java | 16 +- .../core/capsule/utils/AssetUtilTest.java | 3 +- .../capsule/utils/ExchangeProcessorTest.java | 3 +- .../org/tron/core/config/args/ArgsTest.java | 45 +- .../core/config/args/DynamicArgsTest.java | 12 +- .../java/org/tron/core/db/AbiStoreTest.java | 61 + .../tron/core/db/AccountAssetStoreTest.java | 138 ++ .../tron/core/db/AccountIdIndexStoreTest.java | 3 +- .../tron/core/db/AccountIndexStoreTest.java | 3 +- .../org/tron/core/db/AccountStoreTest.java | 3 +- .../tron/core/db/AccountTraceStoreTest.java | 57 + .../org/tron/core/db/AssetIssueStoreTest.java | 90 + .../tron/core/db/AssetIssueV2StoreTest.java | 91 + .../tron/core/db/BalanceTraceStoreTest.java | 131 ++ .../db/BandwidthPriceHistoryLoaderTest.java | 18 +- .../java/org/tron/core/db/BlockStoreTest.java | 3 +- .../tron/core/db/ByteArrayWrapperTest.java | 2 +- .../java/org/tron/core/db/CodeStoreTest.java | 74 + .../org/tron/core/db/ContractStoreTest.java | 101 + ...elegatedResourceAccountIndexStoreTest.java | 150 ++ .../core/db/DelegatedResourceStoreTest.java | 71 + .../org/tron/core/db/DelegationStoreTest.java | 71 + .../core/db/EnergyPriceHistoryLoaderTest.java | 3 +- .../org/tron/core/db/ExchangeStoreTest.java | 62 + .../org/tron/core/db/ExchangeV2StoreTest.java | 44 + .../db/IncrementalMerkleTreeStoreTest.java | 51 + .../org/tron/core/db/KhaosDatabaseTest.java | 10 +- .../java/org/tron/core/db/ManagerTest.java | 33 +- .../tron/core/db/MarketAccountStoreTest.java | 37 + .../tron/core/db/MarketOrderStoreTest.java | 47 + .../db/MarketPairPriceToOrderStoreTest.java | 3 +- .../core/db/MarketPairToPriceStoreTest.java | 83 + .../org/tron/core/db/NullifierStoreTest.java | 6 +- .../org/tron/core/db/ProposalStoreTest.java | 72 + .../tron/core/db/TransactionExpireTest.java | 69 +- .../tron/core/db/TransactionHistoryTest.java | 3 +- .../tron/core/db/TransactionRetStoreTest.java | 4 +- .../tron/core/db/TransactionStoreTest.java | 4 +- .../tron/core/db/TransactionTraceTest.java | 3 +- .../tron/core/db/TreeBlockIndexStoreTest.java | 52 + .../org/tron/core/db/TronDatabaseTest.java | 101 + .../org/tron/core/db/TxCacheDBInitTest.java | 103 + .../java/org/tron/core/db/TxCacheDBTest.java | 7 +- .../java/org/tron/core/db/VotesStoreTest.java | 3 +- .../core/db/WitnessScheduleStoreTest.java | 105 + .../org/tron/core/db/WitnessStoreTest.java | 3 +- .../core/db/api/AssetUpdateHelperTest.java | 3 +- .../tron/core/db/backup/BackupDbUtilTest.java | 4 +- .../java/org/tron/core/db2/ChainbaseTest.java | 18 +- .../org/tron/core/db2/SnapshotImplTest.java | 201 ++ .../org/tron/core/db2/SnapshotRootTest.java | 2 +- .../java/org/tron/core/jsonrpc/BloomTest.java | 2 +- .../core/jsonrpc/BuildTransactionTest.java | 3 +- .../tron/core/jsonrpc/JsonrpcServiceTest.java | 27 +- .../core/jsonrpc/SectionBloomStoreTest.java | 5 +- .../tron/core/jsonrpc/WalletCursorTest.java | 3 +- .../core/metrics/MetricsApiServiceTest.java | 14 +- .../prometheus/PrometheusApiServiceTest.java | 3 +- .../test/java/org/tron/core/net/BaseNet.java | 32 +- .../messagehandler/BlockMsgHandlerTest.java | 3 +- .../FetchInvDataMsgHandlerTest.java | 60 + .../messagehandler/MessageHandlerTest.java | 13 +- .../PbftDataSyncHandlerTest.java | 57 + .../messagehandler/PbftMsgHandlerTest.java | 121 + .../SyncBlockChainMsgHandlerTest.java | 29 +- .../TransactionsMsgHandlerTest.java | 84 + .../core/net/peer/PeerConnectionTest.java | 279 +++ .../tron/core/net/peer/PeerManagerTest.java | 138 ++ .../core/net/services/AdvServiceTest.java | 86 +- .../services/EffectiveCheckServiceTest.java | 16 +- .../net/services/HandShakeServiceTest.java | 16 +- .../core/net/services/RelayServiceTest.java | 3 +- .../core/net/services/SyncServiceTest.java | 19 +- .../java/org/tron/core/pbft/PbftApiTest.java | 4 +- .../core/services/NodeInfoServiceTest.java | 18 + .../core/services/ProposalServiceTest.java | 3 +- .../core/services/RpcApiServicesTest.java | 1213 ++++++++++ .../org/tron/core/services/WalletApiTest.java | 17 +- .../filter/HttpApiAccessFilterTest.java | 16 +- .../LiteFnQueryGrpcInterceptorTest.java | 94 +- .../filter/LiteFnQueryHttpFilterTest.java | 16 +- .../filter/RpcApiAccessInterceptorTest.java | 183 +- .../services/http/BroadcastServletTest.java | 11 +- .../http/GetAssetIssueListServletTest.java | 82 + .../http/GetBandwidthPricesServletTest.java | 57 + .../http/GetBrokerageServletTest.java | 109 + .../http/GetEnergyPricesServletTest.java | 57 + .../http/GetMemoFeePricesServletTest.java | 57 + .../services/http/GetNowBlockServletTest.java | 121 + .../services/http/GetRewardServletTest.java | 139 ++ .../services/http/ListNodesServletTest.java | 82 + .../http/ListProposalsServletTest.java | 82 + .../http/TriggerSmartContractServletTest.java | 8 +- .../org/tron/core/services/http/UtilTest.java | 62 +- ...GetTransactionByIdSolidityServletTest.java | 6 +- .../GetBandwidthPricesOnPBFTServletTest.java | 57 + .../GetEnergyPricesOnPBFTServletTest.java | 57 + ...tBandwidthPricesOnSolidityServletTest.java | 57 + .../GetEnergyPricesOnSolidityServletTest.java | 57 + .../services/stop/BlockHeightStopTest.java | 6 - .../services/stop/BlockSyncCountStopTest.java | 6 - .../core/services/stop/BlockTimeStopTest.java | 6 - .../services/stop/ConditionallyStopTest.java | 11 +- .../core/witness/ProposalControllerTest.java | 5 +- .../core/witness/WitnessControllerTest.java | 3 +- .../tron/core/zksnark/LibrustzcashTest.java | 7 +- .../core/zksnark/MerkleContainerTest.java | 4 +- .../org/tron/core/zksnark/MerkleTreeTest.java | 5 +- .../tron/core/zksnark/NoteEncDecryTest.java | 3 +- .../tron/core/zksnark/SaplingNoteTest.java | 6 +- .../tron/core/zksnark/SendCoinShieldTest.java | 9 +- .../core/zksnark/ShieldedReceiveTest.java | 23 +- .../org/tron/keystore/WalletFileTest.java | 61 +- .../org/tron/keystroe/CredentialsTest.java | 34 + .../tron/program/AccountVoteWitnessTest.java | 3 +- .../tron/program/LiteFullNodeToolTest.java | 8 +- .../org/tron/program/SolidityNodeTest.java | 43 +- .../java/org/tron/program/SupplementTest.java | 20 +- framework/src/test/resources/config-test.conf | 3 + framework/src/test/resources/daily-build.xml | 16 - .../src/test/resources/solcDir/README.txt | 1 - framework/src/test/resources/solidityFile.xml | 81 - .../soliditycode/AssertException002.sol | 17 - .../soliditycode/AssignToExternal.sol | 30 - .../test/resources/soliditycode/BlockHash.sol | 38 - .../resources/soliditycode/ClearAbi001.sol | 7 - .../resources/soliditycode/ClearAbi005.sol | 26 - .../soliditycode/ConstructorDefaults.sol | 9 - .../resources/soliditycode/Create2Test023.sol | 31 - .../resources/soliditycode/Create2Test024.sol | 56 - .../resources/soliditycode/Create2Test025.sol | 34 - .../resources/soliditycode/EthGrammer.sol | 191 -- .../resources/soliditycode/EthGrammer02.sol | 45 - .../soliditycode/ExtCodeHashTest010.sol | 46 - .../soliditycode/ExternalSelector.sol | 92 - .../resources/soliditycode/NewFeature068.sol | 131 -- .../resources/soliditycode/NewFeature076.sol | 21 - .../resources/soliditycode/NewFeature080.sol | 109 - .../resources/soliditycode/NewFeature0811.sol | 101 - .../resources/soliditycode/NewFeature086.sol | 121 - .../test/resources/soliditycode/NoAbi001.sol | 10 - .../test/resources/soliditycode/NoAbi002.sol | 29 - .../resources/soliditycode/ParentTypeBug.sol | 13 - .../test/resources/soliditycode/SafeMath.sol | 149 -- .../soliditycode/ShiftCommand001.sol | 18 - .../soliditycode/SolidityMappingFix.sol | 9 - .../soliditycode/TestMappings_array_pop.sol | 19 - .../soliditycode/TransferFailed001.sol | 147 -- .../soliditycode/TransferFailed005.sol | 90 - .../soliditycode/TransferFailed006.sol | 90 - .../soliditycode/TransferFailed007.sol | 90 - .../soliditycode/TriggerConstant001.sol | 28 - .../soliditycode/TriggerConstant002.sol | 10 - .../soliditycode/TriggerConstant003.sol | 18 - .../soliditycode/TriggerConstant004.sol | 8 - .../soliditycode/TriggerConstant015.sol | 24 - .../soliditycode/TriggerConstant024.sol | 9 - .../resources/soliditycode/TvmIsContract.sol | 15 - .../soliditycode/TvmIsContract001.sol | 24 - .../soliditycode/TvmIsContract002.sol | 5 - .../soliditycode/TvmNewCommand043.sol | 18 - .../soliditycode/TvmNewCommand103.sol | 8 - .../soliditycode/TvmNewCommand107.sol | 9 - .../soliditycode/TvmNewCommand108.sol | 7 - .../soliditycode/TvmNewCommand109.sol | 7 - .../soliditycode/TvmOldCommand001.sol | 11 - .../soliditycode/VerifyBurnProof001.sol | 20 - .../soliditycode/VerifyMintProof001.sol | 33 - .../test/resources/soliditycode/abiencode.sol | 16 - .../resources/soliditycode/abstract001.sol | 11 - .../resources/soliditycode/abstract002.sol | 13 - ...stractContractWithMapParamsConstructor.sol | 23 - .../resources/soliditycode/accountAssert.sol | 94 - .../soliditycode/addMsg001Nonpayable.sol | 20 - .../resources/soliditycode/addMsg002View.sol | 20 - .../soliditycode/addMsg003Constant.sol | 19 - .../resources/soliditycode/addMsg004Pure.sol | 19 - .../addTransferToken001Nonpayable.sol | 13 - .../addTransferToken001payable.sol | 13 - .../soliditycode/addTransferToken002View.sol | 15 - .../addTransferToken003Constant.sol | 14 - .../soliditycode/addTransferToken004Pure.sol | 15 - .../soliditycode/addTrcToken001Assemble.sol | 62 - .../soliditycode/addTrcToken002Cat.sol | 2051 ---------------- .../addTrcToken002Cat_withFinny.sol | 2051 ---------------- .../soliditycode/addressCheckNew.sol | 9 - .../soliditycode/addressCheckOld.sol | 8 - .../src/test/resources/soliditycode/altbn.sol | 61 - .../resources/soliditycode/arrayLength001.sol | 64 - .../resources/soliditycode/assemblyTest.sol | 61 - .../assertExceptiontest1DivideInt.sol | 7 - ...tExceptiontest2FindArgsContractMinTest.sol | 10 - .../assertExceptiontest3ByteMinContract.sol | 11 - .../soliditycode/assertExceptiontest4Enum.sol | 13 - .../assertExceptiontest5MoveRight.sol | 7 - ...ertExceptiontest6UninitializedContract.sol | 27 - ...assertExceptiontest7TestAssertContract.sol | 14 - .../soliditycode/batchvalidatesign.sol | 14 - .../soliditycode/batchvalidatesign001.sol | 10 - .../soliditycode/batchvalidatesign002.sol | 8 - .../soliditycode/batchvalidatesign003.sol | 11 - .../soliditycode/batchvalidatesign005.sol | 14 - .../soliditycode/batchvalidatesign007.sol | 17 - .../soliditycode/batchvalidatesign02.sol | 8 - .../soliditycode/callValueGasPure.sol | 8 - .../test/resources/soliditycode/calldata.sol | 33 - .../test/resources/soliditycode/callvalue.sol | 9 - .../resources/soliditycode/chainid001.sol | 19 - .../soliditycode/codeSaftySupport.sol | 19 - .../soliditycode/codeSaftyUnsupport.sol | 56 - .../soliditycode/constantCallStorage001.sol | 159 -- .../soliditycode/constantCallStorage002.sol | 16 - .../soliditycode/constantCallStorage0425.sol | 156 -- .../soliditycode/constantContract001.sol | 8 - .../soliditycode/contractGetterContract.sol | 17 - .../contractGrammar001test1Grammar001.sol | 18 - .../contractGrammar001test2Grammar002.sol | 44 - .../contractGrammar001test3Grammar003.sol | 44 - .../contractGrammar001test4Grammar004.sol | 31 - .../contractGrammar001test5Grammar006.sol | 45 - .../contractGrammar002test1Grammar007_1.sol | 60 - .../contractGrammar002test1Grammar007_2.sol | 60 - .../contractGrammar002test2Grammar008.sol | 18 - .../contractGrammar002test3Grammar010.sol | 10 - .../contractGrammar002test4Grammar011.sol | 11 - .../contractGrammar002test4Grammar012.sol | 24 - .../contractGrammar002test6Grammar013.sol | 24 - .../contractGrammar003test1Grammar014.sol | 67 - .../contractGrammar003test2Grammar015.sol | 40 - .../contractGrammar003test3Grammar016.sol | 23 - .../contractGrammar003test4Grammar017.sol | 51 - .../contractGrammar003test5Grammar018.sol | 37 - .../contractGrammar003test6Grammar019.sol | 12 - .../contractGrammar003test7Grammar020.sol | 8 - .../soliditycode/contractInnerContract.sol | 32 - ...ansaction001testInternalTransaction001.sol | 41 - ...ansaction001testInternalTransaction002.sol | 20 - ...ansaction001testInternalTransaction003.sol | 30 - ...ansaction001testInternalTransaction004.sol | 24 - ...ansaction001testInternalTransaction005.sol | 53 - ...ansaction001testInternalTransaction006.sol | 54 - ...nsaction002test1InternalTransaction007.sol | 38 - ...nsaction002test2InternalTransaction008.sol | 60 - ...nsaction002test3InternalTransaction009.sol | 47 - ...nsaction002test4InternalTransaction010.sol | 186 -- ...action002test4InternalTransaction010_1.sol | 210 -- ...nsaction002test5InternalTransaction012.sol | 51 - ...ansaction003testInternalTransaction013.sol | 56 - ...ansaction003testInternalTransaction014.sol | 38 - ...ansaction003testInternalTransaction015.sol | 60 - ...ansaction003testInternalTransaction016.sol | 174 -- ...ansaction003testInternalTransaction017.sol | 199 -- ...ansaction003testInternalTransaction018.sol | 97 - .../soliditycode/contractLinkage001.sol | 9 - .../soliditycode/contractLinkage002.sol | 7 - .../soliditycode/contractLinkage003.sol | 7 - .../soliditycode/contractLinkage004.sol | 7 - .../soliditycode/contractLinkage005.sol | 51 - .../soliditycode/contractLinkage006.sol | 18 - .../contractOriginEnergyLimit001.sol | 11 - .../contractOriginEnergyLimit004.sol | 11 - .../soliditycode/contractOtherToTrcToken.sol | 41 - .../soliditycode/contractScenario001.sol | 7 - .../soliditycode/contractScenario002.sol | 53 - .../soliditycode/contractScenario003.sol | 7 - .../soliditycode/contractScenario004.sol | 88 - .../soliditycode/contractScenario005.sol | 103 - .../soliditycode/contractScenario006.sol | 1963 ---------------- .../soliditycode/contractScenario007.sol | 1432 ------------ .../soliditycode/contractScenario008.sol | 2061 ----------------- .../soliditycode/contractScenario009.sol | 51 - .../soliditycode/contractScenario010.sol | 107 - .../soliditycode/contractScenario011.sol | 2060 ---------------- .../soliditycode/contractScenario012.sol | 57 - .../soliditycode/contractScenario013.sol | 8 - .../soliditycode/contractScenario014.sol | 34 - .../resources/soliditycode/contractTest.sol | 19 - .../soliditycode/contractToMathedFeed.sol | 21 - .../soliditycode/contractTransferToken001.sol | 22 - .../soliditycode/contractTrc1155.sol | 612 ----- .../soliditycode/contractTrcToken001.sol | 41 - .../soliditycode/contractTrcToken002.sol | 30 - .../soliditycode/contractTrcToken003.sol | 16 - .../soliditycode/contractTrcToken005.sol | 16 - .../soliditycode/contractTrcToken011.sol | 35 - .../soliditycode/contractTrcToken012.sol | 26 - .../soliditycode/contractTrcToken014.sol | 34 - .../soliditycode/contractTrcToken018.sol | 26 - .../soliditycode/contractTrcToken023.sol | 26 - .../soliditycode/contractTrcToken026.sol | 31 - .../soliditycode/contractTrcToken027.sol | 30 - .../soliditycode/contractTrcToken028.sol | 25 - .../soliditycode/contractTrcToken029.sol | 24 - .../soliditycode/contractTrcToken030.sol | 17 - .../soliditycode/contractTrcToken031.sol | 18 - .../soliditycode/contractTrcToken034.sol | 25 - .../soliditycode/contractTrcToken035.sol | 24 - .../soliditycode/contractTrcToken036.sol | 52 - .../soliditycode/contractTrcToken036_1.sol | 13 - .../soliditycode/contractTrcToken036_2.sol | 13 - .../soliditycode/contractTrcToken036_3.sol | 13 - .../soliditycode/contractTrcToken036_4.sol | 13 - .../soliditycode/contractTrcToken036_old.sol | 41 - .../soliditycode/contractTrcToken037.sol | 24 - .../soliditycode/contractTrcToken038.sol | 24 - .../soliditycode/contractTrcToken039.sol | 44 - .../soliditycode/contractTrcToken041.sol | 20 - .../soliditycode/contractTrcToken043.sol | 35 - .../soliditycode/contractTrcToken048.sol | 14 - .../soliditycode/contractTrcToken049.sol | 9 - .../soliditycode/contractTrcToken050.sol | 10 - .../soliditycode/contractTrcToken051.sol | 11 - .../soliditycode/contractTrcToken052.sol | 10 - .../soliditycode/contractTrcToken054.sol | 16 - .../soliditycode/contractTrcToken055.sol | 16 - .../soliditycode/contractTrcToken060.sol | 30 - .../soliditycode/contractTrcToken061.sol | 30 - .../soliditycode/contractTrcToken064.sol | 49 - .../soliditycode/contractTrcToken066.sol | 35 - .../soliditycode/contractTrcToken067.sol | 35 - .../soliditycode/contractTrcToken073.sol | 16 - .../soliditycode/contractTrcToken075.sol | 26 - .../soliditycode/contractTrcToken076.sol | 19 - .../soliditycode/contractTrcToken077.sol | 11 - .../soliditycode/contractTrcToken078.sol | 35 - .../soliditycode/contractTrcToken079.sol | 16 - .../soliditycode/contractTrcToken080.sol | 30 - .../soliditycode/contractTrcToken081.sol | 51 - .../soliditycode/contractTrcTokenToOther.sol | 44 - .../soliditycode/contractUnknownException.sol | 64 - .../soliditycode/create2CallContract.sol | 37 - .../soliditycode/create2Istanbul.sol | 28 - .../soliditycode/create2contract.sol | 52 - .../soliditycode/create2contract22.sol | 109 - .../soliditycode/create2contractn.sol | 29 - .../soliditycode/create2contractn2.sol | 26 - .../src/test/resources/soliditycode/demo.sol | 73 - .../resources/soliditycode/enumAndStruct.sol | 43 - .../test/resources/soliditycode/event001.sol | 10 - .../test/resources/soliditycode/event002.sol | 52 - .../test/resources/soliditycode/eventLog2.sol | 8 - .../resources/soliditycode/extCodeHash.sol | 13 - .../resources/soliditycode/extCodeHash11.sol | 103 - .../soliditycode/extCodeHashConstruct.sol | 14 - .../soliditycode/extCodeHashStress.sol | 45 - .../soliditycode/extCodeHashTestNoPayable.sol | 8 - .../soliditycode/fallbackUpgrade.sol | 83 - .../soliditycode/freezeContract001.sol | 63 - .../function_type_array_to_storage.sol | 45 - .../soliditycode/getAddressChange.sol | 12 - .../resources/soliditycode/isSRCandidate.sol | 35 - .../resources/soliditycode/mappingGetter.sol | 4 - .../multiValiSignPerformance01.sol | 37 - .../multiValiSignPerformance02.sol | 10 - .../soliditycode/multivalidatesign.sol | 14 - .../soliditycode/multivalidatesign001.sol | 10 - .../soliditycode/multivalidatesign002.sol | 8 - .../soliditycode/multivalidatesign003.sol | 11 - .../soliditycode/multivalidatesign005.sol | 14 - .../soliditycode/multivalidatesign007.sol | 17 - .../soliditycode/multivalidatesign02.sol | 8 - .../resources/soliditycode/negativeArray.sol | 21 - .../test/resources/soliditycode/opCode.sol | 112 - .../resources/soliditycode/override002.sol | 12 - .../resources/soliditycode/override003.sol | 20 - .../resources/soliditycode/override004.sol | 25 - .../resources/soliditycode/override005.sol | 39 - .../soliditycode/overridePrivateFunction.sol | 22 - .../resources/soliditycode/payable001.sol | 31 - .../soliditycode/pedersenHash001.sol | 18 - .../soliditycode/pedersenHash002.sol | 320 --- ...quireExceptiontest1TestRequireContract.sol | 15 - ...equireExceptiontest2TestThrowsContract.sol | 15 - ...equireExceptiontest3TestRevertContract.sol | 15 - ...requireExceptiontest4noPayableContract.sol | 8 - ...quireExceptiontest4noPayableContract_1.sol | 8 - ...uireExceptiontest5noPayableConstructor.sol | 11 - ...reExceptiontest5noPayableConstructor_1.sol | 11 - ...uireExceptiontest6transferTestContract.sol | 8 - ...reExceptiontest7payableFallbakContract.sol | 14 - ...reExceptiontest8newContractGasNoenough.sol | 19 - ...uireExceptiontest9MessageUsedErrorFeed.sol | 18 - ...uireExceptiontestFunctionUsedErrorFeed.sol | 17 - .../test/resources/soliditycode/selector.sol | 21 - .../soliditycode/slotAndOffsetNewGrammer.sol | 32 - .../soliditycode/stackContract001.sol | 61 - .../soliditycode/stackSuicide001.sol | 84 - .../soliditycode/stateVariableShadowing.sol | 21 - .../resources/soliditycode/stringSplit.sol | 45 - .../resources/soliditycode/suicide001.sol | 32 - .../resources/soliditycode/suicide002.sol | 43 - ...kip_unimplemented_in_abstract_contract.sol | 22 - .../soliditycode/testGetFilterChange.sol | 11 - .../resources/soliditycode/testOutOfMem.sol | 7 - .../soliditycode/testStakeSuicide.sol | 71 - .../resources/soliditycode/tryCatch001.sol | 105 - .../soliditycode/tvmAssetIssue001.sol | 25 - .../soliditycode/tvmAssetIssue002.sol | 15 - .../soliditycode/tvmAssetIssue003.sol | 23 - .../soliditycode/tvmAssetIssue004.sol | 39 - .../soliditycode/tvmAssetIssue005.sol | 45 - .../test/resources/soliditycode/tvmVote.sol | 89 - .../test/resources/soliditycode/typeName.sol | 5 - .../resources/soliditycode/unStake001.sol | 90 - .../soliditycode/validatemultisign001.sol | 15 - .../soliditycode/verifyTransferProof001.sol | 15 - .../resources/soliditycode/virtual001.sol | 19 - .../soliditycode/walletTestMutiSign004.sol | 51 - .../AssertException002.sol | 17 - .../soliditycode_0.5.15/AssignToExternal.sol | 30 - .../soliditycode_0.5.15/BlockHash.sol | 38 - .../soliditycode_0.5.15/ClearAbi001.sol | 7 - .../soliditycode_0.5.15/ClearAbi005.sol | 26 - .../ConstructorDefaults.sol | 9 - .../soliditycode_0.5.15/Create2Test023.sol | 31 - .../soliditycode_0.5.15/Create2Test024.sol | 56 - .../soliditycode_0.5.15/Create2Test025.sol | 34 - .../ExtCodeHashTest010.sol | 46 - .../soliditycode_0.5.15/ParentTypeBug.sol | 13 - .../soliditycode_0.5.15/SafeMath.sol | 149 -- .../soliditycode_0.5.15/ShiftCommand001.sol | 18 - .../SolidityMappingFix.sol | 9 - .../TestMappings_array_pop.sol | 19 - .../soliditycode_0.5.15/TransferFailed001.sol | 147 -- .../soliditycode_0.5.15/TransferFailed005.sol | 90 - .../soliditycode_0.5.15/TransferFailed006.sol | 90 - .../soliditycode_0.5.15/TransferFailed007.sol | 90 - .../TriggerConstant001.sol | 28 - .../TriggerConstant002.sol | 10 - .../TriggerConstant003.sol | 18 - .../TriggerConstant004.sol | 8 - .../TriggerConstant015.sol | 24 - .../TriggerConstant024.sol | 9 - .../soliditycode_0.5.15/TvmIsContract.sol | 15 - .../soliditycode_0.5.15/TvmIsContract001.sol | 24 - .../soliditycode_0.5.15/TvmIsContract002.sol | 5 - .../soliditycode_0.5.15/TvmNewCommand043.sol | 18 - .../soliditycode_0.5.15/TvmNewCommand103.sol | 8 - .../soliditycode_0.5.15/TvmNewCommand107.sol | 9 - .../soliditycode_0.5.15/TvmNewCommand108.sol | 7 - .../soliditycode_0.5.15/TvmNewCommand109.sol | 7 - .../soliditycode_0.5.15/TvmOldCommand001.sol | 11 - .../VerifyBurnProof001.sol | 20 - .../VerifyMintProof001.sol | 33 - .../soliditycode_0.5.15/abiencode.sol | 16 - .../addMsg001Nonpayable.sol | 20 - .../soliditycode_0.5.15/addMsg002View.sol | 20 - .../soliditycode_0.5.15/addMsg003Constant.sol | 19 - .../soliditycode_0.5.15/addMsg004Pure.sol | 19 - .../addTransferToken001Nonpayable.sol | 13 - .../addTransferToken001payable.sol | 13 - .../addTransferToken002View.sol | 15 - .../addTransferToken003Constant.sol | 15 - .../addTransferToken004Pure.sol | 15 - .../addTrcToken001Assemble.sol | 62 - .../soliditycode_0.5.15/addTrcToken002Cat.sol | 2051 ---------------- .../addTrcToken002Cat_withFinny.sol | 2051 ---------------- .../soliditycode_0.5.15/addressCheckNew.sol | 9 - .../soliditycode_0.5.15/addressCheckOld.sol | 8 - .../resources/soliditycode_0.5.15/altbn.sol | 63 - .../soliditycode_0.5.15/arrayLength001.sol | 16 - .../soliditycode_0.5.15/assemblyTest.sol | 62 - .../assertExceptiontest1DivideInt.sol | 7 - ...tExceptiontest2FindArgsContractMinTest.sol | 10 - .../assertExceptiontest3ByteMinContract.sol | 11 - .../assertExceptiontest4Enum.sol | 13 - .../assertExceptiontest5MoveRight.sol | 7 - ...ertExceptiontest6UninitializedContract.sol | 27 - ...assertExceptiontest7TestAssertContract.sol | 15 - .../soliditycode_0.5.15/batchvalidatesign.sol | 14 - .../batchvalidatesign001.sol | 10 - .../batchvalidatesign002.sol | 8 - .../batchvalidatesign003.sol | 11 - .../batchvalidatesign005.sol | 14 - .../batchvalidatesign007.sol | 17 - .../batchvalidatesign02.sol | 8 - .../soliditycode_0.5.15/callValueGasPure.sol | 8 - .../soliditycode_0.5.15/calldata.sol | 33 - .../soliditycode_0.5.15/callvalue.sol | 9 - .../soliditycode_0.5.15/chainid001.sol | 20 - .../soliditycode_0.5.15/codeSaftySupport.sol | 19 - .../codeSaftyUnsupport.sol | 56 - .../constantCallStorage001.sol | 159 -- .../constantCallStorage002.sol | 16 - .../constantCallStorage0425.sol | 156 -- .../constantContract001.sol | 8 - .../contractGetterContract.sol | 17 - .../contractGrammar001test1Grammar001.sol | 18 - .../contractGrammar001test2Grammar002.sol | 44 - .../contractGrammar001test3Grammar003.sol | 44 - .../contractGrammar001test4Grammar004.sol | 31 - .../contractGrammar001test5Grammar006.sol | 38 - .../contractGrammar002test1Grammar007_1.sol | 60 - .../contractGrammar002test1Grammar007_2.sol | 60 - .../contractGrammar002test2Grammar008.sol | 14 - .../contractGrammar002test3Grammar010.sol | 10 - .../contractGrammar002test4Grammar011.sol | 11 - .../contractGrammar002test4Grammar012.sol | 24 - .../contractGrammar002test6Grammar013.sol | 24 - .../contractGrammar003test1Grammar014.sol | 68 - .../contractGrammar003test2Grammar015.sol | 39 - .../contractGrammar003test3Grammar016.sol | 23 - .../contractGrammar003test4Grammar017.sol | 50 - .../contractGrammar003test5Grammar018.sol | 37 - .../contractGrammar003test6Grammar019.sol | 12 - .../contractGrammar003test7Grammar020.sol | 8 - .../contractInnerContract.sol | 32 - ...ansaction001testInternalTransaction001.sol | 42 - ...ansaction001testInternalTransaction002.sol | 21 - ...ansaction001testInternalTransaction003.sol | 31 - ...ansaction001testInternalTransaction004.sol | 25 - ...ansaction001testInternalTransaction005.sol | 54 - ...ansaction001testInternalTransaction006.sol | 54 - ...nsaction002test1InternalTransaction007.sol | 38 - ...nsaction002test2InternalTransaction008.sol | 60 - ...nsaction002test3InternalTransaction009.sol | 47 - ...nsaction002test4InternalTransaction010.sol | 186 -- ...action002test4InternalTransaction010_1.sol | 210 -- ...nsaction002test5InternalTransaction012.sol | 51 - ...ansaction003testInternalTransaction013.sol | 56 - ...ansaction003testInternalTransaction014.sol | 38 - ...ansaction003testInternalTransaction015.sol | 60 - ...ansaction003testInternalTransaction016.sol | 174 -- ...ansaction003testInternalTransaction017.sol | 199 -- ...ansaction003testInternalTransaction018.sol | 97 - .../contractLinkage001.sol | 9 - .../contractLinkage002.sol | 7 - .../contractLinkage003.sol | 7 - .../contractLinkage004.sol | 7 - .../contractLinkage005.sol | 51 - .../contractLinkage006.sol | 18 - .../contractOriginEnergyLimit001.sol | 11 - .../contractOriginEnergyLimit004.sol | 11 - .../contractOtherToTrcToken.sol | 41 - .../contractScenario001.sol | 7 - .../contractScenario002.sol | 53 - .../contractScenario003.sol | 7 - .../contractScenario004.sol | 88 - .../contractScenario005.sol | 103 - .../contractScenario006.sol | 1963 ---------------- .../contractScenario007.sol | 1433 ------------ .../contractScenario008.sol | 2050 ---------------- .../contractScenario009.sol | 51 - .../contractScenario010.sol | 107 - .../contractScenario011.sol | 2050 ---------------- .../contractScenario012.sol | 57 - .../contractScenario013.sol | 8 - .../contractScenario014.sol | 34 - .../soliditycode_0.5.15/contractTest.sol | 19 - .../contractToMathedFeed.sol | 21 - .../contractTransferToken001.sol | 22 - .../contractTrcToken001.sol | 30 - .../contractTrcToken002.sol | 30 - .../contractTrcToken003.sol | 16 - .../contractTrcToken005.sol | 16 - .../contractTrcToken011.sol | 35 - .../contractTrcToken012.sol | 26 - .../contractTrcToken014.sol | 34 - .../contractTrcToken018.sol | 26 - .../contractTrcToken023.sol | 26 - .../contractTrcToken026.sol | 31 - .../contractTrcToken027.sol | 30 - .../contractTrcToken028.sol | 25 - .../contractTrcToken029.sol | 24 - .../contractTrcToken030.sol | 18 - .../contractTrcToken031.sol | 18 - .../contractTrcToken034.sol | 25 - .../contractTrcToken035.sol | 24 - .../contractTrcToken036.sol | 52 - .../contractTrcToken036_1.sol | 13 - .../contractTrcToken036_2.sol | 13 - .../contractTrcToken036_3.sol | 13 - .../contractTrcToken036_4.sol | 13 - .../contractTrcToken036_old.sol | 41 - .../contractTrcToken037.sol | 24 - .../contractTrcToken038.sol | 24 - .../contractTrcToken039.sol | 44 - .../contractTrcToken041.sol | 20 - .../contractTrcToken043.sol | 35 - .../contractTrcToken048.sol | 14 - .../contractTrcToken049.sol | 10 - .../contractTrcToken050.sol | 10 - .../contractTrcToken051.sol | 11 - .../contractTrcToken052.sol | 10 - .../contractTrcToken054.sol | 16 - .../contractTrcToken055.sol | 16 - .../contractTrcToken060.sol | 30 - .../contractTrcToken061.sol | 30 - .../contractTrcToken064.sol | 49 - .../contractTrcToken066.sol | 35 - .../contractTrcToken067.sol | 35 - .../contractTrcToken073.sol | 17 - .../contractTrcToken075.sol | 26 - .../contractTrcToken076.sol | 19 - .../contractTrcToken077.sol | 11 - .../contractTrcToken078.sol | 35 - .../contractTrcToken079.sol | 16 - .../contractTrcToken080.sol | 30 - .../contractTrcTokenToOther.sol | 44 - .../contractUnknownException.sol | 65 - .../create2CallContract.sol | 37 - .../soliditycode_0.5.15/create2Istanbul.sol | 28 - .../soliditycode_0.5.15/create2contract.sol | 52 - .../soliditycode_0.5.15/create2contract22.sol | 109 - .../soliditycode_0.5.15/create2contractn.sol | 29 - .../soliditycode_0.5.15/create2contractn2.sol | 26 - .../resources/soliditycode_0.5.15/demo.sol | 73 - .../soliditycode_0.5.15/event001.sol | 10 - .../soliditycode_0.5.15/event002.sol | 52 - .../soliditycode_0.5.15/extCodeHash.sol | 13 - .../soliditycode_0.5.15/extCodeHash11.sol | 103 - .../extCodeHashConstruct.sol | 14 - .../soliditycode_0.5.15/extCodeHashStress.sol | 45 - .../extCodeHashTestNoPayable.sol | 8 - .../soliditycode_0.5.15/isSRCandidate.sol | 35 - .../soliditycode_0.5.15/mappingGetter.sol | 4 - .../multiValiSignPerformance01.sol | 37 - .../multiValiSignPerformance02.sol | 10 - .../soliditycode_0.5.15/multivalidatesign.sol | 14 - .../multivalidatesign001.sol | 10 - .../multivalidatesign002.sol | 8 - .../multivalidatesign003.sol | 11 - .../multivalidatesign005.sol | 14 - .../multivalidatesign007.sol | 17 - .../multivalidatesign02.sol | 8 - .../soliditycode_0.5.15/negativeArray.sol | 20 - .../soliditycode_0.5.15/payable001.sol | 31 - .../soliditycode_0.5.15/pedersenHash001.sol | 18 - .../soliditycode_0.5.15/pedersenHash002.sol | 321 --- ...quireExceptiontest1TestRequireContract.sol | 15 - ...equireExceptiontest2TestThrowsContract.sol | 15 - ...equireExceptiontest3TestRevertContract.sol | 15 - ...requireExceptiontest4noPayableContract.sol | 8 - ...quireExceptiontest4noPayableContract_1.sol | 8 - ...uireExceptiontest5noPayableConstructor.sol | 11 - ...reExceptiontest5noPayableConstructor_1.sol | 11 - ...uireExceptiontest6transferTestContract.sol | 8 - ...reExceptiontest7payableFallbakContract.sol | 14 - ...reExceptiontest8newContractGasNoenough.sol | 19 - ...uireExceptiontest9MessageUsedErrorFeed.sol | 18 - ...uireExceptiontestFunctionUsedErrorFeed.sol | 17 - .../soliditycode_0.5.15/selector.sol | 21 - .../soliditycode_0.5.15/stackContract001.sol | 61 - .../soliditycode_0.5.15/stackSuicide001.sol | 84 - .../soliditycode_0.5.15/stringSplit.sol | 45 - .../soliditycode_0.5.15/suicide001.sol | 32 - .../soliditycode_0.5.15/suicide002.sol | 43 - .../soliditycode_0.5.15/testOutOfMem.sol | 7 - .../soliditycode_0.5.15/testStakeSuicide.sol | 71 - .../soliditycode_0.5.15/tryCatch001.sol | 105 - .../soliditycode_0.5.15/tvmAssetIssue001.sol | 26 - .../soliditycode_0.5.15/tvmAssetIssue002.sol | 15 - .../soliditycode_0.5.15/tvmAssetIssue003.sol | 23 - .../soliditycode_0.5.15/tvmAssetIssue004.sol | 39 - .../soliditycode_0.5.15/tvmAssetIssue005.sol | 45 - .../soliditycode_0.5.15/typeName.sol | 5 - .../soliditycode_0.5.15/unStake001.sol | 90 - .../validatemultisign001.sol | 15 - .../verifyTransferProof001.sol | 15 - .../walletTestMutiSign004.sol | 51 - .../AssertException002.sol | 17 - .../soliditycode_0.6.12/AssignToExternal.sol | 30 - .../soliditycode_0.6.12/BlockHash.sol | 38 - .../soliditycode_0.6.12/ClearAbi001.sol | 7 - .../soliditycode_0.6.12/ClearAbi005.sol | 26 - .../ConstructorDefaults.sol | 9 - .../soliditycode_0.6.12/Create2Test023.sol | 31 - .../soliditycode_0.6.12/Create2Test024.sol | 56 - .../soliditycode_0.6.12/Create2Test025.sol | 34 - .../ExtCodeHashTest010.sol | 46 - .../soliditycode_0.6.12/ExternalSelector.sol | 92 - .../soliditycode_0.6.12/NewFeature068.sol | 126 - .../soliditycode_0.6.12/ParentTypeBug.sol | 13 - .../soliditycode_0.6.12/SafeMath.sol | 149 -- .../soliditycode_0.6.12/ShiftCommand001.sol | 18 - .../SolidityMappingFix.sol | 9 - .../TestMappings_array_pop.sol | 19 - .../soliditycode_0.6.12/TransferFailed001.sol | 147 -- .../soliditycode_0.6.12/TransferFailed005.sol | 90 - .../soliditycode_0.6.12/TransferFailed006.sol | 90 - .../soliditycode_0.6.12/TransferFailed007.sol | 90 - .../TriggerConstant001.sol | 28 - .../TriggerConstant002.sol | 10 - .../TriggerConstant003.sol | 18 - .../TriggerConstant004.sol | 8 - .../TriggerConstant015.sol | 24 - .../TriggerConstant024.sol | 9 - .../soliditycode_0.6.12/TvmIsContract.sol | 15 - .../soliditycode_0.6.12/TvmIsContract001.sol | 24 - .../soliditycode_0.6.12/TvmIsContract002.sol | 5 - .../soliditycode_0.6.12/TvmNewCommand043.sol | 18 - .../soliditycode_0.6.12/TvmNewCommand103.sol | 8 - .../soliditycode_0.6.12/TvmNewCommand107.sol | 9 - .../soliditycode_0.6.12/TvmNewCommand108.sol | 7 - .../soliditycode_0.6.12/TvmNewCommand109.sol | 7 - .../soliditycode_0.6.12/TvmOldCommand001.sol | 11 - .../VerifyBurnProof001.sol | 20 - .../VerifyMintProof001.sol | 33 - .../soliditycode_0.6.12/abiencode.sol | 16 - .../soliditycode_0.6.12/abstract001.sol | 11 - .../soliditycode_0.6.12/abstract002.sol | 13 - .../soliditycode_0.6.12/accountAssert.sol | 94 - .../addMsg001Nonpayable.sol | 20 - .../soliditycode_0.6.12/addMsg002View.sol | 20 - .../soliditycode_0.6.12/addMsg003Constant.sol | 19 - .../soliditycode_0.6.12/addMsg004Pure.sol | 19 - .../addTransferToken001Nonpayable.sol | 13 - .../addTransferToken001payable.sol | 13 - .../addTransferToken002View.sol | 15 - .../addTransferToken003Constant.sol | 14 - .../addTransferToken004Pure.sol | 15 - .../addTrcToken001Assemble.sol | 62 - .../soliditycode_0.6.12/addTrcToken002Cat.sol | 2051 ---------------- .../addTrcToken002Cat_withFinny.sol | 2051 ---------------- .../soliditycode_0.6.12/addressCheckNew.sol | 9 - .../soliditycode_0.6.12/addressCheckOld.sol | 8 - .../resources/soliditycode_0.6.12/altbn.sol | 61 - .../soliditycode_0.6.12/arrayLength001.sol | 64 - .../soliditycode_0.6.12/assemblyTest.sol | 61 - .../assertExceptiontest1DivideInt.sol | 7 - ...tExceptiontest2FindArgsContractMinTest.sol | 10 - .../assertExceptiontest3ByteMinContract.sol | 11 - .../assertExceptiontest4Enum.sol | 13 - .../assertExceptiontest5MoveRight.sol | 7 - ...ertExceptiontest6UninitializedContract.sol | 27 - ...assertExceptiontest7TestAssertContract.sol | 14 - .../soliditycode_0.6.12/batchvalidatesign.sol | 14 - .../batchvalidatesign001.sol | 10 - .../batchvalidatesign002.sol | 8 - .../batchvalidatesign003.sol | 11 - .../batchvalidatesign005.sol | 14 - .../batchvalidatesign007.sol | 17 - .../batchvalidatesign02.sol | 8 - .../soliditycode_0.6.12/callValueGasPure.sol | 8 - .../soliditycode_0.6.12/calldata.sol | 33 - .../soliditycode_0.6.12/callvalue.sol | 9 - .../soliditycode_0.6.12/chainid001.sol | 19 - .../soliditycode_0.6.12/codeSaftySupport.sol | 19 - .../codeSaftyUnsupport.sol | 56 - .../constantCallStorage001.sol | 159 -- .../constantCallStorage002.sol | 16 - .../constantCallStorage0425.sol | 156 -- .../constantContract001.sol | 8 - .../contractGetterContract.sol | 17 - .../contractGrammar001test1Grammar001.sol | 18 - .../contractGrammar001test2Grammar002.sol | 44 - .../contractGrammar001test3Grammar003.sol | 44 - .../contractGrammar001test4Grammar004.sol | 31 - .../contractGrammar001test5Grammar006.sol | 45 - .../contractGrammar002test1Grammar007_1.sol | 60 - .../contractGrammar002test1Grammar007_2.sol | 60 - .../contractGrammar002test2Grammar008.sol | 18 - .../contractGrammar002test3Grammar010.sol | 10 - .../contractGrammar002test4Grammar011.sol | 11 - .../contractGrammar002test4Grammar012.sol | 24 - .../contractGrammar002test6Grammar013.sol | 24 - .../contractGrammar003test1Grammar014.sol | 67 - .../contractGrammar003test2Grammar015.sol | 40 - .../contractGrammar003test3Grammar016.sol | 23 - .../contractGrammar003test4Grammar017.sol | 50 - .../contractGrammar003test5Grammar018.sol | 37 - .../contractGrammar003test6Grammar019.sol | 12 - .../contractGrammar003test7Grammar020.sol | 8 - .../contractInnerContract.sol | 32 - ...ansaction001testInternalTransaction001.sol | 41 - ...ansaction001testInternalTransaction002.sol | 20 - ...ansaction001testInternalTransaction003.sol | 30 - ...ansaction001testInternalTransaction004.sol | 24 - ...ansaction001testInternalTransaction005.sol | 53 - ...ansaction001testInternalTransaction006.sol | 54 - ...nsaction002test1InternalTransaction007.sol | 38 - ...nsaction002test2InternalTransaction008.sol | 60 - ...nsaction002test3InternalTransaction009.sol | 47 - ...nsaction002test4InternalTransaction010.sol | 186 -- ...action002test4InternalTransaction010_1.sol | 210 -- ...nsaction002test5InternalTransaction012.sol | 51 - ...ansaction003testInternalTransaction013.sol | 56 - ...ansaction003testInternalTransaction014.sol | 38 - ...ansaction003testInternalTransaction015.sol | 60 - ...ansaction003testInternalTransaction016.sol | 174 -- ...ansaction003testInternalTransaction017.sol | 199 -- ...ansaction003testInternalTransaction018.sol | 97 - .../contractLinkage001.sol | 9 - .../contractLinkage002.sol | 7 - .../contractLinkage003.sol | 7 - .../contractLinkage004.sol | 7 - .../contractLinkage005.sol | 51 - .../contractLinkage006.sol | 18 - .../contractOriginEnergyLimit001.sol | 11 - .../contractOriginEnergyLimit004.sol | 11 - .../contractOtherToTrcToken.sol | 41 - .../contractScenario001.sol | 7 - .../contractScenario002.sol | 53 - .../contractScenario003.sol | 7 - .../contractScenario004.sol | 88 - .../contractScenario005.sol | 103 - .../contractScenario006.sol | 1963 ---------------- .../contractScenario007.sol | 1432 ------------ .../contractScenario008.sol | 2061 ----------------- .../contractScenario009.sol | 51 - .../contractScenario010.sol | 107 - .../contractScenario011.sol | 2060 ---------------- .../contractScenario012.sol | 57 - .../contractScenario013.sol | 8 - .../contractScenario014.sol | 34 - .../soliditycode_0.6.12/contractTest.sol | 19 - .../contractToMathedFeed.sol | 21 - .../contractTransferToken001.sol | 22 - .../contractTrcToken001.sol | 30 - .../contractTrcToken002.sol | 30 - .../contractTrcToken003.sol | 16 - .../contractTrcToken005.sol | 16 - .../contractTrcToken011.sol | 35 - .../contractTrcToken012.sol | 26 - .../contractTrcToken014.sol | 34 - .../contractTrcToken018.sol | 26 - .../contractTrcToken023.sol | 26 - .../contractTrcToken026.sol | 31 - .../contractTrcToken027.sol | 30 - .../contractTrcToken028.sol | 25 - .../contractTrcToken029.sol | 24 - .../contractTrcToken030.sol | 17 - .../contractTrcToken031.sol | 18 - .../contractTrcToken034.sol | 25 - .../contractTrcToken035.sol | 24 - .../contractTrcToken036.sol | 52 - .../contractTrcToken036_1.sol | 13 - .../contractTrcToken036_2.sol | 13 - .../contractTrcToken036_3.sol | 13 - .../contractTrcToken036_4.sol | 13 - .../contractTrcToken036_old.sol | 41 - .../contractTrcToken037.sol | 24 - .../contractTrcToken038.sol | 24 - .../contractTrcToken039.sol | 44 - .../contractTrcToken041.sol | 20 - .../contractTrcToken043.sol | 35 - .../contractTrcToken048.sol | 14 - .../contractTrcToken049.sol | 9 - .../contractTrcToken050.sol | 10 - .../contractTrcToken051.sol | 11 - .../contractTrcToken052.sol | 10 - .../contractTrcToken054.sol | 16 - .../contractTrcToken055.sol | 16 - .../contractTrcToken060.sol | 30 - .../contractTrcToken061.sol | 30 - .../contractTrcToken064.sol | 49 - .../contractTrcToken066.sol | 35 - .../contractTrcToken067.sol | 35 - .../contractTrcToken073.sol | 16 - .../contractTrcToken075.sol | 26 - .../contractTrcToken076.sol | 19 - .../contractTrcToken077.sol | 11 - .../contractTrcToken078.sol | 35 - .../contractTrcToken079.sol | 16 - .../contractTrcToken080.sol | 30 - .../contractTrcTokenToOther.sol | 44 - .../contractUnknownException.sol | 64 - .../create2CallContract.sol | 37 - .../soliditycode_0.6.12/create2Istanbul.sol | 28 - .../soliditycode_0.6.12/create2contract.sol | 52 - .../soliditycode_0.6.12/create2contract22.sol | 109 - .../soliditycode_0.6.12/create2contractn.sol | 29 - .../soliditycode_0.6.12/create2contractn2.sol | 26 - .../resources/soliditycode_0.6.12/demo.sol | 73 - .../soliditycode_0.6.12/enumAndStruct.sol | 43 - .../soliditycode_0.6.12/event001.sol | 10 - .../soliditycode_0.6.12/event002.sol | 52 - .../soliditycode_0.6.12/extCodeHash.sol | 13 - .../soliditycode_0.6.12/extCodeHash11.sol | 103 - .../extCodeHashConstruct.sol | 14 - .../soliditycode_0.6.12/extCodeHashStress.sol | 45 - .../extCodeHashTestNoPayable.sol | 8 - .../soliditycode_0.6.12/fallbackUpgrade.sol | 83 - .../soliditycode_0.6.12/freezeContract001.sol | 63 - .../soliditycode_0.6.12/getAddressChange.sol | 12 - .../soliditycode_0.6.12/isSRCandidate.sol | 35 - .../soliditycode_0.6.12/mappingGetter.sol | 4 - .../multiValiSignPerformance01.sol | 37 - .../multiValiSignPerformance02.sol | 10 - .../soliditycode_0.6.12/multivalidatesign.sol | 14 - .../multivalidatesign001.sol | 10 - .../multivalidatesign002.sol | 8 - .../multivalidatesign003.sol | 11 - .../multivalidatesign005.sol | 14 - .../multivalidatesign007.sol | 17 - .../multivalidatesign02.sol | 8 - .../soliditycode_0.6.12/negativeArray.sol | 20 - .../soliditycode_0.6.12/override002.sol | 12 - .../soliditycode_0.6.12/override003.sol | 20 - .../soliditycode_0.6.12/override004.sol | 25 - .../soliditycode_0.6.12/override005.sol | 39 - .../overridePrivateFunction.sol | 22 - .../soliditycode_0.6.12/payable001.sol | 31 - .../soliditycode_0.6.12/pedersenHash001.sol | 18 - .../soliditycode_0.6.12/pedersenHash002.sol | 320 --- ...quireExceptiontest1TestRequireContract.sol | 15 - ...equireExceptiontest2TestThrowsContract.sol | 15 - ...equireExceptiontest3TestRevertContract.sol | 15 - ...requireExceptiontest4noPayableContract.sol | 8 - ...quireExceptiontest4noPayableContract_1.sol | 8 - ...uireExceptiontest5noPayableConstructor.sol | 11 - ...reExceptiontest5noPayableConstructor_1.sol | 11 - ...uireExceptiontest6transferTestContract.sol | 8 - ...reExceptiontest7payableFallbakContract.sol | 14 - ...reExceptiontest8newContractGasNoenough.sol | 19 - ...uireExceptiontest9MessageUsedErrorFeed.sol | 18 - ...uireExceptiontestFunctionUsedErrorFeed.sol | 17 - .../soliditycode_0.6.12/selector.sol | 21 - .../soliditycode_0.6.12/stackContract001.sol | 61 - .../soliditycode_0.6.12/stackSuicide001.sol | 84 - .../stateVariableShadowing.sol | 21 - .../soliditycode_0.6.12/stringSplit.sol | 45 - .../soliditycode_0.6.12/suicide001.sol | 32 - .../soliditycode_0.6.12/suicide002.sol | 43 - .../soliditycode_0.6.12/testOutOfMem.sol | 7 - .../soliditycode_0.6.12/testStakeSuicide.sol | 71 - .../soliditycode_0.6.12/tryCatch001.sol | 105 - .../soliditycode_0.6.12/tvmAssetIssue001.sol | 25 - .../soliditycode_0.6.12/tvmAssetIssue002.sol | 15 - .../soliditycode_0.6.12/tvmAssetIssue003.sol | 23 - .../soliditycode_0.6.12/tvmAssetIssue004.sol | 39 - .../soliditycode_0.6.12/tvmAssetIssue005.sol | 45 - .../soliditycode_0.6.12/typeName.sol | 5 - .../soliditycode_0.6.12/unStake001.sol | 90 - .../validatemultisign001.sol | 15 - .../verifyTransferProof001.sol | 15 - .../soliditycode_0.6.12/virtual001.sol | 19 - .../walletTestMutiSign004.sol | 51 - .../soliditycode_0.7.6/AssertException002.sol | 17 - .../soliditycode_0.7.6/AssignToExternal.sol | 30 - .../soliditycode_0.7.6/BlockHash.sol | 38 - .../soliditycode_0.7.6/ClearAbi001.sol | 7 - .../soliditycode_0.7.6/ClearAbi005.sol | 26 - .../ConstructorDefaults.sol | 9 - .../soliditycode_0.7.6/Create2Test023.sol | 31 - .../soliditycode_0.7.6/Create2Test024.sol | 56 - .../soliditycode_0.7.6/Create2Test025.sol | 34 - .../soliditycode_0.7.6/ExtCodeHashTest010.sol | 46 - .../soliditycode_0.7.6/ExternalSelector.sol | 92 - .../soliditycode_0.7.6/NewFeature068.sol | 126 - .../soliditycode_0.7.6/NewFeature076.sol | 21 - .../soliditycode_0.7.6/ParentTypeBug.sol | 13 - .../resources/soliditycode_0.7.6/SafeMath.sol | 149 -- .../soliditycode_0.7.6/ShiftCommand001.sol | 18 - .../soliditycode_0.7.6/SolidityMappingFix.sol | 9 - .../TestMappings_array_pop.sol | 19 - .../soliditycode_0.7.6/TransferFailed001.sol | 147 -- .../soliditycode_0.7.6/TransferFailed005.sol | 90 - .../soliditycode_0.7.6/TransferFailed006.sol | 90 - .../soliditycode_0.7.6/TransferFailed007.sol | 90 - .../soliditycode_0.7.6/TriggerConstant001.sol | 28 - .../soliditycode_0.7.6/TriggerConstant002.sol | 10 - .../soliditycode_0.7.6/TriggerConstant003.sol | 18 - .../soliditycode_0.7.6/TriggerConstant004.sol | 8 - .../soliditycode_0.7.6/TriggerConstant015.sol | 24 - .../soliditycode_0.7.6/TriggerConstant024.sol | 9 - .../soliditycode_0.7.6/TvmIsContract.sol | 15 - .../soliditycode_0.7.6/TvmIsContract001.sol | 24 - .../soliditycode_0.7.6/TvmIsContract002.sol | 5 - .../soliditycode_0.7.6/TvmNewCommand043.sol | 18 - .../soliditycode_0.7.6/TvmNewCommand103.sol | 8 - .../soliditycode_0.7.6/TvmNewCommand107.sol | 9 - .../soliditycode_0.7.6/TvmNewCommand108.sol | 7 - .../soliditycode_0.7.6/TvmNewCommand109.sol | 7 - .../soliditycode_0.7.6/TvmOldCommand001.sol | 11 - .../soliditycode_0.7.6/VerifyBurnProof001.sol | 20 - .../soliditycode_0.7.6/VerifyMintProof001.sol | 33 - .../soliditycode_0.7.6/abiencode.sol | 16 - .../soliditycode_0.7.6/abstract001.sol | 11 - .../soliditycode_0.7.6/abstract002.sol | 13 - .../soliditycode_0.7.6/accountAssert.sol | 94 - .../addMsg001Nonpayable.sol | 20 - .../soliditycode_0.7.6/addMsg002View.sol | 20 - .../soliditycode_0.7.6/addMsg003Constant.sol | 19 - .../soliditycode_0.7.6/addMsg004Pure.sol | 19 - .../addTransferToken001Nonpayable.sol | 13 - .../addTransferToken001payable.sol | 13 - .../addTransferToken002View.sol | 15 - .../addTransferToken003Constant.sol | 14 - .../addTransferToken004Pure.sol | 15 - .../addTrcToken001Assemble.sol | 62 - .../soliditycode_0.7.6/addTrcToken002Cat.sol | 2051 ---------------- .../addTrcToken002Cat_withFinny.sol | 2051 ---------------- .../soliditycode_0.7.6/addressCheckNew.sol | 9 - .../soliditycode_0.7.6/addressCheckOld.sol | 8 - .../resources/soliditycode_0.7.6/altbn.sol | 61 - .../soliditycode_0.7.6/arrayLength001.sol | 64 - .../soliditycode_0.7.6/assemblyTest.sol | 61 - .../assertExceptiontest1DivideInt.sol | 7 - ...tExceptiontest2FindArgsContractMinTest.sol | 10 - .../assertExceptiontest3ByteMinContract.sol | 11 - .../assertExceptiontest4Enum.sol | 13 - .../assertExceptiontest5MoveRight.sol | 7 - ...ertExceptiontest6UninitializedContract.sol | 27 - ...assertExceptiontest7TestAssertContract.sol | 14 - .../soliditycode_0.7.6/batchvalidatesign.sol | 14 - .../batchvalidatesign001.sol | 10 - .../batchvalidatesign002.sol | 8 - .../batchvalidatesign003.sol | 11 - .../batchvalidatesign005.sol | 14 - .../batchvalidatesign007.sol | 17 - .../batchvalidatesign02.sol | 8 - .../soliditycode_0.7.6/callValueGasPure.sol | 8 - .../resources/soliditycode_0.7.6/calldata.sol | 33 - .../soliditycode_0.7.6/callvalue.sol | 9 - .../soliditycode_0.7.6/chainid001.sol | 19 - .../soliditycode_0.7.6/codeSaftySupport.sol | 19 - .../soliditycode_0.7.6/codeSaftyUnsupport.sol | 56 - .../constantCallStorage001.sol | 159 -- .../constantCallStorage002.sol | 16 - .../constantCallStorage0425.sol | 156 -- .../constantContract001.sol | 8 - .../contractGetterContract.sol | 17 - .../contractGrammar001test1Grammar001.sol | 18 - .../contractGrammar001test2Grammar002.sol | 44 - .../contractGrammar001test3Grammar003.sol | 44 - .../contractGrammar001test4Grammar004.sol | 31 - .../contractGrammar001test5Grammar006.sol | 45 - .../contractGrammar002test1Grammar007_1.sol | 60 - .../contractGrammar002test1Grammar007_2.sol | 60 - .../contractGrammar002test2Grammar008.sol | 18 - .../contractGrammar002test3Grammar010.sol | 10 - .../contractGrammar002test4Grammar011.sol | 11 - .../contractGrammar002test4Grammar012.sol | 24 - .../contractGrammar002test6Grammar013.sol | 24 - .../contractGrammar003test1Grammar014.sol | 67 - .../contractGrammar003test2Grammar015.sol | 40 - .../contractGrammar003test3Grammar016.sol | 23 - .../contractGrammar003test4Grammar017.sol | 51 - .../contractGrammar003test5Grammar018.sol | 37 - .../contractGrammar003test6Grammar019.sol | 12 - .../contractGrammar003test7Grammar020.sol | 8 - .../contractInnerContract.sol | 32 - ...ansaction001testInternalTransaction001.sol | 41 - ...ansaction001testInternalTransaction002.sol | 20 - ...ansaction001testInternalTransaction003.sol | 30 - ...ansaction001testInternalTransaction004.sol | 24 - ...ansaction001testInternalTransaction005.sol | 53 - ...ansaction001testInternalTransaction006.sol | 54 - ...nsaction002test1InternalTransaction007.sol | 38 - ...nsaction002test2InternalTransaction008.sol | 60 - ...nsaction002test3InternalTransaction009.sol | 47 - ...nsaction002test4InternalTransaction010.sol | 186 -- ...action002test4InternalTransaction010_1.sol | 210 -- ...nsaction002test5InternalTransaction012.sol | 51 - ...ansaction003testInternalTransaction013.sol | 56 - ...ansaction003testInternalTransaction014.sol | 38 - ...ansaction003testInternalTransaction015.sol | 60 - ...ansaction003testInternalTransaction016.sol | 174 -- ...ansaction003testInternalTransaction017.sol | 199 -- ...ansaction003testInternalTransaction018.sol | 97 - .../soliditycode_0.7.6/contractLinkage001.sol | 9 - .../soliditycode_0.7.6/contractLinkage002.sol | 7 - .../soliditycode_0.7.6/contractLinkage003.sol | 7 - .../soliditycode_0.7.6/contractLinkage004.sol | 7 - .../soliditycode_0.7.6/contractLinkage005.sol | 51 - .../soliditycode_0.7.6/contractLinkage006.sol | 18 - .../contractOriginEnergyLimit001.sol | 11 - .../contractOriginEnergyLimit004.sol | 11 - .../contractOtherToTrcToken.sol | 41 - .../contractScenario001.sol | 7 - .../contractScenario002.sol | 53 - .../contractScenario003.sol | 7 - .../contractScenario004.sol | 88 - .../contractScenario005.sol | 103 - .../contractScenario006.sol | 1963 ---------------- .../contractScenario007.sol | 1432 ------------ .../contractScenario008.sol | 2061 ----------------- .../contractScenario009.sol | 51 - .../contractScenario010.sol | 107 - .../contractScenario011.sol | 2060 ---------------- .../contractScenario012.sol | 57 - .../contractScenario013.sol | 8 - .../contractScenario014.sol | 34 - .../soliditycode_0.7.6/contractTest.sol | 19 - .../contractToMathedFeed.sol | 21 - .../contractTransferToken001.sol | 22 - .../contractTrcToken001.sol | 30 - .../contractTrcToken002.sol | 30 - .../contractTrcToken003.sol | 16 - .../contractTrcToken005.sol | 16 - .../contractTrcToken011.sol | 35 - .../contractTrcToken012.sol | 26 - .../contractTrcToken014.sol | 34 - .../contractTrcToken018.sol | 26 - .../contractTrcToken023.sol | 26 - .../contractTrcToken026.sol | 31 - .../contractTrcToken027.sol | 30 - .../contractTrcToken028.sol | 25 - .../contractTrcToken029.sol | 24 - .../contractTrcToken030.sol | 17 - .../contractTrcToken031.sol | 18 - .../contractTrcToken034.sol | 25 - .../contractTrcToken035.sol | 24 - .../contractTrcToken036.sol | 52 - .../contractTrcToken036_1.sol | 13 - .../contractTrcToken036_2.sol | 13 - .../contractTrcToken036_3.sol | 13 - .../contractTrcToken036_4.sol | 13 - .../contractTrcToken036_old.sol | 41 - .../contractTrcToken037.sol | 24 - .../contractTrcToken038.sol | 24 - .../contractTrcToken039.sol | 44 - .../contractTrcToken041.sol | 20 - .../contractTrcToken043.sol | 35 - .../contractTrcToken048.sol | 14 - .../contractTrcToken049.sol | 9 - .../contractTrcToken050.sol | 10 - .../contractTrcToken051.sol | 11 - .../contractTrcToken052.sol | 10 - .../contractTrcToken054.sol | 16 - .../contractTrcToken055.sol | 16 - .../contractTrcToken060.sol | 30 - .../contractTrcToken061.sol | 30 - .../contractTrcToken064.sol | 49 - .../contractTrcToken066.sol | 35 - .../contractTrcToken067.sol | 35 - .../contractTrcToken073.sol | 16 - .../contractTrcToken075.sol | 26 - .../contractTrcToken076.sol | 19 - .../contractTrcToken077.sol | 11 - .../contractTrcToken078.sol | 35 - .../contractTrcToken079.sol | 16 - .../contractTrcToken080.sol | 30 - .../contractTrcTokenToOther.sol | 44 - .../contractUnknownException.sol | 64 - .../create2CallContract.sol | 37 - .../soliditycode_0.7.6/create2Istanbul.sol | 28 - .../soliditycode_0.7.6/create2contract.sol | 52 - .../soliditycode_0.7.6/create2contract22.sol | 109 - .../soliditycode_0.7.6/create2contractn.sol | 29 - .../soliditycode_0.7.6/create2contractn2.sol | 26 - .../resources/soliditycode_0.7.6/demo.sol | 73 - .../soliditycode_0.7.6/enumAndStruct.sol | 43 - .../resources/soliditycode_0.7.6/event001.sol | 10 - .../resources/soliditycode_0.7.6/event002.sol | 52 - .../soliditycode_0.7.6/extCodeHash.sol | 13 - .../soliditycode_0.7.6/extCodeHash11.sol | 103 - .../extCodeHashConstruct.sol | 14 - .../soliditycode_0.7.6/extCodeHashStress.sol | 45 - .../extCodeHashTestNoPayable.sol | 8 - .../soliditycode_0.7.6/fallbackUpgrade.sol | 83 - .../soliditycode_0.7.6/freezeContract001.sol | 63 - .../soliditycode_0.7.6/getAddressChange.sol | 12 - .../soliditycode_0.7.6/isSRCandidate.sol | 35 - .../soliditycode_0.7.6/mappingGetter.sol | 4 - .../multiValiSignPerformance01.sol | 37 - .../multiValiSignPerformance02.sol | 10 - .../soliditycode_0.7.6/multivalidatesign.sol | 14 - .../multivalidatesign001.sol | 10 - .../multivalidatesign002.sol | 8 - .../multivalidatesign003.sol | 11 - .../multivalidatesign005.sol | 14 - .../multivalidatesign007.sol | 17 - .../multivalidatesign02.sol | 8 - .../soliditycode_0.7.6/negativeArray.sol | 20 - .../soliditycode_0.7.6/override002.sol | 12 - .../soliditycode_0.7.6/override003.sol | 20 - .../soliditycode_0.7.6/override004.sol | 25 - .../soliditycode_0.7.6/override005.sol | 39 - .../overridePrivateFunction.sol | 22 - .../soliditycode_0.7.6/payable001.sol | 31 - .../soliditycode_0.7.6/pedersenHash001.sol | 18 - .../soliditycode_0.7.6/pedersenHash002.sol | 320 --- ...quireExceptiontest1TestRequireContract.sol | 15 - ...equireExceptiontest2TestThrowsContract.sol | 15 - ...equireExceptiontest3TestRevertContract.sol | 15 - ...requireExceptiontest4noPayableContract.sol | 8 - ...quireExceptiontest4noPayableContract_1.sol | 8 - ...uireExceptiontest5noPayableConstructor.sol | 11 - ...reExceptiontest5noPayableConstructor_1.sol | 11 - ...uireExceptiontest6transferTestContract.sol | 8 - ...reExceptiontest7payableFallbakContract.sol | 14 - ...reExceptiontest8newContractGasNoenough.sol | 19 - ...uireExceptiontest9MessageUsedErrorFeed.sol | 18 - ...uireExceptiontestFunctionUsedErrorFeed.sol | 17 - .../resources/soliditycode_0.7.6/selector.sol | 21 - .../slotAndOffsetNewGrammer.sol | 32 - .../soliditycode_0.7.6/stackContract001.sol | 61 - .../soliditycode_0.7.6/stackSuicide001.sol | 84 - .../stateVariableShadowing.sol | 21 - .../soliditycode_0.7.6/stringSplit.sol | 45 - .../soliditycode_0.7.6/suicide001.sol | 32 - .../soliditycode_0.7.6/suicide002.sol | 43 - .../soliditycode_0.7.6/testOutOfMem.sol | 7 - .../soliditycode_0.7.6/testStakeSuicide.sol | 71 - .../soliditycode_0.7.6/tryCatch001.sol | 105 - .../soliditycode_0.7.6/tvmAssetIssue001.sol | 25 - .../soliditycode_0.7.6/tvmAssetIssue002.sol | 15 - .../soliditycode_0.7.6/tvmAssetIssue003.sol | 23 - .../soliditycode_0.7.6/tvmAssetIssue004.sol | 39 - .../soliditycode_0.7.6/tvmAssetIssue005.sol | 45 - .../resources/soliditycode_0.7.6/typeName.sol | 5 - .../soliditycode_0.7.6/unStake001.sol | 90 - .../validatemultisign001.sol | 15 - .../verifyTransferProof001.sol | 15 - .../soliditycode_0.7.6/virtual001.sol | 19 - .../walletTestMutiSign004.sol | 51 - .../TransferFailed001.sol | 0 .../TransferFailed005.sol | 106 - .../TransferFailed007.sol | 90 - .../addMsg001Nonpayable.sol | 20 - .../soliditycode_v0.4.25/addMsg002View.sol | 20 - .../addMsg003Constant.sol | 19 - .../soliditycode_v0.4.25/addMsg004Pure.sol | 19 - .../addTransferToken001Nonpayable.sol | 15 - .../addTransferToken002View.sol | 15 - .../addTransferToken003Constant.sol | 15 - .../addTransferToken004Pure.sol | 15 - .../addTrcToken001Assemble.sol | 81 - .../addTrcToken002Cat.sol | 2017 ---------------- .../addTrcToken002Cat_withFinny.sol | 2017 ---------------- .../assertExceptiontest1DivideInt.sol | 7 - ...tExceptiontest2FindArgsContractMinTest.sol | 10 - .../assertExceptiontest3ByteMinContract.sol | 11 - .../assertExceptiontest4Enum.sol | 13 - .../assertExceptiontest5MoveRight.sol | 7 - ...ertExceptiontest6UninitializedContract.sol | 27 - ...assertExceptiontest7TestAssertContract.sol | 17 - .../soliditycode_v0.4.25/codeSaftySupport.sol | 19 - .../codeSaftyUnsupport.sol | 50 - .../contractGetterContract.sol | 17 - .../contractGrammar001test1Grammar001.sol | 14 - .../contractGrammar001test2Grammar002.sol | 44 - .../contractGrammar001test3Grammar003.sol | 44 - .../contractGrammar001test4Grammar004.sol | 31 - .../contractGrammar001test5Grammar006.sol | 36 - .../contractGrammar002test1Grammar007_1.sol | 60 - .../contractGrammar002test1Grammar007_2.sol | 60 - .../contractGrammar002test2Grammar008.sol | 14 - .../contractGrammar002test3Grammar010.sol | 10 - .../contractGrammar002test4Grammar011.sol | 11 - .../contractGrammar002test4Grammar012.sol | 24 - .../contractGrammar002test6Grammar013.sol | 22 - .../contractGrammar003test1Grammar014.sol | 59 - .../contractGrammar003test2Grammar015.sol | 37 - .../contractGrammar003test3Grammar016.sol | 23 - .../contractGrammar003test4Grammar017.sol | 47 - .../contractGrammar003test5Grammar018.sol | 36 - .../contractGrammar003test6Grammar019.sol | 12 - .../contractGrammar003test7Grammar020.sol | 7 - .../contractInnerContract.sol | 31 - ...ansaction001testInternalTransaction001.sol | 42 - ...ansaction001testInternalTransaction002.sol | 20 - ...ansaction001testInternalTransaction003.sol | 31 - ...ansaction001testInternalTransaction004.sol | 24 - ...ansaction001testInternalTransaction005.sol | 54 - ...ansaction001testInternalTransaction006.sol | 54 - ...nsaction002test1InternalTransaction007.sol | 38 - ...nsaction002test2InternalTransaction008.sol | 60 - ...nsaction002test3InternalTransaction009.sol | 47 - ...nsaction002test4InternalTransaction010.sol | 188 -- ...nsaction002test5InternalTransaction012.sol | 51 - ...ansaction003testInternalTransaction013.sol | 56 - ...ansaction003testInternalTransaction014.sol | 40 - ...ansaction003testInternalTransaction015.sol | 60 - ...ansaction003testInternalTransaction016.sol | 184 -- ...ansaction003testInternalTransaction017.sol | 194 -- ...ansaction003testInternalTransaction018.sol | 149 -- .../contractLinkage001.sol | 9 - .../contractLinkage002.sol | 7 - .../contractLinkage003.sol | 7 - .../contractLinkage004.sol | 7 - .../contractLinkage005.sol | 51 - .../contractLinkage006.sol | 18 - .../contractOriginEnergyLimit001.sol | 11 - .../contractOriginEnergyLimit004.sol | 11 - .../contractOtherToTrcToken.sol | 40 - .../contractScenario001.sol | 7 - .../contractScenario002.sol | 53 - .../contractScenario003.sol | 7 - .../contractScenario004.sol | 88 - .../contractScenario005.sol | 103 - .../contractScenario006.sol | 1954 ---------------- .../contractScenario007.sol | 1433 ------------ .../contractScenario008.sol | 2016 ---------------- .../contractScenario009.sol | 51 - .../contractScenario010.sol | 107 - .../contractScenario011.sol | 2050 ---------------- .../contractScenario012.sol | 57 - .../contractScenario013.sol | 8 - .../contractScenario014.sol | 34 - .../soliditycode_v0.4.25/contractTest.sol | 19 - .../contractToMathedFeed.sol | 19 - .../contractTrcToken001.sol | 30 - .../contractTrcToken002.sol | 30 - .../contractTrcToken003.sol | 16 - .../contractTrcToken005.sol | 16 - .../contractTrcToken011.sol | 35 - .../contractTrcToken012.sol | 26 - .../contractTrcToken014.sol | 34 - .../contractTrcToken018.sol | 26 - .../contractTrcToken023.sol | 26 - .../contractTrcToken026.sol | 30 - .../contractTrcToken027.sol | 30 - .../contractTrcToken028.sol | 25 - .../contractTrcToken029.sol | 24 - .../contractTrcToken030.sol | 18 - .../contractTrcToken031.sol | 18 - .../contractTrcToken034.sol | 23 - .../contractTrcToken035.sol | 23 - .../contractTrcToken036.sol | 65 - .../contractTrcToken037.sol | 23 - .../contractTrcToken038.sol | 22 - .../contractTrcToken039.sol | 44 - .../contractTrcToken041.sol | 20 - .../contractTrcToken043.sol | 35 - .../contractTrcToken048.sol | 14 - .../contractTrcToken049.sol | 10 - .../contractTrcToken050.sol | 10 - .../contractTrcToken051.sol | 10 - .../contractTrcToken052.sol | 10 - .../contractTrcToken054.sol | 16 - .../contractTrcToken055.sol | 16 - .../contractTrcToken060.sol | 30 - .../contractTrcToken061.sol | 30 - .../contractTrcToken064.sol | 49 - .../contractTrcToken066.sol | 35 - .../contractTrcToken067.sol | 35 - .../contractTrcToken073.sol | 17 - .../contractTrcToken075.sol | 26 - .../contractTrcToken076.sol | 19 - .../contractTrcToken077.sol | 11 - .../contractTrcToken078.sol | 35 - .../contractTrcToken079.sol | 16 - .../contractTrcToken080.sol | 30 - .../contractTrcTokenToOther.sol | 44 - .../contractUnknownException.sol | 65 - ...quireExceptiontest1TestRequireContract.sol | 15 - ...equireExceptiontest2TestThrowsContract.sol | 15 - ...equireExceptiontest3TestRevertContract.sol | 15 - ...requireExceptiontest4noPayableContract.sol | 8 - ...uireExceptiontest5noPayableConstructor.sol | 10 - ...uireExceptiontest6transferTestContract.sol | 8 - ...reExceptiontest7payableFallbakContract.sol | 13 - ...reExceptiontest8newContractGasNoenough.sol | 18 - ...uireExceptiontest9MessageUsedErrorFeed.sol | 18 - ...uireExceptiontestFunctionUsedErrorFeed.sol | 17 - .../walletTestMutiSign004.sol | 52 - framework/src/test/resources/testng.xml | 45 - plugins/README.md | 2 +- plugins/build.gradle | 8 +- .../main/java/org/tron/plugins/DbLite.java | 25 +- .../java/org/tron/plugins/DbConvertTest.java | 92 +- .../java/org/tron/plugins/DbCopyTest.java | 53 + .../org/tron/plugins/DbLiteLevelDbTest.java | 13 + .../org/tron/plugins/DbLiteLevelDbV2Test.java | 12 + .../org/tron/plugins/DbLiteRocksDbTest.java | 12 + .../java/org/tron/plugins/DbLiteTest.java | 176 ++ .../test/java/org/tron/plugins/DbTest.java | 89 + protocol/build.gradle | 11 +- protocol/src/main/protos/api/api.proto | 18 + protocol/src/main/protos/core/Tron.proto | 2 + start.sh | 2 +- 1603 files changed, 9853 insertions(+), 102869 deletions(-) create mode 100644 .github/workflows/codeql.yml create mode 100644 SECURITY.md rename {framework => chainbase}/src/main/java/org/tron/core/db/TransactionCache.java (58%) create mode 100644 common/src/main/java/org/tron/common/es/ExecutorServiceManager.java create mode 100644 framework/src/main/java/org/tron/common/application/HttpService.java create mode 100644 framework/src/main/java/org/tron/common/application/RpcService.java create mode 100644 framework/src/main/java/org/tron/common/cache/CacheManagerTest.java create mode 100644 framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/GetBandwidthPricesOnPBFTServlet.java create mode 100644 framework/src/main/java/org/tron/core/services/interfaceOnSolidity/http/GetBandwidthPricesOnSolidityServlet.java create mode 100644 framework/src/main/java/org/tron/core/zen/ZksnarkInitService.java delete mode 100644 framework/src/main/java/org/tron/core/zen/ZksnarkService.java create mode 100644 framework/src/test/java/org/tron/common/backup/BackupServerTest.java create mode 100644 framework/src/test/java/org/tron/common/logsfilter/TransactionLogTriggerCapsuleTest.java create mode 100644 framework/src/test/java/org/tron/core/ShieldWalletTest.java create mode 100644 framework/src/test/java/org/tron/core/db/AbiStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/AccountAssetStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/AccountTraceStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/AssetIssueStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/AssetIssueV2StoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/BalanceTraceStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/CodeStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/ContractStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/DelegatedResourceAccountIndexStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/DelegatedResourceStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/DelegationStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/ExchangeStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/ExchangeV2StoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/IncrementalMerkleTreeStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/MarketAccountStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/MarketOrderStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/MarketPairToPriceStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/ProposalStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/TreeBlockIndexStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/TronDatabaseTest.java create mode 100644 framework/src/test/java/org/tron/core/db/TxCacheDBInitTest.java create mode 100644 framework/src/test/java/org/tron/core/db/WitnessScheduleStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db2/SnapshotImplTest.java create mode 100644 framework/src/test/java/org/tron/core/net/messagehandler/PbftDataSyncHandlerTest.java create mode 100644 framework/src/test/java/org/tron/core/net/messagehandler/PbftMsgHandlerTest.java create mode 100644 framework/src/test/java/org/tron/core/net/messagehandler/TransactionsMsgHandlerTest.java create mode 100644 framework/src/test/java/org/tron/core/net/peer/PeerConnectionTest.java create mode 100644 framework/src/test/java/org/tron/core/net/peer/PeerManagerTest.java create mode 100644 framework/src/test/java/org/tron/core/services/RpcApiServicesTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/GetAssetIssueListServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/GetBandwidthPricesServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/GetBrokerageServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/GetEnergyPricesServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/GetMemoFeePricesServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/GetNowBlockServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/GetRewardServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/ListNodesServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/ListProposalsServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/interfaceOnPBFT/http/GetBandwidthPricesOnPBFTServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/interfaceOnPBFT/http/GetEnergyPricesOnPBFTServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/interfaceOnSolidity/http/GetBandwidthPricesOnSolidityServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/interfaceOnSolidity/http/GetEnergyPricesOnSolidityServletTest.java create mode 100644 framework/src/test/java/org/tron/keystroe/CredentialsTest.java delete mode 100644 framework/src/test/resources/daily-build.xml delete mode 100644 framework/src/test/resources/solcDir/README.txt delete mode 100644 framework/src/test/resources/solidityFile.xml delete mode 100644 framework/src/test/resources/soliditycode/AssertException002.sol delete mode 100644 framework/src/test/resources/soliditycode/AssignToExternal.sol delete mode 100644 framework/src/test/resources/soliditycode/BlockHash.sol delete mode 100644 framework/src/test/resources/soliditycode/ClearAbi001.sol delete mode 100644 framework/src/test/resources/soliditycode/ClearAbi005.sol delete mode 100644 framework/src/test/resources/soliditycode/ConstructorDefaults.sol delete mode 100644 framework/src/test/resources/soliditycode/Create2Test023.sol delete mode 100644 framework/src/test/resources/soliditycode/Create2Test024.sol delete mode 100644 framework/src/test/resources/soliditycode/Create2Test025.sol delete mode 100644 framework/src/test/resources/soliditycode/EthGrammer.sol delete mode 100644 framework/src/test/resources/soliditycode/EthGrammer02.sol delete mode 100644 framework/src/test/resources/soliditycode/ExtCodeHashTest010.sol delete mode 100644 framework/src/test/resources/soliditycode/ExternalSelector.sol delete mode 100644 framework/src/test/resources/soliditycode/NewFeature068.sol delete mode 100644 framework/src/test/resources/soliditycode/NewFeature076.sol delete mode 100644 framework/src/test/resources/soliditycode/NewFeature080.sol delete mode 100644 framework/src/test/resources/soliditycode/NewFeature0811.sol delete mode 100644 framework/src/test/resources/soliditycode/NewFeature086.sol delete mode 100644 framework/src/test/resources/soliditycode/NoAbi001.sol delete mode 100644 framework/src/test/resources/soliditycode/NoAbi002.sol delete mode 100644 framework/src/test/resources/soliditycode/ParentTypeBug.sol delete mode 100644 framework/src/test/resources/soliditycode/SafeMath.sol delete mode 100644 framework/src/test/resources/soliditycode/ShiftCommand001.sol delete mode 100644 framework/src/test/resources/soliditycode/SolidityMappingFix.sol delete mode 100644 framework/src/test/resources/soliditycode/TestMappings_array_pop.sol delete mode 100644 framework/src/test/resources/soliditycode/TransferFailed001.sol delete mode 100644 framework/src/test/resources/soliditycode/TransferFailed005.sol delete mode 100644 framework/src/test/resources/soliditycode/TransferFailed006.sol delete mode 100644 framework/src/test/resources/soliditycode/TransferFailed007.sol delete mode 100644 framework/src/test/resources/soliditycode/TriggerConstant001.sol delete mode 100644 framework/src/test/resources/soliditycode/TriggerConstant002.sol delete mode 100644 framework/src/test/resources/soliditycode/TriggerConstant003.sol delete mode 100644 framework/src/test/resources/soliditycode/TriggerConstant004.sol delete mode 100644 framework/src/test/resources/soliditycode/TriggerConstant015.sol delete mode 100644 framework/src/test/resources/soliditycode/TriggerConstant024.sol delete mode 100644 framework/src/test/resources/soliditycode/TvmIsContract.sol delete mode 100644 framework/src/test/resources/soliditycode/TvmIsContract001.sol delete mode 100644 framework/src/test/resources/soliditycode/TvmIsContract002.sol delete mode 100644 framework/src/test/resources/soliditycode/TvmNewCommand043.sol delete mode 100644 framework/src/test/resources/soliditycode/TvmNewCommand103.sol delete mode 100644 framework/src/test/resources/soliditycode/TvmNewCommand107.sol delete mode 100644 framework/src/test/resources/soliditycode/TvmNewCommand108.sol delete mode 100644 framework/src/test/resources/soliditycode/TvmNewCommand109.sol delete mode 100644 framework/src/test/resources/soliditycode/TvmOldCommand001.sol delete mode 100644 framework/src/test/resources/soliditycode/VerifyBurnProof001.sol delete mode 100644 framework/src/test/resources/soliditycode/VerifyMintProof001.sol delete mode 100644 framework/src/test/resources/soliditycode/abiencode.sol delete mode 100644 framework/src/test/resources/soliditycode/abstract001.sol delete mode 100644 framework/src/test/resources/soliditycode/abstract002.sol delete mode 100644 framework/src/test/resources/soliditycode/abstractContractWithMapParamsConstructor.sol delete mode 100644 framework/src/test/resources/soliditycode/accountAssert.sol delete mode 100644 framework/src/test/resources/soliditycode/addMsg001Nonpayable.sol delete mode 100644 framework/src/test/resources/soliditycode/addMsg002View.sol delete mode 100644 framework/src/test/resources/soliditycode/addMsg003Constant.sol delete mode 100644 framework/src/test/resources/soliditycode/addMsg004Pure.sol delete mode 100644 framework/src/test/resources/soliditycode/addTransferToken001Nonpayable.sol delete mode 100644 framework/src/test/resources/soliditycode/addTransferToken001payable.sol delete mode 100644 framework/src/test/resources/soliditycode/addTransferToken002View.sol delete mode 100644 framework/src/test/resources/soliditycode/addTransferToken003Constant.sol delete mode 100644 framework/src/test/resources/soliditycode/addTransferToken004Pure.sol delete mode 100644 framework/src/test/resources/soliditycode/addTrcToken001Assemble.sol delete mode 100644 framework/src/test/resources/soliditycode/addTrcToken002Cat.sol delete mode 100644 framework/src/test/resources/soliditycode/addTrcToken002Cat_withFinny.sol delete mode 100644 framework/src/test/resources/soliditycode/addressCheckNew.sol delete mode 100644 framework/src/test/resources/soliditycode/addressCheckOld.sol delete mode 100644 framework/src/test/resources/soliditycode/altbn.sol delete mode 100644 framework/src/test/resources/soliditycode/arrayLength001.sol delete mode 100644 framework/src/test/resources/soliditycode/assemblyTest.sol delete mode 100644 framework/src/test/resources/soliditycode/assertExceptiontest1DivideInt.sol delete mode 100644 framework/src/test/resources/soliditycode/assertExceptiontest2FindArgsContractMinTest.sol delete mode 100644 framework/src/test/resources/soliditycode/assertExceptiontest3ByteMinContract.sol delete mode 100644 framework/src/test/resources/soliditycode/assertExceptiontest4Enum.sol delete mode 100644 framework/src/test/resources/soliditycode/assertExceptiontest5MoveRight.sol delete mode 100644 framework/src/test/resources/soliditycode/assertExceptiontest6UninitializedContract.sol delete mode 100644 framework/src/test/resources/soliditycode/assertExceptiontest7TestAssertContract.sol delete mode 100644 framework/src/test/resources/soliditycode/batchvalidatesign.sol delete mode 100644 framework/src/test/resources/soliditycode/batchvalidatesign001.sol delete mode 100644 framework/src/test/resources/soliditycode/batchvalidatesign002.sol delete mode 100644 framework/src/test/resources/soliditycode/batchvalidatesign003.sol delete mode 100644 framework/src/test/resources/soliditycode/batchvalidatesign005.sol delete mode 100644 framework/src/test/resources/soliditycode/batchvalidatesign007.sol delete mode 100644 framework/src/test/resources/soliditycode/batchvalidatesign02.sol delete mode 100644 framework/src/test/resources/soliditycode/callValueGasPure.sol delete mode 100644 framework/src/test/resources/soliditycode/calldata.sol delete mode 100644 framework/src/test/resources/soliditycode/callvalue.sol delete mode 100644 framework/src/test/resources/soliditycode/chainid001.sol delete mode 100644 framework/src/test/resources/soliditycode/codeSaftySupport.sol delete mode 100644 framework/src/test/resources/soliditycode/codeSaftyUnsupport.sol delete mode 100644 framework/src/test/resources/soliditycode/constantCallStorage001.sol delete mode 100644 framework/src/test/resources/soliditycode/constantCallStorage002.sol delete mode 100644 framework/src/test/resources/soliditycode/constantCallStorage0425.sol delete mode 100644 framework/src/test/resources/soliditycode/constantContract001.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGetterContract.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar001test1Grammar001.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar001test2Grammar002.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar001test3Grammar003.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar001test4Grammar004.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar001test5Grammar006.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar002test1Grammar007_1.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar002test1Grammar007_2.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar002test2Grammar008.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar002test3Grammar010.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar002test4Grammar011.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar002test4Grammar012.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar002test6Grammar013.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar003test1Grammar014.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar003test2Grammar015.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar003test3Grammar016.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar003test4Grammar017.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar003test5Grammar018.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar003test6Grammar019.sol delete mode 100644 framework/src/test/resources/soliditycode/contractGrammar003test7Grammar020.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInnerContract.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction001.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction002.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction003.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction004.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction005.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction006.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction002test1InternalTransaction007.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction002test2InternalTransaction008.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction002test3InternalTransaction009.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction002test4InternalTransaction010.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction002test4InternalTransaction010_1.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction002test5InternalTransaction012.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction013.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction014.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction015.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction016.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction017.sol delete mode 100644 framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction018.sol delete mode 100644 framework/src/test/resources/soliditycode/contractLinkage001.sol delete mode 100644 framework/src/test/resources/soliditycode/contractLinkage002.sol delete mode 100644 framework/src/test/resources/soliditycode/contractLinkage003.sol delete mode 100644 framework/src/test/resources/soliditycode/contractLinkage004.sol delete mode 100644 framework/src/test/resources/soliditycode/contractLinkage005.sol delete mode 100644 framework/src/test/resources/soliditycode/contractLinkage006.sol delete mode 100644 framework/src/test/resources/soliditycode/contractOriginEnergyLimit001.sol delete mode 100644 framework/src/test/resources/soliditycode/contractOriginEnergyLimit004.sol delete mode 100644 framework/src/test/resources/soliditycode/contractOtherToTrcToken.sol delete mode 100644 framework/src/test/resources/soliditycode/contractScenario001.sol delete mode 100644 framework/src/test/resources/soliditycode/contractScenario002.sol delete mode 100644 framework/src/test/resources/soliditycode/contractScenario003.sol delete mode 100644 framework/src/test/resources/soliditycode/contractScenario004.sol delete mode 100644 framework/src/test/resources/soliditycode/contractScenario005.sol delete mode 100644 framework/src/test/resources/soliditycode/contractScenario006.sol delete mode 100644 framework/src/test/resources/soliditycode/contractScenario007.sol delete mode 100644 framework/src/test/resources/soliditycode/contractScenario008.sol delete mode 100644 framework/src/test/resources/soliditycode/contractScenario009.sol delete mode 100644 framework/src/test/resources/soliditycode/contractScenario010.sol delete mode 100644 framework/src/test/resources/soliditycode/contractScenario011.sol delete mode 100644 framework/src/test/resources/soliditycode/contractScenario012.sol delete mode 100644 framework/src/test/resources/soliditycode/contractScenario013.sol delete mode 100644 framework/src/test/resources/soliditycode/contractScenario014.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTest.sol delete mode 100644 framework/src/test/resources/soliditycode/contractToMathedFeed.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTransferToken001.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrc1155.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken001.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken002.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken003.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken005.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken011.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken012.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken014.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken018.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken023.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken026.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken027.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken028.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken029.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken030.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken031.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken034.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken035.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken036.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken036_1.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken036_2.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken036_3.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken036_4.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken036_old.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken037.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken038.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken039.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken041.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken043.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken048.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken049.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken050.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken051.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken052.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken054.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken055.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken060.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken061.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken064.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken066.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken067.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken073.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken075.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken076.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken077.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken078.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken079.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken080.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcToken081.sol delete mode 100644 framework/src/test/resources/soliditycode/contractTrcTokenToOther.sol delete mode 100644 framework/src/test/resources/soliditycode/contractUnknownException.sol delete mode 100644 framework/src/test/resources/soliditycode/create2CallContract.sol delete mode 100644 framework/src/test/resources/soliditycode/create2Istanbul.sol delete mode 100644 framework/src/test/resources/soliditycode/create2contract.sol delete mode 100644 framework/src/test/resources/soliditycode/create2contract22.sol delete mode 100644 framework/src/test/resources/soliditycode/create2contractn.sol delete mode 100644 framework/src/test/resources/soliditycode/create2contractn2.sol delete mode 100644 framework/src/test/resources/soliditycode/demo.sol delete mode 100644 framework/src/test/resources/soliditycode/enumAndStruct.sol delete mode 100644 framework/src/test/resources/soliditycode/event001.sol delete mode 100644 framework/src/test/resources/soliditycode/event002.sol delete mode 100644 framework/src/test/resources/soliditycode/eventLog2.sol delete mode 100644 framework/src/test/resources/soliditycode/extCodeHash.sol delete mode 100644 framework/src/test/resources/soliditycode/extCodeHash11.sol delete mode 100644 framework/src/test/resources/soliditycode/extCodeHashConstruct.sol delete mode 100644 framework/src/test/resources/soliditycode/extCodeHashStress.sol delete mode 100644 framework/src/test/resources/soliditycode/extCodeHashTestNoPayable.sol delete mode 100644 framework/src/test/resources/soliditycode/fallbackUpgrade.sol delete mode 100644 framework/src/test/resources/soliditycode/freezeContract001.sol delete mode 100644 framework/src/test/resources/soliditycode/function_type_array_to_storage.sol delete mode 100644 framework/src/test/resources/soliditycode/getAddressChange.sol delete mode 100644 framework/src/test/resources/soliditycode/isSRCandidate.sol delete mode 100644 framework/src/test/resources/soliditycode/mappingGetter.sol delete mode 100644 framework/src/test/resources/soliditycode/multiValiSignPerformance01.sol delete mode 100644 framework/src/test/resources/soliditycode/multiValiSignPerformance02.sol delete mode 100644 framework/src/test/resources/soliditycode/multivalidatesign.sol delete mode 100644 framework/src/test/resources/soliditycode/multivalidatesign001.sol delete mode 100644 framework/src/test/resources/soliditycode/multivalidatesign002.sol delete mode 100644 framework/src/test/resources/soliditycode/multivalidatesign003.sol delete mode 100644 framework/src/test/resources/soliditycode/multivalidatesign005.sol delete mode 100644 framework/src/test/resources/soliditycode/multivalidatesign007.sol delete mode 100644 framework/src/test/resources/soliditycode/multivalidatesign02.sol delete mode 100644 framework/src/test/resources/soliditycode/negativeArray.sol delete mode 100644 framework/src/test/resources/soliditycode/opCode.sol delete mode 100644 framework/src/test/resources/soliditycode/override002.sol delete mode 100644 framework/src/test/resources/soliditycode/override003.sol delete mode 100644 framework/src/test/resources/soliditycode/override004.sol delete mode 100644 framework/src/test/resources/soliditycode/override005.sol delete mode 100644 framework/src/test/resources/soliditycode/overridePrivateFunction.sol delete mode 100644 framework/src/test/resources/soliditycode/payable001.sol delete mode 100644 framework/src/test/resources/soliditycode/pedersenHash001.sol delete mode 100644 framework/src/test/resources/soliditycode/pedersenHash002.sol delete mode 100644 framework/src/test/resources/soliditycode/requireExceptiontest1TestRequireContract.sol delete mode 100644 framework/src/test/resources/soliditycode/requireExceptiontest2TestThrowsContract.sol delete mode 100644 framework/src/test/resources/soliditycode/requireExceptiontest3TestRevertContract.sol delete mode 100644 framework/src/test/resources/soliditycode/requireExceptiontest4noPayableContract.sol delete mode 100644 framework/src/test/resources/soliditycode/requireExceptiontest4noPayableContract_1.sol delete mode 100644 framework/src/test/resources/soliditycode/requireExceptiontest5noPayableConstructor.sol delete mode 100644 framework/src/test/resources/soliditycode/requireExceptiontest5noPayableConstructor_1.sol delete mode 100644 framework/src/test/resources/soliditycode/requireExceptiontest6transferTestContract.sol delete mode 100644 framework/src/test/resources/soliditycode/requireExceptiontest7payableFallbakContract.sol delete mode 100644 framework/src/test/resources/soliditycode/requireExceptiontest8newContractGasNoenough.sol delete mode 100644 framework/src/test/resources/soliditycode/requireExceptiontest9MessageUsedErrorFeed.sol delete mode 100644 framework/src/test/resources/soliditycode/requireExceptiontestFunctionUsedErrorFeed.sol delete mode 100644 framework/src/test/resources/soliditycode/selector.sol delete mode 100644 framework/src/test/resources/soliditycode/slotAndOffsetNewGrammer.sol delete mode 100644 framework/src/test/resources/soliditycode/stackContract001.sol delete mode 100644 framework/src/test/resources/soliditycode/stackSuicide001.sol delete mode 100644 framework/src/test/resources/soliditycode/stateVariableShadowing.sol delete mode 100644 framework/src/test/resources/soliditycode/stringSplit.sol delete mode 100644 framework/src/test/resources/soliditycode/suicide001.sol delete mode 100644 framework/src/test/resources/soliditycode/suicide002.sol delete mode 100644 framework/src/test/resources/soliditycode/super_skip_unimplemented_in_abstract_contract.sol delete mode 100644 framework/src/test/resources/soliditycode/testGetFilterChange.sol delete mode 100644 framework/src/test/resources/soliditycode/testOutOfMem.sol delete mode 100644 framework/src/test/resources/soliditycode/testStakeSuicide.sol delete mode 100644 framework/src/test/resources/soliditycode/tryCatch001.sol delete mode 100644 framework/src/test/resources/soliditycode/tvmAssetIssue001.sol delete mode 100644 framework/src/test/resources/soliditycode/tvmAssetIssue002.sol delete mode 100644 framework/src/test/resources/soliditycode/tvmAssetIssue003.sol delete mode 100644 framework/src/test/resources/soliditycode/tvmAssetIssue004.sol delete mode 100644 framework/src/test/resources/soliditycode/tvmAssetIssue005.sol delete mode 100644 framework/src/test/resources/soliditycode/tvmVote.sol delete mode 100644 framework/src/test/resources/soliditycode/typeName.sol delete mode 100644 framework/src/test/resources/soliditycode/unStake001.sol delete mode 100644 framework/src/test/resources/soliditycode/validatemultisign001.sol delete mode 100644 framework/src/test/resources/soliditycode/verifyTransferProof001.sol delete mode 100644 framework/src/test/resources/soliditycode/virtual001.sol delete mode 100644 framework/src/test/resources/soliditycode/walletTestMutiSign004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/AssertException002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/AssignToExternal.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/BlockHash.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/ClearAbi001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/ClearAbi005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/ConstructorDefaults.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/Create2Test023.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/Create2Test024.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/Create2Test025.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/ExtCodeHashTest010.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/ParentTypeBug.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/SafeMath.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/ShiftCommand001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/SolidityMappingFix.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TestMappings_array_pop.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TransferFailed001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TransferFailed005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TransferFailed006.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TransferFailed007.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TriggerConstant001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TriggerConstant002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TriggerConstant003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TriggerConstant004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TriggerConstant015.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TriggerConstant024.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TvmIsContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TvmIsContract001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TvmIsContract002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand043.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand103.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand107.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand108.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand109.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/TvmOldCommand001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/VerifyBurnProof001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/VerifyMintProof001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/abiencode.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/addMsg001Nonpayable.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/addMsg002View.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/addMsg003Constant.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/addMsg004Pure.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/addTransferToken001Nonpayable.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/addTransferToken001payable.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/addTransferToken002View.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/addTransferToken003Constant.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/addTransferToken004Pure.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/addTrcToken001Assemble.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/addTrcToken002Cat.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/addTrcToken002Cat_withFinny.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/addressCheckNew.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/addressCheckOld.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/altbn.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/arrayLength001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/assemblyTest.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest1DivideInt.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest2FindArgsContractMinTest.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest3ByteMinContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest4Enum.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest5MoveRight.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest6UninitializedContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest7TestAssertContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign007.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign02.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/callValueGasPure.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/calldata.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/callvalue.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/chainid001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/codeSaftySupport.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/codeSaftyUnsupport.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/constantCallStorage001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/constantCallStorage002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/constantCallStorage0425.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/constantContract001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGetterContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test1Grammar001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test2Grammar002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test3Grammar003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test4Grammar004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test5Grammar006.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test1Grammar007_1.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test1Grammar007_2.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test2Grammar008.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test3Grammar010.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test4Grammar011.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test4Grammar012.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test6Grammar013.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test1Grammar014.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test2Grammar015.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test3Grammar016.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test4Grammar017.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test5Grammar018.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test6Grammar019.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test7Grammar020.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInnerContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction006.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test1InternalTransaction007.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test2InternalTransaction008.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test3InternalTransaction009.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test4InternalTransaction010.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test4InternalTransaction010_1.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test5InternalTransaction012.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction013.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction014.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction015.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction016.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction017.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction018.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractLinkage001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractLinkage002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractLinkage003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractLinkage004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractLinkage005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractLinkage006.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractOriginEnergyLimit001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractOriginEnergyLimit004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractOtherToTrcToken.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractScenario001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractScenario002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractScenario003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractScenario004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractScenario005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractScenario006.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractScenario007.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractScenario008.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractScenario009.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractScenario010.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractScenario011.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractScenario012.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractScenario013.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractScenario014.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTest.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractToMathedFeed.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTransferToken001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken011.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken012.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken014.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken018.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken023.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken026.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken027.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken028.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken029.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken030.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken031.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken034.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken035.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_1.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_2.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_3.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_4.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_old.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken037.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken038.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken039.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken041.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken043.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken048.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken049.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken050.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken051.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken052.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken054.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken055.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken060.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken061.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken064.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken066.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken067.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken073.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken075.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken076.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken077.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken078.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken079.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcToken080.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractTrcTokenToOther.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/contractUnknownException.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/create2CallContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/create2Istanbul.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/create2contract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/create2contract22.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/create2contractn.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/create2contractn2.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/demo.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/event001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/event002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/extCodeHash.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/extCodeHash11.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/extCodeHashConstruct.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/extCodeHashStress.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/extCodeHashTestNoPayable.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/isSRCandidate.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/mappingGetter.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/multiValiSignPerformance01.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/multiValiSignPerformance02.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/multivalidatesign.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/multivalidatesign001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/multivalidatesign002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/multivalidatesign003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/multivalidatesign005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/multivalidatesign007.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/multivalidatesign02.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/negativeArray.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/payable001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/pedersenHash001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/pedersenHash002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest1TestRequireContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest2TestThrowsContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest3TestRevertContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest4noPayableContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest4noPayableContract_1.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest5noPayableConstructor.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest5noPayableConstructor_1.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest6transferTestContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest7payableFallbakContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest8newContractGasNoenough.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest9MessageUsedErrorFeed.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/requireExceptiontestFunctionUsedErrorFeed.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/selector.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/stackContract001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/stackSuicide001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/stringSplit.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/suicide001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/suicide002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/testOutOfMem.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/testStakeSuicide.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/tryCatch001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/typeName.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/unStake001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/validatemultisign001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/verifyTransferProof001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.5.15/walletTestMutiSign004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/AssertException002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/AssignToExternal.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/BlockHash.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/ClearAbi001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/ClearAbi005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/ConstructorDefaults.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/Create2Test023.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/Create2Test024.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/Create2Test025.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/ExtCodeHashTest010.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/ExternalSelector.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/NewFeature068.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/ParentTypeBug.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/SafeMath.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/ShiftCommand001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/SolidityMappingFix.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TestMappings_array_pop.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TransferFailed001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TransferFailed005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TransferFailed006.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TransferFailed007.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TriggerConstant001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TriggerConstant002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TriggerConstant003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TriggerConstant004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TriggerConstant015.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TriggerConstant024.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TvmIsContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TvmIsContract001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TvmIsContract002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand043.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand103.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand107.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand108.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand109.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/TvmOldCommand001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/VerifyBurnProof001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/VerifyMintProof001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/abiencode.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/abstract001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/abstract002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/accountAssert.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/addMsg001Nonpayable.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/addMsg002View.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/addMsg003Constant.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/addMsg004Pure.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/addTransferToken001Nonpayable.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/addTransferToken001payable.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/addTransferToken002View.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/addTransferToken003Constant.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/addTransferToken004Pure.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/addTrcToken001Assemble.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/addTrcToken002Cat.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/addTrcToken002Cat_withFinny.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/addressCheckNew.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/addressCheckOld.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/altbn.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/arrayLength001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/assemblyTest.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest1DivideInt.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest2FindArgsContractMinTest.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest3ByteMinContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest4Enum.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest5MoveRight.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest6UninitializedContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest7TestAssertContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign007.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign02.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/callValueGasPure.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/calldata.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/callvalue.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/chainid001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/codeSaftySupport.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/codeSaftyUnsupport.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/constantCallStorage001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/constantCallStorage002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/constantCallStorage0425.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/constantContract001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGetterContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test1Grammar001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test2Grammar002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test3Grammar003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test4Grammar004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test5Grammar006.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test1Grammar007_1.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test1Grammar007_2.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test2Grammar008.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test3Grammar010.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test4Grammar011.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test4Grammar012.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test6Grammar013.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test1Grammar014.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test2Grammar015.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test3Grammar016.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test4Grammar017.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test5Grammar018.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test6Grammar019.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test7Grammar020.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInnerContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction006.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test1InternalTransaction007.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test2InternalTransaction008.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test3InternalTransaction009.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test4InternalTransaction010.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test4InternalTransaction010_1.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test5InternalTransaction012.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction013.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction014.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction015.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction016.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction017.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction018.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractLinkage001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractLinkage002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractLinkage003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractLinkage004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractLinkage005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractLinkage006.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractOriginEnergyLimit001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractOriginEnergyLimit004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractOtherToTrcToken.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractScenario001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractScenario002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractScenario003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractScenario004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractScenario005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractScenario006.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractScenario007.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractScenario008.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractScenario009.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractScenario010.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractScenario011.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractScenario012.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractScenario013.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractScenario014.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTest.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractToMathedFeed.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTransferToken001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken011.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken012.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken014.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken018.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken023.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken026.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken027.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken028.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken029.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken030.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken031.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken034.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken035.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_1.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_2.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_3.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_4.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_old.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken037.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken038.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken039.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken041.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken043.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken048.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken049.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken050.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken051.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken052.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken054.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken055.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken060.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken061.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken064.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken066.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken067.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken073.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken075.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken076.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken077.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken078.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken079.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcToken080.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractTrcTokenToOther.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/contractUnknownException.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/create2CallContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/create2Istanbul.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/create2contract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/create2contract22.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/create2contractn.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/create2contractn2.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/demo.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/enumAndStruct.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/event001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/event002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/extCodeHash.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/extCodeHash11.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/extCodeHashConstruct.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/extCodeHashStress.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/extCodeHashTestNoPayable.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/fallbackUpgrade.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/freezeContract001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/getAddressChange.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/isSRCandidate.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/mappingGetter.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/multiValiSignPerformance01.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/multiValiSignPerformance02.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/multivalidatesign.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/multivalidatesign001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/multivalidatesign002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/multivalidatesign003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/multivalidatesign005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/multivalidatesign007.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/multivalidatesign02.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/negativeArray.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/override002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/override003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/override004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/override005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/overridePrivateFunction.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/payable001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/pedersenHash001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/pedersenHash002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest1TestRequireContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest2TestThrowsContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest3TestRevertContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest4noPayableContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest4noPayableContract_1.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest5noPayableConstructor.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest5noPayableConstructor_1.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest6transferTestContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest7payableFallbakContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest8newContractGasNoenough.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest9MessageUsedErrorFeed.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/requireExceptiontestFunctionUsedErrorFeed.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/selector.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/stackContract001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/stackSuicide001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/stateVariableShadowing.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/stringSplit.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/suicide001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/suicide002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/testOutOfMem.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/testStakeSuicide.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/tryCatch001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/typeName.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/unStake001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/validatemultisign001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/verifyTransferProof001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/virtual001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.6.12/walletTestMutiSign004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/AssertException002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/AssignToExternal.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/BlockHash.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/ClearAbi001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/ClearAbi005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/ConstructorDefaults.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/Create2Test023.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/Create2Test024.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/Create2Test025.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/ExtCodeHashTest010.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/ExternalSelector.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/NewFeature068.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/NewFeature076.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/ParentTypeBug.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/SafeMath.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/ShiftCommand001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/SolidityMappingFix.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TestMappings_array_pop.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TransferFailed001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TransferFailed005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TransferFailed006.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TransferFailed007.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TriggerConstant001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TriggerConstant002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TriggerConstant003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TriggerConstant004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TriggerConstant015.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TriggerConstant024.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TvmIsContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TvmIsContract001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TvmIsContract002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand043.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand103.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand107.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand108.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand109.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/TvmOldCommand001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/VerifyBurnProof001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/VerifyMintProof001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/abiencode.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/abstract001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/abstract002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/accountAssert.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/addMsg001Nonpayable.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/addMsg002View.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/addMsg003Constant.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/addMsg004Pure.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/addTransferToken001Nonpayable.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/addTransferToken001payable.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/addTransferToken002View.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/addTransferToken003Constant.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/addTransferToken004Pure.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/addTrcToken001Assemble.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/addTrcToken002Cat.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/addTrcToken002Cat_withFinny.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/addressCheckNew.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/addressCheckOld.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/altbn.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/arrayLength001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/assemblyTest.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest1DivideInt.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest2FindArgsContractMinTest.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest3ByteMinContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest4Enum.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest5MoveRight.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest6UninitializedContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest7TestAssertContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign007.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign02.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/callValueGasPure.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/calldata.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/callvalue.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/chainid001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/codeSaftySupport.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/codeSaftyUnsupport.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/constantCallStorage001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/constantCallStorage002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/constantCallStorage0425.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/constantContract001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGetterContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test1Grammar001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test2Grammar002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test3Grammar003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test4Grammar004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test5Grammar006.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test1Grammar007_1.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test1Grammar007_2.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test2Grammar008.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test3Grammar010.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test4Grammar011.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test4Grammar012.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test6Grammar013.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test1Grammar014.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test2Grammar015.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test3Grammar016.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test4Grammar017.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test5Grammar018.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test6Grammar019.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test7Grammar020.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInnerContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction006.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test1InternalTransaction007.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test2InternalTransaction008.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test3InternalTransaction009.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test4InternalTransaction010.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test4InternalTransaction010_1.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test5InternalTransaction012.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction013.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction014.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction015.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction016.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction017.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction018.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractLinkage001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractLinkage002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractLinkage003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractLinkage004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractLinkage005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractLinkage006.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractOriginEnergyLimit001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractOriginEnergyLimit004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractOtherToTrcToken.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractScenario001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractScenario002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractScenario003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractScenario004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractScenario005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractScenario006.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractScenario007.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractScenario008.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractScenario009.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractScenario010.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractScenario011.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractScenario012.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractScenario013.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractScenario014.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTest.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractToMathedFeed.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTransferToken001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken011.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken012.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken014.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken018.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken023.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken026.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken027.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken028.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken029.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken030.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken031.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken034.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken035.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_1.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_2.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_3.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_4.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_old.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken037.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken038.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken039.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken041.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken043.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken048.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken049.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken050.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken051.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken052.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken054.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken055.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken060.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken061.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken064.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken066.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken067.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken073.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken075.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken076.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken077.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken078.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken079.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcToken080.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractTrcTokenToOther.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/contractUnknownException.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/create2CallContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/create2Istanbul.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/create2contract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/create2contract22.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/create2contractn.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/create2contractn2.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/demo.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/enumAndStruct.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/event001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/event002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/extCodeHash.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/extCodeHash11.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/extCodeHashConstruct.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/extCodeHashStress.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/extCodeHashTestNoPayable.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/fallbackUpgrade.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/freezeContract001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/getAddressChange.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/isSRCandidate.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/mappingGetter.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/multiValiSignPerformance01.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/multiValiSignPerformance02.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/multivalidatesign.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/multivalidatesign001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/multivalidatesign002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/multivalidatesign003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/multivalidatesign005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/multivalidatesign007.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/multivalidatesign02.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/negativeArray.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/override002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/override003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/override004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/override005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/overridePrivateFunction.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/payable001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/pedersenHash001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/pedersenHash002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest1TestRequireContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest2TestThrowsContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest3TestRevertContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest4noPayableContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest4noPayableContract_1.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest5noPayableConstructor.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest5noPayableConstructor_1.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest6transferTestContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest7payableFallbakContract.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest8newContractGasNoenough.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest9MessageUsedErrorFeed.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/requireExceptiontestFunctionUsedErrorFeed.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/selector.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/slotAndOffsetNewGrammer.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/stackContract001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/stackSuicide001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/stateVariableShadowing.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/stringSplit.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/suicide001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/suicide002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/testOutOfMem.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/testStakeSuicide.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/tryCatch001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue002.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue003.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue004.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue005.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/typeName.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/unStake001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/validatemultisign001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/verifyTransferProof001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/virtual001.sol delete mode 100644 framework/src/test/resources/soliditycode_0.7.6/walletTestMutiSign004.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/TransferFailed001.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/TransferFailed005.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/TransferFailed007.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/addMsg001Nonpayable.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/addMsg002View.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/addMsg003Constant.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/addMsg004Pure.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/addTransferToken001Nonpayable.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/addTransferToken002View.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/addTransferToken003Constant.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/addTransferToken004Pure.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/addTrcToken001Assemble.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/addTrcToken002Cat.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/addTrcToken002Cat_withFinny.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest1DivideInt.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest2FindArgsContractMinTest.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest3ByteMinContract.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest4Enum.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest5MoveRight.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest6UninitializedContract.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest7TestAssertContract.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/codeSaftySupport.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/codeSaftyUnsupport.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGetterContract.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test1Grammar001.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test2Grammar002.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test3Grammar003.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test4Grammar004.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test5Grammar006.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test1Grammar007_1.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test1Grammar007_2.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test2Grammar008.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test3Grammar010.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test4Grammar011.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test4Grammar012.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test6Grammar013.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test1Grammar014.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test2Grammar015.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test3Grammar016.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test4Grammar017.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test5Grammar018.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test6Grammar019.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test7Grammar020.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInnerContract.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction001.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction002.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction003.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction004.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction005.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction006.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test1InternalTransaction007.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test2InternalTransaction008.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test3InternalTransaction009.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test4InternalTransaction010.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test5InternalTransaction012.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction013.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction014.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction015.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction016.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction017.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction018.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractLinkage001.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractLinkage002.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractLinkage003.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractLinkage004.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractLinkage005.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractLinkage006.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractOriginEnergyLimit001.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractOriginEnergyLimit004.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractOtherToTrcToken.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractScenario001.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractScenario002.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractScenario003.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractScenario004.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractScenario005.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractScenario006.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractScenario007.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractScenario008.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractScenario009.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractScenario010.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractScenario011.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractScenario012.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractScenario013.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractScenario014.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTest.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractToMathedFeed.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken001.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken002.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken003.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken005.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken011.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken012.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken014.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken018.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken023.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken026.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken027.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken028.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken029.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken030.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken031.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken034.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken035.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken036.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken037.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken038.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken039.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken041.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken043.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken048.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken049.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken050.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken051.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken052.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken054.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken055.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken060.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken061.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken064.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken066.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken067.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken073.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken075.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken076.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken077.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken078.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken079.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken080.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractTrcTokenToOther.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/contractUnknownException.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest1TestRequireContract.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest2TestThrowsContract.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest3TestRevertContract.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest4noPayableContract.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest5noPayableConstructor.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest6transferTestContract.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest7payableFallbakContract.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest8newContractGasNoenough.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest9MessageUsedErrorFeed.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontestFunctionUsedErrorFeed.sol delete mode 100644 framework/src/test/resources/soliditycode_v0.4.25/walletTestMutiSign004.sol delete mode 100644 framework/src/test/resources/testng.xml create mode 100644 plugins/src/test/java/org/tron/plugins/DbCopyTest.java create mode 100644 plugins/src/test/java/org/tron/plugins/DbLiteLevelDbTest.java create mode 100644 plugins/src/test/java/org/tron/plugins/DbLiteLevelDbV2Test.java create mode 100644 plugins/src/test/java/org/tron/plugins/DbLiteRocksDbTest.java create mode 100644 plugins/src/test/java/org/tron/plugins/DbLiteTest.java create mode 100644 plugins/src/test/java/org/tron/plugins/DbTest.java diff --git a/.github/ISSUE_TEMPLATE/ask-a-question.md b/.github/ISSUE_TEMPLATE/ask-a-question.md index a92239b39eb..e503998b477 100644 --- a/.github/ISSUE_TEMPLATE/ask-a-question.md +++ b/.github/ISSUE_TEMPLATE/ask-a-question.md @@ -2,27 +2,9 @@ name: Ask a question about: Something is unclear title: '' -labels: '' +labels: 'type:docs' assignees: '' --- - - - -### System information - -java-tron version: `java -jar FullNode.jar -v` -OS & Version: Windows/Linux/OSX - - -### 1. What did you do? - - - -### 2. What did you expect to see? - - - -### 3. What did you see instead? - +This should only be used in very rare cases e.g. if you are not 100% sure if something is a bug or asking a question that leads to improving the documentation. For general questions please use [Discord](https://discord.gg/cGKSsRVCGm) or [Telegram](https://t.me/TronOfficialDevelopersGroupEn). diff --git a/.github/ISSUE_TEMPLATE/report-a-bug.md b/.github/ISSUE_TEMPLATE/report-a-bug.md index 649d7e97ed1..cfadd364c21 100644 --- a/.github/ISSUE_TEMPLATE/report-a-bug.md +++ b/.github/ISSUE_TEMPLATE/report-a-bug.md @@ -2,7 +2,7 @@ name: Report a bug about: Create a report to help us improve title: '' -labels: '' +labels: 'type:bug' assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/request-a-feature.md b/.github/ISSUE_TEMPLATE/request-a-feature.md index 9047b7e6a87..5099a72008b 100644 --- a/.github/ISSUE_TEMPLATE/request-a-feature.md +++ b/.github/ISSUE_TEMPLATE/request-a-feature.md @@ -2,7 +2,7 @@ name: Request a feature about: Suggest an idea for this project title: '' -labels: '' +labels: 'type:feature' assignees: '' --- diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000000..4ab98d5cf3c --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,64 @@ +name: "CodeQL" + +on: + push: + branches: [ 'develop', 'master', 'release_**' ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ 'develop' ] + schedule: + - cron: '6 10 * * 0' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'java' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Use only 'java' to analyze code written in Java, Kotlin or both + # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/.gitignore b/.gitignore index 6309bbd79a5..3917bb44679 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,4 @@ Wallet /vm_trace/ /framework/propPath +.cache diff --git a/README.md b/README.md index 916ba25a329..4d1d7b0b3b6 100644 --- a/README.md +++ b/README.md @@ -42,15 +42,14 @@

## Table of Contents -- [What’s TRON?](#What’s-TRON) -- [Building the Source Code](#Building-the-source) - - [Getting the Source Code](#Getting-the-Source-Code) - - [Build](#Build) -- [Running java-tron](#Running-java-tron) -- [Community](#Community) -- [Contribution](#Contribution) -- [Resources](#Resources) -- [License](#License) +- [What’s TRON?](#whats-tron) +- [Building the Source Code](#building-the-source) +- [Running java-tron](#running-java-tron) +- [Community](#community) +- [Contribution](#contribution) +- [Resources](#resources) +- [Integrity Check](#integrity-check) +- [License](#license) ## What's TRON? @@ -63,7 +62,7 @@ TRON is a project dedicated to building the infrastructure for a truly decentral TRON enables large-scale development and engagement. With over 2000 transactions per second (TPS), high concurrency, low latency, and massive data transmission. It is ideal for building decentralized entertainment applications. Free features and incentive systems allow developers to create premium app experiences for users. # Building the source -Building java-tron requires `git` and `Oracle JDK 1.8` to be installed, other JDK versions are not supported yet. Make sure you operate on `Linux` and `MacOS` operating systems. +Building java-tron requires `git` and 64-bit version of `Oracle JDK 1.8` to be installed, other JDK versions are not supported yet. Make sure you operate on `Linux` and `MacOS` operating systems. Clone the repo and switch to the `master` branch @@ -79,7 +78,7 @@ $ ./gradlew clean build -x test # Running java-tron -Running java-tron requires `Oracle JDK 1.8` to be installed, other JDK versions are not supported yet. Make sure you operate on `Linux` and `MacOS` operating systems. +Running java-tron requires 64-bit version of `Oracle JDK 1.8` to be installed, other JDK versions are not supported yet. Make sure you operate on `Linux` and `MacOS` operating systems. Get the mainnet configuration file: [main_net_config.conf](https://github.com/tronprotocol/tron-deployment/blob/master/main_net_config.conf), other network configuration files can be find [here](https://github.com/tronprotocol/tron-deployment). ## Hardware Requirements diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000000..b3125ce6af1 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,7 @@ +## Supported Versions +Please see [Releases](https://github.com/tronprotocol/java-tron/releases). We recommend using the [most recently released version](https://github.com/tronprotocol/java-tron/releases/latest). + +## Reporting a Vulnerability +**Please do not file a public ticket** mentioning the vulnerability. +To find out how to report a vulnerability in TRON, visit [https://hackerone.com/tron_dao](https://hackerone.com/tron_dao?type=team) or email [bounty@tron.network](mailto:bounty@tron.network). +Please read the [disclosure policy](https://www.hackerone.com/disclosure-guidelines) for more information about publicly disclosed security vulnerabilities. diff --git a/actuator/build.gradle b/actuator/build.gradle index a230ef4ca7e..a0ce72b0ee6 100644 --- a/actuator/build.gradle +++ b/actuator/build.gradle @@ -16,8 +16,6 @@ dependencies { testImplementation "junit:junit:$junitVersion" testImplementation "org.mockito:mockito-core:$mockitoVersion" - testImplementation "org.testng:testng:$testNgVersion" - compile "org.slf4j:jcl-over-slf4j:$slf4jVersion" compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.69' compile group: 'commons-codec', name: 'commons-codec', version: '1.11' @@ -49,34 +47,15 @@ test { } } -task testng(type: Test) { - useTestNG() - testLogging { - events = ["skipped", "failed"] - exceptionFormat = "full" - - debug.events = ["skipped", "failed"] - debug.exceptionFormat = "full" - - info.events = ["failed", "skipped"] - info.exceptionFormat = "full" - - warn.events = ["failed", "skipped"] - warn.exceptionFormat = "full" - } -} - jacocoTestReport { reports { xml.enabled = true html.enabled = true } - executionData.from = '../framework/build/jacoco/jacocoTest.exec' + getExecutionData().setFrom(fileTree('../framework/build/jacoco').include("**.exec")) afterEvaluate { classDirectories.from = classDirectories.files.collect { fileTree(dir: it,) } } } - -check.dependsOn testng diff --git a/actuator/src/main/java/org/tron/core/actuator/CancelAllUnfreezeV2Actuator.java b/actuator/src/main/java/org/tron/core/actuator/CancelAllUnfreezeV2Actuator.java index 527c88115ac..048f703e9f7 100755 --- a/actuator/src/main/java/org/tron/core/actuator/CancelAllUnfreezeV2Actuator.java +++ b/actuator/src/main/java/org/tron/core/actuator/CancelAllUnfreezeV2Actuator.java @@ -58,6 +58,11 @@ public boolean execute(Object result) throws ContractExeException { List unfrozenV2List = ownerCapsule.getUnfrozenV2List(); long now = dynamicStore.getLatestBlockHeaderTimestamp(); AtomicLong atomicWithdrawExpireBalance = new AtomicLong(0L); + /* The triple object is defined by resource type, with left representing the pair object + corresponding to bandwidth, middle representing the pair object corresponding to energy, and + right representing the pair object corresponding to tron power. The pair object for each + resource type, left represents resource weight, and right represents the number of unfreeze + resources for that resource type. */ Triple, Pair, Pair> triple = Triple.of( Pair.of(new AtomicLong(0L), new AtomicLong(0L)), diff --git a/actuator/src/main/java/org/tron/core/actuator/DelegateResourceActuator.java b/actuator/src/main/java/org/tron/core/actuator/DelegateResourceActuator.java index c54c00b5697..161f22cfb17 100755 --- a/actuator/src/main/java/org/tron/core/actuator/DelegateResourceActuator.java +++ b/actuator/src/main/java/org/tron/core/actuator/DelegateResourceActuator.java @@ -1,11 +1,14 @@ package org.tron.core.actuator; import static org.tron.core.actuator.ActuatorConstant.NOT_EXIST_STR; +import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; import static org.tron.core.config.Parameter.ChainConstant.DELEGATE_PERIOD; import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION; import static org.tron.protos.contract.Common.ResourceCode; import static org.tron.protos.contract.Common.ResourceCode.BANDWIDTH; import static org.tron.protos.contract.Common.ResourceCode.ENERGY; +import static org.tron.core.vm.utils.FreezeV2Util.getV2EnergyUsage; +import static org.tron.core.vm.utils.FreezeV2Util.getV2NetUsage; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; @@ -64,7 +67,8 @@ public boolean execute(Object result) throws ContractExeException { DynamicPropertiesStore dynamicStore = chainBaseManager.getDynamicPropertiesStore(); long delegateBalance = delegateResourceContract.getBalance(); boolean lock = delegateResourceContract.getLock(); - long lockPeriod = getLockPeriod(dynamicStore, delegateResourceContract); + long lockPeriod = getLockPeriod(dynamicStore.supportMaxDelegateLockPeriod(), + delegateResourceContract); byte[] receiverAddress = delegateResourceContract.getReceiverAddress().toByteArray(); // delegate resource to receiver @@ -143,7 +147,7 @@ public boolean validate() throws ContractValidateException { long delegateBalance = delegateResourceContract.getBalance(); if (delegateBalance < TRX_PRECISION) { - throw new ContractValidateException("delegateBalance must be more than 1TRX"); + throw new ContractValidateException("delegateBalance must be greater than or equal to 1 TRX"); } switch (delegateResourceContract.getResource()) { @@ -153,22 +157,15 @@ public boolean validate() throws ContractValidateException { long accountNetUsage = ownerCapsule.getNetUsage(); if (null != this.getTx() && this.getTx().isTransactionCreate()) { - accountNetUsage += TransactionUtil.estimateConsumeBandWidthSize(ownerCapsule, - chainBaseManager); + accountNetUsage += TransactionUtil.estimateConsumeBandWidthSize(dynamicStore, + ownerCapsule.getFrozenV2BalanceForBandwidth()); } long netUsage = (long) (accountNetUsage * TRX_PRECISION * ((double) (dynamicStore.getTotalNetWeight()) / dynamicStore.getTotalNetLimit())); - - long remainNetUsage = netUsage - - ownerCapsule.getFrozenBalance() - - ownerCapsule.getAcquiredDelegatedFrozenBalanceForBandwidth() - - ownerCapsule.getAcquiredDelegatedFrozenV2BalanceForBandwidth(); - - remainNetUsage = Math.max(0, remainNetUsage); - - if (ownerCapsule.getFrozenV2BalanceForBandwidth() - remainNetUsage < delegateBalance) { + long v2NetUsage = getV2NetUsage(ownerCapsule, netUsage); + if (ownerCapsule.getFrozenV2BalanceForBandwidth() - v2NetUsage < delegateBalance) { throw new ContractValidateException( - "delegateBalance must be less than available FreezeBandwidthV2 balance"); + "delegateBalance must be less than or equal to available FreezeBandwidthV2 balance"); } } break; @@ -178,17 +175,10 @@ public boolean validate() throws ContractValidateException { long energyUsage = (long) (ownerCapsule.getEnergyUsage() * TRX_PRECISION * ((double) (dynamicStore.getTotalEnergyWeight()) / dynamicStore.getTotalEnergyCurrentLimit())); - - long remainEnergyUsage = energyUsage - - ownerCapsule.getEnergyFrozenBalance() - - ownerCapsule.getAcquiredDelegatedFrozenBalanceForEnergy() - - ownerCapsule.getAcquiredDelegatedFrozenV2BalanceForEnergy(); - - remainEnergyUsage = Math.max(0, remainEnergyUsage); - - if (ownerCapsule.getFrozenV2BalanceForEnergy() - remainEnergyUsage < delegateBalance) { + long v2EnergyUsage = getV2EnergyUsage(ownerCapsule, energyUsage); + if (ownerCapsule.getFrozenV2BalanceForEnergy() - v2EnergyUsage < delegateBalance) { throw new ContractValidateException( - "delegateBalance must be less than available FreezeEnergyV2 balance"); + "delegateBalance must be less than or equal to available FreezeEnergyV2 balance"); } } break; @@ -199,7 +189,7 @@ public boolean validate() throws ContractValidateException { byte[] receiverAddress = delegateResourceContract.getReceiverAddress().toByteArray(); - if (ArrayUtils.isEmpty(receiverAddress) || !DecodeUtil.addressValid(receiverAddress)) { + if (!DecodeUtil.addressValid(receiverAddress)) { throw new ContractValidateException("Invalid receiverAddress"); } @@ -219,7 +209,7 @@ public boolean validate() throws ContractValidateException { boolean lock = delegateResourceContract.getLock(); if (lock && dynamicStore.supportMaxDelegateLockPeriod()) { - long lockPeriod = getLockPeriod(dynamicStore, delegateResourceContract); + long lockPeriod = getLockPeriod(true, delegateResourceContract); long maxDelegateLockPeriod = dynamicStore.getMaxDelegateLockPeriod(); if (lockPeriod < 0 || lockPeriod > maxDelegateLockPeriod) { throw new ContractValidateException( @@ -257,20 +247,20 @@ public boolean validate() throws ContractValidateException { return true; } - private long getLockPeriod(DynamicPropertiesStore dynamicStore, + private long getLockPeriod(boolean supportMaxDelegateLockPeriod, DelegateResourceContract delegateResourceContract) { long lockPeriod = delegateResourceContract.getLockPeriod(); - if (dynamicStore.supportMaxDelegateLockPeriod()) { - return lockPeriod == 0 ? DELEGATE_PERIOD / 3000 : lockPeriod; + if (supportMaxDelegateLockPeriod) { + return lockPeriod == 0 ? DELEGATE_PERIOD / BLOCK_PRODUCED_INTERVAL : lockPeriod; } else { - return 0; + return DELEGATE_PERIOD / BLOCK_PRODUCED_INTERVAL; } } private void validRemainTime(ResourceCode resourceCode, long lockPeriod, long expireTime, long now) throws ContractValidateException { long remainTime = expireTime - now; - if (lockPeriod * 3 * 1000 < remainTime) { + if (lockPeriod * BLOCK_PRODUCED_INTERVAL < remainTime) { throw new ContractValidateException( "The lock period for " + resourceCode.name() + " this time cannot be less than the " + "remaining time[" + remainTime + "ms] of the last lock period for " @@ -303,11 +293,7 @@ private void delegateResource(byte[] ownerAddress, byte[] receiverAddress, boole //modify DelegatedResourceStore long expireTime = 0; if (lock) { - if (dynamicPropertiesStore.supportMaxDelegateLockPeriod()) { - expireTime = now + lockPeriod * 3 * 1000; - } else { - expireTime = now + DELEGATE_PERIOD; - } + expireTime = now + lockPeriod * BLOCK_PRODUCED_INTERVAL; } byte[] key = DelegatedResourceCapsule.createDbKeyV2(ownerAddress, receiverAddress, lock); DelegatedResourceCapsule delegatedResourceCapsule = delegatedResourceStore.get(key); diff --git a/actuator/src/main/java/org/tron/core/actuator/FreezeBalanceActuator.java b/actuator/src/main/java/org/tron/core/actuator/FreezeBalanceActuator.java index 0cfd981217f..421b4e3013a 100755 --- a/actuator/src/main/java/org/tron/core/actuator/FreezeBalanceActuator.java +++ b/actuator/src/main/java/org/tron/core/actuator/FreezeBalanceActuator.java @@ -189,7 +189,7 @@ public boolean validate() throws ContractValidateException { throw new ContractValidateException("frozenBalance must be positive"); } if (frozenBalance < TRX_PRECISION) { - throw new ContractValidateException("frozenBalance must be more than 1TRX"); + throw new ContractValidateException("frozenBalance must be greater than or equal to 1 TRX"); } int frozenCount = accountCapsule.getFrozenCount(); @@ -197,7 +197,7 @@ public boolean validate() throws ContractValidateException { throw new ContractValidateException("frozenCount must be 0 or 1"); } if (frozenBalance > accountCapsule.getBalance()) { - throw new ContractValidateException("frozenBalance must be less than accountBalance"); + throw new ContractValidateException("frozenBalance must be less than or equal to accountBalance"); } long frozenDuration = freezeBalanceContract.getFrozenDuration(); diff --git a/actuator/src/main/java/org/tron/core/actuator/FreezeBalanceV2Actuator.java b/actuator/src/main/java/org/tron/core/actuator/FreezeBalanceV2Actuator.java index 90b03e43e1a..f0e5505be9c 100755 --- a/actuator/src/main/java/org/tron/core/actuator/FreezeBalanceV2Actuator.java +++ b/actuator/src/main/java/org/tron/core/actuator/FreezeBalanceV2Actuator.java @@ -54,8 +54,8 @@ public boolean execute(Object result) throws ContractExeException { accountCapsule.initializeOldTronPower(); } - long newBalance = accountCapsule.getBalance() - freezeBalanceV2Contract.getFrozenBalance(); long frozenBalance = freezeBalanceV2Contract.getFrozenBalance(); + long newBalance = accountCapsule.getBalance() - frozenBalance; switch (freezeBalanceV2Contract.getResource()) { case BANDWIDTH: @@ -133,11 +133,11 @@ public boolean validate() throws ContractValidateException { throw new ContractValidateException("frozenBalance must be positive"); } if (frozenBalance < TRX_PRECISION) { - throw new ContractValidateException("frozenBalance must be more than 1TRX"); + throw new ContractValidateException("frozenBalance must be greater than or equal to 1 TRX"); } if (frozenBalance > accountCapsule.getBalance()) { - throw new ContractValidateException("frozenBalance must be less than accountBalance"); + throw new ContractValidateException("frozenBalance must be less than or equal to accountBalance"); } switch (freezeBalanceV2Contract.getResource()) { diff --git a/actuator/src/main/java/org/tron/core/actuator/UnDelegateResourceActuator.java b/actuator/src/main/java/org/tron/core/actuator/UnDelegateResourceActuator.java index a99d462b61c..79a09664180 100755 --- a/actuator/src/main/java/org/tron/core/actuator/UnDelegateResourceActuator.java +++ b/actuator/src/main/java/org/tron/core/actuator/UnDelegateResourceActuator.java @@ -10,7 +10,6 @@ import java.util.Arrays; import java.util.Objects; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.ArrayUtils; import org.tron.common.utils.DecodeUtil; import org.tron.common.utils.StringUtil; import org.tron.core.capsule.AccountCapsule; @@ -144,9 +143,8 @@ public boolean execute(Object result) throws ContractExeException { long now = chainBaseManager.getHeadSlot(); if (Objects.nonNull(receiverCapsule) && transferUsage > 0) { - ownerCapsule.setNetUsage(processor.unDelegateIncrease(ownerCapsule, receiverCapsule, - transferUsage, BANDWIDTH, now)); - ownerCapsule.setLatestConsumeTime(now); + processor.unDelegateIncrease(ownerCapsule, receiverCapsule, + transferUsage, BANDWIDTH, now); } } break; @@ -160,9 +158,7 @@ public boolean execute(Object result) throws ContractExeException { long now = chainBaseManager.getHeadSlot(); if (Objects.nonNull(receiverCapsule) && transferUsage > 0) { - ownerCapsule.setEnergyUsage(processor.unDelegateIncrease(ownerCapsule, receiverCapsule, - transferUsage, ENERGY, now)); - ownerCapsule.setLatestConsumeTimeForEnergy(now); + processor.unDelegateIncrease(ownerCapsule, receiverCapsule, transferUsage, ENERGY, now); } } break; @@ -240,7 +236,7 @@ public boolean validate() throws ContractValidateException { } byte[] receiverAddress = unDelegateResourceContract.getReceiverAddress().toByteArray(); - if (ArrayUtils.isEmpty(receiverAddress) || !DecodeUtil.addressValid(receiverAddress)) { + if (!DecodeUtil.addressValid(receiverAddress)) { throw new ContractValidateException("Invalid receiverAddress"); } if (Arrays.equals(receiverAddress, ownerAddress)) { diff --git a/actuator/src/main/java/org/tron/core/actuator/UnfreezeBalanceV2Actuator.java b/actuator/src/main/java/org/tron/core/actuator/UnfreezeBalanceV2Actuator.java index 45b05ec8bec..fb41c97f7ed 100755 --- a/actuator/src/main/java/org/tron/core/actuator/UnfreezeBalanceV2Actuator.java +++ b/actuator/src/main/java/org/tron/core/actuator/UnfreezeBalanceV2Actuator.java @@ -11,6 +11,8 @@ import com.google.common.collect.Lists; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; + +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Objects; @@ -365,19 +367,23 @@ private void updateVote(AccountCapsule accountCapsule, } // Update Owner Voting - votesCapsule.clearNewVotes(); + List addVotes = new ArrayList<>(); for (Vote vote : accountCapsule.getVotesList()) { long newVoteCount = (long) ((double) vote.getVoteCount() / totalVote * ownedTronPower / TRX_PRECISION); if (newVoteCount > 0) { - votesCapsule.addNewVotes(vote.getVoteAddress(), newVoteCount); + Vote newVote = Vote.newBuilder() + .setVoteAddress(vote.getVoteAddress()) + .setVoteCount(newVoteCount) + .build(); + addVotes.add(newVote); } } + votesCapsule.clearNewVotes(); + votesCapsule.addAllNewVotes(addVotes); votesStore.put(ownerAddress, votesCapsule); accountCapsule.clearVotes(); - for (Vote vote : votesCapsule.getNewVotes()) { - accountCapsule.addVotes(vote.getVoteAddress(), vote.getVoteCount()); - } + accountCapsule.addAllVotes(addVotes); } } \ No newline at end of file diff --git a/actuator/src/main/java/org/tron/core/actuator/WithdrawExpireUnfreezeActuator.java b/actuator/src/main/java/org/tron/core/actuator/WithdrawExpireUnfreezeActuator.java index 0c547d2b5a3..fd71ebf1404 100755 --- a/actuator/src/main/java/org/tron/core/actuator/WithdrawExpireUnfreezeActuator.java +++ b/actuator/src/main/java/org/tron/core/actuator/WithdrawExpireUnfreezeActuator.java @@ -125,8 +125,8 @@ private long getTotalWithdrawUnfreeze(List unfrozenV2List, long now) } private List getTotalWithdrawList(List unfrozenV2List, long now) { - return unfrozenV2List.stream().filter(unfrozenV2 -> (unfrozenV2.getUnfreezeAmount() > 0 - && unfrozenV2.getUnfreezeExpireTime() <= now)).collect(Collectors.toList()); + return unfrozenV2List.stream().filter(unfrozenV2 -> unfrozenV2.getUnfreezeExpireTime() <= now) + .collect(Collectors.toList()); } private List getRemainWithdrawList(List unfrozenV2List, long now) { diff --git a/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java b/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java index 0e0cc81446c..0f55bbae9b7 100644 --- a/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java +++ b/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java @@ -2,6 +2,7 @@ import static org.tron.core.Constant.DYNAMIC_ENERGY_INCREASE_FACTOR_RANGE; import static org.tron.core.Constant.DYNAMIC_ENERGY_MAX_FACTOR_RANGE; +import static org.tron.core.config.Parameter.ChainConstant.ONE_YEAR_BLOCK_NUMBERS; import org.tron.common.utils.ForkController; import org.tron.core.config.Parameter.ForkBlockVersionConsts; @@ -714,10 +715,11 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore, "Bad chain parameter id [MAX_DELEGATE_LOCK_PERIOD]"); } long maxDelegateLockPeriod = dynamicPropertiesStore.getMaxDelegateLockPeriod(); - if (value <= maxDelegateLockPeriod || value > 10512000L) { + if (value <= maxDelegateLockPeriod || value > ONE_YEAR_BLOCK_NUMBERS) { throw new ContractValidateException( "This value[MAX_DELEGATE_LOCK_PERIOD] is only allowed to be greater than " - + maxDelegateLockPeriod + " and less than or equal to 10512000 !"); + + maxDelegateLockPeriod + " and less than or equal to " + ONE_YEAR_BLOCK_NUMBERS + + " !"); } if (dynamicPropertiesStore.getUnfreezeDelayDays() == 0) { throw new ContractValidateException( diff --git a/actuator/src/main/java/org/tron/core/utils/TransactionUtil.java b/actuator/src/main/java/org/tron/core/utils/TransactionUtil.java index 462a80fa600..7044564b1e1 100644 --- a/actuator/src/main/java/org/tron/core/utils/TransactionUtil.java +++ b/actuator/src/main/java/org/tron/core/utils/TransactionUtil.java @@ -44,6 +44,7 @@ import org.tron.core.capsule.TransactionCapsule; import org.tron.core.exception.PermissionException; import org.tron.core.exception.SignatureFormatException; +import org.tron.core.store.DynamicPropertiesStore; import org.tron.protos.Protocol.Permission; import org.tron.protos.Protocol.Permission.PermissionType; import org.tron.protos.Protocol.Transaction; @@ -222,7 +223,7 @@ public TransactionSignWeight getTransactionSignWeight(Transaction trx) { } tswBuilder.setPermission(permission); if (trx.getSignatureCount() > 0) { - List approveList = new ArrayList(); + List approveList = new ArrayList<>(); long currentWeight = TransactionCapsule.checkWeight(permission, trx.getSignatureList(), Sha256Hash.hash(CommonParameter.getInstance() .isECKeyCryptoEngine(), trx.getRawData().toByteArray()), approveList); @@ -253,56 +254,24 @@ public TransactionSignWeight getTransactionSignWeight(Transaction trx) { return tswBuilder.build(); } - public static long consumeBandWidthSize( - final TransactionCapsule transactionCapsule, - ChainBaseManager chainBaseManager) { - long bytesSize; - - boolean supportVM = chainBaseManager.getDynamicPropertiesStore().supportVM(); - if (supportVM) { - bytesSize = transactionCapsule.getInstance().toBuilder().clearRet().build().getSerializedSize(); - } else { - bytesSize = transactionCapsule.getSerializedSize(); - } - - List contracts = transactionCapsule.getInstance().getRawData().getContractList(); - for (Transaction.Contract contract : contracts) { - if (contract.getType() == Contract.ContractType.ShieldedTransferContract) { - continue; - } - if (supportVM) { - bytesSize += Constant.MAX_RESULT_SIZE_IN_TX; - } - } - - return bytesSize; - } - - public static long estimateConsumeBandWidthSize(final AccountCapsule ownerCapsule, - ChainBaseManager chainBaseManager) { + public static long estimateConsumeBandWidthSize(DynamicPropertiesStore dps, long balance) { DelegateResourceContract.Builder builder; - if (chainBaseManager.getDynamicPropertiesStore().supportMaxDelegateLockPeriod()) { + if (dps.supportMaxDelegateLockPeriod()) { builder = DelegateResourceContract.newBuilder() - .setLock(true) - .setLockPeriod(chainBaseManager.getDynamicPropertiesStore().getMaxDelegateLockPeriod()) - .setBalance(ownerCapsule.getFrozenV2BalanceForBandwidth()); + .setLock(true) + .setLockPeriod(dps.getMaxDelegateLockPeriod()) + .setBalance(balance); } else { builder = DelegateResourceContract.newBuilder() - .setLock(true) - .setBalance(ownerCapsule.getFrozenV2BalanceForBandwidth()); + .setLock(true) + .setBalance(balance); } - TransactionCapsule fakeTransactionCapsule = new TransactionCapsule(builder.build() - , ContractType.DelegateResourceContract); - long size1 = consumeBandWidthSize(fakeTransactionCapsule, chainBaseManager); - + long builderSize = builder.build().getSerializedSize(); DelegateResourceContract.Builder builder2 = DelegateResourceContract.newBuilder() - .setBalance(TRX_PRECISION); - TransactionCapsule fakeTransactionCapsule2 = new TransactionCapsule(builder2.build() - , ContractType.DelegateResourceContract); - long size2 = consumeBandWidthSize(fakeTransactionCapsule2, chainBaseManager); - long addSize = Math.max(size1 - size2, 0L); + .setBalance(TRX_PRECISION); + long builder2Size = builder2.build().getSerializedSize(); + long addSize = Math.max(builderSize - builder2Size, 0L); return DELEGATE_COST_BASE_SIZE + addSize; } - } diff --git a/actuator/src/main/java/org/tron/core/vm/PrecompiledContracts.java b/actuator/src/main/java/org/tron/core/vm/PrecompiledContracts.java index 9d4aef2bf36..be7b9423f5c 100644 --- a/actuator/src/main/java/org/tron/core/vm/PrecompiledContracts.java +++ b/actuator/src/main/java/org/tron/core/vm/PrecompiledContracts.java @@ -26,7 +26,6 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import lombok.AllArgsConstructor; @@ -46,6 +45,7 @@ import org.tron.common.crypto.zksnark.BN128G2; import org.tron.common.crypto.zksnark.Fp; import org.tron.common.crypto.zksnark.PairingCheck; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.parameter.CommonParameter; import org.tron.common.runtime.ProgramResult; import org.tron.common.runtime.vm.DataWord; @@ -983,11 +983,13 @@ public Pair execute(byte[] rawData) { public static class BatchValidateSign extends PrecompiledContract { private static final ExecutorService workers; + private static final String workersName = "validate-sign-contract"; private static final int ENGERYPERSIGN = 1500; private static final int MAX_SIZE = 16; static { - workers = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() / 2 + 1); + workers = ExecutorServiceManager.newFixedThreadPool(workersName, + Runtime.getRuntime().availableProcessors() / 2 + 1); } @Override @@ -1290,10 +1292,12 @@ public static class VerifyTransferProof extends VerifyProof { private static final Integer[] SIZE = {2080, 2368, 2464, 2752}; private static final ExecutorService workersInConstantCall; private static final ExecutorService workersInNonConstantCall; + private static final String constantCallName = "verify-transfer-constant-call"; + private static final String nonConstantCallName = "verify-transfer-non-constant-call"; static { - workersInConstantCall = Executors.newFixedThreadPool(5); - workersInNonConstantCall = Executors.newFixedThreadPool(5); + workersInConstantCall = ExecutorServiceManager.newFixedThreadPool(constantCallName, 5); + workersInNonConstantCall = ExecutorServiceManager.newFixedThreadPool(nonConstantCallName, 5); } @Override diff --git a/actuator/src/main/java/org/tron/core/vm/nativecontract/DelegateResourceProcessor.java b/actuator/src/main/java/org/tron/core/vm/nativecontract/DelegateResourceProcessor.java index d0778819f2d..bff17ec0ec5 100644 --- a/actuator/src/main/java/org/tron/core/vm/nativecontract/DelegateResourceProcessor.java +++ b/actuator/src/main/java/org/tron/core/vm/nativecontract/DelegateResourceProcessor.java @@ -3,6 +3,8 @@ import static org.tron.core.actuator.ActuatorConstant.NOT_EXIST_STR; import static org.tron.core.actuator.ActuatorConstant.STORE_NOT_EXIST; import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION; +import static org.tron.core.vm.utils.FreezeV2Util.getV2EnergyUsage; +import static org.tron.core.vm.utils.FreezeV2Util.getV2NetUsage; import com.google.common.primitives.Bytes; import com.google.protobuf.ByteString; @@ -48,7 +50,7 @@ public void validate(DelegateResourceParam param, Repository repo) throws Contra } long delegateBalance = param.getDelegateBalance(); if (delegateBalance < TRX_PRECISION) { - throw new ContractValidateException("delegateBalance must be more than 1TRX"); + throw new ContractValidateException("delegateBalance must be greater than or equal to 1 TRX"); } switch (param.getResourceType()) { @@ -61,16 +63,11 @@ public void validate(DelegateResourceParam param, Repository repo) throws Contra long netUsage = (long) (ownerCapsule.getNetUsage() * TRX_PRECISION * ((double) (repo.getTotalNetWeight()) / dynamicStore.getTotalNetLimit())); - long remainNetUsage = netUsage - - ownerCapsule.getFrozenBalance() - - ownerCapsule.getAcquiredDelegatedFrozenBalanceForBandwidth() - - ownerCapsule.getAcquiredDelegatedFrozenV2BalanceForBandwidth(); + long v2NetUsage = getV2NetUsage(ownerCapsule, netUsage); - remainNetUsage = Math.max(0, remainNetUsage); - - if (ownerCapsule.getFrozenV2BalanceForBandwidth() - remainNetUsage < delegateBalance) { + if (ownerCapsule.getFrozenV2BalanceForBandwidth() - v2NetUsage < delegateBalance) { throw new ContractValidateException( - "delegateBalance must be less than available FreezeBandwidthV2 balance"); + "delegateBalance must be less than or equal to available FreezeBandwidthV2 balance"); } } break; @@ -81,16 +78,11 @@ public void validate(DelegateResourceParam param, Repository repo) throws Contra long energyUsage = (long) (ownerCapsule.getEnergyUsage() * TRX_PRECISION * ((double) (repo.getTotalEnergyWeight()) / dynamicStore.getTotalEnergyCurrentLimit())); - long remainEnergyUsage = energyUsage - - ownerCapsule.getEnergyFrozenBalance() - - ownerCapsule.getAcquiredDelegatedFrozenBalanceForEnergy() - - ownerCapsule.getAcquiredDelegatedFrozenV2BalanceForEnergy(); - - remainEnergyUsage = Math.max(0, remainEnergyUsage); + long v2EnergyUsage = getV2EnergyUsage(ownerCapsule, energyUsage); - if (ownerCapsule.getFrozenV2BalanceForEnergy() - remainEnergyUsage < delegateBalance) { + if (ownerCapsule.getFrozenV2BalanceForEnergy() - v2EnergyUsage < delegateBalance) { throw new ContractValidateException( - "delegateBalance must be less than available FreezeEnergyV2 balance"); + "delegateBalance must be less than or equal to available FreezeEnergyV2 balance"); } } break; @@ -101,7 +93,7 @@ public void validate(DelegateResourceParam param, Repository repo) throws Contra byte[] receiverAddress = param.getReceiverAddress(); - if (ArrayUtils.isEmpty(receiverAddress) || !DecodeUtil.addressValid(receiverAddress)) { + if (!DecodeUtil.addressValid(receiverAddress)) { throw new ContractValidateException("Invalid receiverAddress"); } if (Arrays.equals(receiverAddress, ownerAddress)) { diff --git a/actuator/src/main/java/org/tron/core/vm/nativecontract/FreezeBalanceProcessor.java b/actuator/src/main/java/org/tron/core/vm/nativecontract/FreezeBalanceProcessor.java index c5c8fa91344..3088527ace6 100644 --- a/actuator/src/main/java/org/tron/core/vm/nativecontract/FreezeBalanceProcessor.java +++ b/actuator/src/main/java/org/tron/core/vm/nativecontract/FreezeBalanceProcessor.java @@ -30,9 +30,9 @@ public void validate(FreezeBalanceParam param, Repository repo) throws ContractV if (frozenBalance <= 0) { throw new ContractValidateException("FrozenBalance must be positive"); } else if (frozenBalance < TRX_PRECISION) { - throw new ContractValidateException("FrozenBalance must be more than 1TRX"); + throw new ContractValidateException("FrozenBalance must be greater than or equal to 1 TRX"); } else if (frozenBalance > ownerCapsule.getBalance()) { - throw new ContractValidateException("FrozenBalance must be less than accountBalance"); + throw new ContractValidateException("FrozenBalance must be less than or equal to accountBalance"); } // validate frozen count of owner account diff --git a/actuator/src/main/java/org/tron/core/vm/nativecontract/FreezeBalanceV2Processor.java b/actuator/src/main/java/org/tron/core/vm/nativecontract/FreezeBalanceV2Processor.java index b3dd258ae59..e7e932194ed 100644 --- a/actuator/src/main/java/org/tron/core/vm/nativecontract/FreezeBalanceV2Processor.java +++ b/actuator/src/main/java/org/tron/core/vm/nativecontract/FreezeBalanceV2Processor.java @@ -37,9 +37,10 @@ public void validate(FreezeBalanceV2Param param, Repository repo) throws Contrac if (frozenBalance <= 0) { throw new ContractValidateException("FrozenBalance must be positive"); } else if (frozenBalance < TRX_PRECISION) { - throw new ContractValidateException("FrozenBalance must be more than 1TRX"); + throw new ContractValidateException("FrozenBalance must be greater than or equal to 1 TRX"); } else if (frozenBalance > ownerCapsule.getBalance()) { - throw new ContractValidateException("FrozenBalance must be less than accountBalance"); + throw new ContractValidateException( + "FrozenBalance must be less than or equal to accountBalance"); } // validate arg @resourceType diff --git a/actuator/src/main/java/org/tron/core/vm/nativecontract/UnDelegateResourceProcessor.java b/actuator/src/main/java/org/tron/core/vm/nativecontract/UnDelegateResourceProcessor.java index 62fd3c0635b..1d40d5cd3d9 100644 --- a/actuator/src/main/java/org/tron/core/vm/nativecontract/UnDelegateResourceProcessor.java +++ b/actuator/src/main/java/org/tron/core/vm/nativecontract/UnDelegateResourceProcessor.java @@ -10,7 +10,6 @@ import java.util.Arrays; import java.util.Objects; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.ArrayUtils; import org.tron.common.utils.DecodeUtil; import org.tron.common.utils.StringUtil; import org.tron.core.capsule.AccountCapsule; @@ -48,7 +47,7 @@ public void validate(UnDelegateResourceParam param, Repository repo) throws Cont } byte[] receiverAddress = param.getReceiverAddress(); - if (ArrayUtils.isEmpty(receiverAddress) || !DecodeUtil.addressValid(receiverAddress)) { + if (!DecodeUtil.addressValid(receiverAddress)) { throw new ContractValidateException("Invalid receiverAddress"); } if (Arrays.equals(receiverAddress, ownerAddress)) { @@ -104,7 +103,9 @@ public void execute(UnDelegateResourceParam param, Repository repo) { repo.getAccountStore(), repo.getAssetIssueStore(), repo.getAssetIssueV2Store()); bandwidthProcessor.updateUsageForDelegated(receiverCapsule); - + /* For example, in a scenario where a regular account can be upgraded to a contract + account through an interface, the account information will be cleared after the + contract suicide, and this account will be converted to a regular account in the future */ if (receiverCapsule.getAcquiredDelegatedFrozenV2BalanceForBandwidth() < unDelegateBalance) { // A TVM contract suicide, re-create will produce this situation @@ -169,9 +170,8 @@ public void execute(UnDelegateResourceParam param, Repository repo) { repo.getAccountStore(), repo.getAssetIssueStore(), repo.getAssetIssueV2Store()); if (Objects.nonNull(receiverCapsule) && transferUsage > 0) { - ownerCapsule.setNetUsage(processor.unDelegateIncrease(ownerCapsule, receiverCapsule, - transferUsage, BANDWIDTH, now)); - ownerCapsule.setLatestConsumeTime(now); + processor.unDelegateIncrease(ownerCapsule, receiverCapsule, + transferUsage, BANDWIDTH, now); } } break; @@ -184,9 +184,7 @@ public void execute(UnDelegateResourceParam param, Repository repo) { EnergyProcessor processor = new EnergyProcessor(dynamicStore, repo.getAccountStore()); if (Objects.nonNull(receiverCapsule) && transferUsage > 0) { - ownerCapsule.setEnergyUsage(processor.unDelegateIncrease(ownerCapsule, receiverCapsule, - transferUsage, ENERGY, now)); - ownerCapsule.setLatestConsumeTimeForEnergy(now); + processor.unDelegateIncrease(ownerCapsule, receiverCapsule, transferUsage, ENERGY, now); } } break; diff --git a/actuator/src/main/java/org/tron/core/vm/nativecontract/WithdrawExpireUnfreezeProcessor.java b/actuator/src/main/java/org/tron/core/vm/nativecontract/WithdrawExpireUnfreezeProcessor.java index da08a002677..0bcdb10d46f 100644 --- a/actuator/src/main/java/org/tron/core/vm/nativecontract/WithdrawExpireUnfreezeProcessor.java +++ b/actuator/src/main/java/org/tron/core/vm/nativecontract/WithdrawExpireUnfreezeProcessor.java @@ -60,8 +60,8 @@ private long getTotalWithdrawUnfreeze(List unfrozen } private List getTotalWithdrawList(List unfrozenV2List, long now) { - return unfrozenV2List.stream().filter(unfrozenV2 -> (unfrozenV2.getUnfreezeAmount() > 0 - && unfrozenV2.getUnfreezeExpireTime() <= now)).collect(Collectors.toList()); + return unfrozenV2List.stream().filter(unfrozenV2 -> unfrozenV2.getUnfreezeExpireTime() <= now) + .collect(Collectors.toList()); } public long execute(WithdrawExpireUnfreezeParam param, Repository repo) throws ContractExeException { diff --git a/actuator/src/main/java/org/tron/core/vm/program/Program.java b/actuator/src/main/java/org/tron/core/vm/program/Program.java index 6d5f87b91bb..3e86c3042b0 100644 --- a/actuator/src/main/java/org/tron/core/vm/program/Program.java +++ b/actuator/src/main/java/org/tron/core/vm/program/Program.java @@ -9,6 +9,10 @@ import static org.apache.commons.lang3.ArrayUtils.nullToEmpty; import static org.tron.common.utils.ByteUtil.stripLeadingZeroes; import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION; +import static org.tron.protos.contract.Common.ResourceCode.BANDWIDTH; +import static org.tron.protos.contract.Common.ResourceCode.ENERGY; +import static org.tron.protos.contract.Common.ResourceCode.TRON_POWER; +import static org.tron.protos.contract.Common.ResourceCode.UNRECOGNIZED; import com.google.protobuf.ByteString; import java.math.BigInteger; @@ -556,15 +560,8 @@ private long transferFrozenV2BalanceToInheritor(byte[] ownerAddr, byte[] inherit bandwidthProcessor.updateUsageForDelegated(ownerCapsule); ownerCapsule.setLatestConsumeTime(now); if (ownerCapsule.getNetUsage() > 0) { - long newNetUsage = - bandwidthProcessor.unDelegateIncrease( - inheritorCapsule, - ownerCapsule, - ownerCapsule.getNetUsage(), - Common.ResourceCode.BANDWIDTH, - now); - inheritorCapsule.setNetUsage(newNetUsage); - inheritorCapsule.setLatestConsumeTime(now); + bandwidthProcessor.unDelegateIncrease(inheritorCapsule, ownerCapsule, + ownerCapsule.getNetUsage(), BANDWIDTH, now); } EnergyProcessor energyProcessor = @@ -573,15 +570,8 @@ private long transferFrozenV2BalanceToInheritor(byte[] ownerAddr, byte[] inherit energyProcessor.updateUsage(ownerCapsule); ownerCapsule.setLatestConsumeTimeForEnergy(now); if (ownerCapsule.getEnergyUsage() > 0) { - long newEnergyUsage = - energyProcessor.unDelegateIncrease( - inheritorCapsule, - ownerCapsule, - ownerCapsule.getEnergyUsage(), - Common.ResourceCode.ENERGY, - now); - inheritorCapsule.setEnergyUsage(newEnergyUsage); - inheritorCapsule.setLatestConsumeTimeForEnergy(now); + energyProcessor.unDelegateIncrease(inheritorCapsule, ownerCapsule, + ownerCapsule.getEnergyUsage(), ENERGY, now); } // withdraw expire unfrozen balance @@ -608,9 +598,9 @@ private long transferFrozenV2BalanceToInheritor(byte[] ownerAddr, byte[] inherit private void clearOwnerFreezeV2(AccountCapsule ownerCapsule) { ownerCapsule.clearFrozenV2(); ownerCapsule.setNetUsage(0); - ownerCapsule.setNewWindowSize(Common.ResourceCode.BANDWIDTH, 0); + ownerCapsule.setNewWindowSize(BANDWIDTH, 0); ownerCapsule.setEnergyUsage(0); - ownerCapsule.setNewWindowSize(Common.ResourceCode.ENERGY, 0); + ownerCapsule.setNewWindowSize(ENERGY, 0); ownerCapsule.clearUnfrozenV2(); } @@ -2091,11 +2081,11 @@ public boolean unDelegateResource( private Common.ResourceCode parseResourceCode(DataWord resourceType) { switch (resourceType.intValue()) { case 0: - return Common.ResourceCode.BANDWIDTH; + return BANDWIDTH; case 1: - return Common.ResourceCode.ENERGY; + return ENERGY; default: - return Common.ResourceCode.UNRECOGNIZED; + return UNRECOGNIZED; } } @@ -2104,13 +2094,13 @@ private Common.ResourceCode parseResourceCodeV2(DataWord resourceType) { byte type = resourceType.sValue().byteValueExact(); switch (type) { case 0: - return Common.ResourceCode.BANDWIDTH; + return BANDWIDTH; case 1: - return Common.ResourceCode.ENERGY; + return ENERGY; case 2: - return Common.ResourceCode.TRON_POWER; + return TRON_POWER; default: - return Common.ResourceCode.UNRECOGNIZED; + return UNRECOGNIZED; } } catch (ArithmeticException e) { logger.warn("TVM ParseResourceCodeV2: invalid resource code: {}", resourceType.sValue()); diff --git a/actuator/src/main/java/org/tron/core/vm/utils/FreezeV2Util.java b/actuator/src/main/java/org/tron/core/vm/utils/FreezeV2Util.java index 9a22f796228..7bc760f9edf 100644 --- a/actuator/src/main/java/org/tron/core/vm/utils/FreezeV2Util.java +++ b/actuator/src/main/java/org/tron/core/vm/utils/FreezeV2Util.java @@ -12,8 +12,6 @@ import org.tron.core.vm.repository.Repository; import org.tron.protos.Protocol; -import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION; - public class FreezeV2Util { private FreezeV2Util() { @@ -163,13 +161,8 @@ public static long queryDelegatableResource(byte[] address, long type, Repositor return frozenV2Resource; } - long remainNetUsage = usage - - accountCapsule.getFrozenBalance() - - accountCapsule.getAcquiredDelegatedFrozenBalanceForBandwidth() - - accountCapsule.getAcquiredDelegatedFrozenV2BalanceForBandwidth(); - - remainNetUsage = Math.max(0, remainNetUsage); - return Math.max(0L, frozenV2Resource - remainNetUsage); + long v2NetUsage = getV2NetUsage(accountCapsule, usage); + return Math.max(0L, frozenV2Resource - v2NetUsage); } if (type == 1) { @@ -188,13 +181,8 @@ public static long queryDelegatableResource(byte[] address, long type, Repositor return frozenV2Resource; } - long remainEnergyUsage = usage - - accountCapsule.getEnergyFrozenBalance() - - accountCapsule.getAcquiredDelegatedFrozenBalanceForEnergy() - - accountCapsule.getAcquiredDelegatedFrozenV2BalanceForEnergy(); - - remainEnergyUsage = Math.max(0, remainEnergyUsage); - return Math.max(0L, frozenV2Resource - remainEnergyUsage); + long v2EnergyUsage = getV2EnergyUsage(accountCapsule, usage); + return Math.max(0L, frozenV2Resource - v2EnergyUsage); } return 0L; @@ -246,8 +234,24 @@ private static long getTotalWithdrawUnfreeze(List u } private static List getTotalWithdrawList(List unfrozenV2List, long now) { - return unfrozenV2List.stream().filter(unfrozenV2 -> (unfrozenV2.getUnfreezeAmount() > 0 - && unfrozenV2.getUnfreezeExpireTime() <= now)).collect(Collectors.toList()); + return unfrozenV2List.stream().filter(unfrozenV2 -> unfrozenV2.getUnfreezeExpireTime() <= now) + .collect(Collectors.toList()); + } + + public static long getV2NetUsage(AccountCapsule ownerCapsule, long netUsage) { + long v2NetUsage= netUsage + - ownerCapsule.getFrozenBalance() + - ownerCapsule.getAcquiredDelegatedFrozenBalanceForBandwidth() + - ownerCapsule.getAcquiredDelegatedFrozenV2BalanceForBandwidth(); + return Math.max(0, v2NetUsage); + } + + public static long getV2EnergyUsage(AccountCapsule ownerCapsule, long energyUsage) { + long v2EnergyUsage= energyUsage + - ownerCapsule.getEnergyFrozenBalance() + - ownerCapsule.getAcquiredDelegatedFrozenBalanceForEnergy() + - ownerCapsule.getAcquiredDelegatedFrozenV2BalanceForEnergy(); + return Math.max(0, v2EnergyUsage); } } diff --git a/build.gradle b/build.gradle index 58cfab2667f..2e1803fad4b 100644 --- a/build.gradle +++ b/build.gradle @@ -78,12 +78,6 @@ subprojects { details.useVersion "4.1.27.Final" } } - resolutionStrategy.eachDependency { details -> - // TODO if update grpc remove - if(details.requested.group == 'io.netty') { - details.useVersion "4.1.27.Final" - } - } } } diff --git a/chainbase/build.gradle b/chainbase/build.gradle index 5c9a874227e..f2f37cc4ec1 100644 --- a/chainbase/build.gradle +++ b/chainbase/build.gradle @@ -33,8 +33,6 @@ dependencies { testImplementation "junit:junit:$junitVersion" testImplementation "org.mockito:mockito-core:$mockitoVersion" - testImplementation "org.testng:testng:$testNgVersion" - compile group: leveldbGroup, name: leveldbName, version: leveldbVersion compile "org.fusesource.jansi:jansi:$jansiVersion" compile group: 'org.rocksdb', name: 'rocksdbjni', version: '7.7.3' @@ -74,25 +72,6 @@ test { } } -task testng(type: Test) { - useTestNG() - testLogging { - events = ["skipped", "failed"] - exceptionFormat = "full" - - debug.events = ["skipped", "failed"] - debug.exceptionFormat = "full" - - info.events = ["failed", "skipped"] - info.exceptionFormat = "full" - - warn.events = ["failed", "skipped"] - warn.exceptionFormat = "full" - } -} - -check.dependsOn testng - jacoco { toolVersion = jacocoVersion // See http://www.eclemma.org/jacoco/. } @@ -102,7 +81,7 @@ jacocoTestReport { xml.enabled = true html.enabled = true } - executionData.from = '../framework/build/jacoco/jacocoTest.exec' + getExecutionData().setFrom(fileTree('../framework/build/jacoco').include("**.exec")) afterEvaluate { classDirectories.from = classDirectories.files.collect { fileTree(dir: it,) diff --git a/chainbase/src/main/java/org/tron/common/storage/leveldb/LevelDbDataSourceImpl.java b/chainbase/src/main/java/org/tron/common/storage/leveldb/LevelDbDataSourceImpl.java index 2292f974c4b..43a24ff4416 100644 --- a/chainbase/src/main/java/org/tron/common/storage/leveldb/LevelDbDataSourceImpl.java +++ b/chainbase/src/main/java/org/tron/common/storage/leveldb/LevelDbDataSourceImpl.java @@ -142,11 +142,22 @@ private void openDatabase(Options dbOptions) throws IOException { if (!Files.isSymbolicLink(dbPath.getParent())) { Files.createDirectories(dbPath.getParent()); } - database = factory.open(dbPath.toFile(), dbOptions); - if (!this.getDBName().startsWith("checkpoint")) { - logger.info("DB {} open success with writeBufferSize {} M, cacheSize {} M, maxOpenFiles {}.", - this.getDBName(), dbOptions.writeBufferSize() / 1024 / 1024, - dbOptions.cacheSize() / 1024 / 1024, dbOptions.maxOpenFiles()); + try { + database = factory.open(dbPath.toFile(), dbOptions); + if (!this.getDBName().startsWith("checkpoint")) { + logger + .info("DB {} open success with writeBufferSize {} M, cacheSize {} M, maxOpenFiles {}.", + this.getDBName(), dbOptions.writeBufferSize() / 1024 / 1024, + dbOptions.cacheSize() / 1024 / 1024, dbOptions.maxOpenFiles()); + } + } catch (IOException e) { + if (e.getMessage().contains("Corruption:")) { + logger.error("Database {} corrupted, please delete database directory({}) and restart.", + dataBaseName, parentPath, e); + } else { + logger.error("Open Database {} failed", dataBaseName, e); + } + System.exit(1); } } diff --git a/chainbase/src/main/java/org/tron/common/storage/metric/DbStatService.java b/chainbase/src/main/java/org/tron/common/storage/metric/DbStatService.java index 46dbe149070..a46f676a8de 100644 --- a/chainbase/src/main/java/org/tron/common/storage/metric/DbStatService.java +++ b/chainbase/src/main/java/org/tron/common/storage/metric/DbStatService.java @@ -1,20 +1,18 @@ package org.tron.common.storage.metric; -import com.google.common.util.concurrent.ThreadFactoryBuilder; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.prometheus.Metrics; @Slf4j(topic = "metrics") @Component public class DbStatService { - private static final ScheduledExecutorService statExecutor = - Executors.newSingleThreadScheduledExecutor( - new ThreadFactoryBuilder().setNameFormat("db-stats-thread-%d").build()); - + private final String esName = "db-stats"; + private final ScheduledExecutorService statExecutor = + ExecutorServiceManager.newSingleThreadScheduledExecutor(esName); public void register(Stat stat) { if (Metrics.enabled()) { @@ -24,11 +22,7 @@ public void register(Stat stat) { public void shutdown() { if (Metrics.enabled()) { - try { - statExecutor.shutdown(); - } catch (Exception e) { - logger.error("{}", e.getMessage()); - } + ExecutorServiceManager.shutdownAndAwaitTermination(statExecutor, esName); } } } diff --git a/chainbase/src/main/java/org/tron/common/storage/rocksdb/RocksDbDataSourceImpl.java b/chainbase/src/main/java/org/tron/common/storage/rocksdb/RocksDbDataSourceImpl.java index 15a93425292..a749a9a5a64 100644 --- a/chainbase/src/main/java/org/tron/common/storage/rocksdb/RocksDbDataSourceImpl.java +++ b/chainbase/src/main/java/org/tron/common/storage/rocksdb/RocksDbDataSourceImpl.java @@ -32,6 +32,7 @@ import org.rocksdb.RocksDBException; import org.rocksdb.RocksIterator; import org.rocksdb.Statistics; +import org.rocksdb.Status; import org.rocksdb.WriteBatch; import org.rocksdb.WriteOptions; import org.slf4j.LoggerFactory; @@ -266,8 +267,13 @@ protected void log(InfoLogLevel infoLogLevel, String logMsg) { try { database = RocksDB.open(options, dbPath.toString()); } catch (RocksDBException e) { - throw new RuntimeException( - String.format("failed to open database: %s", dataBaseName), e); + if (Objects.equals(e.getStatus().getCode(), Status.Code.Corruption)) { + logger.error("Database {} corrupted, please delete database directory({}) " + + "and restart.", dataBaseName, parentPath, e); + } else { + logger.error("Open Database {} failed", dataBaseName, e); + } + System.exit(1); } alive = true; diff --git a/chainbase/src/main/java/org/tron/core/ChainBaseManager.java b/chainbase/src/main/java/org/tron/core/ChainBaseManager.java index 3418d6c15ef..f24ab4999fb 100644 --- a/chainbase/src/main/java/org/tron/core/ChainBaseManager.java +++ b/chainbase/src/main/java/org/tron/core/ChainBaseManager.java @@ -38,7 +38,6 @@ import org.tron.core.db.RecentBlockStore; import org.tron.core.db.RecentTransactionStore; import org.tron.core.db.TransactionStore; -import org.tron.core.db2.core.ITronChainBase; import org.tron.core.exception.BadItemException; import org.tron.core.exception.HeaderNotFound; import org.tron.core.exception.ItemNotFoundException; @@ -264,54 +263,6 @@ public class ChainBaseManager { @Setter private long lowestBlockNum = -1; // except num = 0. - public void closeOneStore(ITronChainBase database) { - logger.info("******** Begin to close {}. ********", database.getName()); - try { - database.close(); - } catch (Exception e) { - logger.info("Failed to close {}.", database.getName(), e); - } finally { - logger.info("******** End to close {}. ********", database.getName()); - } - } - - public void closeAllStore() { - dbStatService.shutdown(); - closeOneStore(transactionRetStore); - closeOneStore(recentBlockStore); - closeOneStore(transactionHistoryStore); - closeOneStore(transactionStore); - closeOneStore(accountStore); - closeOneStore(blockStore); - closeOneStore(blockIndexStore); - closeOneStore(accountIdIndexStore); - closeOneStore(accountIndexStore); - closeOneStore(witnessScheduleStore); - closeOneStore(assetIssueStore); - closeOneStore(dynamicPropertiesStore); - closeOneStore(abiStore); - closeOneStore(codeStore); - closeOneStore(contractStore); - closeOneStore(contractStateStore); - closeOneStore(storageRowStore); - closeOneStore(exchangeStore); - closeOneStore(proposalStore); - closeOneStore(votesStore); - closeOneStore(delegatedResourceStore); - closeOneStore(delegatedResourceAccountIndexStore); - closeOneStore(assetIssueV2Store); - closeOneStore(exchangeV2Store); - closeOneStore(nullifierStore); - closeOneStore(merkleTreeStore); - closeOneStore(delegationStore); - closeOneStore(proofStore); - closeOneStore(commonStore); - closeOneStore(commonDataBase); - closeOneStore(pbftSignDataStore); - closeOneStore(sectionBloomStore); - closeOneStore(accountAssetStore); - } - // for test only public List getWitnesses() { return witnessScheduleStore.getActiveWitnesses(); @@ -335,9 +286,7 @@ public BlockCapsule getHead() throws HeaderNotFound { } public synchronized BlockId getHeadBlockId() { - return new BlockId( - dynamicPropertiesStore.getLatestBlockHeaderHash(), - dynamicPropertiesStore.getLatestBlockHeaderNumber()); + return new BlockId(dynamicPropertiesStore.getLatestBlockHeaderHash()); } public long getHeadBlockNum() { @@ -461,6 +410,10 @@ private void init() { this.nodeType = getLowestBlockNum() > 1 ? NodeType.LITE : NodeType.FULL; } + public void shutdown() { + dbStatService.shutdown(); + } + public boolean isLiteNode() { return getNodeType() == NodeType.LITE; } diff --git a/chainbase/src/main/java/org/tron/core/capsule/AccountCapsule.java b/chainbase/src/main/java/org/tron/core/capsule/AccountCapsule.java index 3edf76e99b4..8e77bcd7c39 100644 --- a/chainbase/src/main/java/org/tron/core/capsule/AccountCapsule.java +++ b/chainbase/src/main/java/org/tron/core/capsule/AccountCapsule.java @@ -1460,6 +1460,22 @@ public void setNewWindowSizeV2( ResourceCode resourceCode, long newWindowSize) { } } + public void setUsage(ResourceCode resourceCode, long usage) { + if (resourceCode == BANDWIDTH) { + setNetUsage(usage); + } else { + setEnergyUsage(usage); + } + } + + public void setLatestTime(ResourceCode resourceCode, long time) { + if (resourceCode == BANDWIDTH) { + setLatestConsumeTime(time); + } else { + setLatestConsumeTimeForEnergy(time); + } + } + private boolean hasAssetV2(byte[] key) { if (Bytes32.ZERO.equals(this.root)) { return AssetUtil.hasAssetV2(this.account, key); diff --git a/chainbase/src/main/java/org/tron/core/capsule/BlockCapsule.java b/chainbase/src/main/java/org/tron/core/capsule/BlockCapsule.java index 10b3cb487f8..44819985688 100755 --- a/chainbase/src/main/java/org/tron/core/capsule/BlockCapsule.java +++ b/chainbase/src/main/java/org/tron/core/capsule/BlockCapsule.java @@ -57,7 +57,6 @@ public class BlockCapsule implements ProtoCapsule { private Block block; private List transactions = new ArrayList<>(); - private StringBuilder toStringBuff = new StringBuilder(); private boolean isSwitch; @Getter @Setter @@ -327,7 +326,7 @@ public boolean hasWitnessSignature() { @Override public String toString() { - toStringBuff.setLength(0); + StringBuilder toStringBuff = new StringBuilder(); toStringBuff.append("BlockCapsule \n[ "); toStringBuff.append("hash=").append(getBlockId()).append("\n"); diff --git a/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java b/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java index a33f445c15f..9598fd99a6b 100755 --- a/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java +++ b/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java @@ -33,7 +33,6 @@ import java.util.HashMap; import java.util.List; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicInteger; import lombok.Getter; @@ -43,6 +42,7 @@ import org.tron.common.crypto.ECKey.ECDSASignature; import org.tron.common.crypto.SignInterface; import org.tron.common.crypto.SignUtils; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.overlay.message.Message; import org.tron.common.parameter.CommonParameter; import org.tron.common.utils.ByteArray; @@ -86,8 +86,9 @@ @Slf4j(topic = "capsule") public class TransactionCapsule implements ProtoCapsule { - private static final ExecutorService executorService = Executors - .newFixedThreadPool(CommonParameter.getInstance() + private static final String esName = "valid-contract-proto"; + private static final ExecutorService executorService = ExecutorServiceManager + .newFixedThreadPool(esName, CommonParameter.getInstance() .getValidContractProtoThreadNum()); private static final String OWNER_ADDRESS = "ownerAddress_"; @@ -346,6 +347,10 @@ public static byte[] getOwner(Transaction.Contract contract) { } } return owner.toByteArray(); + } catch (InvalidProtocolBufferException invalidProtocolBufferException) { + logger.warn("InvalidProtocolBufferException occurred because {}, please verify the interface " + + "input parameters", invalidProtocolBufferException.getMessage()); + return new byte[0]; } catch (Exception ex) { logger.error(ex.getMessage()); return new byte[0]; diff --git a/chainbase/src/main/java/org/tron/core/db/ResourceProcessor.java b/chainbase/src/main/java/org/tron/core/db/ResourceProcessor.java index ee0142c9298..387fd09e4b1 100644 --- a/chainbase/src/main/java/org/tron/core/db/ResourceProcessor.java +++ b/chainbase/src/main/java/org/tron/core/db/ResourceProcessor.java @@ -1,7 +1,5 @@ package org.tron.core.db; -import static java.lang.Math.ceil; -import static java.lang.Math.round; import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; import static org.tron.core.config.Parameter.ChainConstant.WINDOW_SIZE_PRECISION; @@ -142,16 +140,17 @@ public long increaseV2(AccountCapsule accountCapsule, ResourceCode resourceCode, long remainWindowSize = oldWindowSizeV2 - (now - lastTime) * WINDOW_SIZE_PRECISION; long newWindowSize = divideCeil( - remainUsage * remainWindowSize + usage * this.windowSize * WINDOW_SIZE_PRECISION, newUsage); + remainUsage * remainWindowSize + usage * this.windowSize * WINDOW_SIZE_PRECISION, newUsage); newWindowSize = Math.min(newWindowSize, this.windowSize * WINDOW_SIZE_PRECISION); accountCapsule.setNewWindowSizeV2(resourceCode, newWindowSize); return newUsage; } - public long unDelegateIncrease(AccountCapsule owner, final AccountCapsule receiver, + public void unDelegateIncrease(AccountCapsule owner, final AccountCapsule receiver, long transferUsage, ResourceCode resourceCode, long now) { if (dynamicPropertiesStore.supportAllowCancelAllUnfreezeV2()) { - return unDelegateIncreaseV2(owner, receiver, transferUsage, resourceCode, now); + unDelegateIncreaseV2(owner, receiver, transferUsage, resourceCode, now); + return; } long lastOwnerTime = owner.getLastConsumeTime(resourceCode); long ownerUsage = owner.getUsage(resourceCode); @@ -167,16 +166,19 @@ public long unDelegateIncrease(AccountCapsule owner, final AccountCapsule receiv // mean ownerUsage == 0 and transferUsage == 0 if (newOwnerUsage == 0) { owner.setNewWindowSize(resourceCode, this.windowSize); - return newOwnerUsage; + owner.setUsage(resourceCode, 0); + owner.setLatestTime(resourceCode, now); + return; } // calculate new windowSize long newOwnerWindowSize = getNewWindowSize(ownerUsage, remainOwnerWindowSize, transferUsage, remainReceiverWindowSize, newOwnerUsage); owner.setNewWindowSize(resourceCode, newOwnerWindowSize); - return newOwnerUsage; + owner.setUsage(resourceCode, newOwnerUsage); + owner.setLatestTime(resourceCode, now); } - public long unDelegateIncreaseV2(AccountCapsule owner, final AccountCapsule receiver, + public void unDelegateIncreaseV2(AccountCapsule owner, final AccountCapsule receiver, long transferUsage, ResourceCode resourceCode, long now) { long lastOwnerTime = owner.getLastConsumeTime(resourceCode); long ownerUsage = owner.getUsage(resourceCode); @@ -186,7 +188,9 @@ public long unDelegateIncreaseV2(AccountCapsule owner, final AccountCapsule rece // mean ownerUsage == 0 and transferUsage == 0 if (newOwnerUsage == 0) { owner.setNewWindowSizeV2(resourceCode, this.windowSize * WINDOW_SIZE_PRECISION); - return newOwnerUsage; + owner.setUsage(resourceCode, 0); + owner.setLatestTime(resourceCode, now); + return; } long remainOwnerWindowSizeV2 = owner.getWindowSizeV2(resourceCode); @@ -201,7 +205,8 @@ public long unDelegateIncreaseV2(AccountCapsule owner, final AccountCapsule rece newOwnerUsage); newOwnerWindowSize = Math.min(newOwnerWindowSize, this.windowSize * WINDOW_SIZE_PRECISION); owner.setNewWindowSizeV2(resourceCode, newOwnerWindowSize); - return newOwnerUsage; + owner.setUsage(resourceCode, newOwnerUsage); + owner.setLatestTime(resourceCode, now); } private long getNewWindowSize(long lastUsage, long lastWindowSize, long usage, diff --git a/framework/src/main/java/org/tron/core/db/TransactionCache.java b/chainbase/src/main/java/org/tron/core/db/TransactionCache.java similarity index 58% rename from framework/src/main/java/org/tron/core/db/TransactionCache.java rename to chainbase/src/main/java/org/tron/core/db/TransactionCache.java index 70b42ca7226..58ed9be9145 100644 --- a/framework/src/main/java/org/tron/core/db/TransactionCache.java +++ b/chainbase/src/main/java/org/tron/core/db/TransactionCache.java @@ -3,16 +3,20 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; import org.tron.core.capsule.BytesCapsule; import org.tron.core.db2.common.TxCacheDB; +import org.tron.core.store.DynamicPropertiesStore; @Slf4j +@Component public class TransactionCache extends TronStoreWithRevoking { @Autowired public TransactionCache(@Value("trans-cache") String dbName, - RecentTransactionStore recentTransactionStore) { - super(new TxCacheDB(dbName, recentTransactionStore)); + @Autowired RecentTransactionStore recentTransactionStore, + @Autowired DynamicPropertiesStore dynamicPropertiesStore) { + super(new TxCacheDB(dbName, recentTransactionStore, dynamicPropertiesStore)); } public void initCache() { diff --git a/chainbase/src/main/java/org/tron/core/db/TronDatabase.java b/chainbase/src/main/java/org/tron/core/db/TronDatabase.java index ffdfed81523..f6d82bd3cd9 100644 --- a/chainbase/src/main/java/org/tron/core/db/TronDatabase.java +++ b/chainbase/src/main/java/org/tron/core/db/TronDatabase.java @@ -94,7 +94,14 @@ public void reset() { */ @Override public void close() { - dbSource.closeDB(); + logger.info("******** Begin to close {}. ********", getName()); + try { + dbSource.closeDB(); + } catch (Exception e) { + logger.warn("Failed to close {}.", getName(), e); + } finally { + logger.info("******** End to close {}. ********", getName()); + } } public abstract void put(byte[] key, T item); diff --git a/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java b/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java index cd333b7c0f7..449df035e13 100644 --- a/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java +++ b/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java @@ -200,7 +200,14 @@ public String getName() { @Override public void close() { - revokingDB.close(); + logger.info("******** Begin to close {}. ********", getName()); + try { + revokingDB.close(); + } catch (Exception e) { + logger.warn("Failed to close {}.", getName(), e); + } finally { + logger.info("******** End to close {}. ********", getName()); + } } @Override diff --git a/chainbase/src/main/java/org/tron/core/db2/common/TxCacheDB.java b/chainbase/src/main/java/org/tron/core/db2/common/TxCacheDB.java index 4ea53469941..5d605a7fa90 100644 --- a/chainbase/src/main/java/org/tron/core/db2/common/TxCacheDB.java +++ b/chainbase/src/main/java/org/tron/core/db2/common/TxCacheDB.java @@ -2,11 +2,32 @@ import com.google.common.hash.BloomFilter; import com.google.common.hash.Funnels; +import com.google.common.hash.HashCode; +import com.google.common.hash.Hashing; +import com.google.common.io.ByteSource; import com.google.common.primitives.Longs; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; +import java.util.Properties; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicBoolean; +import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ArrayUtils; import org.bouncycastle.util.encoders.Hex; @@ -17,12 +38,14 @@ import org.tron.common.storage.leveldb.LevelDbDataSourceImpl; import org.tron.common.storage.rocksdb.RocksDbDataSourceImpl; import org.tron.common.utils.ByteArray; +import org.tron.common.utils.FileUtil; import org.tron.common.utils.JsonUtil; import org.tron.common.utils.StorageUtils; import org.tron.core.capsule.BytesCapsule; import org.tron.core.db.RecentTransactionItem; import org.tron.core.db.RecentTransactionStore; import org.tron.core.db.common.iterator.DBIterator; +import org.tron.core.store.DynamicPropertiesStore; @Slf4j(topic = "DB") public class TxCacheDB implements DB, Flusher { @@ -57,11 +80,28 @@ public class TxCacheDB implements DB, Flusher { // replace persistentStore and optimizes startup performance private RecentTransactionStore recentTransactionStore; - public TxCacheDB(String name, RecentTransactionStore recentTransactionStore) { + private DynamicPropertiesStore dynamicPropertiesStore; + + private final Path cacheFile0; + private final Path cacheFile1; + private String crc32c0; + private String crc32c1; + private final Path cacheProperties; + private final Path cacheDir; + private AtomicBoolean isValid = new AtomicBoolean(false); + private boolean txCacheInitOptimization; + + @Getter + @Setter + private volatile boolean alive; + + public TxCacheDB(String name, RecentTransactionStore recentTransactionStore, + DynamicPropertiesStore dynamicPropertiesStore) { this.name = name; this.TRANSACTION_COUNT = CommonParameter.getInstance().getStorage().getEstimatedBlockTransactions(); this.recentTransactionStore = recentTransactionStore; + this.dynamicPropertiesStore = dynamicPropertiesStore; String dbEngine = CommonParameter.getInstance().getStorage().getDbEngine(); if ("LEVELDB".equals(dbEngine.toUpperCase())) { this.persistentStore = new LevelDB( @@ -85,6 +125,12 @@ public TxCacheDB(String name, RecentTransactionStore recentTransactionStore) { MAX_BLOCK_SIZE * TRANSACTION_COUNT); this.bloomFilters[1] = BloomFilter.create(Funnels.byteArrayFunnel(), MAX_BLOCK_SIZE * TRANSACTION_COUNT); + cacheDir = Paths.get(CommonParameter.getInstance().getOutputDirectory(), ".cache"); + this.cacheFile0 = Paths.get(cacheDir.toString(), "bloomFilters_0"); + this.cacheFile1 = Paths.get(cacheDir.toString(), "bloomFilters_1"); + this.cacheProperties = Paths.get(cacheDir.toString(), "txCache.properties"); + this.txCacheInitOptimization = CommonParameter.getInstance() + .getStorage().isTxCacheInitOptimization(); } @@ -113,6 +159,11 @@ public void init() { if (CommonParameter.getInstance().isP2pDisable()) { return; } + if (recovery()) { + isValid.set(true); + setAlive(true); + return; + } long size = recentTransactionStore.size(); if (size != MAX_BLOCK_SIZE) { // 0. load from persistentStore @@ -132,6 +183,8 @@ public void init() { logger.info("Load cache from recentTransactionStore, filter: {}, filter-fpp: {}, cost: {} ms.", bloomFilters[1].approximateElementCount(), bloomFilters[1].expectedFpp(), System.currentTimeMillis() - start); + isValid.set(true); + setAlive(true); } @Override @@ -175,7 +228,6 @@ public void put(byte[] key, byte[] value) { MAX_BLOCK_SIZE * TRANSACTION_COUNT); } bloomFilters[currentFilterIndex].put(key); - if (lastMetricBlock != blockNum) { lastMetricBlock = blockNum; Metrics.gaugeSet(MetricKeys.Gauge.TX_CACHE, @@ -211,25 +263,202 @@ public Iterator> iterator() { } @Override - public void flush(Map batch) { + public synchronized void flush(Map batch) { + isValid.set(false); batch.forEach((k, v) -> this.put(k.getBytes(), v.getBytes())); + isValid.set(true); } @Override public void close() { - reset(); + if (!isAlive()) { + return; + } + dump(); bloomFilters[0] = null; bloomFilters[1] = null; persistentStore.close(); + setAlive(false); } @Override public void reset() { } + private boolean recovery() { + if (!txCacheInitOptimization) { + logger.info("txCache init optimization is disabled, skip fast recovery mode."); + logger.info("If you want fast recovery mode," + + " please set `storage.txCache.initOptimization = true` in config.conf."); + return false; + } + FileUtil.createDirIfNotExists(this.cacheDir.toString()); + logger.info("recovery bloomFilters start."); + CompletableFuture loadProperties = CompletableFuture.supplyAsync(this::loadProperties); + CompletableFuture tk0 = loadProperties.thenApplyAsync( + v -> recovery(0, this.cacheFile0)); + CompletableFuture tk1 = loadProperties.thenApplyAsync( + v -> recovery(1, this.cacheFile1)); + + try { + return CompletableFuture.allOf(tk0, tk1).thenApply(v -> { + logger.info("recovery bloomFilters success."); + return true; + }).exceptionally(this::handleException).join(); + } finally { + clearCrc32c(); + } + } + + private boolean recovery(int index, Path file) { + checkCrc32c(index, file); + try (InputStream in = new BufferedInputStream(Files.newInputStream(file, + StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE))) { + logger.info("recovery bloomFilter[{}] from file.", index); + long start = System.currentTimeMillis(); + bloomFilters[index] = BloomFilter.readFrom(in, Funnels.byteArrayFunnel()); + logger.info("recovery bloomFilter[{}] from file done,filter: {}, filter-fpp: {}, cost {} ms.", + index, bloomFilters[index].approximateElementCount(), bloomFilters[index].expectedFpp(), + System.currentTimeMillis() - start); + return true; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private boolean handleException(Throwable e) { + bloomFilters[0] = BloomFilter.create(Funnels.byteArrayFunnel(), + MAX_BLOCK_SIZE * TRANSACTION_COUNT); + bloomFilters[1] = BloomFilter.create(Funnels.byteArrayFunnel(), + MAX_BLOCK_SIZE * TRANSACTION_COUNT); + try { + Files.deleteIfExists(this.cacheFile0); + Files.deleteIfExists(this.cacheFile1); + } catch (Exception ignored) { + + } + logger.info("recovery bloomFilters failed. {}", e.getMessage()); + logger.info("rollback to previous mode."); + return false; + } + + private void dump() { + if (!isValid.get()) { + logger.info("bloomFilters is not valid."); + return; + } + FileUtil.createDirIfNotExists(this.cacheDir.toString()); + logger.info("dump bloomFilters start."); + CompletableFuture task0 = CompletableFuture.runAsync( + () -> dump(0, this.cacheFile0)); + CompletableFuture task1 = CompletableFuture.runAsync( + () -> dump(1, this.cacheFile1)); + try { + CompletableFuture.allOf(task0, task1).thenRun(() -> { + writeProperties(); + logger.info("dump bloomFilters done."); + }).exceptionally(e -> { + logger.info("dump bloomFilters to file failed. {}", e.getMessage()); + return null; + }).join(); + } finally { + clearCrc32c(); + } + } + + private void dump(int index, Path file) { + logger.info("dump bloomFilters[{}] to file.", index); + long start = System.currentTimeMillis(); + try (OutputStream out = new BufferedOutputStream(Files.newOutputStream(file))) { + bloomFilters[index].writeTo(out); + } catch (Exception e) { + throw new RuntimeException(e); + } + try { + String crc32c = getCrc32c(file); + if (index == 0) { + this.crc32c0 = crc32c; + } else { + this.crc32c1 = crc32c; + } + logger.info("dump bloomFilters[{}] to file done,filter: {}, filter-fpp: {}, " + + "crc32c: {}, cost {} ms.", + index, bloomFilters[index].approximateElementCount(), bloomFilters[index].expectedFpp(), + crc32c, System.currentTimeMillis() - start); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private boolean loadProperties() { + try (Reader r = new InputStreamReader(new BufferedInputStream(Files.newInputStream( + this.cacheProperties, StandardOpenOption.READ, StandardOpenOption.DELETE_ON_CLOSE)), + StandardCharsets.UTF_8)) { + Properties properties = new Properties(); + properties.load(r); + filterStartBlock = Long.parseLong(properties.getProperty("filterStartBlock")); + long currentBlockNum = Long.parseLong(properties.getProperty("currentBlockNum")); + long currentBlockNumFromDB = dynamicPropertiesStore.getLatestBlockHeaderNumberFromDB(); + currentFilterIndex = Integer.parseInt(properties.getProperty("currentFilterIndex")); + if (currentBlockNum != currentBlockNumFromDB) { + throw new IllegalStateException( + String.format("currentBlockNum not match. filter: %d, db: %d", + currentBlockNum, currentBlockNumFromDB)); + } + this.crc32c0 = properties.getProperty("crc32c0"); + this.crc32c1 = properties.getProperty("crc32c1"); + logger.info("filterStartBlock: {}, currentBlockNum: {}, currentFilterIndex: {}, load done.", + filterStartBlock, currentBlockNum, currentFilterIndex); + return true; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void writeProperties() { + try (Writer w = Files.newBufferedWriter(this.cacheProperties, StandardCharsets.UTF_8)) { + Properties properties = new Properties(); + long currentBlockNum = dynamicPropertiesStore.getLatestBlockHeaderNumberFromDB(); + properties.setProperty("filterStartBlock", String.valueOf(filterStartBlock)); + properties.setProperty("currentBlockNum", String.valueOf(currentBlockNum)); + properties.setProperty("currentFilterIndex", String.valueOf(currentFilterIndex)); + properties.setProperty("crc32c0", this.crc32c0); + properties.setProperty("crc32c1", this.crc32c1); + properties.store(w, "Generated by the application. PLEASE DO NOT EDIT! "); + logger.info("filterStartBlock: {}, currentBlockNum: {}, currentFilterIndex: {}, write done.", + filterStartBlock, currentBlockNum, currentFilterIndex); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private String getCrc32c(Path file) throws IOException { + ByteSource byteSource = com.google.common.io.Files.asByteSource(file.toFile()); + HashCode hc = byteSource.hash(Hashing.crc32c()); + return hc.toString(); + } + + private void checkCrc32c(int index, Path file) { + try { + String actual = getCrc32c(file); + String expect = index == 0 ? this.crc32c0 : this.crc32c1; + if (!Objects.equals(actual, expect)) { + throw new IllegalStateException("crc32c not match. index: " + index + ", expect: " + expect + + ", actual: " + actual); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void clearCrc32c() { + this.crc32c0 = null; + this.crc32c1 = null; + } + @Override public TxCacheDB newInstance() { - return new TxCacheDB(name, recentTransactionStore); + return new TxCacheDB(name, recentTransactionStore, dynamicPropertiesStore); } @Override diff --git a/chainbase/src/main/java/org/tron/core/db2/core/AbstractSnapshot.java b/chainbase/src/main/java/org/tron/core/db2/core/AbstractSnapshot.java index 496a0fd09ac..ba6c77d43a2 100644 --- a/chainbase/src/main/java/org/tron/core/db2/core/AbstractSnapshot.java +++ b/chainbase/src/main/java/org/tron/core/db2/core/AbstractSnapshot.java @@ -15,6 +15,8 @@ public abstract class AbstractSnapshot implements Snapshot { protected WeakReference next; + protected boolean isOptimized; + @Override public Snapshot advance() { return new SnapshotImpl(this); @@ -34,4 +36,9 @@ public void setNext(Snapshot next) { public String getDbName() { return db.getDbName(); } + + @Override + public boolean isOptimized(){ + return isOptimized; + } } diff --git a/chainbase/src/main/java/org/tron/core/db2/core/Snapshot.java b/chainbase/src/main/java/org/tron/core/db2/core/Snapshot.java index e1ca149b207..75545dc29b4 100644 --- a/chainbase/src/main/java/org/tron/core/db2/core/Snapshot.java +++ b/chainbase/src/main/java/org/tron/core/db2/core/Snapshot.java @@ -46,4 +46,8 @@ static boolean isImpl(Snapshot snapshot) { void updateSolidity(); String getDbName(); + + boolean isOptimized(); + + void reloadToMem(); } diff --git a/chainbase/src/main/java/org/tron/core/db2/core/SnapshotImpl.java b/chainbase/src/main/java/org/tron/core/db2/core/SnapshotImpl.java index ae8073f668b..bc31b406b30 100644 --- a/chainbase/src/main/java/org/tron/core/db2/core/SnapshotImpl.java +++ b/chainbase/src/main/java/org/tron/core/db2/core/SnapshotImpl.java @@ -30,6 +30,10 @@ public class SnapshotImpl extends AbstractSnapshot { } previous = snapshot; snapshot.setNext(this); + isOptimized = snapshot.isOptimized(); + if (isOptimized && root == previous) { + Streams.stream(root.iterator()).forEach( e -> put(e.getKey(),e.getValue())); + } } @Override @@ -40,6 +44,7 @@ public byte[] get(byte[] key) { private byte[] get(Snapshot head, byte[] key) { Snapshot snapshot = head; Value value; + while (Snapshot.isImpl(snapshot)) { if ((value = ((SnapshotImpl) snapshot).db.get(Key.of(key))) != null) { return value.getBytes(); @@ -83,6 +88,19 @@ public void merge(Snapshot from) { Streams.stream(fromImpl.db).forEach(e -> db.put(e.getKey(), e.getValue())); } + public void mergeAhead(Snapshot from) { + if (from instanceof SnapshotRoot) { + return ; + } + SnapshotImpl fromImpl = (SnapshotImpl) from; + Streams.stream(fromImpl.db).forEach(e -> { + if (db.get(e.getKey()) == null) { + db.put(e.getKey(), e.getValue()); + } + } + ); + } + @Override public Snapshot retreat() { return previous; @@ -177,4 +195,9 @@ public String getDbName() { public Snapshot newInstance() { return new SnapshotImpl(this); } + + @Override + public void reloadToMem() { + mergeAhead(previous); + } } diff --git a/chainbase/src/main/java/org/tron/core/db2/core/SnapshotManager.java b/chainbase/src/main/java/org/tron/core/db2/core/SnapshotManager.java index 230a812e093..f0f169ae340 100644 --- a/chainbase/src/main/java/org/tron/core/db2/core/SnapshotManager.java +++ b/chainbase/src/main/java/org/tron/core/db2/core/SnapshotManager.java @@ -16,8 +16,6 @@ import java.util.Map; import java.util.Objects; import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -25,12 +23,12 @@ import java.util.concurrent.locks.LockSupport; import java.util.stream.Collectors; import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.tron.common.error.TronDBException; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.parameter.CommonParameter; import org.tron.common.storage.WriteOptionsWrapper; import org.tron.common.utils.FileUtil; @@ -76,6 +74,7 @@ public class SnapshotManager implements RevokingDatabase { private Map flushServices = new HashMap<>(); private ScheduledExecutorService pruneCheckpointThread = null; + private final String pruneName = "checkpoint-prune"; @Autowired @Setter @@ -95,7 +94,7 @@ public void init() { checkpointVersion = CommonParameter.getInstance().getStorage().getCheckpointVersion(); // prune checkpoint if (isV2Open()) { - pruneCheckpointThread = Executors.newSingleThreadScheduledExecutor(); + pruneCheckpointThread = ExecutorServiceManager.newSingleThreadScheduledExecutor(pruneName); pruneCheckpointThread.scheduleWithFixedDelay(() -> { try { if (!unChecked) { @@ -117,18 +116,6 @@ public void init() { exitThread.start(); } - @PreDestroy - public void close() { - try { - exitThread.interrupt(); - // help GC - exitThread = null; - flushServices.values().forEach(ExecutorService::shutdown); - } catch (Exception e) { - logger.warn("exitThread interrupt error", e); - } - } - public static String simpleDecode(byte[] bytes) { byte[] lengthBytes = Arrays.copyOf(bytes, 4); int length = Ints.fromByteArray(lengthBytes); @@ -177,7 +164,8 @@ public void add(IRevokingDB db) { Chainbase revokingDB = (Chainbase) db; dbs.add(revokingDB); flushServices.put(revokingDB.getDbName(), - MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor())); + MoreExecutors.listeningDecorator(ExecutorServiceManager.newSingleThreadExecutor( + "flush-service-" + revokingDB.getDbName()))); } private void advance() { @@ -233,6 +221,12 @@ public synchronized void commit() { } --activeSession; + + dbs.forEach(db -> { + if (db.getHead().isOptimized()) { + db.getHead().reloadToMem(); + } + }); } public synchronized void pop() { @@ -284,12 +278,15 @@ public synchronized void disable() { @Override public void shutdown() { - logger.info("******** Begin to pop revokingDb. ********"); - logger.info("******** Before revokingDb size: {}.", size); - checkTmpStore.close(); - logger.info("******** End to pop revokingDb. ********"); - if (pruneCheckpointThread != null) { - pruneCheckpointThread.shutdown(); + ExecutorServiceManager.shutdownAndAwaitTermination(pruneCheckpointThread, pruneName); + flushServices.forEach((key, value) -> ExecutorServiceManager.shutdownAndAwaitTermination(value, + "flush-service-" + key)); + try { + exitThread.interrupt(); + // help GC + exitThread = null; + } catch (Exception e) { + logger.warn("exitThread interrupt error", e); } } @@ -493,7 +490,9 @@ public void check() { if (!isV2Open()) { List cpList = getCheckpointList(); if (cpList != null && cpList.size() != 0) { - logger.error("checkpoint check failed, can't convert checkpoint from v2 to v1"); + logger.error("checkpoint check failed, the checkpoint version of database not match your " + + "config file, please set storage.checkpoint.version = 2 in your config file " + + "and restart the node."); System.exit(-1); } checkV1(); diff --git a/chainbase/src/main/java/org/tron/core/db2/core/SnapshotRoot.java b/chainbase/src/main/java/org/tron/core/db2/core/SnapshotRoot.java index 709e2ae1b62..f95cf68dafe 100644 --- a/chainbase/src/main/java/org/tron/core/db2/core/SnapshotRoot.java +++ b/chainbase/src/main/java/org/tron/core/db2/core/SnapshotRoot.java @@ -38,6 +38,7 @@ public SnapshotRoot(DB db) { if (CACHE_DBS.contains(this.db.getDbName())) { this.cache = CacheManager.allocate(CacheType.findByType(this.db.getDbName())); } + isOptimized = "properties".equalsIgnoreCase(db.getDbName()); } private boolean needOptAsset() { @@ -221,4 +222,7 @@ public String getDbName() { public Snapshot newInstance() { return new SnapshotRoot(db.newInstance()); } + + @Override + public void reloadToMem() { } } diff --git a/chainbase/src/main/java/org/tron/core/store/CheckPointV2Store.java b/chainbase/src/main/java/org/tron/core/store/CheckPointV2Store.java index 046df7f6643..2f952e6b82a 100644 --- a/chainbase/src/main/java/org/tron/core/store/CheckPointV2Store.java +++ b/chainbase/src/main/java/org/tron/core/store/CheckPointV2Store.java @@ -1,6 +1,7 @@ package org.tron.core.store; import com.google.protobuf.InvalidProtocolBufferException; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.tron.core.db.TronDatabase; import org.tron.core.exception.BadItemException; @@ -9,6 +10,7 @@ import java.util.Spliterator; import java.util.function.Consumer; +@Slf4j(topic = "DB") public class CheckPointV2Store extends TronDatabase { @Autowired @@ -50,4 +52,19 @@ public Spliterator spliterator() { protected void init() { } + /** + * close the database. + */ + @Override + public void close() { + logger.debug("******** Begin to close {}. ********", getName()); + try { + dbSource.closeDB(); + } catch (Exception e) { + logger.warn("Failed to close {}.", getName(), e); + } finally { + logger.debug("******** End to close {}. ********", getName()); + } + } + } diff --git a/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java b/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java index 809c2060951..99b868d3a26 100644 --- a/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java +++ b/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java @@ -1,5 +1,6 @@ package org.tron.core.store; +import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; import static org.tron.core.config.Parameter.ChainConstant.DELEGATE_PERIOD; import com.google.protobuf.ByteString; @@ -2831,11 +2832,12 @@ public long getMaxDelegateLockPeriod() { return Optional.ofNullable(getUnchecked(MAX_DELEGATE_LOCK_PERIOD)) .map(BytesCapsule::getData) .map(ByteArray::toLong) - .orElse(DELEGATE_PERIOD / 3000); + .orElse(DELEGATE_PERIOD / BLOCK_PRODUCED_INTERVAL); } public boolean supportMaxDelegateLockPeriod() { - return (getMaxDelegateLockPeriod() > DELEGATE_PERIOD / 3000) && getUnfreezeDelayDays() > 0; + return (getMaxDelegateLockPeriod() > DELEGATE_PERIOD / BLOCK_PRODUCED_INTERVAL) && + getUnfreezeDelayDays() > 0; } private static class DynamicResourceProperties { diff --git a/chainbase/src/main/java/org/tron/core/store/WitnessStore.java b/chainbase/src/main/java/org/tron/core/store/WitnessStore.java index e01680cfc74..d23a73f92f9 100644 --- a/chainbase/src/main/java/org/tron/core/store/WitnessStore.java +++ b/chainbase/src/main/java/org/tron/core/store/WitnessStore.java @@ -11,10 +11,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import org.tron.common.cache.CacheManager; -import org.tron.common.cache.CacheStrategies; -import org.tron.common.cache.CacheType; -import org.tron.common.cache.TronCache; import org.tron.core.capsule.WitnessCapsule; import org.tron.core.config.Parameter; import org.tron.core.db.TronStoreWithRevoking; @@ -22,14 +18,10 @@ @Slf4j(topic = "DB") @Component public class WitnessStore extends TronStoreWithRevoking { - // cache for 127 SR - private final TronCache> witnessStandbyCache; @Autowired protected WitnessStore(@Value("witness") String dbName) { super(dbName); - String strategy = String.format(CacheStrategies.PATTERNS, 1, 1, "30s", 1); - witnessStandbyCache = CacheManager.allocate(CacheType.witnessStandby, strategy); } /** @@ -48,19 +40,8 @@ public WitnessCapsule get(byte[] key) { } public List getWitnessStandby() { - List list = - witnessStandbyCache.getIfPresent(Parameter.ChainConstant.WITNESS_STANDBY_LENGTH); - if (list != null) { - return list; - } - return updateWitnessStandby(null); - } - - public List updateWitnessStandby(List all) { List ret; - if (all == null) { - all = getAllWitnesses(); - } + List all = getAllWitnesses(); all.sort(Comparator.comparingLong(WitnessCapsule::getVoteCount) .reversed().thenComparing(Comparator.comparingInt( (WitnessCapsule w) -> w.getAddress().hashCode()).reversed())); @@ -71,7 +52,6 @@ public List updateWitnessStandby(List all) { } // trim voteCount = 0 ret.removeIf(w -> w.getVoteCount() < 1); - witnessStandbyCache.put(Parameter.ChainConstant.WITNESS_STANDBY_LENGTH, ret); return ret; } diff --git a/common/build.gradle b/common/build.gradle index e00528d7a94..3949b47edb5 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -53,7 +53,7 @@ dependencies { compile 'org.aspectj:aspectjrt:1.8.13' compile 'org.aspectj:aspectjweaver:1.8.13' compile 'org.aspectj:aspectjtools:1.8.13' - compile group: 'io.github.tronprotocol', name: 'libp2p', version: '1.2.0',{ + compile group: 'io.github.tronprotocol', name: 'libp2p', version: '2.1.0',{ exclude group: 'io.grpc', module: 'grpc-context' exclude group: 'io.grpc', module: 'grpc-core' exclude group: 'io.grpc', module: 'grpc-netty' @@ -69,7 +69,7 @@ jacocoTestReport { xml.enabled = true html.enabled = true } - executionData.from = '../framework/build/jacoco/jacocoTest.exec' + getExecutionData().setFrom(fileTree('../framework/build/jacoco').include("**.exec")) afterEvaluate { classDirectories.from = classDirectories.files.collect { fileTree(dir: it,) diff --git a/common/src/main/java/org/tron/common/es/ExecutorServiceManager.java b/common/src/main/java/org/tron/common/es/ExecutorServiceManager.java new file mode 100644 index 00000000000..196d44ba722 --- /dev/null +++ b/common/src/main/java/org/tron/common/es/ExecutorServiceManager.java @@ -0,0 +1,83 @@ +package org.tron.common.es; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; + +@Slf4j(topic = "common-executor") +public class ExecutorServiceManager { + + public static ExecutorService newSingleThreadExecutor(String name) { + return newSingleThreadExecutor(name, false); + } + + public static ExecutorService newSingleThreadExecutor(String name, boolean isDaemon) { + return Executors.newSingleThreadExecutor( + new ThreadFactoryBuilder().setNameFormat(name).setDaemon(isDaemon).build()); + } + + + public static ScheduledExecutorService newSingleThreadScheduledExecutor(String name) { + return newSingleThreadScheduledExecutor(name, false); + } + + public static ScheduledExecutorService newSingleThreadScheduledExecutor(String name, + boolean isDaemon) { + return Executors.newSingleThreadScheduledExecutor( + new ThreadFactoryBuilder().setNameFormat(name).setDaemon(isDaemon).build()); + } + + public static ExecutorService newFixedThreadPool(String name, int fixThreads) { + return newFixedThreadPool(name, fixThreads, false); + } + + public static ExecutorService newFixedThreadPool(String name, int fixThreads, boolean isDaemon) { + return Executors.newFixedThreadPool(fixThreads, + new ThreadFactoryBuilder().setNameFormat(name + "-%d").setDaemon(isDaemon).build()); + } + + public static ExecutorService newThreadPoolExecutor(int corePoolSize, int maximumPoolSize, + long keepAliveTime, TimeUnit unit, + BlockingQueue workQueue, + String name) { + return newThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, + name, false); + } + + public static ExecutorService newThreadPoolExecutor(int corePoolSize, int maximumPoolSize, + long keepAliveTime, TimeUnit unit, + BlockingQueue workQueue, + String name, boolean isDaemon) { + return new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, + new ThreadFactoryBuilder().setNameFormat(name + "-%d").setDaemon(isDaemon).build()); + } + + public static void shutdownAndAwaitTermination(ExecutorService pool, String name) { + if (pool == null) { + return; + } + logger.info("Pool {} shutdown...", name); + pool.shutdown(); // Disable new tasks from being submitted + try { + // Wait a while for existing tasks to terminate + if (!pool.awaitTermination(60, java.util.concurrent.TimeUnit.SECONDS)) { + pool.shutdownNow(); // Cancel currently executing tasks + // Wait a while for tasks to respond to being cancelled + if (!pool.awaitTermination(60, java.util.concurrent.TimeUnit.SECONDS)) { + logger.warn("Pool {} did not terminate", name); + } + } + } catch (InterruptedException ie) { + // (Re-)Cancel if current thread also interrupted + pool.shutdownNow(); + // Preserve interrupt status + Thread.currentThread().interrupt(); + } + logger.info("Pool {} shutdown done", name); + } +} diff --git a/common/src/main/java/org/tron/common/logsfilter/trigger/TransactionLogTrigger.java b/common/src/main/java/org/tron/common/logsfilter/trigger/TransactionLogTrigger.java index dec4170efb8..a4fb1fddb79 100644 --- a/common/src/main/java/org/tron/common/logsfilter/trigger/TransactionLogTrigger.java +++ b/common/src/main/java/org/tron/common/logsfilter/trigger/TransactionLogTrigger.java @@ -1,6 +1,8 @@ package org.tron.common.logsfilter.trigger; import java.util.List; +import java.util.Map; + import lombok.Getter; import lombok.Setter; @@ -91,6 +93,10 @@ public class TransactionLogTrigger extends Trigger { @Setter private long energyUnitPrice; + @Getter + @Setter + private Map extMap; + public TransactionLogTrigger() { setTriggerName(Trigger.TRANSACTION_TRIGGER_NAME); } diff --git a/common/src/main/java/org/tron/common/parameter/CommonParameter.java b/common/src/main/java/org/tron/common/parameter/CommonParameter.java index 4e07f601003..ce4f3681372 100644 --- a/common/src/main/java/org/tron/common/parameter/CommonParameter.java +++ b/common/src/main/java/org/tron/common/parameter/CommonParameter.java @@ -18,6 +18,7 @@ import org.tron.core.config.args.Overlay; import org.tron.core.config.args.SeedNode; import org.tron.core.config.args.Storage; +import org.tron.p2p.P2pConfig; import org.tron.p2p.dns.update.PublishConfig; public class CommonParameter { @@ -169,6 +170,8 @@ public class CommonParameter { @Setter public int minParticipationRate; @Getter + public P2pConfig p2pConfig; + @Getter @Setter public int nodeListenPort; @Getter @@ -179,21 +182,9 @@ public class CommonParameter { public String nodeExternalIp; @Getter @Setter - public boolean nodeDiscoveryPublicHomeNode; - @Getter - @Setter - public long nodeDiscoveryPingTimeout; - @Getter - @Setter - public long nodeP2pPingInterval; - @Getter - @Setter public int nodeP2pVersion; @Getter @Setter - public String p2pNodeId; - @Getter - @Setter public boolean nodeEnableIpv6 = false; @Getter @Setter @@ -424,6 +415,8 @@ public class CommonParameter { @Setter public int rateLimiterGlobalIpQps; @Getter + public int rateLimiterGlobalApiQps; + @Getter public DbBackupConfig dbBackupConfig; @Getter public RocksDbSettings rocksDBCustomSettings; @@ -537,6 +530,9 @@ public class CommonParameter { public int pBFTHttpPort; @Getter @Setter + public long pBFTExpireNum; + @Getter + @Setter public long oldSolidityBlockNum = -1; @Getter/**/ diff --git a/common/src/main/java/org/tron/core/Constant.java b/common/src/main/java/org/tron/core/Constant.java index b063132db69..56135c495cf 100644 --- a/common/src/main/java/org/tron/core/Constant.java +++ b/common/src/main/java/org/tron/core/Constant.java @@ -101,10 +101,6 @@ public class Constant { public static final String NODE_MAX_CONNECTIONS_WITH_SAME_IP = "node.maxConnectionsWithSameIp"; public static final String NODE_MIN_PARTICIPATION_RATE = "node.minParticipationRate"; public static final String NODE_LISTEN_PORT = "node.listen.port"; - public static final String NODE_DISCOVERY_PUBLIC_HOME_NODE = "node.discovery.public.home.node"; - public static final String NODE_DISCOVERY_PING_TIMEOUT = "node.discovery.ping.timeout"; - - public static final String NODE_P2P_PING_INTERVAL = "node.p2p.pingInterval"; public static final String NODE_P2P_VERSION = "node.p2p.version"; public static final String NODE_ENABLE_IPV6 = "node.enableIpv6"; public static final String NODE_DNS_TREE_URLS = "node.dns.treeUrls"; @@ -264,6 +260,8 @@ public class Constant { public static final String RATE_LIMITER_GLOBAL_IP_QPS = "rate.limiter.global.ip.qps"; + public static final String RATE_LIMITER_GLOBAL_API_QPS = "rate.limiter.global.api.qps"; + public static final String COMMITTEE_CHANGED_DELEGATION = "committee.changedDelegation"; public static final String CRYPTO_ENGINE = "crypto.engine"; @@ -288,7 +286,6 @@ public class Constant { public static final String NODE_DISCOVERY_BIND_IP = "node.discovery.bind.ip"; public static final String NODE_DISCOVERY_EXTERNAL_IP = "node.discovery.external.ip"; - public static final String AMAZONAWS_URL = "http://checkip.amazonaws.com"; public static final String NODE_BACKUP_PRIORITY = "node.backup.priority"; public static final String NODE_BACKUP_PORT = "node.backup.port"; @@ -310,6 +307,7 @@ public class Constant { public static final String SEED_NODE_IP_LIST = "seed.node.ip.list"; public static final String NODE_METRICS_ENABLE = "node.metricsEnable"; public static final String COMMITTEE_ALLOW_PBFT = "committee.allowPBFT"; + public static final String COMMITTEE_PBFT_EXPIRE_NUM = "committee.pBFTExpireNum"; public static final String NODE_AGREE_NODE_COUNT = "node.agreeNodeCount"; public static final String COMMITTEE_ALLOW_TRANSACTION_FEE_POOL = "committee.allowTransactionFeePool"; diff --git a/common/src/main/java/org/tron/core/config/Parameter.java b/common/src/main/java/org/tron/core/config/Parameter.java index 6bbc66846bd..b1a948e9fdf 100644 --- a/common/src/main/java/org/tron/core/config/Parameter.java +++ b/common/src/main/java/org/tron/core/config/Parameter.java @@ -77,6 +77,7 @@ public class ChainConstant { public static final long TRX_PRECISION = 1000_000L; public static final long DELEGATE_COST_BASE_SIZE = 275L; public static final long WINDOW_SIZE_PRECISION = 1000L; + public static final long ONE_YEAR_BLOCK_NUMBERS = 10512000L; } public class NodeConstant { diff --git a/common/src/main/java/org/tron/core/config/args/Storage.java b/common/src/main/java/org/tron/core/config/args/Storage.java index 479565ed0a1..b7459a2ac83 100644 --- a/common/src/main/java/org/tron/core/config/args/Storage.java +++ b/common/src/main/java/org/tron/core/config/args/Storage.java @@ -78,6 +78,7 @@ public class Storage { private static final String CHECKPOINT_SYNC_KEY = "storage.checkpoint.sync"; private static final String CACHE_STRATEGIES = "storage.cache.strategies"; + public static final String TX_CACHE_INIT_OPTIMIZATION = "storage.txCache.initOptimization"; private static final String STATE_ROOT_SWITCH_KEY = "storage.stateRoot.switch"; private static final String STATE_DB_MAX_OPEN_FILES_KEY = "storage.stateRoot.db.maxOpenFiles"; @@ -156,6 +157,10 @@ public class Storage { @Setter private int estimatedBlockTransactions; + @Getter + @Setter + private boolean txCacheInitOptimization = false; + // second cache private final Map cacheStrategies = Maps.newConcurrentMap(); @@ -256,6 +261,11 @@ public static int getEstimatedTransactionsFromConfig(final Config config) { return estimatedTransactions; } + public static boolean getTxCacheInitOptimizationFromConfig(final Config config) { + return config.hasPath(TX_CACHE_INIT_OPTIMIZATION) + && config.getBoolean(TX_CACHE_INIT_OPTIMIZATION); + } + public void setCacheStrategies(Config config) { if (config.hasPath(CACHE_STRATEGIES)) { diff --git a/consensus/build.gradle b/consensus/build.gradle index c22e961572e..78f60bd7530 100644 --- a/consensus/build.gradle +++ b/consensus/build.gradle @@ -13,7 +13,6 @@ dependencies { compile project(":protocol") testImplementation "junit:junit:$junitVersion" testImplementation "org.mockito:mockito-core:$mockitoVersion" - testImplementation "org.testng:testng:$testNgVersion" compile "org.slf4j:jcl-over-slf4j:$slf4jVersion" compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.69' compile group: 'commons-codec', name: 'commons-codec', version: '1.11' @@ -44,34 +43,15 @@ test { } } -task testng(type: Test) { - useTestNG() - testLogging { - events = ["skipped", "failed"] - exceptionFormat = "full" - - debug.events = ["skipped", "failed"] - debug.exceptionFormat = "full" - - info.events = ["failed", "skipped"] - info.exceptionFormat = "full" - - warn.events = ["failed", "skipped"] - warn.exceptionFormat = "full" - } -} - jacocoTestReport { reports { xml.enabled = true html.enabled = true } - executionData.from = '../framework/build/jacoco/jacocoTest.exec' + getExecutionData().setFrom(fileTree('../framework/build/jacoco').include("**.exec")) afterEvaluate { classDirectories.from = classDirectories.files.collect { fileTree(dir: it,) } } } - -check.dependsOn testng diff --git a/consensus/src/main/java/org/tron/consensus/ConsensusDelegate.java b/consensus/src/main/java/org/tron/consensus/ConsensusDelegate.java index 4a98c933bd1..767463a6a5b 100644 --- a/consensus/src/main/java/org/tron/consensus/ConsensusDelegate.java +++ b/consensus/src/main/java/org/tron/consensus/ConsensusDelegate.java @@ -108,10 +108,6 @@ public List getAllWitnesses() { return witnessStore.getAllWitnesses(); } - public List updateWitnessStandby(List all) { - return witnessStore.updateWitnessStandby(all); - } - public void saveStateFlag(int flag) { dynamicPropertiesStore.saveStateFlag(flag); } diff --git a/consensus/src/main/java/org/tron/consensus/dpos/DposTask.java b/consensus/src/main/java/org/tron/consensus/dpos/DposTask.java index dcfa85ca5f3..537fe49ae65 100644 --- a/consensus/src/main/java/org/tron/consensus/dpos/DposTask.java +++ b/consensus/src/main/java/org/tron/consensus/dpos/DposTask.java @@ -3,12 +3,14 @@ import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; import com.google.protobuf.ByteString; +import java.util.concurrent.ExecutorService; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.joda.time.DateTime; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; +import org.springframework.util.ObjectUtils; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.parameter.CommonParameter; import org.tron.common.utils.ByteArray; import org.tron.common.utils.Sha256Hash; @@ -34,16 +36,18 @@ public class DposTask { @Setter private DposService dposService; - private Thread produceThread; + private ExecutorService produceExecutor; + + private final String name = "DPosMiner"; private volatile boolean isRunning = true; public void init() { - if (!dposService.isEnable() || StringUtils.isEmpty(dposService.getMiners())) { + if (!dposService.isEnable() || ObjectUtils.isEmpty(dposService.getMiners())) { return; } - + produceExecutor = ExecutorServiceManager.newSingleThreadExecutor(name); Runnable runnable = () -> { while (isRunning) { try { @@ -67,17 +71,13 @@ public void init() { } } }; - produceThread = new Thread(runnable, "DPosMiner"); - produceThread.start(); + produceExecutor.submit(runnable); logger.info("DPoS task started."); } public void stop() { isRunning = false; - if (produceThread != null) { - produceThread.interrupt(); - } - logger.info("DPoS task stopped."); + ExecutorServiceManager.shutdownAndAwaitTermination(produceExecutor, name); } private State produceBlock() { diff --git a/consensus/src/main/java/org/tron/consensus/dpos/MaintenanceManager.java b/consensus/src/main/java/org/tron/consensus/dpos/MaintenanceManager.java index fc6cdd55c15..012169bdb87 100644 --- a/consensus/src/main/java/org/tron/consensus/dpos/MaintenanceManager.java +++ b/consensus/src/main/java/org/tron/consensus/dpos/MaintenanceManager.java @@ -151,13 +151,11 @@ public void doMaintenance() { if (dynamicPropertiesStore.allowChangeDelegation()) { long nextCycle = dynamicPropertiesStore.getCurrentCycleNumber() + 1; dynamicPropertiesStore.saveCurrentCycleNumber(nextCycle); - List all = consensusDelegate.getAllWitnesses(); - all.forEach(witness -> { + consensusDelegate.getAllWitnesses().forEach(witness -> { delegationStore.setBrokerage(nextCycle, witness.createDbKey(), delegationStore.getBrokerage(witness.createDbKey())); delegationStore.setWitnessVote(nextCycle, witness.createDbKey(), witness.getVoteCount()); }); - consensusDelegate.updateWitnessStandby(all); } } diff --git a/consensus/src/main/java/org/tron/consensus/pbft/PbftManager.java b/consensus/src/main/java/org/tron/consensus/pbft/PbftManager.java index 2f42524e03e..9be925bdbc6 100644 --- a/consensus/src/main/java/org/tron/consensus/pbft/PbftManager.java +++ b/consensus/src/main/java/org/tron/consensus/pbft/PbftManager.java @@ -1,13 +1,14 @@ package org.tron.consensus.pbft; import com.google.protobuf.ByteString; +import java.io.Closeable; import java.util.List; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import javax.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.common.es.ExecutorServiceManager; import org.tron.consensus.base.Param; import org.tron.consensus.base.Param.Miner; import org.tron.consensus.dpos.MaintenanceManager; @@ -18,7 +19,7 @@ @Slf4j(topic = "pbft") @Component -public class PbftManager { +public class PbftManager implements Closeable { @Autowired private PbftMessageHandle pbftMessageHandle; @@ -29,8 +30,8 @@ public class PbftManager { @Autowired private ChainBaseManager chainBaseManager; - private ExecutorService executorService = Executors.newFixedThreadPool(10, - r -> new Thread(r, "Pbft")); + private final String esName = "pbft-msg-manager"; + private ExecutorService executorService = ExecutorServiceManager.newFixedThreadPool(esName, 10); @PostConstruct public void init() { @@ -111,4 +112,9 @@ public boolean verifyMsg(PbftBaseMessage msg) { return witnessList.contains(ByteString.copyFrom(msg.getPublicKey())); } + @Override + public void close() { + ExecutorServiceManager.shutdownAndAwaitTermination(executorService, esName); + } + } \ No newline at end of file diff --git a/crypto/build.gradle b/crypto/build.gradle index 19ae8e805fe..5bbfc630c45 100644 --- a/crypto/build.gradle +++ b/crypto/build.gradle @@ -15,3 +15,16 @@ dependencies { compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.69' compile project(":common") } + +jacocoTestReport { + reports { + xml.enabled = true + html.enabled = true + } + getExecutionData().setFrom(fileTree('../framework/build/jacoco').include("**.exec")) + afterEvaluate { + classDirectories.from = classDirectories.files.collect { + fileTree(dir: it,) + } + } +} diff --git a/crypto/src/main/java/org/tron/common/crypto/SignUtils.java b/crypto/src/main/java/org/tron/common/crypto/SignUtils.java index 87a55ffe655..b921d548e8b 100644 --- a/crypto/src/main/java/org/tron/common/crypto/SignUtils.java +++ b/crypto/src/main/java/org/tron/common/crypto/SignUtils.java @@ -26,10 +26,14 @@ public static SignInterface fromPrivate(byte[] privKeyBytes, boolean isECKeyCryp public static byte[] signatureToAddress( byte[] messageHash, String signatureBase64, boolean isECKeyCryptoEngine) throws SignatureException { - if (isECKeyCryptoEngine) { - return ECKey.signatureToAddress(messageHash, signatureBase64); + try { + if (isECKeyCryptoEngine) { + return ECKey.signatureToAddress(messageHash, signatureBase64); + } + return SM2.signatureToAddress(messageHash, signatureBase64); + } catch (Exception e) { + throw new SignatureException(e); } - return SM2.signatureToAddress(messageHash, signatureBase64); } public static SignatureInterface fromComponents( diff --git a/docker/docker.md b/docker/docker.md index a187f04631b..79aa6b08e2d 100644 --- a/docker/docker.md +++ b/docker/docker.md @@ -62,7 +62,7 @@ Or use the `-c` parameter to specify your own configuration file, which will not If you want to see the logs of the java-tron service, please use the `--log` parameter ```shell -$ sh docker.sh --log | grep 'pushBlock' +$ sh docker.sh --log | grep 'PushBlock' ``` ### Stop the service diff --git a/framework/build.gradle b/framework/build.gradle index fbe1fc0308b..c894ae1e03d 100644 --- a/framework/build.gradle +++ b/framework/build.gradle @@ -43,8 +43,7 @@ dependencies { testCompile group: 'junit', name: 'junit', version: '4.13.2' testCompile group: 'org.mockito', name: 'mockito-core', version: '2.13.0' testCompile group: 'org.hamcrest', name: 'hamcrest-junit', version: '1.0.0.1' - - testCompile group: 'org.testng', name: 'testng', version: '6.14.3' + testCompile group: 'com.github.stefanbirkner', name: 'system-rules', version: '1.16.0' compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.69' @@ -67,8 +66,8 @@ dependencies { compile group: 'com.carrotsearch', name: 'java-sizeof', version: '0.0.5' - compile 'com.googlecode.cqengine:cqengine:2.12.4' - compile group: 'com.google.api.grpc', name: 'googleapis-common-protos', version: '0.0.3' + //compile 'com.googlecode.cqengine:cqengine:2.12.4' + compile group: 'com.google.api.grpc', name: 'proto-google-common-protos', version: '2.15.0' // http compile 'org.eclipse.jetty:jetty-server:9.4.49.v20220914' @@ -87,6 +86,7 @@ dependencies { compile group: 'org.pf4j', name: 'pf4j', version: '2.5.0' testImplementation group: 'org.springframework', name: 'spring-test', version: '5.2.0.RELEASE' + testImplementation group: 'org.springframework', name: 'spring-web', version: '5.2.0.RELEASE' compile group: 'org.zeromq', name: 'jeromq', version: '0.5.3' compile project(":chainbase") @@ -165,7 +165,7 @@ jacocoTestReport { csv.enabled false html.destination file("${buildDir}/jacocoHtml") } - executionData.from = 'build/jacoco/jacocoTest.exec' + getExecutionData().setFrom(fileTree('../framework/build/jacoco').include("**.exec")) } def binaryRelease(taskName, jarName, mainClass) { diff --git a/framework/src/main/java/org/tron/common/application/Application.java b/framework/src/main/java/org/tron/common/application/Application.java index fdc0abc19e0..3d7e7a10864 100644 --- a/framework/src/main/java/org/tron/common/application/Application.java +++ b/framework/src/main/java/org/tron/common/application/Application.java @@ -34,6 +34,10 @@ public interface Application { void startServices(); + // DO NOT USE THIS METHOD IN TEST CASES MAIN-THREAD + default void blockUntilShutdown() { + } + void shutdownServices(); void addService(Service service); diff --git a/framework/src/main/java/org/tron/common/application/ApplicationImpl.java b/framework/src/main/java/org/tron/common/application/ApplicationImpl.java index 0e38e97baaf..9133fddf434 100644 --- a/framework/src/main/java/org/tron/common/application/ApplicationImpl.java +++ b/framework/src/main/java/org/tron/common/application/ApplicationImpl.java @@ -3,17 +3,13 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.tron.common.logsfilter.EventPluginLoader; import org.tron.common.parameter.CommonParameter; import org.tron.core.ChainBaseManager; import org.tron.core.config.args.Args; -import org.tron.core.config.args.DynamicArgs; import org.tron.core.consensus.ConsensusService; import org.tron.core.db.Manager; import org.tron.core.metrics.MetricsUtil; import org.tron.core.net.TronNetService; -import org.tron.program.FullNode; -import org.tron.program.SolidityNode; @Slf4j(topic = "app") @Component @@ -33,9 +29,6 @@ public class ApplicationImpl implements Application { @Autowired private ConsensusService consensusService; - @Autowired - private DynamicArgs dynamicArgs; - @Override public void setOptions(Args args) { // not used @@ -66,28 +59,18 @@ public void startup() { } consensusService.start(); MetricsUtil.init(); - dynamicArgs.init(); + this.initServices(Args.getInstance()); + this.startServices(); } @Override public void shutdown() { - logger.info("******** start to shutdown ********"); + this.shutdownServices(); + consensusService.stop(); if (!Args.getInstance().isSolidityNode() && (!Args.getInstance().p2pDisable)) { tronNetService.close(); } - consensusService.stop(); - synchronized (dbManager.getRevokingStore()) { - dbManager.getSession().reset(); - closeRevokingStore(); - closeAllStore(); - } - dbManager.stopRePushThread(); - dbManager.stopRePushTriggerThread(); - EventPluginLoader.getInstance().stopPlugin(); - dbManager.stopFilterProcessThread(); - dynamicArgs.close(); - logger.info("******** end to shutdown ********"); - FullNode.shutDownSign = true; + dbManager.close(); } @Override @@ -95,6 +78,11 @@ public void startServices() { services.start(); } + @Override + public void blockUntilShutdown() { + services.blockUntilShutdown(); + } + @Override public void shutdownServices() { services.stop(); @@ -110,13 +98,4 @@ public ChainBaseManager getChainBaseManager() { return chainBaseManager; } - private void closeRevokingStore() { - logger.info("******** start to closeRevokingStore ********"); - dbManager.getRevokingStore().shutdown(); - } - - private void closeAllStore() { - dbManager.closeAllStore(); - } - } diff --git a/framework/src/main/java/org/tron/common/application/HttpService.java b/framework/src/main/java/org/tron/common/application/HttpService.java new file mode 100644 index 00000000000..76f8e74d65c --- /dev/null +++ b/framework/src/main/java/org/tron/common/application/HttpService.java @@ -0,0 +1,81 @@ +/* + * java-tron is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * java-tron is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.tron.common.application; + +import com.google.common.base.Objects; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.jetty.server.Server; + +@Slf4j(topic = "rpc") +public abstract class HttpService implements Service { + + protected Server apiServer; + protected int port; + + @Override + public void blockUntilShutdown() { + if (apiServer != null) { + try { + apiServer.join(); + } catch (InterruptedException e) { + logger.warn("{}", e.getMessage()); + Thread.currentThread().interrupt(); + } + } + } + + @Override + public void start() { + if (apiServer != null) { + try { + apiServer.start(); + logger.info("{} started, listening on {}", this.getClass().getSimpleName(), port); + } catch (Exception e) { + logger.error("{}", this.getClass().getSimpleName(), e); + } + } + } + + @Override + public void stop() { + if (apiServer != null) { + logger.info("{} shutdown...", this.getClass().getSimpleName()); + try { + apiServer.stop(); + } catch (Exception e) { + logger.warn("{}", this.getClass().getSimpleName(), e); + } + logger.info("{} shutdown complete", this.getClass().getSimpleName()); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + HttpService that = (HttpService) o; + return port == that.port; + } + + @Override + public int hashCode() { + return Objects.hashCode(getClass().getSimpleName(), port); + } +} diff --git a/framework/src/main/java/org/tron/common/application/RpcService.java b/framework/src/main/java/org/tron/common/application/RpcService.java new file mode 100644 index 00000000000..cb89441174a --- /dev/null +++ b/framework/src/main/java/org/tron/common/application/RpcService.java @@ -0,0 +1,85 @@ +/* + * java-tron is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * java-tron is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.tron.common.application; + +import com.google.common.base.Objects; +import io.grpc.Server; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; + +@Slf4j(topic = "rpc") +public abstract class RpcService implements Service { + + protected Server apiServer; + protected int port; + + @Override + public void blockUntilShutdown() { + if (apiServer != null) { + try { + apiServer.awaitTermination(); + } catch (InterruptedException e) { + logger.warn("{}", e.getMessage()); + Thread.currentThread().interrupt(); + } + } + } + + @Override + public void start() { + if (apiServer != null) { + try { + apiServer.start(); + logger.info("{} started, listening on {}", this.getClass().getSimpleName(), port); + } catch (IOException e) { + logger.error("{}", this.getClass().getSimpleName(), e); + } + } + } + + @Override + public void stop() { + if (apiServer != null) { + logger.info("{} shutdown...", this.getClass().getSimpleName()); + try { + apiServer.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.warn("{}", this.getClass().getSimpleName(), e); + } + logger.info("{} shutdown complete", this.getClass().getSimpleName()); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + RpcService that = (RpcService) o; + return port == that.port; + } + + @Override + public int hashCode() { + return Objects.hashCode(getClass().getSimpleName(), port); + } + +} diff --git a/framework/src/main/java/org/tron/common/application/Service.java b/framework/src/main/java/org/tron/common/application/Service.java index 72cfad9bcc8..67b4e3ce9ae 100644 --- a/framework/src/main/java/org/tron/common/application/Service.java +++ b/framework/src/main/java/org/tron/common/application/Service.java @@ -23,7 +23,14 @@ public interface Service { void init(CommonParameter parameter); + /** + * Start the service. + * {@link Service#init(CommonParameter parameter) init(CommonParameter parameter)} must be called + * before this method. + */ void start(); void stop(); + + void blockUntilShutdown(); } diff --git a/framework/src/main/java/org/tron/common/application/ServiceContainer.java b/framework/src/main/java/org/tron/common/application/ServiceContainer.java index d194360c5ea..2951596add7 100644 --- a/framework/src/main/java/org/tron/common/application/ServiceContainer.java +++ b/framework/src/main/java/org/tron/common/application/ServiceContainer.java @@ -15,17 +15,19 @@ package org.tron.common.application; -import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; import lombok.extern.slf4j.Slf4j; import org.tron.common.parameter.CommonParameter; @Slf4j(topic = "app") public class ServiceContainer { - private ArrayList services; + private final Set services; public ServiceContainer() { - this.services = new ArrayList<>(); + this.services = Collections.synchronizedSet(new LinkedHashSet<>()); } public void add(Service service) { @@ -34,31 +36,38 @@ public void add(Service service) { public void init() { - for (Service service : this.services) { + this.services.forEach(service -> { logger.debug("Initing {}.", service.getClass().getSimpleName()); service.init(); - } + }); } public void init(CommonParameter parameter) { - for (Service service : this.services) { + this.services.forEach(service -> { logger.debug("Initing {}.", service.getClass().getSimpleName()); service.init(parameter); - } + }); } public void start() { - logger.debug("Starting services."); - for (Service service : this.services) { + logger.info("Starting api services."); + this.services.forEach(service -> { logger.debug("Starting {}.", service.getClass().getSimpleName()); service.start(); - } + }); + logger.info("All api services started."); } public void stop() { - for (Service service : this.services) { + logger.info("Stopping api services."); + this.services.forEach(service -> { logger.debug("Stopping {}.", service.getClass().getSimpleName()); service.stop(); - } + }); + logger.info("All api services stopped."); + } + + public void blockUntilShutdown() { + this.services.stream().findFirst().ifPresent(Service::blockUntilShutdown); } } diff --git a/framework/src/main/java/org/tron/common/application/TronApplicationContext.java b/framework/src/main/java/org/tron/common/application/TronApplicationContext.java index 7f0aea813a3..64edec77c9c 100644 --- a/framework/src/main/java/org/tron/common/application/TronApplicationContext.java +++ b/framework/src/main/java/org/tron/common/application/TronApplicationContext.java @@ -2,8 +2,7 @@ import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.tron.core.db.Manager; -import org.tron.core.net.TronNetService; +import org.tron.core.config.TronLogShutdownHook; public class TronApplicationContext extends AnnotationConfigApplicationContext { @@ -23,19 +22,18 @@ public TronApplicationContext(String... basePackages) { } @Override - public void destroy() { - + public void doClose() { + logger.info("******** start to close ********"); Application appT = ApplicationFactory.create(this); - appT.shutdownServices(); appT.shutdown(); + super.doClose(); + logger.info("******** close end ********"); + TronLogShutdownHook.shutDown = true; + } - TronNetService tronNetService = getBean(TronNetService.class); - tronNetService.close(); - - Manager dbManager = getBean(Manager.class); - dbManager.stopRePushThread(); - dbManager.stopRePushTriggerThread(); - dbManager.stopFilterProcessThread(); - super.destroy(); + @Override + public void registerShutdownHook() { + super.registerShutdownHook(); + TronLogShutdownHook.shutDown = false; } } diff --git a/framework/src/main/java/org/tron/common/backup/BackupManager.java b/framework/src/main/java/org/tron/common/backup/BackupManager.java index ef304164f1a..0c4a3e60dfd 100644 --- a/framework/src/main/java/org/tron/common/backup/BackupManager.java +++ b/framework/src/main/java/org/tron/common/backup/BackupManager.java @@ -9,7 +9,6 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.Set; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; @@ -19,6 +18,7 @@ import org.tron.common.backup.socket.EventHandler; import org.tron.common.backup.socket.MessageHandler; import org.tron.common.backup.socket.UdpEvent; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.parameter.CommonParameter; @Slf4j(topic = "backup") @@ -39,7 +39,10 @@ public class BackupManager implements EventHandler { private Set members = new ConcurrentSet<>(); - private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); + private final String esName = "backup-manager"; + + private ScheduledExecutorService executorService = + ExecutorServiceManager.newSingleThreadScheduledExecutor(esName); private MessageHandler messageHandler; @@ -144,6 +147,10 @@ public void handleEvent(UdpEvent udpEvent) { } } + public void stop() { + ExecutorServiceManager.shutdownAndAwaitTermination(executorService, esName); + } + @Override public void channelActivated() { init(); diff --git a/framework/src/main/java/org/tron/common/backup/socket/BackupServer.java b/framework/src/main/java/org/tron/common/backup/socket/BackupServer.java index e3b1de31736..2acf1e12633 100644 --- a/framework/src/main/java/org/tron/common/backup/socket/BackupServer.java +++ b/framework/src/main/java/org/tron/common/backup/socket/BackupServer.java @@ -7,17 +7,19 @@ import io.netty.channel.socket.nio.NioDatagramChannel; import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder; import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.tron.common.backup.BackupManager; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.parameter.CommonParameter; import org.tron.p2p.stats.TrafficStats; @Slf4j(topic = "backup") @Component -public class BackupServer { +public class BackupServer implements AutoCloseable { private CommonParameter commonParameter = CommonParameter.getInstance(); @@ -29,6 +31,9 @@ public class BackupServer { private volatile boolean shutdown = false; + private final String name = "BackupServer"; + private ExecutorService executor; + @Autowired public BackupServer(final BackupManager backupManager) { this.backupManager = backupManager; @@ -36,13 +41,14 @@ public BackupServer(final BackupManager backupManager) { public void initServer() { if (port > 0 && commonParameter.getBackupMembers().size() > 0) { - new Thread(() -> { + executor = ExecutorServiceManager.newSingleThreadExecutor(name); + executor.submit(() -> { try { start(); } catch (Exception e) { logger.error("Start backup server failed, {}", e); } - }, "BackupServer").start(); + }); } } @@ -85,9 +91,12 @@ public void initChannel(NioDatagramChannel ch) } } + @Override public void close() { logger.info("Closing backup server..."); shutdown = true; + ExecutorServiceManager.shutdownAndAwaitTermination(executor, name); + backupManager.stop(); if (channel != null) { try { channel.close().await(10, TimeUnit.SECONDS); @@ -95,5 +104,6 @@ public void close() { logger.warn("Closing backup server failed.", e); } } + logger.info("Backup server closed."); } } diff --git a/framework/src/main/java/org/tron/common/cache/CacheManagerTest.java b/framework/src/main/java/org/tron/common/cache/CacheManagerTest.java new file mode 100644 index 00000000000..b02b135552a --- /dev/null +++ b/framework/src/main/java/org/tron/common/cache/CacheManagerTest.java @@ -0,0 +1,14 @@ +package org.tron.common.cache; + +import org.junit.Assert; +import org.junit.Test; + +public class CacheManagerTest { + + @Test + public void allocate() { + String strategy = String.format(CacheStrategies.PATTERNS, 1, 1, "30s", 1); + TronCache cache = CacheManager.allocate(CacheType.witnessStandby, strategy); + Assert.assertNull(cache.getIfPresent("test")); + } +} diff --git a/framework/src/main/java/org/tron/common/logsfilter/capsule/TransactionLogTriggerCapsule.java b/framework/src/main/java/org/tron/common/logsfilter/capsule/TransactionLogTriggerCapsule.java index 8600cb6ef8c..f5d457f541d 100644 --- a/framework/src/main/java/org/tron/common/logsfilter/capsule/TransactionLogTriggerCapsule.java +++ b/framework/src/main/java/org/tron/common/logsfilter/capsule/TransactionLogTriggerCapsule.java @@ -1,6 +1,7 @@ package org.tron.common.logsfilter.capsule; import static org.tron.protos.Protocol.Transaction.Contract.ContractType.CreateSmartContract; +import static org.tron.protos.contract.Common.ResourceCode.ENERGY; import com.google.protobuf.Any; import com.google.protobuf.ByteString; @@ -26,7 +27,14 @@ import org.tron.protos.Protocol.Transaction.Contract.ContractType; import org.tron.protos.Protocol.TransactionInfo; import org.tron.protos.contract.AssetIssueContractOuterClass.TransferAssetContract; +import org.tron.protos.contract.BalanceContract.CancelAllUnfreezeV2Contract; +import org.tron.protos.contract.BalanceContract.DelegateResourceContract; +import org.tron.protos.contract.BalanceContract.FreezeBalanceV2Contract; import org.tron.protos.contract.BalanceContract.TransferContract; +import org.tron.protos.contract.BalanceContract.UnDelegateResourceContract; +import org.tron.protos.contract.BalanceContract.UnfreezeBalanceContract; +import org.tron.protos.contract.BalanceContract.UnfreezeBalanceV2Contract; +import org.tron.protos.contract.BalanceContract.WithdrawExpireUnfreezeContract; import org.tron.protos.contract.SmartContractOuterClass.CreateSmartContract; import org.tron.protos.contract.SmartContractOuterClass.TriggerSmartContract; @@ -156,6 +164,88 @@ public TransactionLogTriggerCapsule(TransactionCapsule trxCapsule, BlockCapsule StringUtil.encode58Check(createSmartContract.getOwnerAddress().toByteArray())); } break; + case UnfreezeBalanceContract: + UnfreezeBalanceContract unfreezeBalanceContract = contractParameter + .unpack(UnfreezeBalanceContract.class); + + transactionLogTrigger.setFromAddress(StringUtil + .encode58Check(unfreezeBalanceContract.getOwnerAddress().toByteArray())); + if (!ByteString.EMPTY.equals(unfreezeBalanceContract.getReceiverAddress())) { + transactionLogTrigger.setToAddress(StringUtil + .encode58Check(unfreezeBalanceContract.getReceiverAddress().toByteArray())); + } + transactionLogTrigger.setAssetName("trx"); + if (Objects.nonNull(transactionInfo)) { + transactionLogTrigger.setAssetAmount( + transactionInfo.getUnfreezeAmount()); + } + break; + case FreezeBalanceV2Contract: + FreezeBalanceV2Contract freezeBalanceV2Contract = contractParameter + .unpack(FreezeBalanceV2Contract.class); + + transactionLogTrigger.setFromAddress(StringUtil + .encode58Check(freezeBalanceV2Contract.getOwnerAddress().toByteArray())); + transactionLogTrigger.setAssetName("trx"); + transactionLogTrigger.setAssetAmount(freezeBalanceV2Contract.getFrozenBalance()); + break; + case UnfreezeBalanceV2Contract: + UnfreezeBalanceV2Contract unfreezeBalanceV2Contract = contractParameter + .unpack(UnfreezeBalanceV2Contract.class); + + transactionLogTrigger.setFromAddress(StringUtil + .encode58Check(unfreezeBalanceV2Contract.getOwnerAddress().toByteArray())); + transactionLogTrigger.setAssetName("trx"); + transactionLogTrigger.setAssetAmount( + unfreezeBalanceV2Contract.getUnfreezeBalance()); + break; + case WithdrawExpireUnfreezeContract: + WithdrawExpireUnfreezeContract withdrawExpireUnfreezeContract = contractParameter + .unpack(WithdrawExpireUnfreezeContract.class); + + transactionLogTrigger.setFromAddress(StringUtil.encode58Check( + withdrawExpireUnfreezeContract.getOwnerAddress().toByteArray())); + transactionLogTrigger.setAssetName("trx"); + if (Objects.nonNull(transactionInfo)) { + transactionLogTrigger.setAssetAmount(transactionInfo.getWithdrawExpireAmount()); + } + break; + case DelegateResourceContract: + DelegateResourceContract delegateResourceContract = contractParameter + .unpack(DelegateResourceContract.class); + + transactionLogTrigger.setFromAddress(StringUtil + .encode58Check(delegateResourceContract.getOwnerAddress().toByteArray())); + transactionLogTrigger.setToAddress(StringUtil + .encode58Check(delegateResourceContract.getReceiverAddress().toByteArray())); + transactionLogTrigger.setAssetName("trx"); + transactionLogTrigger.setAssetAmount( + delegateResourceContract.getBalance()); + break; + case UnDelegateResourceContract: + UnDelegateResourceContract unDelegateResourceContract = contractParameter + .unpack(UnDelegateResourceContract.class); + + transactionLogTrigger.setFromAddress(StringUtil + .encode58Check(unDelegateResourceContract.getOwnerAddress().toByteArray())); + transactionLogTrigger.setToAddress(StringUtil.encode58Check( + unDelegateResourceContract.getReceiverAddress().toByteArray())); + + transactionLogTrigger.setAssetName("trx"); + transactionLogTrigger.setAssetAmount( + unDelegateResourceContract.getBalance()); + break; + case CancelAllUnfreezeV2Contract: + CancelAllUnfreezeV2Contract cancelAllUnfreezeV2Contract = contractParameter + .unpack(CancelAllUnfreezeV2Contract.class); + + transactionLogTrigger.setFromAddress(StringUtil + .encode58Check(cancelAllUnfreezeV2Contract.getOwnerAddress().toByteArray())); + transactionLogTrigger.setAssetName("trx"); + if (Objects.nonNull(transactionInfo)) { + transactionLogTrigger.setExtMap(transactionInfo.getCancelUnfreezeV2AmountMap()); + } + break; default: break; } @@ -269,4 +359,5 @@ private List getInternalTransactionList( public void processTrigger() { EventPluginLoader.getInstance().postTransactionTrigger(transactionLogTrigger); } + } diff --git a/framework/src/main/java/org/tron/core/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java index 3f26f9b398b..ba28bee4d68 100755 --- a/framework/src/main/java/org/tron/core/Wallet.java +++ b/framework/src/main/java/org/tron/core/Wallet.java @@ -21,6 +21,7 @@ import static org.tron.common.utils.Commons.getAssetIssueStoreFinal; import static org.tron.common.utils.Commons.getExchangeStoreFinal; import static org.tron.common.utils.WalletUtil.isConstant; +import static org.tron.core.capsule.utils.TransactionUtil.buildInternalTransaction; import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL; import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION; import static org.tron.core.config.Parameter.DatabaseConstants.EXCHANGE_COUNT_LIMIT_MAX; @@ -28,6 +29,8 @@ import static org.tron.core.config.Parameter.DatabaseConstants.PROPOSAL_COUNT_LIMIT_MAX; import static org.tron.core.services.jsonrpc.JsonRpcApiUtil.parseEnergyFee; import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.EARLIEST_STR; +import static org.tron.core.vm.utils.FreezeV2Util.getV2EnergyUsage; +import static org.tron.core.vm.utils.FreezeV2Util.getV2NetUsage; import static org.tron.protos.contract.Common.ResourceCode; import com.google.common.collect.ContiguousSet; @@ -82,6 +85,7 @@ import org.tron.api.GrpcAPI.NoteParameters; import org.tron.api.GrpcAPI.NumberMessage; import org.tron.api.GrpcAPI.PaymentAddressMessage; +import org.tron.api.GrpcAPI.PricesResponseMessage; import org.tron.api.GrpcAPI.PrivateParameters; import org.tron.api.GrpcAPI.PrivateParametersWithoutAsk; import org.tron.api.GrpcAPI.PrivateShieldedTRC20Parameters; @@ -154,7 +158,6 @@ import org.tron.core.capsule.TransactionRetCapsule; import org.tron.core.capsule.WitnessCapsule; import org.tron.core.capsule.utils.MarketUtils; -import org.tron.core.capsule.utils.TransactionUtil; import org.tron.core.config.args.Args; import org.tron.core.db.BandwidthProcessor; import org.tron.core.db.BlockIndexStore; @@ -195,6 +198,7 @@ import org.tron.core.store.MarketPairPriceToOrderStore; import org.tron.core.store.MarketPairToPriceStore; import org.tron.core.store.StoreFactory; +import org.tron.core.utils.TransactionUtil; import org.tron.core.vm.program.Program; import org.tron.core.vm.program.Storage; import org.tron.core.zen.ShieldedTRC20ParametersBuilder; @@ -814,6 +818,10 @@ public GrpcAPI.CanWithdrawUnfreezeAmountResponseMessage getCanWithdrawUnfreezeAm ByteString ownerAddress, long timestamp) { GrpcAPI.CanWithdrawUnfreezeAmountResponseMessage.Builder builder = GrpcAPI.CanWithdrawUnfreezeAmountResponseMessage.newBuilder(); + if (timestamp < 0) { + return builder.build(); + } + long canWithdrawUnfreezeAmount; AccountStore accountStore = chainBaseManager.getAccountStore(); @@ -831,13 +839,8 @@ public GrpcAPI.CanWithdrawUnfreezeAmountResponseMessage getCanWithdrawUnfreezeAm long finalTimestamp = timestamp; canWithdrawUnfreezeAmount = unfrozenV2List - .stream() - .filter(unfrozenV2 -> - (unfrozenV2.getUnfreezeAmount() > 0 - && unfrozenV2.getUnfreezeExpireTime() <= finalTimestamp)) - .mapToLong(UnFreezeV2::getUnfreezeAmount) - .sum(); - + .stream().filter(unfrozenV2 -> unfrozenV2.getUnfreezeExpireTime() <= finalTimestamp) + .mapToLong(UnFreezeV2::getUnfreezeAmount).sum(); builder.setAmount(canWithdrawUnfreezeAmount); return builder.build(); @@ -876,13 +879,7 @@ public GrpcAPI.GetAvailableUnfreezeCountResponseMessage getAvailableUnfreezeCoun } long now = dynamicStore.getLatestBlockHeaderTimestamp(); - List unfrozenV2List = accountCapsule.getInstance().getUnfrozenV2List(); - long getUsedUnfreezeCount = unfrozenV2List - .stream() - .filter(unfrozenV2 -> - (unfrozenV2.getUnfreezeAmount() > 0 - && unfrozenV2.getUnfreezeExpireTime() > now)) - .count(); + long getUsedUnfreezeCount = accountCapsule.getUnfreezingV2Count(now); getAvailableUnfreezeCount = UnfreezeBalanceV2Actuator.getUNFREEZE_MAX_TIMES() - getUsedUnfreezeCount; builder.setCount(getAvailableUnfreezeCount); @@ -902,20 +899,15 @@ public long calcCanDelegatedBandWidthMaxSize( processor.updateUsage(ownerCapsule); long accountNetUsage = ownerCapsule.getNetUsage(); - accountNetUsage += org.tron.core.utils.TransactionUtil.estimateConsumeBandWidthSize( - ownerCapsule, chainBaseManager); + accountNetUsage += TransactionUtil.estimateConsumeBandWidthSize(dynamicStore, + ownerCapsule.getFrozenV2BalanceForBandwidth()); long netUsage = (long) (accountNetUsage * TRX_PRECISION * ((double) (dynamicStore.getTotalNetWeight()) / dynamicStore.getTotalNetLimit())); - long remainNetUsage = netUsage - - ownerCapsule.getFrozenBalance() - - ownerCapsule.getAcquiredDelegatedFrozenBalanceForBandwidth() - - ownerCapsule.getAcquiredDelegatedFrozenV2BalanceForBandwidth(); - - remainNetUsage = Math.max(0, remainNetUsage); + long v2NetUsage = getV2NetUsage(ownerCapsule, netUsage); - long maxSize = ownerCapsule.getFrozenV2BalanceForBandwidth() - remainNetUsage; + long maxSize = ownerCapsule.getFrozenV2BalanceForBandwidth() - v2NetUsage; return Math.max(0, maxSize); } @@ -933,14 +925,9 @@ public long calcCanDelegatedEnergyMaxSize(ByteString ownerAddress) { long energyUsage = (long) (ownerCapsule.getEnergyUsage() * TRX_PRECISION * ((double) (dynamicStore.getTotalEnergyWeight()) / dynamicStore.getTotalEnergyCurrentLimit())); - long remainEnergyUsage = energyUsage - - ownerCapsule.getEnergyFrozenBalance() - - ownerCapsule.getAcquiredDelegatedFrozenBalanceForEnergy() - - ownerCapsule.getAcquiredDelegatedFrozenV2BalanceForEnergy(); + long v2EnergyUsage = getV2EnergyUsage(ownerCapsule, energyUsage); - remainEnergyUsage = Math.max(0, remainEnergyUsage); - - long maxSize = ownerCapsule.getFrozenV2BalanceForEnergy() - remainEnergyUsage; + long maxSize = ownerCapsule.getFrozenV2BalanceForEnergy() - v2EnergyUsage; return Math.max(0, maxSize); } @@ -2090,7 +2077,7 @@ public IncrementalMerkleTree getMerkleTreeOfBlock(long blockNum) throws ZksnarkE .parseFrom(chainBaseManager.getMerkleTreeIndexStore().get(blockNum)); } } catch (Exception ex) { - logger.error(ex.getMessage()); + logger.error("GetMerkleTreeOfBlock failed, blockNum:{}", blockNum, ex); } return null; @@ -3108,7 +3095,7 @@ public Transaction callConstantContract(TransactionCapsule trxCap, result.getLogInfoList().forEach(logInfo -> builder.addLogs(LogInfo.buildLog(logInfo))); result.getInternalTransactions().forEach(it -> - builder.addInternalTransactions(TransactionUtil.buildInternalTransaction(it))); + builder.addInternalTransactions(buildInternalTransaction(it))); ret.setStatus(0, code.SUCESS); if (StringUtils.isNoneEmpty(result.getRuntimeError())) { ret.setStatus(0, code.FAILED); @@ -4163,7 +4150,7 @@ private void checkBigIntegerRange(BigInteger in) throws ContractValidateExceptio } } - private byte[] getShieldedContractScalingFactor(byte[] contractAddress) + public byte[] getShieldedContractScalingFactor(byte[] contractAddress) throws ContractExeException { String methodSign = "scalingFactor()"; byte[] selector = new byte[4]; @@ -4354,28 +4341,30 @@ public long getEnergyFee(long timestamp) { return energyFee; } catch (Exception e) { - logger.error("getEnergyFee timestamp={} failed, error is {}", timestamp, e.getMessage()); + logger.error("GetEnergyFee timestamp={} failed", timestamp, e); return getEnergyFee(); } } - public String getEnergyPrices() { + public PricesResponseMessage getEnergyPrices() { + PricesResponseMessage.Builder builder = PricesResponseMessage.newBuilder(); try { - return chainBaseManager.getDynamicPropertiesStore().getEnergyPriceHistory(); + builder.setPrices(chainBaseManager.getDynamicPropertiesStore().getEnergyPriceHistory()); + return builder.build(); } catch (Exception e) { - logger.error("getEnergyPrices failed, error is {}", e.getMessage()); + logger.error("GetEnergyPrices failed", e); } - return null; } - public String getBandwidthPrices() { + public PricesResponseMessage getBandwidthPrices() { + PricesResponseMessage.Builder builder = PricesResponseMessage.newBuilder(); try { - return chainBaseManager.getDynamicPropertiesStore().getBandwidthPriceHistory(); + builder.setPrices(chainBaseManager.getDynamicPropertiesStore().getBandwidthPriceHistory()); + return builder.build(); } catch (Exception e) { - logger.error("getBandwidthPrices failed, error is {}", e.getMessage()); + logger.error("GetBandwidthPrices failed", e); } - return null; } @@ -4490,11 +4479,13 @@ public Block getBlock(GrpcAPI.BlockReq request) { return block.toBuilder().clearTransactions().build(); } - public String getMemoFeePrices() { + public PricesResponseMessage getMemoFeePrices() { + PricesResponseMessage.Builder builder = PricesResponseMessage.newBuilder(); try { - return chainBaseManager.getDynamicPropertiesStore().getMemoFeeHistory(); + builder.setPrices(chainBaseManager.getDynamicPropertiesStore().getMemoFeeHistory()); + return builder.build(); } catch (Exception e) { - logger.error("getMemoFeePrices failed, error is {}", e.getMessage()); + logger.error("GetMemoFeePrices failed", e); } return null; } diff --git a/framework/src/main/java/org/tron/core/config/DefaultConfig.java b/framework/src/main/java/org/tron/core/config/DefaultConfig.java index 6c6a0e2c566..7cc32d9a581 100755 --- a/framework/src/main/java/org/tron/core/config/DefaultConfig.java +++ b/framework/src/main/java/org/tron/core/config/DefaultConfig.java @@ -11,9 +11,7 @@ import org.springframework.context.annotation.Import; import org.tron.common.utils.StorageUtils; import org.tron.core.config.args.Args; -import org.tron.core.db.RecentTransactionStore; import org.tron.core.db.RevokingDatabase; -import org.tron.core.db.TransactionCache; import org.tron.core.db.backup.BackupRocksDBAspect; import org.tron.core.db.backup.NeedBeanCondition; import org.tron.core.db2.core.SnapshotManager; @@ -42,7 +40,7 @@ public DefaultConfig() { Thread.setDefaultUncaughtExceptionHandler((t, e) -> logger.error("Uncaught exception", e)); } - @Bean + @Bean(destroyMethod = "") public RevokingDatabase revokingDatabase() { try { return new SnapshotManager( @@ -93,11 +91,6 @@ public HttpApiOnPBFTService getHttpApiOnPBFTService() { return null; } - @Bean - public TransactionCache transactionCache() { - return new TransactionCache("trans-cache", appCtx.getBean(RecentTransactionStore.class)); - } - @Bean @Conditional(NeedBeanCondition.class) public BackupRocksDBAspect backupRocksDBAspect() { diff --git a/framework/src/main/java/org/tron/core/config/TronLogShutdownHook.java b/framework/src/main/java/org/tron/core/config/TronLogShutdownHook.java index 880aa7e3090..f497b9a85d8 100644 --- a/framework/src/main/java/org/tron/core/config/TronLogShutdownHook.java +++ b/framework/src/main/java/org/tron/core/config/TronLogShutdownHook.java @@ -16,9 +16,12 @@ public class TronLogShutdownHook extends ShutdownHookBase { private static final Duration CHECK_SHUTDOWN_DELAY = Duration.buildByMilliseconds(100); /** - * The check times before shutdown. default is 50 + * The check times before shutdown. default is 60000/100 = 600 times. */ - private Integer check_times = 50; + private final long check_times = 60 * 1000 / CHECK_SHUTDOWN_DELAY.getMilliseconds(); + + // if true, shutdown hook will be executed , for example, 'java -jar FullNode.jar -[v|h]'. + public static volatile boolean shutDown = true; public TronLogShutdownHook() { } @@ -27,7 +30,7 @@ public TronLogShutdownHook() { public void run() { try { for (int i = 0; i < check_times; i++) { - if (FullNode.shutDownSign) { + if (shutDown) { break; } addInfo("Sleeping for " + CHECK_SHUTDOWN_DELAY); diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java index 15dfeb5d799..5ef9131d6a0 100644 --- a/framework/src/main/java/org/tron/core/config/args/Args.java +++ b/framework/src/main/java/org/tron/core/config/args/Args.java @@ -15,15 +15,12 @@ import com.typesafe.config.ConfigObject; import io.grpc.internal.GrpcUtil; import io.grpc.netty.NettyServerBuilder; -import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; -import java.net.URL; import java.text.ParseException; import java.util.ArrayList; import java.util.Arrays; @@ -73,6 +70,7 @@ import org.tron.core.store.AccountStore; import org.tron.keystore.Credentials; import org.tron.keystore.WalletUtils; +import org.tron.p2p.P2pConfig; import org.tron.p2p.dns.update.DnsType; import org.tron.p2p.dns.update.PublishConfig; import org.tron.p2p.utils.NetUtil; @@ -140,9 +138,6 @@ public static void clearParam() { PARAMETER.nodeListenPort = 0; PARAMETER.nodeDiscoveryBindIp = ""; PARAMETER.nodeExternalIp = ""; - PARAMETER.nodeDiscoveryPublicHomeNode = false; - PARAMETER.nodeDiscoveryPingTimeout = 15000; - PARAMETER.nodeP2pPingInterval = 0L; PARAMETER.nodeP2pVersion = 0; PARAMETER.nodeEnableIpv6 = false; PARAMETER.dnsTreeUrls = new ArrayList<>(); @@ -154,6 +149,7 @@ public static void clearParam() { PARAMETER.fullNodeHttpPort = 0; PARAMETER.solidityHttpPort = 0; PARAMETER.pBFTHttpPort = 0; + PARAMETER.pBFTExpireNum = 20; PARAMETER.jsonRpcHttpFullNodePort = 0; PARAMETER.jsonRpcHttpSolidityPort = 0; PARAMETER.jsonRpcHttpPBFTPort = 0; @@ -170,7 +166,6 @@ public static void clearParam() { PARAMETER.forbidTransferToContract = 0; PARAMETER.tcpNettyWorkThreadNum = 0; PARAMETER.udpNettyWorkThreadNum = 0; - PARAMETER.p2pNodeId = ""; PARAMETER.solidityNode = false; PARAMETER.trustNodeAddr = ""; PARAMETER.walletExtensionApi = false; @@ -234,6 +229,7 @@ public static void clearParam() { PARAMETER.memoFee = 0; PARAMETER.rateLimiterGlobalQps = 50000; PARAMETER.rateLimiterGlobalIpQps = 10000; + PARAMETER.rateLimiterGlobalApiQps = 1000; PARAMETER.p2pDisable = false; PARAMETER.dynamicConfigEnable = false; PARAMETER.dynamicConfigCheckInterval = 600; @@ -545,6 +541,8 @@ public static void setParam(final String[] args, final String confFileName) { PARAMETER.storage.setEstimatedBlockTransactions( Storage.getEstimatedTransactionsFromConfig(config)); + PARAMETER.storage.setTxCacheInitOptimization( + Storage.getTxCacheInitOptimizationFromConfig(config)); PARAMETER.storage.setMaxFlushCount(Storage.getSnapshotMaxFlushCountFromConfig(config)); PARAMETER.storage.setDefaultDbOptions(config); @@ -654,6 +652,7 @@ public static void setParam(final String[] args, final String confFileName) { ? config.getInt(Constant.NODE_MIN_PARTICIPATION_RATE) : 0; + PARAMETER.p2pConfig = new P2pConfig(); PARAMETER.nodeListenPort = config.hasPath(Constant.NODE_LISTEN_PORT) ? config.getInt(Constant.NODE_LISTEN_PORT) : 0; @@ -661,18 +660,6 @@ public static void setParam(final String[] args, final String confFileName) { bindIp(config); externalIp(config); - PARAMETER.nodeDiscoveryPublicHomeNode = - config.hasPath(Constant.NODE_DISCOVERY_PUBLIC_HOME_NODE) && config - .getBoolean(Constant.NODE_DISCOVERY_PUBLIC_HOME_NODE); - - PARAMETER.nodeDiscoveryPingTimeout = - config.hasPath(Constant.NODE_DISCOVERY_PING_TIMEOUT) - ? config.getLong(Constant.NODE_DISCOVERY_PING_TIMEOUT) : 15000; - - PARAMETER.nodeP2pPingInterval = - config.hasPath(Constant.NODE_P2P_PING_INTERVAL) - ? config.getLong(Constant.NODE_P2P_PING_INTERVAL) : 0; - PARAMETER.nodeP2pVersion = config.hasPath(Constant.NODE_P2P_VERSION) ? config.getInt(Constant.NODE_P2P_VERSION) : 0; @@ -846,7 +833,7 @@ public static void setParam(final String[] args, final String confFileName) { PARAMETER.validateSignThreadNum = config.hasPath(Constant.NODE_VALIDATE_SIGN_THREAD_NUM) ? config .getInt(Constant.NODE_VALIDATE_SIGN_THREAD_NUM) - : (Runtime.getRuntime().availableProcessors() + 1) / 2; + : Runtime.getRuntime().availableProcessors(); PARAMETER.walletExtensionApi = config.hasPath(Constant.NODE_WALLET_EXTENSION_API) @@ -996,6 +983,10 @@ public static void setParam(final String[] args, final String confFileName) { config.hasPath(Constant.RATE_LIMITER_GLOBAL_IP_QPS) ? config .getInt(Constant.RATE_LIMITER_GLOBAL_IP_QPS) : 10000; + PARAMETER.rateLimiterGlobalApiQps = + config.hasPath(Constant.RATE_LIMITER_GLOBAL_API_QPS) ? config + .getInt(Constant.RATE_LIMITER_GLOBAL_API_QPS) : 1000; + PARAMETER.rateLimiterInitialization = getRateLimiterFromConfig(config); PARAMETER.changedDelegation = @@ -1006,6 +997,10 @@ public static void setParam(final String[] args, final String confFileName) { config.hasPath(Constant.COMMITTEE_ALLOW_PBFT) ? config .getLong(Constant.COMMITTEE_ALLOW_PBFT) : 0; + PARAMETER.pBFTExpireNum = + config.hasPath(Constant.COMMITTEE_PBFT_EXPIRE_NUM) ? config + .getLong(Constant.COMMITTEE_PBFT_EXPIRE_NUM) : 20; + PARAMETER.agreeNodeCount = config.hasPath(Constant.NODE_AGREE_NODE_COUNT) ? config .getInt(Constant.NODE_AGREE_NODE_COUNT) : MAX_ACTIVE_WITNESS_NUM * 2 / 3 + 1; PARAMETER.agreeNodeCount = PARAMETER.agreeNodeCount > MAX_ACTIVE_WITNESS_NUM @@ -1571,36 +1566,10 @@ private static void externalIp(final com.typesafe.config.Config config) { if (!config.hasPath(Constant.NODE_DISCOVERY_EXTERNAL_IP) || config .getString(Constant.NODE_DISCOVERY_EXTERNAL_IP).trim().isEmpty()) { if (PARAMETER.nodeExternalIp == null) { - logger.info("External IP wasn't set, using checkip.amazonaws.com to identify it..."); - BufferedReader in = null; - try { - in = new BufferedReader(new InputStreamReader( - new URL(Constant.AMAZONAWS_URL).openStream())); - PARAMETER.nodeExternalIp = in.readLine(); - if (PARAMETER.nodeExternalIp == null || PARAMETER.nodeExternalIp.trim().isEmpty()) { - throw new IOException("Invalid address: '" + PARAMETER.nodeExternalIp + "'"); - } - try { - InetAddress.getByName(PARAMETER.nodeExternalIp); - } catch (Exception e) { - throw new IOException("Invalid address: '" + PARAMETER.nodeExternalIp + "'"); - } - logger.info("External address identified: {}", PARAMETER.nodeExternalIp); - } catch (IOException e) { + logger.info("External IP wasn't set, using ipv4 from libp2p"); + PARAMETER.nodeExternalIp = PARAMETER.p2pConfig.getIp(); + if (StringUtils.isEmpty(PARAMETER.nodeExternalIp)) { PARAMETER.nodeExternalIp = PARAMETER.nodeDiscoveryBindIp; - logger.warn( - "Can't get external IP. Fall back to peer.bind.ip: " - + PARAMETER.nodeExternalIp + " :" - + e); - } finally { - if (in != null) { - try { - in.close(); - } catch (IOException e) { - //ignore - } - } - } } } else { @@ -1692,6 +1661,7 @@ public static void logConfig() { logger.info("Node effective check enable: {}", parameter.isNodeEffectiveCheckEnable()); logger.info("Rate limiter global qps: {}", parameter.getRateLimiterGlobalQps()); logger.info("Rate limiter global ip qps: {}", parameter.getRateLimiterGlobalIpQps()); + logger.info("Rate limiter global api qps: {}", parameter.getRateLimiterGlobalApiQps()); logger.info("************************ Backup config ************************"); logger.info("Backup priority: {}", parameter.getBackupPriority()); logger.info("Backup listen port: {}", parameter.getBackupPort()); diff --git a/framework/src/main/java/org/tron/core/config/args/DynamicArgs.java b/framework/src/main/java/org/tron/core/config/args/DynamicArgs.java index cbf167cb955..557b8f1211b 100644 --- a/framework/src/main/java/org/tron/core/config/args/DynamicArgs.java +++ b/framework/src/main/java/org/tron/core/config/args/DynamicArgs.java @@ -7,12 +7,13 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.List; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; - +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.parameter.CommonParameter; import org.tron.core.Constant; import org.tron.core.config.Configuration; @@ -26,10 +27,13 @@ public class DynamicArgs { private long lastModified = 0; - private ScheduledExecutorService reloadExecutor = Executors.newSingleThreadScheduledExecutor(); + private ScheduledExecutorService reloadExecutor; + private final String esName = "dynamic-reload"; + @PostConstruct public void init() { if (parameter.isDynamicConfigEnable()) { + reloadExecutor = ExecutorServiceManager.newSingleThreadScheduledExecutor(esName); logger.info("Start the dynamic loading configuration service"); long checkInterval = parameter.getDynamicConfigCheckInterval(); File config = getConfigFile(); @@ -107,8 +111,8 @@ private void updateTrustNodes(Config config) { TronNetService.getP2pConfig().getTrustNodes().toString()); } + @PreDestroy public void close() { - logger.info("Closing the dynamic loading configuration service"); - reloadExecutor.shutdown(); + ExecutorServiceManager.shutdownAndAwaitTermination(reloadExecutor, esName); } -} \ No newline at end of file +} diff --git a/framework/src/main/java/org/tron/core/db/Manager.java b/framework/src/main/java/org/tron/core/db/Manager.java index 34db850f8c0..54a59f87221 100644 --- a/framework/src/main/java/org/tron/core/db/Manager.java +++ b/framework/src/main/java/org/tron/core/db/Manager.java @@ -29,7 +29,6 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.PriorityBlockingQueue; @@ -49,6 +48,7 @@ import org.tron.api.GrpcAPI.TransactionInfoList; import org.tron.common.args.GenesisBlock; import org.tron.common.bloom.Bloom; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.logsfilter.EventPluginLoader; import org.tron.common.logsfilter.FilterQuery; import org.tron.common.logsfilter.capsule.BlockFilterCapsule; @@ -104,7 +104,6 @@ import org.tron.core.db.api.MoveAbiHelper; import org.tron.core.db2.ISession; import org.tron.core.db2.core.Chainbase; -import org.tron.core.db2.core.ITronChainBase; import org.tron.core.db2.core.SnapshotManager; import org.tron.core.exception.AccountResourceInsufficientException; import org.tron.core.exception.BadBlockException; @@ -182,8 +181,8 @@ public class Manager { @Setter public boolean eventPluginLoaded = false; private int maxTransactionPendingSize = Args.getInstance().getMaxTransactionPendingSize(); - @Autowired(required = false) @Getter + @Autowired private TransactionCache transactionCache; @Autowired private KhaosDatabase khaosDb; @@ -208,6 +207,7 @@ public class Manager { @Setter private MerkleContainer merkleContainer; private ExecutorService validateSignService; + private String validateSignName = "validate-sign"; private boolean isRunRePushThread = true; private boolean isRunTriggerCapsuleProcessThread = true; private BlockingQueue pushTransactionQueue = new LinkedBlockingQueue<>(); @@ -259,6 +259,13 @@ public class Manager { private AtomicInteger blockWaitLock = new AtomicInteger(0); private Object transactionLock = new Object(); + private ExecutorService rePushEs; + private static final String rePushEsName = "repush"; + private ExecutorService triggerEs; + private static final String triggerEsName = "event-trigger"; + private ExecutorService filterEs; + private static final String filterEsName = "filter"; + /** * Cycle thread to rePush Transactions */ @@ -435,14 +442,21 @@ public BlockingQueue getRePushTransactions() { public void stopRePushThread() { isRunRePushThread = false; + ExecutorServiceManager.shutdownAndAwaitTermination(rePushEs, rePushEsName); } public void stopRePushTriggerThread() { isRunTriggerCapsuleProcessThread = false; + ExecutorServiceManager.shutdownAndAwaitTermination(triggerEs, triggerEsName); } public void stopFilterProcessThread() { isRunFilterProcessThread = false; + ExecutorServiceManager.shutdownAndAwaitTermination(filterEs, filterEsName); + } + + public void stopValidateSignThread() { + ExecutorServiceManager.shutdownAndAwaitTermination(validateSignService, "validate-sign"); } @PostConstruct @@ -531,23 +545,21 @@ public void init() { logger.info("Lite node lowestNum: {}", chainBaseManager.getLowestBlockNum()); } revokingStore.enable(); - validateSignService = Executors - .newFixedThreadPool(Args.getInstance().getValidateSignThreadNum()); - Thread rePushThread = new Thread(rePushLoop); - rePushThread.setDaemon(true); - rePushThread.start(); + validateSignService = ExecutorServiceManager + .newFixedThreadPool(validateSignName, Args.getInstance().getValidateSignThreadNum()); + rePushEs = ExecutorServiceManager.newSingleThreadExecutor(rePushEsName, true); + rePushEs.submit(rePushLoop); // add contract event listener for subscribing if (Args.getInstance().isEventSubscribe()) { startEventSubscribing(); - Thread triggerCapsuleProcessThread = new Thread(triggerCapsuleProcessLoop); - triggerCapsuleProcessThread.setDaemon(true); - triggerCapsuleProcessThread.start(); + triggerEs = ExecutorServiceManager.newSingleThreadExecutor(triggerEsName, true); + triggerEs.submit(triggerCapsuleProcessLoop); } // start json rpc filter process if (CommonParameter.getInstance().isJsonRpcFilterEnabled()) { - Thread filterProcessThread = new Thread(filterProcessLoop); - filterProcessThread.start(); + filterEs = ExecutorServiceManager.newSingleThreadExecutor(filterEsName); + filterEs.submit(filterProcessLoop); } //initStoreFactory @@ -1937,24 +1949,6 @@ public NullifierStore getNullifierStore() { return chainBaseManager.getNullifierStore(); } - public void closeAllStore() { - logger.info("******** Begin to close db. ********"); - chainBaseManager.closeAllStore(); - validateSignService.shutdown(); - logger.info("******** End to close db. ********"); - } - - public void closeOneStore(ITronChainBase database) { - logger.info("******** Begin to close {}. ********", database.getName()); - try { - database.close(); - } catch (Exception e) { - logger.info("Failed to close {}.", database.getName(), e); - } finally { - logger.info("******** End to close {}. ********", database.getName()); - } - } - public boolean isTooManyPending() { return getPendingTransactions().size() + getRePushTransactions().size() > maxTransactionPendingSize; @@ -2445,6 +2439,17 @@ private boolean isBlockWaitingLock() { return blockWaitLock.get() > NO_BLOCK_WAITING_LOCK; } + public void close() { + stopRePushThread(); + stopRePushTriggerThread(); + EventPluginLoader.getInstance().stopPlugin(); + stopFilterProcessThread(); + stopValidateSignThread(); + chainBaseManager.shutdown(); + revokingStore.shutdown(); + session.reset(); + } + private static class ValidateSignTask implements Callable { private TransactionCapsule trx; diff --git a/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java b/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java index 10615b70ce3..7518b1347a7 100644 --- a/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java +++ b/framework/src/main/java/org/tron/core/net/P2pEventHandlerImpl.java @@ -38,6 +38,7 @@ import org.tron.p2p.P2pEventHandler; import org.tron.p2p.connection.Channel; import org.tron.protos.Protocol; +import org.tron.protos.Protocol.ReasonCode; @Slf4j(topic = "net") @Component @@ -232,7 +233,8 @@ private void processException(PeerConnection peer, TronMessage msg, Exception ex code = Protocol.ReasonCode.BAD_BLOCK; break; case NO_SUCH_MESSAGE: - case MESSAGE_WITH_WRONG_LENGTH: + code = Protocol.ReasonCode.NO_SUCH_MESSAGE; + break; case BAD_MESSAGE: code = Protocol.ReasonCode.BAD_PROTOCOL; break; diff --git a/framework/src/main/java/org/tron/core/net/TronNetDelegate.java b/framework/src/main/java/org/tron/core/net/TronNetDelegate.java index 1eba8e5ea59..16a378e6b42 100644 --- a/framework/src/main/java/org/tron/core/net/TronNetDelegate.java +++ b/framework/src/main/java/org/tron/core/net/TronNetDelegate.java @@ -359,4 +359,12 @@ public Object getForkLock() { return dbManager.getForkLock(); } + public long getNextMaintenanceTime() { + return chainBaseManager.getDynamicPropertiesStore().getNextMaintenanceTime(); + } + + public long getMaintenanceTimeInterval() { + return chainBaseManager.getDynamicPropertiesStore().getMaintenanceTimeInterval(); + } + } diff --git a/framework/src/main/java/org/tron/core/net/TronNetService.java b/framework/src/main/java/org/tron/core/net/TronNetService.java index 87d878be8c9..03becf5d4e9 100644 --- a/framework/src/main/java/org/tron/core/net/TronNetService.java +++ b/framework/src/main/java/org/tron/core/net/TronNetService.java @@ -148,7 +148,7 @@ public static boolean hasIpv4Stack(Set ipSet) { } private P2pConfig getConfig() { - P2pConfig config = new P2pConfig(); + P2pConfig config = parameter.getP2pConfig(); return updateConfig(config); } diff --git a/framework/src/main/java/org/tron/core/net/message/sync/ChainInventoryMessage.java b/framework/src/main/java/org/tron/core/net/message/sync/ChainInventoryMessage.java index 4179544ebf7..610a5ff2f11 100644 --- a/framework/src/main/java/org/tron/core/net/message/sync/ChainInventoryMessage.java +++ b/framework/src/main/java/org/tron/core/net/message/sync/ChainInventoryMessage.java @@ -73,6 +73,7 @@ public String toString() { sb.append(", end blockId: ").append(blockIdWeGet.peekLast().getString()); } } + sb.append(", remain_num: ").append(chainInventory.getRemainNum()); return sb.toString(); } } diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/PbftDataSyncHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/PbftDataSyncHandler.java index 238d131abe8..60f614632a4 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/PbftDataSyncHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/PbftDataSyncHandler.java @@ -4,6 +4,7 @@ import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import io.netty.util.internal.ConcurrentSet; +import java.io.Closeable; import java.security.SignatureException; import java.util.ArrayList; import java.util.List; @@ -12,12 +13,12 @@ import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.Future; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.tron.common.crypto.ECKey; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.utils.ByteArray; import org.tron.common.utils.Sha256Hash; import org.tron.consensus.base.Param; @@ -34,12 +35,14 @@ @Slf4j(topic = "pbft-data-sync") @Service -public class PbftDataSyncHandler implements TronMsgHandler { +public class PbftDataSyncHandler implements TronMsgHandler, Closeable { private Map pbftCommitMessageCache = new ConcurrentHashMap<>(); - private ExecutorService executorService = Executors.newFixedThreadPool(19, - r -> new Thread(r, "valid-header-pbft-sign")); + private final String esName = "valid-header-pbft-sign"; + + private ExecutorService executorService = ExecutorServiceManager.newFixedThreadPool( + esName, 19); @Autowired private ChainBaseManager chainBaseManager; @@ -81,6 +84,11 @@ public void processPBFTCommitData(BlockCapsule block) { } } + @Override + public void close() { + ExecutorServiceManager.shutdownAndAwaitTermination(executorService, esName); + } + private void processPBFTCommitMessage(PbftCommitMessage pbftCommitMessage) { try { PbftSignDataStore pbftSignDataStore = chainBaseManager.getPbftSignDataStore(); diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/PbftMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/PbftMsgHandler.java index 44eed8d1c2f..4e4cc858898 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/PbftMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/PbftMsgHandler.java @@ -11,9 +11,12 @@ import org.tron.consensus.pbft.PbftManager; import org.tron.consensus.pbft.message.PbftBaseMessage; import org.tron.consensus.pbft.message.PbftMessage; +import org.tron.core.config.args.Args; import org.tron.core.exception.P2pException; +import org.tron.core.net.TronNetDelegate; import org.tron.core.net.TronNetService; import org.tron.core.net.peer.PeerConnection; +import org.tron.protos.Protocol.PBFTMessage.DataType; @Component public class PbftMsgHandler { @@ -26,10 +29,24 @@ public class PbftMsgHandler { @Autowired private PbftManager pbftManager; + @Autowired + private TronNetDelegate tronNetDelegate; + public void processMessage(PeerConnection peer, PbftMessage msg) throws Exception { if (Param.getInstance().getPbftInterface().isSyncing()) { return; } + if (msg.getDataType().equals(DataType.BLOCK) + && tronNetDelegate.getHeadBlockId().getNum() - msg.getNumber() + > Args.getInstance().getPBFTExpireNum()) { + return; + } + long currentEpoch = tronNetDelegate.getNextMaintenanceTime(); + long expireEpoch = 2 * tronNetDelegate.getMaintenanceTimeInterval(); + if (msg.getDataType().equals(DataType.SRL) + && currentEpoch - msg.getEpoch() > expireEpoch) { + return; + } msg.analyzeSignature(); String key = buildKey(msg); Lock lock = striped.get(key); diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandler.java index 9027034ccc7..958ebfe5561 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandler.java @@ -37,8 +37,8 @@ public void processMessage(PeerConnection peer, TronMessage msg) throws P2pExcep long remainNum = 0; List summaryChainIds = syncBlockChainMessage.getBlockIds(); - - LinkedList blockIds = getLostBlockIds(summaryChainIds); + BlockId headID = tronNetDelegate.getHeadBlockId(); + LinkedList blockIds = getLostBlockIds(summaryChainIds, headID); if (blockIds.size() == 0) { logger.warn("Can't get lost block Ids"); @@ -48,7 +48,7 @@ public void processMessage(PeerConnection peer, TronMessage msg) throws P2pExcep peer.setNeedSyncFromUs(false); } else { peer.setNeedSyncFromUs(true); - remainNum = tronNetDelegate.getHeadBlockId().getNum() - blockIds.peekLast().getNum(); + remainNum = headID.getNum() - blockIds.peekLast().getNum(); } peer.setLastSyncBlockId(blockIds.peekLast()); @@ -85,8 +85,21 @@ private boolean check(PeerConnection peer, SyncBlockChainMessage msg) throws P2p return true; } - private LinkedList getLostBlockIds(List blockIds) throws P2pException { + private LinkedList getLostBlockIds(List blockIds, BlockId headID) + throws P2pException { + + BlockId unForkId = getUnForkId(blockIds); + LinkedList ids = getBlockIds(unForkId.getNum(), headID); + if (ids.isEmpty() || !unForkId.equals(ids.peekFirst())) { + unForkId = getUnForkId(blockIds); + ids = getBlockIds(unForkId.getNum(), headID); + } + + return ids; + } + + private BlockId getUnForkId(List blockIds) throws P2pException { BlockId unForkId = null; for (int i = blockIds.size() - 1; i >= 0; i--) { if (tronNetDelegate.containBlockInMainChain(blockIds.get(i))) { @@ -99,13 +112,16 @@ private LinkedList getLostBlockIds(List blockIds) throws P2pEx throw new P2pException(TypeEnum.SYNC_FAILED, "unForkId is null"); } - BlockId headID = tronNetDelegate.getHeadBlockId(); + return unForkId; + } + + private LinkedList getBlockIds(Long unForkNum, BlockId headID) throws P2pException { long headNum = headID.getNum(); - long len = Math.min(headNum, unForkId.getNum() + NetConstants.SYNC_FETCH_BATCH_NUM); + long len = Math.min(headNum, unForkNum + NetConstants.SYNC_FETCH_BATCH_NUM); LinkedList ids = new LinkedList<>(); - for (long i = unForkId.getNum(); i <= len; i++) { + for (long i = unForkNum; i <= len; i++) { if (i == headNum) { ids.add(headID); } else { diff --git a/framework/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java b/framework/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java index 5f8b3fcef16..665381b31a8 100644 --- a/framework/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java +++ b/framework/src/main/java/org/tron/core/net/messagehandler/TransactionsMsgHandler.java @@ -2,15 +2,14 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.common.es.ExecutorServiceManager; import org.tron.core.config.args.Args; import org.tron.core.exception.P2pException; import org.tron.core.exception.P2pException.TypeEnum; @@ -42,19 +41,21 @@ public class TransactionsMsgHandler implements TronMsgHandler { private BlockingQueue queue = new LinkedBlockingQueue(); private int threadNum = Args.getInstance().getValidateSignThreadNum(); - private ExecutorService trxHandlePool = new ThreadPoolExecutor(threadNum, threadNum, 0L, - TimeUnit.MILLISECONDS, queue); - - private ScheduledExecutorService smartContractExecutor = Executors - .newSingleThreadScheduledExecutor(); + private final String trxEsName = "trx-msg-handler"; + private ExecutorService trxHandlePool = ExecutorServiceManager.newThreadPoolExecutor( + threadNum, threadNum, 0L, + TimeUnit.MILLISECONDS, queue, trxEsName); + private final String smartEsName = "contract-msg-handler"; + private final ScheduledExecutorService smartContractExecutor = ExecutorServiceManager + .newSingleThreadScheduledExecutor(smartEsName); public void init() { handleSmartContract(); } public void close() { - trxHandlePool.shutdown(); - smartContractExecutor.shutdown(); + ExecutorServiceManager.shutdownAndAwaitTermination(trxHandlePool, trxEsName); + ExecutorServiceManager.shutdownAndAwaitTermination(smartContractExecutor, smartEsName); } public boolean isBusy() { @@ -102,7 +103,7 @@ private void check(PeerConnection peer, TransactionsMessage msg) throws P2pExcep private void handleSmartContract() { smartContractExecutor.scheduleWithFixedDelay(() -> { try { - while (queue.size() < MAX_SMART_CONTRACT_SUBMIT_SIZE) { + while (queue.size() < MAX_SMART_CONTRACT_SUBMIT_SIZE && smartContractQueue.size() > 0) { TrxEvent event = smartContractQueue.take(); trxHandlePool.submit(() -> handleTransaction(event.getPeer(), event.getMsg())); } @@ -116,8 +117,8 @@ private void handleSmartContract() { } private void handleTransaction(PeerConnection peer, TransactionMessage trx) { - if (peer.isDisconnect()) { - logger.warn("Drop trx {} from {}, peer is disconnect", trx.getMessageId(), + if (peer.isBadPeer()) { + logger.warn("Drop trx {} from {}, peer is bad peer", trx.getMessageId(), peer.getInetAddress()); return; } @@ -133,6 +134,7 @@ private void handleTransaction(PeerConnection peer, TransactionMessage trx) { logger.warn("Trx {} from peer {} process failed. type: {}, reason: {}", trx.getMessageId(), peer.getInetAddress(), e.getType(), e.getMessage()); if (e.getType().equals(TypeEnum.BAD_TRX)) { + peer.setBadPeer(true); peer.disconnect(ReasonCode.BAD_TX); } } catch (Exception e) { diff --git a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java index 0499fb4f818..666c99208ba 100644 --- a/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java +++ b/framework/src/main/java/org/tron/core/net/peer/PeerConnection.java @@ -71,6 +71,10 @@ public class PeerConnection { @Getter private volatile boolean fetchAble; + @Setter + @Getter + private volatile boolean isBadPeer; + @Getter @Setter private ByteString address; diff --git a/framework/src/main/java/org/tron/core/net/peer/PeerManager.java b/framework/src/main/java/org/tron/core/net/peer/PeerManager.java index 6817720dff5..537f2083691 100644 --- a/framework/src/main/java/org/tron/core/net/peer/PeerManager.java +++ b/framework/src/main/java/org/tron/core/net/peer/PeerManager.java @@ -5,17 +5,18 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationContext; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.prometheus.MetricKeys; import org.tron.common.prometheus.MetricLabels; import org.tron.common.prometheus.Metrics; import org.tron.p2p.connection.Channel; +import org.tron.protos.Protocol.ReasonCode; @Slf4j(topic = "net") public class PeerManager { @@ -25,8 +26,11 @@ public class PeerManager { private static AtomicInteger passivePeersCount = new AtomicInteger(0); @Getter private static AtomicInteger activePeersCount = new AtomicInteger(0); + private static final String esName = "peer-manager"; + + private static ScheduledExecutorService executor = + ExecutorServiceManager.newSingleThreadScheduledExecutor(esName); - private static ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); private static long DISCONNECTION_TIME_OUT = 60_000; @@ -45,10 +49,11 @@ public static void close() { try { for (PeerConnection p : new ArrayList<>(peers)) { if (!p.isDisconnect()) { + p.disconnect(ReasonCode.PEER_QUITING); p.getChannel().close(); } } - executor.shutdownNow(); + ExecutorServiceManager.shutdownAndAwaitTermination(executor, esName); } catch (Exception e) { logger.error("Peer manager shutdown failed", e); } diff --git a/framework/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java b/framework/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java index 84cf59b9bd7..6ccbf6427a7 100644 --- a/framework/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java +++ b/framework/src/main/java/org/tron/core/net/peer/PeerStatusCheck.java @@ -1,11 +1,11 @@ package org.tron.core.net.peer; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.common.es.ExecutorServiceManager; import org.tron.core.config.Parameter.NetConstants; import org.tron.core.net.TronNetDelegate; import org.tron.protos.Protocol.ReasonCode; @@ -17,8 +17,10 @@ public class PeerStatusCheck { @Autowired private TronNetDelegate tronNetDelegate; - private ScheduledExecutorService peerStatusCheckExecutor = Executors - .newSingleThreadScheduledExecutor(); + private final String name = "peer-status-check"; + + private ScheduledExecutorService peerStatusCheckExecutor = ExecutorServiceManager + .newSingleThreadScheduledExecutor(name); private int blockUpdateTimeout = 30_000; @@ -33,7 +35,7 @@ public void init() { } public void close() { - peerStatusCheckExecutor.shutdown(); + ExecutorServiceManager.shutdownAndAwaitTermination(peerStatusCheckExecutor, name); } public void statusCheck() { diff --git a/framework/src/main/java/org/tron/core/net/service/adv/AdvService.java b/framework/src/main/java/org/tron/core/net/service/adv/AdvService.java index 03668d01837..ea608c1ea86 100644 --- a/framework/src/main/java/org/tron/core/net/service/adv/AdvService.java +++ b/framework/src/main/java/org/tron/core/net/service/adv/AdvService.java @@ -6,7 +6,6 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; - import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; @@ -15,15 +14,14 @@ import java.util.List; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; - import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.overlay.message.Message; import org.tron.common.utils.Sha256Hash; import org.tron.common.utils.Time; @@ -43,11 +41,11 @@ @Slf4j(topic = "net") @Component public class AdvService { - private final int MAX_INV_TO_FETCH_CACHE_SIZE = 100_000; private final int MAX_TRX_CACHE_SIZE = 50_000; private final int MAX_BLOCK_CACHE_SIZE = 10; private final int MAX_SPREAD_SIZE = 1_000; + private final long TIMEOUT = MSG_CACHE_DURATION_IN_BLOCKS * BLOCK_PRODUCED_INTERVAL; @Autowired private TronNetDelegate tronNetDelegate; @@ -73,9 +71,13 @@ public class AdvService { .maximumSize(MAX_BLOCK_CACHE_SIZE).expireAfterWrite(1, TimeUnit.MINUTES) .recordStats().build(); - private ScheduledExecutorService spreadExecutor = Executors.newSingleThreadScheduledExecutor(); + private final String spreadName = "adv-spread"; + private final String fetchName = "adv-fetch"; + private final ScheduledExecutorService spreadExecutor = ExecutorServiceManager + .newSingleThreadScheduledExecutor(spreadName); - private ScheduledExecutorService fetchExecutor = Executors.newSingleThreadScheduledExecutor(); + private final ScheduledExecutorService fetchExecutor = ExecutorServiceManager + .newSingleThreadScheduledExecutor(fetchName); @Getter private MessageCount trxCount = new MessageCount(); @@ -102,8 +104,8 @@ public void init() { } public void close() { - spreadExecutor.shutdown(); - fetchExecutor.shutdown(); + ExecutorServiceManager.shutdownAndAwaitTermination(spreadExecutor, spreadName); + ExecutorServiceManager.shutdownAndAwaitTermination(fetchExecutor, fetchName); } public synchronized void addInvToCache(Item item) { @@ -262,30 +264,30 @@ private void consumerInvToFetch() { Collection peers = tronNetDelegate.getActivePeer().stream() .filter(peer -> peer.isIdle()) .collect(Collectors.toList()); - InvSender invSender = new InvSender(); - long now = System.currentTimeMillis(); synchronized (this) { if (invToFetch.isEmpty() || peers.isEmpty()) { return; } + long now = System.currentTimeMillis(); invToFetch.forEach((item, time) -> { - if (time < now - MSG_CACHE_DURATION_IN_BLOCKS * BLOCK_PRODUCED_INTERVAL) { + if (time < now - TIMEOUT) { logger.info("This obj is too late to fetch, type: {} hash: {}", item.getType(), item.getHash()); invToFetch.remove(item); invToFetchCache.invalidate(item); return; } - peers.stream().filter(peer -> peer.getAdvInvReceive().getIfPresent(item) != null - && invSender.getSize(peer) < MAX_TRX_FETCH_PER_PEER) - .sorted(Comparator.comparingInt(peer -> invSender.getSize(peer))) - .findFirst().ifPresent(peer -> { - if (peer.checkAndPutAdvInvRequest(item, now)) { - invSender.add(item, peer); - } - invToFetch.remove(item); - }); + peers.stream().filter(peer -> { + Long t = peer.getAdvInvReceive().getIfPresent(item); + return t != null && now - t < TIMEOUT && invSender.getSize(peer) < MAX_TRX_FETCH_PER_PEER; + }).sorted(Comparator.comparingInt(peer -> invSender.getSize(peer))) + .findFirst().ifPresent(peer -> { + if (peer.checkAndPutAdvInvRequest(item, now)) { + invSender.add(item, peer); + } + invToFetch.remove(item); + }); }); } diff --git a/framework/src/main/java/org/tron/core/net/service/effective/EffectiveCheckService.java b/framework/src/main/java/org/tron/core/net/service/effective/EffectiveCheckService.java index 44fdc56f938..a4e89412bae 100644 --- a/framework/src/main/java/org/tron/core/net/service/effective/EffectiveCheckService.java +++ b/framework/src/main/java/org/tron/core/net/service/effective/EffectiveCheckService.java @@ -2,14 +2,12 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; -import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.net.InetSocketAddress; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -18,6 +16,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.common.es.ExecutorServiceManager; import org.tron.core.config.args.Args; import org.tron.core.net.TronNetDelegate; import org.tron.core.net.TronNetService; @@ -42,12 +41,13 @@ public class EffectiveCheckService { @Setter private volatile InetSocketAddress cur; private final AtomicInteger count = new AtomicInteger(0); - private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor( - new ThreadFactoryBuilder().setNameFormat("effective-thread-%d").build()); + private final String esName = "effective-check"; + private ScheduledExecutorService executor; private long MAX_HANDSHAKE_TIME = 60_000; public void init() { if (isEffectiveCheck) { + executor = ExecutorServiceManager.newSingleThreadScheduledExecutor(esName); executor.scheduleWithFixedDelay(() -> { try { findEffectiveNode(); @@ -69,13 +69,7 @@ public void triggerNext() { } public void close() { - if (executor != null) { - try { - executor.shutdown(); - } catch (Exception e) { - logger.error("Exception in shutdown effective service worker, {}", e.getMessage()); - } - } + ExecutorServiceManager.shutdownAndAwaitTermination(executor, esName); } public boolean isIsolateLand() { diff --git a/framework/src/main/java/org/tron/core/net/service/fetchblock/FetchBlockService.java b/framework/src/main/java/org/tron/core/net/service/fetchblock/FetchBlockService.java index 6a5b120a896..889f6f6e132 100644 --- a/framework/src/main/java/org/tron/core/net/service/fetchblock/FetchBlockService.java +++ b/framework/src/main/java/org/tron/core/net/service/fetchblock/FetchBlockService.java @@ -5,20 +5,17 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.concurrent.BasicThreadFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; - +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.parameter.CommonParameter; import org.tron.common.utils.Sha256Hash; import org.tron.core.ChainBaseManager; import org.tron.core.capsule.BlockCapsule; -import org.tron.core.config.Parameter; import org.tron.core.metrics.MetricsKey; import org.tron.core.metrics.MetricsUtil; import org.tron.core.net.TronNetDelegate; @@ -43,9 +40,10 @@ public class FetchBlockService { private static final double BLOCK_FETCH_LEFT_TIME_PERCENT = 0.5; + private final String esName = "fetch-block"; + private final ScheduledExecutorService fetchBlockWorkerExecutor = - new ScheduledThreadPoolExecutor(1, - new BasicThreadFactory.Builder().namingPattern("FetchBlockWorkerSchedule-").build()); + ExecutorServiceManager.newSingleThreadScheduledExecutor(esName); public void init() { fetchBlockWorkerExecutor.scheduleWithFixedDelay(() -> { @@ -58,7 +56,7 @@ public void init() { } public void close() { - fetchBlockWorkerExecutor.shutdown(); + ExecutorServiceManager.shutdownAndAwaitTermination(fetchBlockWorkerExecutor, esName); } public void fetchBlock(List sha256HashList, PeerConnection peer) { diff --git a/framework/src/main/java/org/tron/core/net/service/nodepersist/NodePersistService.java b/framework/src/main/java/org/tron/core/net/service/nodepersist/NodePersistService.java index 457fe7c55cb..2445a7d64e5 100644 --- a/framework/src/main/java/org/tron/core/net/service/nodepersist/NodePersistService.java +++ b/framework/src/main/java/org/tron/core/net/service/nodepersist/NodePersistService.java @@ -4,12 +4,12 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import java.util.Objects; -import java.util.Timer; -import java.util.TimerTask; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.parameter.CommonParameter; import org.tron.common.utils.ByteArray; import org.tron.common.utils.JsonUtil; @@ -27,28 +27,22 @@ public class NodePersistService { private final boolean isNodePersist = CommonParameter.getInstance().isNodeDiscoveryPersist(); @Autowired private CommonStore commonStore; - private Timer nodePersistTaskTimer; + + private ScheduledExecutorService nodePersistExecutor; + + private final String name = "NodePersistTask"; public void init() { if (isNodePersist) { - nodePersistTaskTimer = new Timer("NodePersistTaskTimer"); - nodePersistTaskTimer.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - dbWrite(); - } - }, DB_COMMIT_RATE, DB_COMMIT_RATE); + nodePersistExecutor = ExecutorServiceManager.newSingleThreadScheduledExecutor(name); + nodePersistExecutor.scheduleAtFixedRate(this::dbWrite, DB_COMMIT_RATE, DB_COMMIT_RATE, + TimeUnit.MILLISECONDS); } } public void close() { - if (Objects.isNull(nodePersistTaskTimer)) { - return; - } - try { - nodePersistTaskTimer.cancel(); - } catch (Exception e) { - logger.error("Close nodePersistTaskTimer failed", e); + if (isNodePersist) { + ExecutorServiceManager.shutdownAndAwaitTermination(nodePersistExecutor, name); } } diff --git a/framework/src/main/java/org/tron/core/net/service/relay/RelayService.java b/framework/src/main/java/org/tron/core/net/service/relay/RelayService.java index 665255a6594..dfc5f2e89da 100644 --- a/framework/src/main/java/org/tron/core/net/service/relay/RelayService.java +++ b/framework/src/main/java/org/tron/core/net/service/relay/RelayService.java @@ -6,7 +6,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -18,6 +17,7 @@ import org.tron.common.backup.BackupManager.BackupStatusEnum; import org.tron.common.crypto.SignInterface; import org.tron.common.crypto.SignUtils; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.parameter.CommonParameter; import org.tron.common.utils.ByteArray; import org.tron.common.utils.Sha256Hash; @@ -34,6 +34,7 @@ import org.tron.core.store.WitnessScheduleStore; import org.tron.p2p.connection.Channel; import org.tron.protos.Protocol; +import org.tron.protos.Protocol.ReasonCode; @Slf4j(topic = "net") @Component @@ -53,8 +54,10 @@ public class RelayService { private WitnessScheduleStore witnessScheduleStore; private BackupManager backupManager; + private final String esName = "relay-service"; - private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); + private ScheduledExecutorService executorService = ExecutorServiceManager + .newSingleThreadScheduledExecutor(esName); private CommonParameter parameter = Args.getInstance(); @@ -95,7 +98,7 @@ public void init() { } public void close() { - executorService.shutdown(); + ExecutorServiceManager.shutdownAndAwaitTermination(executorService, esName); } public void fillHelloMessage(HelloMessage message, Channel channel) { @@ -182,6 +185,7 @@ private void disconnect() { TronNetService.getP2pConfig().getActiveNodes().remove(address); TronNetService.getPeers().forEach(peer -> { if (peer.getInetAddress().equals(address.getAddress())) { + peer.disconnect(ReasonCode.NOT_WITNESS); peer.getChannel().close(); } }); diff --git a/framework/src/main/java/org/tron/core/net/service/statistics/TronStatsManager.java b/framework/src/main/java/org/tron/core/net/service/statistics/TronStatsManager.java index da9b4b0f2d3..caac3f7f325 100644 --- a/framework/src/main/java/org/tron/core/net/service/statistics/TronStatsManager.java +++ b/framework/src/main/java/org/tron/core/net/service/statistics/TronStatsManager.java @@ -3,11 +3,11 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import java.net.InetAddress; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.prometheus.MetricKeys; import org.tron.common.prometheus.MetricLabels; import org.tron.common.prometheus.Metrics; @@ -27,7 +27,10 @@ public class TronStatsManager { private static Cache cache = CacheBuilder.newBuilder() .maximumSize(3000).recordStats().build(); - private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); + private final String esName = "net-traffic-collector"; + + private ScheduledExecutorService executor = + ExecutorServiceManager.newSingleThreadScheduledExecutor(esName); public static NodeStatistics getNodeStatistics(InetAddress inetAddress) { NodeStatistics nodeStatistics = cache.getIfPresent(inetAddress); @@ -49,11 +52,7 @@ public void init() { } public void close() { - try { - executor.shutdownNow(); - } catch (Exception e) { - logger.error("Exception in shutdown traffic stats worker, {}", e.getMessage()); - } + ExecutorServiceManager.shutdownAndAwaitTermination(executor, esName); } private void work() { diff --git a/framework/src/main/java/org/tron/core/net/service/sync/SyncService.java b/framework/src/main/java/org/tron/core/net/service/sync/SyncService.java index eae134758cd..1e3e18441b9 100644 --- a/framework/src/main/java/org/tron/core/net/service/sync/SyncService.java +++ b/framework/src/main/java/org/tron/core/net/service/sync/SyncService.java @@ -11,13 +11,13 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.utils.Pair; import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.BlockCapsule.BlockId; @@ -54,10 +54,13 @@ public class SyncService { .expireAfterWrite(blockCacheTimeout, TimeUnit.MINUTES).initialCapacity(10_000) .recordStats().build(); - private ScheduledExecutorService fetchExecutor = Executors.newSingleThreadScheduledExecutor(); + private final String fetchEsName = "sync-fetch-block"; + private final String handleEsName = "sync-handle-block"; + private final ScheduledExecutorService fetchExecutor = ExecutorServiceManager + .newSingleThreadScheduledExecutor(fetchEsName); - private ScheduledExecutorService blockHandleExecutor = Executors - .newSingleThreadScheduledExecutor(); + private final ScheduledExecutorService blockHandleExecutor = ExecutorServiceManager + .newSingleThreadScheduledExecutor(handleEsName); private volatile boolean handleFlag = false; @@ -91,8 +94,8 @@ public void init() { } public void close() { - fetchExecutor.shutdown(); - blockHandleExecutor.shutdown(); + ExecutorServiceManager.shutdownAndAwaitTermination(fetchExecutor, fetchEsName); + ExecutorServiceManager.shutdownAndAwaitTermination(blockHandleExecutor, handleEsName); } public void startSync(PeerConnection peer) { diff --git a/framework/src/main/java/org/tron/core/services/RpcApiService.java b/framework/src/main/java/org/tron/core/services/RpcApiService.java index ee12db817d3..94d5b97decd 100755 --- a/framework/src/main/java/org/tron/core/services/RpcApiService.java +++ b/framework/src/main/java/org/tron/core/services/RpcApiService.java @@ -5,14 +5,11 @@ import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; import com.google.protobuf.ProtocolStringList; -import io.grpc.Server; import io.grpc.Status; import io.grpc.StatusRuntimeException; import io.grpc.netty.NettyServerBuilder; import io.grpc.stub.StreamObserver; -import java.io.IOException; import java.util.Objects; -import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -50,6 +47,7 @@ import org.tron.api.GrpcAPI.OvkDecryptTRC20Parameters; import org.tron.api.GrpcAPI.PaginatedMessage; import org.tron.api.GrpcAPI.PaymentAddressMessage; +import org.tron.api.GrpcAPI.PricesResponseMessage; import org.tron.api.GrpcAPI.PrivateParameters; import org.tron.api.GrpcAPI.PrivateParametersWithoutAsk; import org.tron.api.GrpcAPI.PrivateShieldedTRC20Parameters; @@ -75,7 +73,8 @@ import org.tron.api.WalletExtensionGrpc; import org.tron.api.WalletGrpc.WalletImplBase; import org.tron.api.WalletSolidityGrpc.WalletSolidityImplBase; -import org.tron.common.application.Service; +import org.tron.common.application.RpcService; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.parameter.CommonParameter; import org.tron.common.utils.ByteArray; import org.tron.common.utils.Sha256Hash; @@ -163,27 +162,21 @@ @Component @Slf4j(topic = "API") -public class RpcApiService implements Service { +public class RpcApiService extends RpcService { public static final String CONTRACT_VALIDATE_EXCEPTION = "ContractValidateException: {}"; private static final String EXCEPTION_CAUGHT = "exception caught"; private static final String UNKNOWN_EXCEPTION_CAUGHT = "unknown exception caught: "; private static final long BLOCK_LIMIT_NUM = 100; private static final long TRANSACTION_LIMIT_NUM = 1000; - private int port = Args.getInstance().getRpcPort(); - private Server apiServer; @Autowired private Manager dbManager; - @Autowired private ChainBaseManager chainBaseManager; - @Autowired private Wallet wallet; - @Autowired private TransactionUtil transactionUtil; - @Autowired private NodeInfoService nodeInfoService; @Autowired @@ -192,10 +185,8 @@ public class RpcApiService implements Service { private LiteFnQueryGrpcInterceptor liteFnQueryGrpcInterceptor; @Autowired private RpcApiAccessInterceptor apiAccessInterceptor; - @Autowired private MetricsApiService metricsApiService; - @Getter private DatabaseApi databaseApi = new DatabaseApi(); private WalletApi walletApi = new WalletApi(); @@ -204,6 +195,8 @@ public class RpcApiService implements Service { @Getter private MonitorApi monitorApi = new MonitorApi(); + private final String executorName = "rpc-full-executor"; + @Override public void init() { @@ -211,6 +204,7 @@ public void init() { @Override public void init(CommonParameter args) { + port = Args.getInstance().getRpcPort(); } @Override @@ -221,7 +215,8 @@ public void start() { if (parameter.getRpcThreadNum() > 0) { serverBuilder = serverBuilder - .executor(Executors.newFixedThreadPool(parameter.getRpcThreadNum())); + .executor(ExecutorServiceManager.newFixedThreadPool( + executorName, parameter.getRpcThreadNum())); } if (parameter.isSolidityNode()) { @@ -257,19 +252,10 @@ public void start() { apiServer = serverBuilder.build(); rateLimiterInterceptor.init(apiServer); - - apiServer.start(); - } catch (IOException e) { + super.start(); + } catch (Exception e) { logger.debug(e.getMessage(), e); } - - logger.info("RpcApiService has started, listening on " + port); - - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - System.err.println("*** shutting down gRPC server since JVM is shutting down"); - //server.this.stop(); - System.err.println("*** server is shutdown"); - })); } @@ -368,32 +354,6 @@ private void checkSupportShieldedTRC20Transaction() throws ZksnarkException { } } - @Override - public void stop() { - if (apiServer != null) { - try { - apiServer.shutdown().awaitTermination(); - } catch (InterruptedException e) { - logger.warn("{}", e); - Thread.currentThread().interrupt(); - } - } - } - - /** - * ... - */ - public void blockUntilShutdown() { - if (apiServer != null) { - try { - apiServer.awaitTermination(); - } catch (InterruptedException e) { - logger.warn("{}", e); - Thread.currentThread().interrupt(); - } - } - } - /** * DatabaseApi. */ @@ -999,6 +959,28 @@ public void getBlock(GrpcAPI.BlockReq request, StreamObserver responseObserver) { getBlockCommon(request, responseObserver); } + + @Override + public void getBandwidthPrices(EmptyMessage request, + StreamObserver responseObserver) { + try { + responseObserver.onNext(wallet.getBandwidthPrices()); + } catch (Exception e) { + responseObserver.onError(getRunTimeException(e)); + } + responseObserver.onCompleted(); + } + + @Override + public void getEnergyPrices(EmptyMessage request, + StreamObserver responseObserver) { + try { + responseObserver.onNext(wallet.getEnergyPrices()); + } catch (Exception e) { + responseObserver.onError(getRunTimeException(e)); + } + responseObserver.onCompleted(); + } } /** @@ -2032,6 +2014,39 @@ public void getCanWithdrawUnfreezeAmount(CanWithdrawUnfreezeAmountRequestMessage responseObserver.onCompleted(); } + @Override + public void getBandwidthPrices(EmptyMessage request, + StreamObserver responseObserver) { + try { + responseObserver.onNext(wallet.getBandwidthPrices()); + } catch (Exception e) { + responseObserver.onError(getRunTimeException(e)); + } + responseObserver.onCompleted(); + } + + @Override + public void getEnergyPrices(EmptyMessage request, + StreamObserver responseObserver) { + try { + responseObserver.onNext(wallet.getEnergyPrices()); + } catch (Exception e) { + responseObserver.onError(getRunTimeException(e)); + } + responseObserver.onCompleted(); + } + + @Override + public void getMemoFee(EmptyMessage request, + StreamObserver responseObserver) { + try { + responseObserver.onNext(wallet.getMemoFeePrices()); + } catch (Exception e) { + responseObserver.onError(getRunTimeException(e)); + } + responseObserver.onCompleted(); + } + @Override public void getPaginatedProposalList(PaginatedMessage request, StreamObserver responseObserver) { diff --git a/framework/src/main/java/org/tron/core/services/filter/HttpApiAccessFilter.java b/framework/src/main/java/org/tron/core/services/filter/HttpApiAccessFilter.java index ae7ab75a473..0405165ff99 100644 --- a/framework/src/main/java/org/tron/core/services/filter/HttpApiAccessFilter.java +++ b/framework/src/main/java/org/tron/core/services/filter/HttpApiAccessFilter.java @@ -65,7 +65,7 @@ private boolean isDisabled(String endpoint) { disabled = disabledApiList.contains(endpoint.split("/")[2].toLowerCase()); } } catch (Exception e) { - logger.error("check isDisabled except, endpoint={}, error is {}", endpoint, e.getMessage()); + logger.warn("check isDisabled except, endpoint={}, {}", endpoint, e.getMessage()); } return disabled; diff --git a/framework/src/main/java/org/tron/core/services/filter/HttpInterceptor.java b/framework/src/main/java/org/tron/core/services/filter/HttpInterceptor.java index 51b4d60f856..2cce8272dd5 100644 --- a/framework/src/main/java/org/tron/core/services/filter/HttpInterceptor.java +++ b/framework/src/main/java/org/tron/core/services/filter/HttpInterceptor.java @@ -19,8 +19,9 @@ public class HttpInterceptor implements Filter { private String endpoint; - private final int HTTP_NOT_FOUND = 404; private final int HTTP_SUCCESS = 200; + private final int HTTP_BAD_REQUEST = 400; + private final int HTTP_NOT_ACCEPTABLE = 406; @Override public void init(FilterConfig filterConfig) { @@ -29,64 +30,47 @@ public void init(FilterConfig filterConfig) { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { try { - if (request instanceof HttpServletRequest) { - endpoint = ((HttpServletRequest) request).getRequestURI(); - - CharResponseWrapper responseWrapper = new CharResponseWrapper( - (HttpServletResponse) response); - chain.doFilter(request, responseWrapper); - - HttpServletResponse resp = (HttpServletResponse) response; - - if (resp.getStatus() != HTTP_NOT_FOUND) { // correct endpoint - String endpointQPS = MetricsKey.NET_API_DETAIL_QPS + endpoint; - MetricsUtil.meterMark(MetricsKey.NET_API_QPS); - MetricsUtil.meterMark(endpointQPS); - - int reposeContentSize = responseWrapper.getByteSize(); - String endpointOutTraffic = MetricsKey.NET_API_DETAIL_OUT_TRAFFIC + endpoint; - MetricsUtil.meterMark(MetricsKey.NET_API_OUT_TRAFFIC, - reposeContentSize); - MetricsUtil.meterMark(endpointOutTraffic, reposeContentSize); - - if (resp.getStatus() != HTTP_SUCCESS) { //http fail - String endpointFailQPS = MetricsKey.NET_API_DETAIL_FAIL_QPS + endpoint; - MetricsUtil.meterMark(MetricsKey.NET_API_FAIL_QPS); - MetricsUtil.meterMark(endpointFailQPS); - } - } else { // wrong endpoint - MetricsUtil.meterMark(MetricsKey.NET_API_QPS); - MetricsUtil.meterMark(MetricsKey.NET_API_FAIL_QPS); - } + if (!(request instanceof HttpServletRequest)) { + chain.doFilter(request, response); + return; + } + endpoint = ((HttpServletRequest) request).getRequestURI(); + CharResponseWrapper responseWrapper = new CharResponseWrapper( + (HttpServletResponse) response); + chain.doFilter(request, responseWrapper); + HttpServletResponse resp = (HttpServletResponse) response; + int size = responseWrapper.getByteSize(); + MetricsUtil.meterMark(MetricsKey.NET_API_OUT_TRAFFIC, size); + MetricsUtil.meterMark(MetricsKey.NET_API_QPS); + if (resp.getStatus() >= HTTP_BAD_REQUEST && resp.getStatus() <= HTTP_NOT_ACCEPTABLE) { + MetricsUtil.meterMark(MetricsKey.NET_API_FAIL_QPS); Metrics.histogramObserve(MetricKeys.Histogram.HTTP_BYTES, - responseWrapper.getByteSize(), - Strings.isNullOrEmpty(endpoint) ? MetricLabels.UNDEFINED : endpoint, - String.valueOf(responseWrapper.getStatus())); + size, MetricLabels.UNDEFINED, String.valueOf(responseWrapper.getStatus())); + return; + } + if (resp.getStatus() == HTTP_SUCCESS) { + MetricsUtil.meterMark(MetricsKey.NET_API_DETAIL_QPS + endpoint); } else { - chain.doFilter(request, response); + MetricsUtil.meterMark(MetricsKey.NET_API_FAIL_QPS); + MetricsUtil.meterMark(MetricsKey.NET_API_DETAIL_FAIL_QPS + endpoint); } - + MetricsUtil.meterMark(MetricsKey.NET_API_DETAIL_OUT_TRAFFIC + endpoint, size); + Metrics.histogramObserve(MetricKeys.Histogram.HTTP_BYTES, + size, endpoint, String.valueOf(responseWrapper.getStatus())); } catch (Exception e) { - - if (MetricsUtil.getMeters(MetricsKey.NET_API_DETAIL_QPS).containsKey( - MetricsKey.NET_API_DETAIL_QPS + endpoint)) { // correct endpoint - MetricsUtil.meterMark(MetricsKey.NET_API_DETAIL_FAIL_QPS - + endpoint, 1); - MetricsUtil.meterMark(MetricsKey.NET_API_DETAIL_QPS - + endpoint, 1); + String key = MetricsKey.NET_API_DETAIL_QPS + endpoint; + if (MetricsUtil.getMeters(MetricsKey.NET_API_DETAIL_QPS).containsKey(key)) { + MetricsUtil.meterMark(key, 1); + MetricsUtil.meterMark(MetricsKey.NET_API_DETAIL_FAIL_QPS + endpoint, 1); } MetricsUtil.meterMark(MetricsKey.NET_API_QPS, 1); MetricsUtil.meterMark(MetricsKey.NET_API_FAIL_QPS, 1); - } - } @Override public void destroy() { - } - } diff --git a/framework/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java b/framework/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java index 135f98627a1..55e6e07b5ec 100644 --- a/framework/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java +++ b/framework/src/main/java/org/tron/core/services/http/FullNodeHttpApiService.java @@ -1,13 +1,9 @@ package org.tron.core.services.http; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; import java.util.EnumSet; import javax.servlet.DispatcherType; import javax.servlet.Filter; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.FileUtils; import org.eclipse.jetty.server.ConnectionLimit; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.FilterHolder; @@ -16,24 +12,17 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.tron.common.application.Service; +import org.tron.common.application.HttpService; import org.tron.common.parameter.CommonParameter; -import org.tron.common.zksnark.JLibrustzcash; -import org.tron.common.zksnark.LibrustzcashParam.InitZksnarkParams; import org.tron.core.config.args.Args; -import org.tron.core.exception.ZksnarkException; import org.tron.core.services.filter.HttpApiAccessFilter; import org.tron.core.services.filter.HttpInterceptor; import org.tron.core.services.filter.LiteFnQueryHttpFilter; -@Component +@Component("fullNodeHttpApiService") @Slf4j(topic = "API") -public class FullNodeHttpApiService implements Service { - - private int port = Args.getInstance().getFullNodeHttpPort(); - - private Server server; +public class FullNodeHttpApiService extends HttpService { @Autowired private GetAccountServlet getAccountServlet; @@ -305,59 +294,22 @@ public class FullNodeHttpApiService implements Service { @Autowired private CancelAllUnfreezeV2Servlet cancelAllUnfreezeV2Servlet; - private static String getParamsFile(String fileName) { - InputStream in = Thread.currentThread().getContextClassLoader() - .getResourceAsStream("params" + File.separator + fileName); - File fileOut = new File(System.getProperty("java.io.tmpdir") - + File.separator + fileName + "." + System.currentTimeMillis()); - try { - FileUtils.copyToFile(in, fileOut); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - return fileOut.getAbsolutePath(); - } - - public static void librustzcashInitZksnarkParams() { - logger.info("init zk param begin"); - - if (!JLibrustzcash.isOpenZen()) { - logger.info("zen switch is off, zen will not start."); - return; - } - - String spendPath = getParamsFile("sapling-spend.params"); - String spendHash = "25fd9a0d1c1be0526c14662947ae95b758fe9f3d7fb7f55e9b4437830dcc6215a7ce3ea465" - + "914b157715b7a4d681389ea4aa84438190e185d5e4c93574d3a19a"; - - String outputPath = getParamsFile("sapling-output.params"); - String outputHash = "a1cb23b93256adce5bce2cb09cefbc96a1d16572675ceb691e9a3626ec15b5b546926ff1c" - + "536cfe3a9df07d796b32fdfc3e5d99d65567257bf286cd2858d71a6"; - - try { - JLibrustzcash.librustzcashInitZksnarkParams( - new InitZksnarkParams(spendPath, spendHash, outputPath, outputHash)); - } catch (ZksnarkException e) { - logger.error("librustzcashInitZksnarkParams fail!", e); - } - logger.info("init zk param done"); - } - @Override public void init() { } @Override public void init(CommonParameter args) { + port = Args.getInstance().getFullNodeHttpPort(); } @Override public void start() { try { - server = new Server(port); + apiServer = new Server(port); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); - server.setHandler(context); + apiServer.setHandler(context); context.addServlet(new ServletHolder(getAccountServlet), "/wallet/getaccount"); context.addServlet(new ServletHolder(transferServlet), "/wallet/createtransaction"); @@ -570,7 +522,7 @@ public void start() { int maxHttpConnectNumber = Args.getInstance().getMaxHttpConnectNumber(); if (maxHttpConnectNumber > 0) { - server.addBean(new ConnectionLimit(maxHttpConnectNumber, server)); + apiServer.addBean(new ConnectionLimit(maxHttpConnectNumber, apiServer)); } // filters the specified APIs @@ -594,17 +546,7 @@ public void start() { .addFilterWithMapping((Class) HttpInterceptor.class, "/*", EnumSet.of(DispatcherType.REQUEST)); context.addFilter(fh, "/*", EnumSet.of(DispatcherType.REQUEST)); - - server.start(); - } catch (Exception e) { - logger.debug("IOException: {}", e.getMessage()); - } - } - - @Override - public void stop() { - try { - server.stop(); + super.start(); } catch (Exception e) { logger.debug("IOException: {}", e.getMessage()); } diff --git a/framework/src/main/java/org/tron/core/services/http/GetAssetIssueListServlet.java b/framework/src/main/java/org/tron/core/services/http/GetAssetIssueListServlet.java index 7757ecd8722..3968554a671 100644 --- a/framework/src/main/java/org/tron/core/services/http/GetAssetIssueListServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/GetAssetIssueListServlet.java @@ -8,7 +8,6 @@ import org.tron.api.GrpcAPI.AssetIssueList; import org.tron.core.Wallet; - @Component @Slf4j(topic = "API") public class GetAssetIssueListServlet extends RateLimiterServlet { @@ -16,6 +15,7 @@ public class GetAssetIssueListServlet extends RateLimiterServlet { @Autowired private Wallet wallet; + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { try { boolean visible = Util.getVisible(request); @@ -30,6 +30,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) { } } + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { doGet(request, response); } diff --git a/framework/src/main/java/org/tron/core/services/http/GetAvailableUnfreezeCountServlet.java b/framework/src/main/java/org/tron/core/services/http/GetAvailableUnfreezeCountServlet.java index 28fec9f3ee3..51f78fc4390 100644 --- a/framework/src/main/java/org/tron/core/services/http/GetAvailableUnfreezeCountServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/GetAvailableUnfreezeCountServlet.java @@ -23,6 +23,9 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) { try { boolean visible = Util.getVisible(request); String ownerAddress = request.getParameter("ownerAddress"); + if (ownerAddress == null) { + ownerAddress = request.getParameter("owner_address"); + } if (visible) { ownerAddress = Util.getHexAddress(ownerAddress); } diff --git a/framework/src/main/java/org/tron/core/services/http/GetBandwidthPricesServlet.java b/framework/src/main/java/org/tron/core/services/http/GetBandwidthPricesServlet.java index ea4b535af39..09d51cc8635 100644 --- a/framework/src/main/java/org/tron/core/services/http/GetBandwidthPricesServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/GetBandwidthPricesServlet.java @@ -1,14 +1,13 @@ package org.tron.core.services.http; -import com.alibaba.fastjson.JSONObject; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.api.GrpcAPI.PricesResponseMessage; import org.tron.core.Wallet; - @Component @Slf4j(topic = "API") public class GetBandwidthPricesServlet extends RateLimiterServlet { @@ -16,21 +15,17 @@ public class GetBandwidthPricesServlet extends RateLimiterServlet { @Autowired private Wallet wallet; + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { try { - String reply = wallet.getBandwidthPrices(); - if (reply != null) { - JSONObject jsonObject = new JSONObject(); - jsonObject.put("prices", reply); - response.getWriter().println(jsonObject); - } else { - response.getWriter().println("{}"); - } + PricesResponseMessage reply = wallet.getBandwidthPrices(); + response.getWriter().println(reply == null ? "{}" : JsonFormat.printToString(reply)); } catch (Exception e) { Util.processError(e, response); } } + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { doGet(request, response); } diff --git a/framework/src/main/java/org/tron/core/services/http/GetBlockByNumServlet.java b/framework/src/main/java/org/tron/core/services/http/GetBlockByNumServlet.java index 44babc69551..800b421ace0 100644 --- a/framework/src/main/java/org/tron/core/services/http/GetBlockByNumServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/GetBlockByNumServlet.java @@ -18,14 +18,21 @@ public class GetBlockByNumServlet extends RateLimiterServlet { @Autowired private Wallet wallet; + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { try { - fillResponse(Util.getVisible(request), Long.parseLong(request.getParameter("num")), response); + long num = 0; + String numStr = request.getParameter("num"); + if (numStr != null) { + num = Long.parseLong(numStr); + } + fillResponse(Util.getVisible(request), num, response); } catch (Exception e) { Util.processError(e, response); } } + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { try { PostParams params = PostParams.getPostParams(request); diff --git a/framework/src/main/java/org/tron/core/services/http/GetCanDelegatedMaxSizeServlet.java b/framework/src/main/java/org/tron/core/services/http/GetCanDelegatedMaxSizeServlet.java index 81dd52400b5..924306a6a3f 100644 --- a/framework/src/main/java/org/tron/core/services/http/GetCanDelegatedMaxSizeServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/GetCanDelegatedMaxSizeServlet.java @@ -18,10 +18,15 @@ public class GetCanDelegatedMaxSizeServlet extends RateLimiterServlet { @Autowired private Wallet wallet; + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { try { boolean visible = Util.getVisible(request); - int type = Integer.parseInt(request.getParameter("type")); + int type = 0; + String typeStr = request.getParameter("type"); + if (typeStr != null) { + type = Integer.parseInt(typeStr); + } String ownerAddress = request.getParameter("owner_address"); if (visible) { ownerAddress = Util.getHexAddress(ownerAddress); @@ -34,6 +39,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) { } } + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { try { PostParams params = PostParams.getPostParams(request); diff --git a/framework/src/main/java/org/tron/core/services/http/GetCanWithdrawUnfreezeAmountServlet.java b/framework/src/main/java/org/tron/core/services/http/GetCanWithdrawUnfreezeAmountServlet.java index 4c1bbaf4f99..435cca9e5fb 100644 --- a/framework/src/main/java/org/tron/core/services/http/GetCanWithdrawUnfreezeAmountServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/GetCanWithdrawUnfreezeAmountServlet.java @@ -18,23 +18,29 @@ public class GetCanWithdrawUnfreezeAmountServlet extends RateLimiterServlet { @Autowired private Wallet wallet; + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { try { boolean visible = Util.getVisible(request); String ownerAddress = request.getParameter("owner_address"); - long timestamp = Long.valueOf(request.getParameter("timestamp")); + long timestamp = 0; + String timestampStr = request.getParameter("timestamp"); + if (timestampStr != null) { + timestamp = Long.parseLong(timestampStr); + } if (visible) { ownerAddress = Util.getHexAddress(ownerAddress); } fillResponse(visible, - ByteString.copyFrom(ByteArray.fromHexString(ownerAddress)), - timestamp, - response); + ByteString.copyFrom(ByteArray.fromHexString(ownerAddress)), + timestamp, + response); } catch (Exception e) { Util.processError(e, response); } } + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { try { PostParams params = PostParams.getPostParams(request); diff --git a/framework/src/main/java/org/tron/core/services/http/GetEnergyPricesServlet.java b/framework/src/main/java/org/tron/core/services/http/GetEnergyPricesServlet.java index 36129d8ffdb..b9b6ba0d893 100644 --- a/framework/src/main/java/org/tron/core/services/http/GetEnergyPricesServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/GetEnergyPricesServlet.java @@ -1,14 +1,13 @@ package org.tron.core.services.http; -import com.alibaba.fastjson.JSONObject; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.api.GrpcAPI.PricesResponseMessage; import org.tron.core.Wallet; - @Component @Slf4j(topic = "API") public class GetEnergyPricesServlet extends RateLimiterServlet { @@ -16,21 +15,17 @@ public class GetEnergyPricesServlet extends RateLimiterServlet { @Autowired private Wallet wallet; + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { try { - String reply = wallet.getEnergyPrices(); - if (reply != null) { - JSONObject jsonObject = new JSONObject(); - jsonObject.put("prices", reply); - response.getWriter().println(jsonObject); - } else { - response.getWriter().println("{}"); - } + PricesResponseMessage reply = wallet.getEnergyPrices(); + response.getWriter().println(reply == null ? "{}" : JsonFormat.printToString(reply)); } catch (Exception e) { Util.processError(e, response); } } + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { doGet(request, response); } diff --git a/framework/src/main/java/org/tron/core/services/http/GetMemoFeePricesServlet.java b/framework/src/main/java/org/tron/core/services/http/GetMemoFeePricesServlet.java index 8d5f46d8236..0da52bf9d35 100644 --- a/framework/src/main/java/org/tron/core/services/http/GetMemoFeePricesServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/GetMemoFeePricesServlet.java @@ -1,14 +1,13 @@ package org.tron.core.services.http; -import com.alibaba.fastjson.JSONObject; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.api.GrpcAPI.PricesResponseMessage; import org.tron.core.Wallet; - @Component @Slf4j(topic = "API") public class GetMemoFeePricesServlet extends RateLimiterServlet { @@ -16,21 +15,17 @@ public class GetMemoFeePricesServlet extends RateLimiterServlet { @Autowired private Wallet wallet; + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { try { - String reply = wallet.getMemoFeePrices(); - if (reply != null) { - JSONObject jsonObject = new JSONObject(); - jsonObject.put("prices", reply); - response.getWriter().println(jsonObject); - } else { - response.getWriter().println("{}"); - } + PricesResponseMessage reply = wallet.getMemoFeePrices(); + response.getWriter().println(reply == null ? "{}" : JsonFormat.printToString(reply)); } catch (Exception e) { Util.processError(e, response); } } + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { doGet(request, response); } diff --git a/framework/src/main/java/org/tron/core/services/http/GetNowBlockServlet.java b/framework/src/main/java/org/tron/core/services/http/GetNowBlockServlet.java index f7d9700aeb9..56e01d557f5 100644 --- a/framework/src/main/java/org/tron/core/services/http/GetNowBlockServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/GetNowBlockServlet.java @@ -8,7 +8,6 @@ import org.tron.core.Wallet; import org.tron.protos.Protocol.Block; - @Component @Slf4j(topic = "API") public class GetNowBlockServlet extends RateLimiterServlet { @@ -16,6 +15,7 @@ public class GetNowBlockServlet extends RateLimiterServlet { @Autowired private Wallet wallet; + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { try { boolean visible = Util.getVisible(request); @@ -30,6 +30,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) { } } + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { doGet(request, response); } diff --git a/framework/src/main/java/org/tron/core/services/http/ListNodesServlet.java b/framework/src/main/java/org/tron/core/services/http/ListNodesServlet.java index 94fd568a3f4..6b7b2b251a8 100644 --- a/framework/src/main/java/org/tron/core/services/http/ListNodesServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/ListNodesServlet.java @@ -8,7 +8,6 @@ import org.tron.api.GrpcAPI.NodeList; import org.tron.core.Wallet; - @Component @Slf4j(topic = "API") public class ListNodesServlet extends RateLimiterServlet { @@ -16,6 +15,7 @@ public class ListNodesServlet extends RateLimiterServlet { @Autowired private Wallet wallet; + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { try { boolean visible = Util.getVisible(request); @@ -30,6 +30,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) { } } + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { doGet(request, response); } diff --git a/framework/src/main/java/org/tron/core/services/http/ListProposalsServlet.java b/framework/src/main/java/org/tron/core/services/http/ListProposalsServlet.java index f8c67395b1b..a3b26d4afc6 100644 --- a/framework/src/main/java/org/tron/core/services/http/ListProposalsServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/ListProposalsServlet.java @@ -8,7 +8,6 @@ import org.tron.api.GrpcAPI.ProposalList; import org.tron.core.Wallet; - @Component @Slf4j(topic = "API") public class ListProposalsServlet extends RateLimiterServlet { @@ -16,6 +15,7 @@ public class ListProposalsServlet extends RateLimiterServlet { @Autowired private Wallet wallet; + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { try { boolean visible = Util.getVisible(request); @@ -30,6 +30,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) { } } + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { doGet(request, response); } diff --git a/framework/src/main/java/org/tron/core/services/http/PostParams.java b/framework/src/main/java/org/tron/core/services/http/PostParams.java index a2077fb3c78..7dcb0be6ae3 100644 --- a/framework/src/main/java/org/tron/core/services/http/PostParams.java +++ b/framework/src/main/java/org/tron/core/services/http/PostParams.java @@ -1,5 +1,8 @@ package org.tron.core.services.http; +import static org.apache.http.entity.ContentType.APPLICATION_FORM_URLENCODED; +import static org.tron.core.services.http.Util.getJsonString; + import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import lombok.Getter; @@ -21,6 +24,9 @@ public PostParams(String params, boolean visible) { public static PostParams getPostParams(HttpServletRequest request) throws Exception { String input = request.getReader().lines().collect(Collectors.joining(System.lineSeparator())); Util.checkBodySize(input); + if (APPLICATION_FORM_URLENCODED.getMimeType().equals(request.getContentType())) { + input = getJsonString(input); + } boolean visible = Util.getVisiblePost(input); return new PostParams(input, visible); } diff --git a/framework/src/main/java/org/tron/core/services/http/RateLimiterServlet.java b/framework/src/main/java/org/tron/core/services/http/RateLimiterServlet.java index eb8b7b86257..805fa2785b1 100644 --- a/framework/src/main/java/org/tron/core/services/http/RateLimiterServlet.java +++ b/framework/src/main/java/org/tron/core/services/http/RateLimiterServlet.java @@ -25,10 +25,10 @@ import org.tron.core.services.ratelimiter.adapter.IPreemptibleRateLimiter; import org.tron.core.services.ratelimiter.adapter.IRateLimiter; import org.tron.core.services.ratelimiter.adapter.QpsRateLimiterAdapter; +import org.tron.core.services.ratelimiter.strategy.QpsStrategy; @Slf4j public abstract class RateLimiterServlet extends HttpServlet { - private static final String KEY_PREFIX_HTTP = "http_"; private static final String ADAPTER_PREFIX = "org.tron.core.services.ratelimiter.adapter."; @@ -37,12 +37,9 @@ public abstract class RateLimiterServlet extends HttpServlet { @PostConstruct private void addRateContainer() { - RateLimiterInitialization.HttpRateLimiterItem item = Args.getInstance() .getRateLimiterInitialization().getHttpMap().get(getClass().getSimpleName()); - boolean success = false; - if (item != null) { String cName = ""; String params = ""; @@ -50,7 +47,6 @@ private void addRateContainer() { try { cName = item.getStrategy(); params = item.getParams(); - // add the specific rate limiter strategy of servlet. Class c = Class.forName(ADAPTER_PREFIX + cName); Constructor constructor; @@ -59,34 +55,29 @@ private void addRateContainer() { constructor = c.getConstructor(String.class); obj = constructor.newInstance(params); container.add(KEY_PREFIX_HTTP, getClass().getSimpleName(), (IRateLimiter) obj); - } else { constructor = c.getConstructor(); - obj = constructor.newInstance(); + obj = constructor.newInstance(QpsStrategy.DEFAULT_QPS_PARAM); container.add(KEY_PREFIX_HTTP, getClass().getSimpleName(), (IRateLimiter) obj); } success = true; } catch (Exception e) { - logger.warn( - "failure to add the rate limiter strategy. servlet = {}, " + logger.warn("failure to add the rate limiter strategy. servlet = {}, " + "strategy name = {}, params = \"{}\".", getClass().getSimpleName(), cName, params); } } - if (!success) { // if the specific rate limiter strategy of servlet is not defined or fail to add, // then add a default Strategy. try { - IRateLimiter rateLimiter = new DefaultBaseQqsAdapter("qps=1000"); + IRateLimiter rateLimiter = new DefaultBaseQqsAdapter(QpsStrategy.DEFAULT_QPS_PARAM); container.add(KEY_PREFIX_HTTP, getClass().getSimpleName(), rateLimiter); } catch (Exception e) { - logger.warn( - "failure to add the default rate limiter strategy. servlet = {}.", + logger.warn("failure to add the default rate limiter strategy. servlet = {}.", getClass().getSimpleName()); } } - } @Override diff --git a/framework/src/main/java/org/tron/core/services/http/Util.java b/framework/src/main/java/org/tron/core/services/http/Util.java index 2cbf5d2e718..8f27521495a 100644 --- a/framework/src/main/java/org/tron/core/services/http/Util.java +++ b/framework/src/main/java/org/tron/core/services/http/Util.java @@ -1,5 +1,6 @@ package org.tron.core.services.http; +import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.tron.common.utils.Commons.decodeFromBase58Check; import com.alibaba.fastjson.JSON; @@ -11,20 +12,28 @@ import com.google.protobuf.GeneratedMessageV3; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; + +import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStreamReader; import java.lang.reflect.Constructor; import java.math.BigDecimal; import java.nio.charset.Charset; import java.security.InvalidParameterException; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; +import java.util.Map; +import java.util.Objects; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.bouncycastle.util.encoders.Hex; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.MimeTypes; +import org.eclipse.jetty.util.MultiMap; import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.UrlEncoded; import org.tron.api.GrpcAPI; import org.tron.api.GrpcAPI.BlockList; import org.tron.api.GrpcAPI.TransactionApprovedList; @@ -333,12 +342,16 @@ public static boolean getVisible(final HttpServletRequest request) { return visible; } + public static boolean existVisible(final HttpServletRequest request) { + return Objects.nonNull(request.getParameter(VISIBLE)); + } + public static boolean getVisiblePost(final String input) { boolean visible = false; if (StringUtil.isNotBlank(input)) { JSONObject jsonObject = JSON.parseObject(input); if (jsonObject.containsKey(VISIBLE)) { - visible = jsonObject.getBoolean(VISIBLE); + visible = Boolean.parseBoolean(jsonObject.getString(VISIBLE)); } } @@ -498,16 +511,7 @@ public static void printAccount(Account reply, HttpServletResponse response, Boo public static byte[] getAddress(HttpServletRequest request) throws Exception { byte[] address = null; String addressParam = "address"; - String addressStr = request.getParameter(addressParam); - if (StringUtils.isBlank(addressStr)) { - String input = request.getReader().lines() - .collect(Collectors.joining(System.lineSeparator())); - Util.checkBodySize(input); - JSONObject jsonObject = JSON.parseObject(input); - if (jsonObject != null) { - addressStr = jsonObject.getString(addressParam); - } - } + String addressStr = checkGetParam(request, addressParam); if (StringUtils.isNotBlank(addressStr)) { if (StringUtils.startsWith(addressStr, Constant.ADD_PRE_FIX_STRING_MAINNET)) { address = Hex.decode(addressStr); @@ -518,6 +522,45 @@ public static byte[] getAddress(HttpServletRequest request) throws Exception { return address; } + private static String checkGetParam(HttpServletRequest request, String key) throws Exception { + String method = request.getMethod(); + + if (HttpMethod.GET.toString().toUpperCase().equalsIgnoreCase(method)) { + return request.getParameter(key); + } + if (HttpMethod.POST.toString().toUpperCase().equals(method)) { + String contentType = request.getContentType(); + if (StringUtils.isBlank(contentType)) { + return null; + } + if (contentType.contains(MimeTypes.Type.FORM_ENCODED.asString())) { + return request.getParameter(key); + } else { + String value = getRequestValue(request); + if (StringUtils.isBlank(value)) { + return null; + } + + JSONObject jsonObject = JSON.parseObject(value); + if (jsonObject != null) { + return jsonObject.getString(key); + } + return null; + } + } + return null; + } + + public static String getRequestValue(HttpServletRequest request) throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream())); + String line; + StringBuilder sb = new StringBuilder(); + while ((line = reader.readLine()) != null) { + sb.append(line); + } + return sb.toString(); + } + public static List convertLogAddressToTronAddress(TransactionInfo transactionInfo) { List newLogList = new ArrayList<>(); @@ -569,4 +612,34 @@ public static void validateParameter(String contract) throws InvalidParameterExc } } + public static String getJsonString(String str) { + if (StringUtils.isEmpty(str)) { + return EMPTY; + } + if (isValidJson(str)) { + return str; + } + MultiMap params = new MultiMap<>(); + UrlEncoded.decodeUtf8To(str, params); + JSONObject json = new JSONObject(); + for (Map.Entry> entry : params.entrySet()) { + String key = entry.getKey(); + List values = entry.getValue(); + if (values.size() == 1) { + json.put(key, values.get(0)); + } else { + json.put(key, values); + } + } + return json.toString(); + } + + public static boolean isValidJson(String json) { + try { + JSON.parse(json); + return true; + } catch (Exception e) { + return false; + } + } } diff --git a/framework/src/main/java/org/tron/core/services/http/solidity/SolidityNodeHttpApiService.java b/framework/src/main/java/org/tron/core/services/http/solidity/SolidityNodeHttpApiService.java index bc3cd667e2c..0c66b220e09 100644 --- a/framework/src/main/java/org/tron/core/services/http/solidity/SolidityNodeHttpApiService.java +++ b/framework/src/main/java/org/tron/core/services/http/solidity/SolidityNodeHttpApiService.java @@ -10,12 +10,11 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.tron.common.application.Service; +import org.tron.common.application.HttpService; import org.tron.common.parameter.CommonParameter; import org.tron.core.config.args.Args; import org.tron.core.services.filter.HttpApiAccessFilter; import org.tron.core.services.http.EstimateEnergyServlet; -import org.tron.core.services.http.FullNodeHttpApiService; import org.tron.core.services.http.GetAccountByIdServlet; import org.tron.core.services.http.GetAccountServlet; import org.tron.core.services.http.GetAssetIssueByIdServlet; @@ -23,6 +22,7 @@ import org.tron.core.services.http.GetAssetIssueListByNameServlet; import org.tron.core.services.http.GetAssetIssueListServlet; import org.tron.core.services.http.GetAvailableUnfreezeCountServlet; +import org.tron.core.services.http.GetBandwidthPricesServlet; import org.tron.core.services.http.GetBlockByIdServlet; import org.tron.core.services.http.GetBlockByLatestNumServlet; import org.tron.core.services.http.GetBlockByLimitNextServlet; @@ -36,6 +36,7 @@ import org.tron.core.services.http.GetDelegatedResourceAccountIndexV2Servlet; import org.tron.core.services.http.GetDelegatedResourceServlet; import org.tron.core.services.http.GetDelegatedResourceV2Servlet; +import org.tron.core.services.http.GetEnergyPricesServlet; import org.tron.core.services.http.GetExchangeByIdServlet; import org.tron.core.services.http.GetMarketOrderByAccountServlet; import org.tron.core.services.http.GetMarketOrderByIdServlet; @@ -63,15 +64,10 @@ @Component @Slf4j(topic = "API") -public class SolidityNodeHttpApiService implements Service { - - private int port = Args.getInstance().getSolidityHttpPort(); - - private Server server; +public class SolidityNodeHttpApiService extends HttpService { @Autowired private GetAccountServlet getAccountServlet; - @Autowired private GetTransactionByIdSolidityServlet getTransactionByIdServlet; @Autowired @@ -96,7 +92,6 @@ public class SolidityNodeHttpApiService implements Service { private GetExchangeByIdServlet getExchangeByIdServlet; @Autowired private ListExchangesServlet listExchangesServlet; - @Autowired private ListWitnessesServlet listWitnessesServlet; @Autowired @@ -159,15 +154,16 @@ public class SolidityNodeHttpApiService implements Service { private TriggerConstantContractServlet triggerConstantContractServlet; @Autowired private EstimateEnergyServlet estimateEnergyServlet; - @Autowired private GetTransactionInfoByBlockNumServlet getTransactionInfoByBlockNumServlet; - @Autowired private HttpApiAccessFilter httpApiAccessFilter; - @Autowired private GetBlockServlet getBlockServlet; + @Autowired + private GetBandwidthPricesServlet getBandwidthPricesServlet; + @Autowired + private GetEnergyPricesServlet getEnergyPricesServlet; @Override @@ -176,15 +172,16 @@ public void init() { @Override public void init(CommonParameter args) { + port = Args.getInstance().getSolidityHttpPort(); } @Override public void start() { try { - server = new Server(port); + apiServer = new Server(port); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); - server.setHandler(context); + apiServer.setHandler(context); // same as FullNode context.addServlet(new ServletHolder(getAccountServlet), "/walletsolidity/getaccount"); @@ -283,6 +280,10 @@ public void start() { context.addServlet(new ServletHolder(getRewardServlet), "/walletsolidity/getReward"); context.addServlet(new ServletHolder(getBurnTrxServlet), "/walletsolidity/getburntrx"); context.addServlet(new ServletHolder(getBlockServlet), "/walletsolidity/getblock"); + context.addServlet(new ServletHolder(getBandwidthPricesServlet), + "/walletsolidity/getbandwidthprices"); + context.addServlet(new ServletHolder(getEnergyPricesServlet), + "/walletsolidity/getenergyprices"); // http access filter context.addFilter(new FilterHolder(httpApiAccessFilter), "/walletsolidity/*", @@ -293,22 +294,12 @@ public void start() { int maxHttpConnectNumber = Args.getInstance().getMaxHttpConnectNumber(); if (maxHttpConnectNumber > 0) { - server.addBean(new ConnectionLimit(maxHttpConnectNumber, server)); + apiServer.addBean(new ConnectionLimit(maxHttpConnectNumber, apiServer)); } - server.start(); + super.start(); } catch (Exception e) { logger.debug("IOException: {}", e.getMessage()); } } - - @Override - public void stop() { - try { - server.stop(); - } catch (Exception e) { - logger.debug("Exception: {}", e.getMessage()); - } - } - } diff --git a/framework/src/main/java/org/tron/core/services/interfaceJsonRpcOnPBFT/JsonRpcServiceOnPBFT.java b/framework/src/main/java/org/tron/core/services/interfaceJsonRpcOnPBFT/JsonRpcServiceOnPBFT.java index 96da1515610..1893a46045a 100644 --- a/framework/src/main/java/org/tron/core/services/interfaceJsonRpcOnPBFT/JsonRpcServiceOnPBFT.java +++ b/framework/src/main/java/org/tron/core/services/interfaceJsonRpcOnPBFT/JsonRpcServiceOnPBFT.java @@ -7,16 +7,12 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.tron.common.application.Service; +import org.tron.common.application.HttpService; import org.tron.common.parameter.CommonParameter; @Component @Slf4j(topic = "API") -public class JsonRpcServiceOnPBFT implements Service { - - private int port = CommonParameter.getInstance().getJsonRpcHttpPBFTPort(); - - private Server server; +public class JsonRpcServiceOnPBFT extends HttpService { @Autowired private JsonRpcOnPBFTServlet jsonRpcOnPBFTServlet; @@ -27,36 +23,28 @@ public void init() { @Override public void init(CommonParameter args) { + port = CommonParameter.getInstance().getJsonRpcHttpPBFTPort(); } @Override public void start() { try { - server = new Server(port); + apiServer = new Server(port); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); - server.setHandler(context); + apiServer.setHandler(context); context.addServlet(new ServletHolder(jsonRpcOnPBFTServlet), "/jsonrpc"); int maxHttpConnectNumber = CommonParameter.getInstance().getMaxHttpConnectNumber(); if (maxHttpConnectNumber > 0) { - server.addBean(new ConnectionLimit(maxHttpConnectNumber, server)); + apiServer.addBean(new ConnectionLimit(maxHttpConnectNumber, apiServer)); } - server.start(); + super.start(); } catch (Exception e) { logger.debug("IOException: {}", e.getMessage()); } } - - @Override - public void stop() { - try { - server.stop(); - } catch (Exception e) { - logger.debug("IOException: {}", e.getMessage()); - } - } } diff --git a/framework/src/main/java/org/tron/core/services/interfaceJsonRpcOnSolidity/JsonRpcServiceOnSolidity.java b/framework/src/main/java/org/tron/core/services/interfaceJsonRpcOnSolidity/JsonRpcServiceOnSolidity.java index 41357c13dc2..52f5b761ae2 100644 --- a/framework/src/main/java/org/tron/core/services/interfaceJsonRpcOnSolidity/JsonRpcServiceOnSolidity.java +++ b/framework/src/main/java/org/tron/core/services/interfaceJsonRpcOnSolidity/JsonRpcServiceOnSolidity.java @@ -7,16 +7,12 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.tron.common.application.Service; +import org.tron.common.application.HttpService; import org.tron.common.parameter.CommonParameter; @Component @Slf4j(topic = "API") -public class JsonRpcServiceOnSolidity implements Service { - - private int port = CommonParameter.getInstance().getJsonRpcHttpSolidityPort(); - - private Server server; +public class JsonRpcServiceOnSolidity extends HttpService { @Autowired private JsonRpcOnSolidityServlet jsonRpcOnSolidityServlet; @@ -27,34 +23,25 @@ public void init() { @Override public void init(CommonParameter args) { + port = CommonParameter.getInstance().getJsonRpcHttpSolidityPort(); } @Override public void start() { try { - server = new Server(port); + apiServer = new Server(port); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); - server.setHandler(context); + apiServer.setHandler(context); context.addServlet(new ServletHolder(jsonRpcOnSolidityServlet), "/jsonrpc"); int maxHttpConnectNumber = CommonParameter.getInstance().getMaxHttpConnectNumber(); if (maxHttpConnectNumber > 0) { - server.addBean(new ConnectionLimit(maxHttpConnectNumber, server)); + apiServer.addBean(new ConnectionLimit(maxHttpConnectNumber, apiServer)); } + super.start(); - server.start(); - - } catch (Exception e) { - logger.debug("IOException: {}", e.getMessage()); - } - } - - @Override - public void stop() { - try { - server.stop(); } catch (Exception e) { logger.debug("IOException: {}", e.getMessage()); } diff --git a/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/RpcApiServiceOnPBFT.java b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/RpcApiServiceOnPBFT.java index 937decd7b57..2f7b1dcc15c 100755 --- a/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/RpcApiServiceOnPBFT.java +++ b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/RpcApiServiceOnPBFT.java @@ -1,10 +1,7 @@ package org.tron.core.services.interfaceOnPBFT; -import io.grpc.Server; import io.grpc.netty.NettyServerBuilder; import io.grpc.stub.StreamObserver; -import java.io.IOException; -import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -32,15 +29,14 @@ import org.tron.api.GrpcAPI.NumberMessage; import org.tron.api.GrpcAPI.OvkDecryptTRC20Parameters; import org.tron.api.GrpcAPI.PaginatedMessage; +import org.tron.api.GrpcAPI.PricesResponseMessage; import org.tron.api.GrpcAPI.SpendResult; import org.tron.api.GrpcAPI.TransactionExtention; import org.tron.api.GrpcAPI.WitnessList; import org.tron.api.WalletSolidityGrpc.WalletSolidityImplBase; -import org.tron.common.application.Service; -import org.tron.common.crypto.ECKey; +import org.tron.common.application.RpcService; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.parameter.CommonParameter; -import org.tron.common.utils.StringUtil; -import org.tron.common.utils.Utils; import org.tron.core.config.args.Args; import org.tron.core.services.RpcApiService; import org.tron.core.services.filter.LiteFnQueryGrpcInterceptor; @@ -65,10 +61,7 @@ @Slf4j(topic = "API") -public class RpcApiServiceOnPBFT implements Service { - - private int port = Args.getInstance().getRpcOnPBFTPort(); - private Server apiServer; +public class RpcApiServiceOnPBFT extends RpcService { @Autowired private WalletOnPBFT walletOnPBFT; @@ -85,13 +78,15 @@ public class RpcApiServiceOnPBFT implements Service { @Autowired private RpcApiAccessInterceptor apiAccessInterceptor; + private final String executorName = "rpc-pbft-executor"; + @Override public void init() { } @Override public void init(CommonParameter parameter) { - + port = Args.getInstance().getRpcOnPBFTPort(); } @Override @@ -104,7 +99,8 @@ public void start() { if (args.getRpcThreadNum() > 0) { serverBuilder = serverBuilder - .executor(Executors.newFixedThreadPool(args.getRpcThreadNum())); + .executor(ExecutorServiceManager.newFixedThreadPool( + executorName, args.getRpcThreadNum())); } serverBuilder = serverBuilder.addService(new WalletPBFTApi()); @@ -129,32 +125,10 @@ public void start() { apiServer = serverBuilder.build(); rateLimiterInterceptor.init(apiServer); - - apiServer.start(); - - } catch (IOException e) { + super.start(); + } catch (Exception e) { logger.debug(e.getMessage(), e); } - - logger.info("RpcApiServiceOnPBFT started, listening on " + port); - - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - System.err.println("*** shutting down gRPC server on PBFT since JVM is shutting down"); - //server.this.stop(); - System.err.println("*** server on PBFT shut down"); - })); - } - - @Override - public void stop() { - if (apiServer != null) { - try { - apiServer.shutdown().awaitTermination(); - } catch (InterruptedException e) { - logger.warn("{}", e); - Thread.currentThread().interrupt(); - } - } } /** @@ -559,5 +533,19 @@ public void getBlock(GrpcAPI.BlockReq request, () -> rpcApiService.getWalletSolidityApi().getBlock(request, responseObserver)); } + @Override + public void getBandwidthPrices(EmptyMessage request, + StreamObserver responseObserver) { + walletOnPBFT.futureGet( + () -> rpcApiService.getWalletSolidityApi().getBandwidthPrices(request, responseObserver)); + } + + @Override + public void getEnergyPrices(EmptyMessage request, + StreamObserver responseObserver) { + walletOnPBFT.futureGet( + () -> rpcApiService.getWalletSolidityApi().getEnergyPrices(request, responseObserver)); + } + } } diff --git a/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/GetBandwidthPricesOnPBFTServlet.java b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/GetBandwidthPricesOnPBFTServlet.java new file mode 100644 index 00000000000..c89bc5f9646 --- /dev/null +++ b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/GetBandwidthPricesOnPBFTServlet.java @@ -0,0 +1,27 @@ +package org.tron.core.services.interfaceOnPBFT.http; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.core.services.http.GetBandwidthPricesServlet; +import org.tron.core.services.interfaceOnPBFT.WalletOnPBFT; + +@Component +@Slf4j(topic = "API") +public class GetBandwidthPricesOnPBFTServlet extends GetBandwidthPricesServlet { + + @Autowired + private WalletOnPBFT walletOnPBFT; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) { + walletOnPBFT.futureGet(() -> super.doGet(request, response)); + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) { + walletOnPBFT.futureGet(() -> super.doPost(request, response)); + } +} diff --git a/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/GetEnergyPricesOnPBFTServlet.java b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/GetEnergyPricesOnPBFTServlet.java index 4cf8ad06b27..11c1dcaa0e8 100644 --- a/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/GetEnergyPricesOnPBFTServlet.java +++ b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/GetEnergyPricesOnPBFTServlet.java @@ -8,7 +8,6 @@ import org.tron.core.services.http.GetEnergyPricesServlet; import org.tron.core.services.interfaceOnPBFT.WalletOnPBFT; - @Component @Slf4j(topic = "API") public class GetEnergyPricesOnPBFTServlet extends GetEnergyPricesServlet { @@ -16,10 +15,12 @@ public class GetEnergyPricesOnPBFTServlet extends GetEnergyPricesServlet { @Autowired private WalletOnPBFT walletOnPBFT; + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { walletOnPBFT.futureGet(() -> super.doGet(request, response)); } + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { walletOnPBFT.futureGet(() -> super.doPost(request, response)); } diff --git a/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/PBFT/HttpApiOnPBFTService.java b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/PBFT/HttpApiOnPBFTService.java index 33da1414bbe..7a5fd0cbcde 100644 --- a/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/PBFT/HttpApiOnPBFTService.java +++ b/framework/src/main/java/org/tron/core/services/interfaceOnPBFT/http/PBFT/HttpApiOnPBFTService.java @@ -9,7 +9,7 @@ import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.springframework.beans.factory.annotation.Autowired; -import org.tron.common.application.Service; +import org.tron.common.application.HttpService; import org.tron.common.parameter.CommonParameter; import org.tron.core.config.args.Args; import org.tron.core.services.filter.HttpApiAccessFilter; @@ -22,6 +22,7 @@ import org.tron.core.services.interfaceOnPBFT.http.GetAssetIssueListByNameOnPBFTServlet; import org.tron.core.services.interfaceOnPBFT.http.GetAssetIssueListOnPBFTServlet; import org.tron.core.services.interfaceOnPBFT.http.GetAvailableUnfreezeCountOnPBFTServlet; +import org.tron.core.services.interfaceOnPBFT.http.GetBandwidthPricesOnPBFTServlet; import org.tron.core.services.interfaceOnPBFT.http.GetBlockByIdOnPBFTServlet; import org.tron.core.services.interfaceOnPBFT.http.GetBlockByLatestNumOnPBFTServlet; import org.tron.core.services.interfaceOnPBFT.http.GetBlockByLimitNextOnPBFTServlet; @@ -59,11 +60,7 @@ import org.tron.core.services.interfaceOnPBFT.http.TriggerConstantContractOnPBFTServlet; @Slf4j(topic = "API") -public class HttpApiOnPBFTService implements Service { - - private int port = Args.getInstance().getPBFTHttpPort(); - - private Server server; +public class HttpApiOnPBFTService extends HttpService { @Autowired private GetAccountOnPBFTServlet accountOnPBFTServlet; @@ -156,6 +153,8 @@ public class HttpApiOnPBFTService implements Service { @Autowired private GetBurnTrxOnPBFTServlet getBurnTrxOnPBFTServlet; @Autowired + private GetBandwidthPricesOnPBFTServlet getBandwidthPricesOnPBFTServlet; + @Autowired private GetEnergyPricesOnPBFTServlet getEnergyPricesOnPBFTServlet; @Autowired @@ -180,16 +179,16 @@ public void init() { @Override public void init(CommonParameter parameter) { - + port = Args.getInstance().getPBFTHttpPort(); } @Override public void start() { try { - server = new Server(port); + apiServer = new Server(port); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/walletpbft/"); - server.setHandler(context); + apiServer.setHandler(context); // same as FullNode context.addServlet(new ServletHolder(accountOnPBFTServlet), "/getaccount"); @@ -258,6 +257,8 @@ public void start() { "/isshieldedtrc20contractnotespent"); context.addServlet(new ServletHolder(getBurnTrxOnPBFTServlet), "/getburntrx"); + context.addServlet(new ServletHolder(getBandwidthPricesOnPBFTServlet), + "/getbandwidthprices"); context.addServlet(new ServletHolder(getEnergyPricesOnPBFTServlet), "/getenergyprices"); context.addServlet(new ServletHolder(getBlockOnPBFTServlet), @@ -276,7 +277,7 @@ public void start() { int maxHttpConnectNumber = Args.getInstance().getMaxHttpConnectNumber(); if (maxHttpConnectNumber > 0) { - server.addBean(new ConnectionLimit(maxHttpConnectNumber, server)); + apiServer.addBean(new ConnectionLimit(maxHttpConnectNumber, apiServer)); } // filters the specified APIs @@ -288,18 +289,9 @@ public void start() { context.addFilter(new FilterHolder(httpApiAccessFilter), "/*", EnumSet.allOf(DispatcherType.class)); - server.start(); + super.start(); } catch (Exception e) { logger.debug("IOException: {}", e.getMessage()); } } - - @Override - public void stop() { - try { - server.stop(); - } catch (Exception e) { - logger.debug("Exception: {}", e.getMessage()); - } - } } diff --git a/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/RpcApiServiceOnSolidity.java b/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/RpcApiServiceOnSolidity.java index 19755d744db..68ec79175fa 100755 --- a/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/RpcApiServiceOnSolidity.java +++ b/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/RpcApiServiceOnSolidity.java @@ -1,11 +1,8 @@ package org.tron.core.services.interfaceOnSolidity; import com.google.protobuf.ByteString; -import io.grpc.Server; import io.grpc.netty.NettyServerBuilder; import io.grpc.stub.StreamObserver; -import java.io.IOException; -import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -28,6 +25,7 @@ import org.tron.api.GrpcAPI.NoteParameters; import org.tron.api.GrpcAPI.NumberMessage; import org.tron.api.GrpcAPI.PaginatedMessage; +import org.tron.api.GrpcAPI.PricesResponseMessage; import org.tron.api.GrpcAPI.Return; import org.tron.api.GrpcAPI.Return.response_code; import org.tron.api.GrpcAPI.SpendResult; @@ -35,13 +33,10 @@ import org.tron.api.GrpcAPI.TransactionInfoList; import org.tron.api.GrpcAPI.WitnessList; import org.tron.api.WalletSolidityGrpc.WalletSolidityImplBase; -import org.tron.common.application.Service; -import org.tron.common.crypto.SignInterface; -import org.tron.common.crypto.SignUtils; +import org.tron.common.application.RpcService; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.parameter.CommonParameter; import org.tron.common.utils.Sha256Hash; -import org.tron.common.utils.StringUtil; -import org.tron.common.utils.Utils; import org.tron.core.capsule.BlockCapsule; import org.tron.core.config.args.Args; import org.tron.core.services.RpcApiService; @@ -67,10 +62,8 @@ @Slf4j(topic = "API") -public class RpcApiServiceOnSolidity implements Service { +public class RpcApiServiceOnSolidity extends RpcService { - private int port = Args.getInstance().getRpcOnSolidityPort(); - private Server apiServer; @Autowired private WalletOnSolidity walletOnSolidity; @@ -87,12 +80,15 @@ public class RpcApiServiceOnSolidity implements Service { @Autowired private RpcApiAccessInterceptor apiAccessInterceptor; + private final String executorName = "rpc-solidity-executor"; + @Override public void init() { } @Override public void init(CommonParameter args) { + port = Args.getInstance().getRpcOnSolidityPort(); } @Override @@ -105,7 +101,8 @@ public void start() { if (parameter.getRpcThreadNum() > 0) { serverBuilder = serverBuilder - .executor(Executors.newFixedThreadPool(parameter.getRpcThreadNum())); + .executor(ExecutorServiceManager.newFixedThreadPool( + executorName, parameter.getRpcThreadNum())); } serverBuilder = serverBuilder.addService(new WalletSolidityApi()); @@ -129,20 +126,10 @@ public void start() { apiServer = serverBuilder.build(); rateLimiterInterceptor.init(apiServer); - - apiServer.start(); - - } catch (IOException e) { + super.start(); + } catch (Exception e) { logger.debug(e.getMessage(), e); } - - logger.info("RpcApiServiceOnSolidity started, listening on " + port); - - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - System.err.println("*** shutting down gRPC server on solidity since JVM is shutting down"); - //server.this.stop(); - System.err.println("*** server on solidity shut down"); - })); } private TransactionExtention transaction2Extention(Transaction transaction) { @@ -174,18 +161,6 @@ private BlockExtention block2Extention(Block block) { return builder.build(); } - @Override - public void stop() { - if (apiServer != null) { - try { - apiServer.shutdown().awaitTermination(); - } catch (InterruptedException e) { - logger.warn("{}", e); - Thread.currentThread().interrupt(); - } - } - } - /** * DatabaseApi. */ @@ -542,5 +517,19 @@ public void getBlock(GrpcAPI.BlockReq request, () -> rpcApiService.getWalletSolidityApi().getBlock(request, responseObserver)); } + @Override + public void getBandwidthPrices(EmptyMessage request, + StreamObserver responseObserver) { + walletOnSolidity.futureGet( + () -> rpcApiService.getWalletSolidityApi().getBandwidthPrices(request, responseObserver)); + } + + @Override + public void getEnergyPrices(EmptyMessage request, + StreamObserver responseObserver) { + walletOnSolidity.futureGet( + () -> rpcApiService.getWalletSolidityApi().getEnergyPrices(request, responseObserver)); + } + } } diff --git a/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/http/GetBandwidthPricesOnSolidityServlet.java b/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/http/GetBandwidthPricesOnSolidityServlet.java new file mode 100644 index 00000000000..bb2fca37a97 --- /dev/null +++ b/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/http/GetBandwidthPricesOnSolidityServlet.java @@ -0,0 +1,28 @@ +package org.tron.core.services.interfaceOnSolidity.http; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.core.services.http.GetBandwidthPricesServlet; +import org.tron.core.services.interfaceOnSolidity.WalletOnSolidity; + +@Component +@Slf4j(topic = "API") +public class GetBandwidthPricesOnSolidityServlet extends GetBandwidthPricesServlet { + + @Autowired + private WalletOnSolidity walletOnSolidity; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) { + walletOnSolidity.futureGet(() -> super.doGet(request, response)); + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) { + walletOnSolidity.futureGet(() -> super.doPost(request, response)); + } +} + diff --git a/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/http/GetEnergyPricesOnSolidityServlet.java b/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/http/GetEnergyPricesOnSolidityServlet.java index b9d4fb765f6..a867fc3596a 100644 --- a/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/http/GetEnergyPricesOnSolidityServlet.java +++ b/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/http/GetEnergyPricesOnSolidityServlet.java @@ -8,7 +8,6 @@ import org.tron.core.services.http.GetEnergyPricesServlet; import org.tron.core.services.interfaceOnSolidity.WalletOnSolidity; - @Component @Slf4j(topic = "API") public class GetEnergyPricesOnSolidityServlet extends GetEnergyPricesServlet { @@ -16,10 +15,12 @@ public class GetEnergyPricesOnSolidityServlet extends GetEnergyPricesServlet { @Autowired private WalletOnSolidity walletOnSolidity; + @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { walletOnSolidity.futureGet(() -> super.doGet(request, response)); } + @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) { walletOnSolidity.futureGet(() -> super.doPost(request, response)); } diff --git a/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/http/solidity/HttpApiOnSolidityService.java b/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/http/solidity/HttpApiOnSolidityService.java index bddec04d6a6..f89be80c71b 100644 --- a/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/http/solidity/HttpApiOnSolidityService.java +++ b/framework/src/main/java/org/tron/core/services/interfaceOnSolidity/http/solidity/HttpApiOnSolidityService.java @@ -9,7 +9,7 @@ import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.springframework.beans.factory.annotation.Autowired; -import org.tron.common.application.Service; +import org.tron.common.application.HttpService; import org.tron.common.parameter.CommonParameter; import org.tron.core.config.args.Args; import org.tron.core.services.filter.HttpApiAccessFilter; @@ -22,6 +22,7 @@ import org.tron.core.services.interfaceOnSolidity.http.GetAssetIssueListByNameOnSolidityServlet; import org.tron.core.services.interfaceOnSolidity.http.GetAssetIssueListOnSolidityServlet; import org.tron.core.services.interfaceOnSolidity.http.GetAvailableUnfreezeCountOnSolidityServlet; +import org.tron.core.services.interfaceOnSolidity.http.GetBandwidthPricesOnSolidityServlet; import org.tron.core.services.interfaceOnSolidity.http.GetBlockByIdOnSolidityServlet; import org.tron.core.services.interfaceOnSolidity.http.GetBlockByLatestNumOnSolidityServlet; import org.tron.core.services.interfaceOnSolidity.http.GetBlockByLimitNextOnSolidityServlet; @@ -62,11 +63,7 @@ @Slf4j(topic = "API") -public class HttpApiOnSolidityService implements Service { - - private int port = Args.getInstance().getSolidityHttpPort(); - - private Server server; +public class HttpApiOnSolidityService extends HttpService { @Autowired private GetAccountOnSolidityServlet accountOnSolidityServlet; @@ -168,6 +165,8 @@ public class HttpApiOnSolidityService implements Service { @Autowired private GetMarketPairListOnSolidityServlet getMarketPairListOnSolidityServlet; @Autowired + private GetBandwidthPricesOnSolidityServlet getBandwidthPricesOnSolidityServlet; + @Autowired private GetEnergyPricesOnSolidityServlet getEnergyPricesOnSolidityServlet; @Autowired @@ -186,16 +185,16 @@ public void init() { @Override public void init(CommonParameter args) { - + port = Args.getInstance().getSolidityHttpPort(); } @Override public void start() { try { - server = new Server(port); + apiServer = new Server(port); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); - server.setHandler(context); + apiServer.setHandler(context); // same as FullNode context.addServlet(new ServletHolder(accountOnSolidityServlet), "/walletsolidity/getaccount"); @@ -290,6 +289,8 @@ public void start() { context.addServlet(new ServletHolder(getRewardServlet), "/walletsolidity/getReward"); context .addServlet(new ServletHolder(getBurnTrxOnSolidityServlet), "/walletsolidity/getburntrx"); + context.addServlet(new ServletHolder(getBandwidthPricesOnSolidityServlet), + "/walletsolidity/getbandwidthprices"); context.addServlet(new ServletHolder(getEnergyPricesOnSolidityServlet), "/walletsolidity/getenergyprices"); @@ -310,20 +311,11 @@ public void start() { int maxHttpConnectNumber = Args.getInstance().getMaxHttpConnectNumber(); if (maxHttpConnectNumber > 0) { - server.addBean(new ConnectionLimit(maxHttpConnectNumber, server)); + apiServer.addBean(new ConnectionLimit(maxHttpConnectNumber, apiServer)); } - server.start(); + super.start(); } catch (Exception e) { logger.debug("IOException: {}", e.getMessage()); } } - - @Override - public void stop() { - try { - server.stop(); - } catch (Exception e) { - logger.debug("Exception: {}", e.getMessage()); - } - } } diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/FullNodeJsonRpcHttpService.java b/framework/src/main/java/org/tron/core/services/jsonrpc/FullNodeJsonRpcHttpService.java index 3b6f0ac4b71..02e7fd61a08 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/FullNodeJsonRpcHttpService.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/FullNodeJsonRpcHttpService.java @@ -11,17 +11,13 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.tron.common.application.Service; +import org.tron.common.application.HttpService; import org.tron.common.parameter.CommonParameter; import org.tron.core.services.filter.HttpInterceptor; @Component @Slf4j(topic = "API") -public class FullNodeJsonRpcHttpService implements Service { - - private final int port = CommonParameter.getInstance().getJsonRpcHttpFullNodePort(); - - private Server server; +public class FullNodeJsonRpcHttpService extends HttpService { @Autowired private JsonRpcServlet jsonRpcServlet; @@ -32,21 +28,22 @@ public void init() { @Override public void init(CommonParameter args) { + port = CommonParameter.getInstance().getJsonRpcHttpFullNodePort(); } @Override public void start() { try { - server = new Server(port); + apiServer = new Server(port); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); - server.setHandler(context); + apiServer.setHandler(context); context.addServlet(new ServletHolder(jsonRpcServlet), "/jsonrpc"); int maxHttpConnectNumber = CommonParameter.getInstance().getMaxHttpConnectNumber(); if (maxHttpConnectNumber > 0) { - server.addBean(new ConnectionLimit(maxHttpConnectNumber, server)); + apiServer.addBean(new ConnectionLimit(maxHttpConnectNumber, apiServer)); } // filter @@ -56,7 +53,7 @@ public void start() { EnumSet.of(DispatcherType.REQUEST)); context.addFilter(fh, "/*", EnumSet.of(DispatcherType.REQUEST)); - server.start(); + super.start(); logger.info("JsonRpcHttpService start at {}, success", port); @@ -64,13 +61,4 @@ public void start() { logger.debug("IOException: {}", e.getMessage()); } } - - @Override - public void stop() { - try { - server.stop(); - } catch (Exception e) { - logger.debug("IOException: {}", e.getMessage()); - } - } } diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcServlet.java b/framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcServlet.java index 61d163a3e8a..878b71d86b5 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcServlet.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcServlet.java @@ -26,11 +26,7 @@ public class JsonRpcServlet extends RateLimiterServlet { private JsonRpcServer rpcServer = null; @Autowired - private NodeInfoService nodeInfoService; - @Autowired - private Wallet wallet; - @Autowired - private Manager manager; + private TronJsonRpc tronJsonRpc; @Autowired private JsonRpcInterceptor interceptor; @@ -40,10 +36,9 @@ public void init(ServletConfig config) throws ServletException { super.init(config); ClassLoader cl = Thread.currentThread().getContextClassLoader(); - TronJsonRpcImpl jsonRpcImpl = new TronJsonRpcImpl(nodeInfoService, wallet, manager); Object compositeService = ProxyUtil.createCompositeServiceProxy( cl, - new Object[] {jsonRpcImpl}, + new Object[] {tronJsonRpc}, new Class[] {TronJsonRpc.class}, true); diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index 751cd2c79bd..1461963282d 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -13,6 +13,8 @@ import com.alibaba.fastjson.JSON; import com.google.protobuf.ByteString; import com.google.protobuf.GeneratedMessageV3; +import java.io.Closeable; +import java.io.IOException; import java.math.BigInteger; import java.util.ArrayList; @@ -26,7 +28,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.regex.Matcher; import java.util.regex.Pattern; import lombok.Getter; @@ -42,6 +43,7 @@ import org.tron.api.GrpcAPI.Return.response_code; import org.tron.api.GrpcAPI.TransactionExtention; import org.tron.common.crypto.Hash; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.logsfilter.ContractEventParser; import org.tron.common.logsfilter.capsule.BlockFilterCapsule; import org.tron.common.logsfilter.capsule.LogsFilterCapsule; @@ -99,7 +101,7 @@ @Slf4j(topic = "API") @Component -public class TronJsonRpcImpl implements TronJsonRpc { +public class TronJsonRpcImpl implements TronJsonRpc, Closeable { public enum RequestSource { FULLNODE, @@ -156,16 +158,18 @@ public enum RequestSource { private final NodeInfoService nodeInfoService; private final Wallet wallet; private final Manager manager; + private final String esName = "query-section"; private final boolean allowStateRoot = CommonParameter.getInstance().getStorage() .isAllowStateRoot(); + @Autowired public TronJsonRpcImpl(@Autowired NodeInfoService nodeInfoService, @Autowired Wallet wallet, @Autowired Manager manager) { this.nodeInfoService = nodeInfoService; this.wallet = wallet; this.manager = manager; - this.sectionExecutor = Executors.newFixedThreadPool(5); + this.sectionExecutor = ExecutorServiceManager.newFixedThreadPool(esName, 5); } public static void handleBLockFilter(BlockFilterCapsule blockFilterCapsule) { @@ -1487,4 +1491,9 @@ public static Object[] getFilterResult(String filterId, Map method : service.getMethods()) { container.add(KEY_PREFIX_RPC, method.getMethodDescriptor().getFullMethodName(), - new DefaultBaseQqsAdapter("qps=1000")); + new DefaultBaseQqsAdapter(QpsStrategy.DEFAULT_QPS_PARAM)); } } diff --git a/framework/src/main/java/org/tron/core/services/ratelimiter/adapter/GlobalPreemptibleAdapter.java b/framework/src/main/java/org/tron/core/services/ratelimiter/adapter/GlobalPreemptibleAdapter.java index e13c44e6b9f..7f446d4f7e4 100644 --- a/framework/src/main/java/org/tron/core/services/ratelimiter/adapter/GlobalPreemptibleAdapter.java +++ b/framework/src/main/java/org/tron/core/services/ratelimiter/adapter/GlobalPreemptibleAdapter.java @@ -8,7 +8,6 @@ public class GlobalPreemptibleAdapter implements IPreemptibleRateLimiter { private GlobalPreemptibleStrategy strategy; public GlobalPreemptibleAdapter(String paramString) { - strategy = new GlobalPreemptibleStrategy(paramString); } diff --git a/framework/src/main/java/org/tron/core/services/ratelimiter/strategy/QpsStrategy.java b/framework/src/main/java/org/tron/core/services/ratelimiter/strategy/QpsStrategy.java index a4d56af8ba2..34f2042cf99 100644 --- a/framework/src/main/java/org/tron/core/services/ratelimiter/strategy/QpsStrategy.java +++ b/framework/src/main/java/org/tron/core/services/ratelimiter/strategy/QpsStrategy.java @@ -4,12 +4,13 @@ import java.util.HashMap; import java.util.Map; import lombok.extern.slf4j.Slf4j; +import org.tron.core.config.args.Args; @Slf4j public class QpsStrategy extends Strategy { - public static final String STRATEGY_PARAM_QPS = "qps"; - public static final Double DEFAULT_QPS = 100D; + public static final int DEFAULT_QPS = Args.getInstance().getRateLimiterGlobalApiQps(); + public static final String DEFAULT_QPS_PARAM = "qps=" + DEFAULT_QPS; private RateLimiter rateLimiter; public QpsStrategy(String paramString) { diff --git a/framework/src/main/java/org/tron/core/trie/TrieImpl.java b/framework/src/main/java/org/tron/core/trie/TrieImpl.java index ab47bbd9d22..b256cbe323d 100644 --- a/framework/src/main/java/org/tron/core/trie/TrieImpl.java +++ b/framework/src/main/java/org/tron/core/trie/TrieImpl.java @@ -7,7 +7,6 @@ import static org.tron.core.capsule.utils.RLP.EMPTY_ELEMENT_RLP; import static org.tron.core.capsule.utils.RLP.encodeList; -import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; @@ -15,13 +14,13 @@ import java.util.Map.Entry; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.Future; import org.apache.commons.lang3.text.StrBuilder; import org.bouncycastle.util.encoders.Hex; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.tron.common.crypto.Hash; +import org.tron.common.es.ExecutorServiceManager; import org.tron.core.capsule.BytesCapsule; import org.tron.core.capsule.utils.FastByteComparisons; import org.tron.core.capsule.utils.RLP; @@ -60,8 +59,7 @@ public TrieImpl(DB cache, byte[] root) { public static ExecutorService getExecutor() { if (executor == null) { - executor = Executors.newFixedThreadPool(4, - new ThreadFactoryBuilder().setNameFormat("trie-calc-thread-%d").build()); + executor = ExecutorServiceManager.newFixedThreadPool("trie-calc", 4); } return executor; } diff --git a/framework/src/main/java/org/tron/core/zen/ZksnarkInitService.java b/framework/src/main/java/org/tron/core/zen/ZksnarkInitService.java new file mode 100644 index 00000000000..8b9aafe4715 --- /dev/null +++ b/framework/src/main/java/org/tron/core/zen/ZksnarkInitService.java @@ -0,0 +1,65 @@ +package org.tron.core.zen; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import javax.annotation.PostConstruct; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FileUtils; +import org.springframework.context.annotation.DependsOn; +import org.springframework.stereotype.Component; +import org.tron.common.zksnark.JLibrustzcash; +import org.tron.common.zksnark.LibrustzcashParam; +import org.tron.core.exception.ZksnarkException; + +@Slf4j(topic = "API") +@Component +@DependsOn("fullNodeHttpApiService") +public class ZksnarkInitService { + + @PostConstruct + private void init() { + librustzcashInitZksnarkParams(); + } + + public static void librustzcashInitZksnarkParams() { + logger.info("init zk param begin"); + + if (!JLibrustzcash.isOpenZen()) { + logger.info("zen switch is off, zen will not start."); + return; + } + + String spendPath = getParamsFile("sapling-spend.params"); + String spendHash = "25fd9a0d1c1be0526c14662947ae95b758fe9f3d7fb7f55e9b4437830dcc6215a7ce3ea465" + + "914b157715b7a4d681389ea4aa84438190e185d5e4c93574d3a19a"; + + String outputPath = getParamsFile("sapling-output.params"); + String outputHash = "a1cb23b93256adce5bce2cb09cefbc96a1d16572675ceb691e9a3626ec15b5b546926ff1c" + + "536cfe3a9df07d796b32fdfc3e5d99d65567257bf286cd2858d71a6"; + + try { + JLibrustzcash.librustzcashInitZksnarkParams( + new LibrustzcashParam.InitZksnarkParams(spendPath, spendHash, outputPath, outputHash)); + } catch (ZksnarkException e) { + logger.error("librustzcashInitZksnarkParams fail!", e); + } + logger.info("init zk param done"); + } + + private static String getParamsFile(String fileName) { + InputStream in = Thread.currentThread().getContextClassLoader() + .getResourceAsStream("params" + File.separator + fileName); + File fileOut = new File(System.getProperty("java.io.tmpdir") + + File.separator + fileName + "." + System.currentTimeMillis()); + try { + FileUtils.copyToFile(in, fileOut); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + if (fileOut.exists()) { + fileOut.deleteOnExit(); + } + return fileOut.getAbsolutePath(); + } +} \ No newline at end of file diff --git a/framework/src/main/java/org/tron/core/zen/ZksnarkService.java b/framework/src/main/java/org/tron/core/zen/ZksnarkService.java deleted file mode 100644 index b9a0485a2d6..00000000000 --- a/framework/src/main/java/org/tron/core/zen/ZksnarkService.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.tron.core.zen; - -import javax.annotation.PostConstruct; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; -import org.tron.core.services.http.FullNodeHttpApiService; - -@Slf4j(topic = "API") -@Component -public class ZksnarkService { - - @PostConstruct - private void init() { - FullNodeHttpApiService.librustzcashInitZksnarkParams(); - } -} diff --git a/framework/src/main/java/org/tron/keystore/Credentials.java b/framework/src/main/java/org/tron/keystore/Credentials.java index 687bbdaa5dc..1c44b21a80c 100644 --- a/framework/src/main/java/org/tron/keystore/Credentials.java +++ b/framework/src/main/java/org/tron/keystore/Credentials.java @@ -1,5 +1,6 @@ package org.tron.keystore; +import java.util.Objects; import org.tron.common.crypto.SignInterface; import org.tron.common.crypto.sm2.SM2; import org.tron.common.utils.StringUtil; @@ -46,12 +47,11 @@ public boolean equals(Object o) { Credentials that = (Credentials) o; - if (cryptoEngine != null ? !cryptoEngine - .equals(that.cryptoEngine) : that.cryptoEngine != null) { + if (!Objects.equals(cryptoEngine, that.cryptoEngine)) { return false; } - return address != null ? address.equals(that.address) : that.address == null; + return Objects.equals(address, that.address); } @Override diff --git a/framework/src/main/java/org/tron/program/FullNode.java b/framework/src/main/java/org/tron/program/FullNode.java index 8ca16b7db83..0fd87eb5de0 100644 --- a/framework/src/main/java/org/tron/program/FullNode.java +++ b/framework/src/main/java/org/tron/program/FullNode.java @@ -30,8 +30,6 @@ public class FullNode { - public static volatile boolean shutDownSign = false; - public static void load(String path) { try { File file = new File(path); @@ -81,17 +79,15 @@ public static void main(String[] args) { context.register(DefaultConfig.class); context.refresh(); Application appT = ApplicationFactory.create(context); - shutdown(appT); + context.registerShutdownHook(); // grpc api server - if (CommonParameter.getInstance().fullNodeRpcEnable) { - RpcApiService rpcApiService = context.getBean(RpcApiService.class); - appT.addService(rpcApiService); - } + RpcApiService rpcApiService = context.getBean(RpcApiService.class); + appT.addService(rpcApiService); // http api server + FullNodeHttpApiService httpApiService = context.getBean(FullNodeHttpApiService.class); if (CommonParameter.getInstance().fullNodeHttpEnable) { - FullNodeHttpApiService httpApiService = context.getBean(FullNodeHttpApiService.class); appT.addService(httpApiService); } @@ -104,15 +100,12 @@ public static void main(String[] args) { // full node and solidity node fuse together // provide solidity rpc and http server on the full node. - if (CommonParameter.getInstance().solidityNodeRpcEnable) { - RpcApiServiceOnSolidity rpcApiServiceOnSolidity = context - .getBean(RpcApiServiceOnSolidity.class); - appT.addService(rpcApiServiceOnSolidity); - } - + RpcApiServiceOnSolidity rpcApiServiceOnSolidity = context + .getBean(RpcApiServiceOnSolidity.class); + appT.addService(rpcApiServiceOnSolidity); + HttpApiOnSolidityService httpApiOnSolidityService = context + .getBean(HttpApiOnSolidityService.class); if (CommonParameter.getInstance().solidityNodeHttpEnable) { - HttpApiOnSolidityService httpApiOnSolidityService = context - .getBean(HttpApiOnSolidityService.class); appT.addService(httpApiOnSolidityService); } @@ -124,32 +117,19 @@ public static void main(String[] args) { } // PBFT API (HTTP and GRPC) - if (CommonParameter.getInstance().PBFTNodeRpcEnable) { - RpcApiServiceOnPBFT rpcApiServiceOnPBFT = context - .getBean(RpcApiServiceOnPBFT.class); - appT.addService(rpcApiServiceOnPBFT); - } - - if (CommonParameter.getInstance().PBFTNodeHttpEnable) { - HttpApiOnPBFTService httpApiOnPBFTService = context - .getBean(HttpApiOnPBFTService.class); - appT.addService(httpApiOnPBFTService); - } - + RpcApiServiceOnPBFT rpcApiServiceOnPBFT = context + .getBean(RpcApiServiceOnPBFT.class); + appT.addService(rpcApiServiceOnPBFT); + HttpApiOnPBFTService httpApiOnPBFTService = context + .getBean(HttpApiOnPBFTService.class); + appT.addService(httpApiOnPBFTService); // JSON-RPC on PBFT if (CommonParameter.getInstance().jsonRpcHttpPBFTNodeEnable) { JsonRpcServiceOnPBFT jsonRpcServiceOnPBFT = context.getBean(JsonRpcServiceOnPBFT.class); appT.addService(jsonRpcServiceOnPBFT); } - - appT.initServices(parameter); - appT.startServices(); appT.startup(); - } - - public static void shutdown(final Application app) { - logger.info("********register application shutdown hook********"); - Runtime.getRuntime().addShutdownHook(new Thread(app::shutdown)); + appT.blockUntilShutdown(); } } diff --git a/framework/src/main/java/org/tron/program/SolidityNode.java b/framework/src/main/java/org/tron/program/SolidityNode.java index 0ca001da7bb..4cf71177803 100644 --- a/framework/src/main/java/org/tron/program/SolidityNode.java +++ b/framework/src/main/java/org/tron/program/SolidityNode.java @@ -71,7 +71,8 @@ public static void main(String[] args) { } parameter.setSolidityNode(true); - ApplicationContext context = new TronApplicationContext(DefaultConfig.class); + TronApplicationContext context = new TronApplicationContext(DefaultConfig.class); + context.registerShutdownHook(); if (parameter.isHelp()) { logger.info("Here is the help message."); @@ -81,8 +82,6 @@ public static void main(String[] args) { Metrics.init(); Application appT = ApplicationFactory.create(context); - FullNode.shutdown(appT); - RpcApiService rpcApiService = context.getBean(RpcApiService.class); appT.addService(rpcApiService); //http @@ -91,14 +90,10 @@ public static void main(String[] args) { appT.addService(httpApiService); } - appT.initServices(parameter); - appT.startServices(); - appT.startup(); - SolidityNode node = new SolidityNode(appT.getDbManager()); node.start(); - - rpcApiService.blockUntilShutdown(); + appT.startup(); + appT.blockUntilShutdown(); } private void start() { diff --git a/framework/src/main/java/org/tron/program/Version.java b/framework/src/main/java/org/tron/program/Version.java index b0837871d5d..74400376acd 100644 --- a/framework/src/main/java/org/tron/program/Version.java +++ b/framework/src/main/java/org/tron/program/Version.java @@ -2,9 +2,9 @@ public class Version { - public static final String VERSION_NAME = "GreatVoyage-v4.7.1.1-343-g959e0199de"; - public static final String VERSION_CODE = "18031"; - private static final String VERSION = "4.7.2"; + public static final String VERSION_NAME = "GreatVoyage-v4.7.2-140-g9d13f9cb69"; + public static final String VERSION_CODE = "18173"; + private static final String VERSION = "4.7.3.1"; public static String getVersion() { return VERSION; diff --git a/framework/src/main/java/org/tron/tool/litefullnode/LiteFullNodeTool.java b/framework/src/main/java/org/tron/tool/litefullnode/LiteFullNodeTool.java index 4c60e8a7e11..b5cbbb22e84 100644 --- a/framework/src/main/java/org/tron/tool/litefullnode/LiteFullNodeTool.java +++ b/framework/src/main/java/org/tron/tool/litefullnode/LiteFullNodeTool.java @@ -39,6 +39,7 @@ import org.tron.tool.litefullnode.iterator.DBIterator; @Slf4j(topic = "tool") +@Deprecated public class LiteFullNodeTool { private static final long START_TIME = System.currentTimeMillis() / 1000; @@ -556,6 +557,8 @@ private void run(Args argv) { * main. */ public static void main(String[] args) { + logger.info("LiteFullNodeTool is deprecated and it will be removed in the next major release," + + " use Toolkit.jar db lite instead, parameters are fully compatible."); Args argv = new Args(); CommonParameter.getInstance().setValidContractProtoThreadNum(1); LiteFullNodeTool tool = new LiteFullNodeTool(); diff --git a/framework/src/main/resources/config.conf b/framework/src/main/resources/config.conf index e1d25a63934..9cbfcbc9c64 100644 --- a/framework/src/main/resources/config.conf +++ b/framework/src/main/resources/config.conf @@ -16,7 +16,7 @@ storage { # block_KDB, peers, properties, recent-block, trans, # utxo, votes, witness, witness_schedule. - # Otherwise, db configs will remain defualt and data will be stored in + # Otherwise, db configs will remain default and data will be stored in # the path of "output-directory" or which is set by "-d" ("--output-directory"). # setting can impove leveldb performance .... start @@ -95,6 +95,8 @@ storage { # the estimated number of block transactions (default 1000, min 100, max 10000). # so the total number of cached transactions is 65536 * txCache.estimatedTransactions # txCache.estimatedTransactions = 1000 + # if true, transaction cache initialization will be faster. default false + # txCache.initOptimization = true # world state # stateRoot.switch = false @@ -376,23 +378,24 @@ seed.node = { "34.220.77.106:18888", "13.127.47.162:18888", "13.124.62.58:18888", - "13.229.128.108:18888", - "35.182.37.246:18888", - "34.200.228.125:18888", - "18.220.232.201:18888", - "13.57.30.186:18888", - "35.165.103.105:18888", - "18.184.238.21:18888", - "34.250.140.143:18888", - "35.176.192.130:18888", - "52.47.197.188:18888", - "52.62.210.100:18888", - "13.231.4.243:18888", - "18.231.76.29:18888", - "35.154.90.144:18888", - "13.125.210.234:18888", - "13.250.40.82:18888", - "35.183.101.48:18888" + "54.151.226.240:18888", + "35.174.93.198:18888", + "18.210.241.149:18888", + "54.177.115.127:18888", + "54.254.131.82:18888", + "18.167.171.167:18888", + "54.167.11.177:18888", + "35.74.7.196:18888", + "52.196.244.176:18888", + "54.248.129.19:18888", + "43.198.142.160:18888", + "3.0.214.7:18888", + "54.153.59.116:18888", + "54.153.94.160:18888", + "54.82.161.39:18888", + "54.179.207.68:18888", + "18.142.82.44:18888", + "18.163.230.203:18888" ] } diff --git a/framework/src/test/java/org/tron/common/BaseTest.java b/framework/src/test/java/org/tron/common/BaseTest.java index 1826dddea64..959a746a141 100644 --- a/framework/src/test/java/org/tron/common/BaseTest.java +++ b/framework/src/test/java/org/tron/common/BaseTest.java @@ -1,18 +1,21 @@ package org.tron.common; import com.google.protobuf.ByteString; -import java.io.File; +import java.io.IOException; +import javax.annotation.PostConstruct; import javax.annotation.Resource; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.ClassRule; +import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.tron.common.application.Application; import org.tron.common.crypto.ECKey; import org.tron.common.parameter.CommonParameter; -import org.tron.common.utils.FileUtil; import org.tron.common.utils.Sha256Hash; import org.tron.consensus.base.Param; import org.tron.core.ChainBaseManager; @@ -28,20 +31,38 @@ @DirtiesContext public abstract class BaseTest { - protected static String dbPath; + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); + @Resource protected Manager dbManager; @Resource protected ChainBaseManager chainBaseManager; + @Resource + protected Application appT; + + private static Application appT1; + + + @PostConstruct + private void prepare() { + appT1 = appT; + } + + public static String dbPath() { + try { + return temporaryFolder.newFolder().toString(); + } catch (IOException e) { + Assert.fail("create temp folder failed"); + } + return null; + } + @AfterClass public static void destroy() { + appT1.shutdown(); Args.clearParam(); - if (StringUtils.isNotEmpty(dbPath) && FileUtil.deleteDir(new File(dbPath))) { - logger.info("Release resources successful."); - } else { - logger.info("Release resources failure."); - } } public Protocol.Block getSignedBlock(ByteString witness, long time, byte[] privateKey) { diff --git a/framework/src/test/java/org/tron/common/ComparatorTest.java b/framework/src/test/java/org/tron/common/ComparatorTest.java index 51ae5c2d6d6..fec38624364 100644 --- a/framework/src/test/java/org/tron/common/ComparatorTest.java +++ b/framework/src/test/java/org/tron/common/ComparatorTest.java @@ -1,6 +1,7 @@ package org.tron.common; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; import java.util.Comparator; import java.util.List; import lombok.AllArgsConstructor; @@ -8,7 +9,6 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.Test; -import org.testng.collections.Lists; @Slf4j diff --git a/framework/src/test/java/org/tron/common/backup/BackupServerTest.java b/framework/src/test/java/org/tron/common/backup/BackupServerTest.java new file mode 100644 index 00000000000..34b17ec186f --- /dev/null +++ b/framework/src/test/java/org/tron/common/backup/BackupServerTest.java @@ -0,0 +1,44 @@ +package org.tron.common.backup; + +import java.util.ArrayList; +import java.util.List; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.tron.common.backup.socket.BackupServer; +import org.tron.common.parameter.CommonParameter; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; + + +public class BackupServerTest { + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + private BackupServer backupServer; + + @Before + public void setUp() throws Exception { + Args.setParam(new String[]{"-d", temporaryFolder.newFolder().toString()}, Constant.TEST_CONF); + CommonParameter.getInstance().setBackupPort(80); + List members = new ArrayList<>(); + members.add("127.0.0.2"); + CommonParameter.getInstance().setBackupMembers(members); + BackupManager backupManager = new BackupManager(); + backupManager.init(); + backupServer = new BackupServer(backupManager); + } + + @After + public void tearDown() { + backupServer.close(); + Args.clearParam(); + } + + @Test + public void test() throws InterruptedException { + backupServer.initServer(); + } +} diff --git a/framework/src/test/java/org/tron/common/backup/KeepAliveMessageTest.java b/framework/src/test/java/org/tron/common/backup/KeepAliveMessageTest.java index a93e044db03..67658331913 100644 --- a/framework/src/test/java/org/tron/common/backup/KeepAliveMessageTest.java +++ b/framework/src/test/java/org/tron/common/backup/KeepAliveMessageTest.java @@ -2,8 +2,8 @@ import static org.tron.common.backup.message.UdpMessageTypeEnum.BACKUP_KEEP_ALIVE; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.common.backup.message.KeepAliveMessage; import org.tron.protos.Discover; @@ -15,7 +15,7 @@ public void test() throws Exception { Assert.assertTrue(m1.getFlag()); Assert.assertEquals(m1.getPriority(), 10); Assert.assertEquals(m1.getType(), BACKUP_KEEP_ALIVE); - Assert.assertEquals(m1.getFrom(), null); + Assert.assertNull(m1.getFrom()); Assert.assertEquals(m1.getTimestamp(), 0); Assert.assertEquals(m1.getData().length + 1, m1.getSendData().length); @@ -27,6 +27,6 @@ public void test() throws Exception { Assert.assertEquals(m2.getPriority(), 10); Assert.assertEquals(m2.getType(), BACKUP_KEEP_ALIVE); - Assert.assertEquals(m2.getMessageId().getBytes(), m1.getMessageId().getBytes()); + Assert.assertArrayEquals(m2.getMessageId().getBytes(), m1.getMessageId().getBytes()); } } diff --git a/framework/src/test/java/org/tron/common/backup/UdpMessageTypeEnumTest.java b/framework/src/test/java/org/tron/common/backup/UdpMessageTypeEnumTest.java index e3ded4a23e5..72253fa710e 100644 --- a/framework/src/test/java/org/tron/common/backup/UdpMessageTypeEnumTest.java +++ b/framework/src/test/java/org/tron/common/backup/UdpMessageTypeEnumTest.java @@ -3,8 +3,8 @@ import static org.tron.common.backup.message.UdpMessageTypeEnum.BACKUP_KEEP_ALIVE; import static org.tron.common.backup.message.UdpMessageTypeEnum.UNKNOWN; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.common.backup.message.UdpMessageTypeEnum; public class UdpMessageTypeEnumTest { diff --git a/framework/src/test/java/org/tron/common/config/args/ArgsTest.java b/framework/src/test/java/org/tron/common/config/args/ArgsTest.java index 7ad8069db06..b95d47bfa39 100644 --- a/framework/src/test/java/org/tron/common/config/args/ArgsTest.java +++ b/framework/src/test/java/org/tron/common/config/args/ArgsTest.java @@ -1,48 +1,66 @@ package org.tron.common.config.args; -import java.io.File; +import com.beust.jcommander.JCommander; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.tron.common.parameter.RateLimiterInitialization; -import org.tron.common.utils.FileUtil; import org.tron.core.Constant; import org.tron.core.config.args.Args; - - public class ArgsTest { - private static final String dbPath = "output_arg_test"; + @Rule + public final TemporaryFolder temporaryFolder = new TemporaryFolder(); @Before - public void init() { - Args.setParam(new String[]{"--output-directory", dbPath, "--p2p-disable", "true", + public void init() throws IOException { + Args.setParam(new String[] {"--output-directory", + temporaryFolder.newFolder().toString(), "--p2p-disable", "true", "--debug"}, Constant.TEST_CONF); } @After public void destroy() { Args.clearParam(); - FileUtil.deleteDir(new File(dbPath)); } @Test public void testConfig() { + Args.logConfig(); Assert.assertEquals(Args.getInstance().getMaxTransactionPendingSize(), 2000); Assert.assertEquals(Args.getInstance().getPendingTransactionTimeout(), 60_000); - Assert.assertEquals(Args.getInstance().getNodeDiscoveryPingTimeout(), 15_000); Assert.assertEquals(Args.getInstance().getMaxFastForwardNum(), 3); Assert.assertEquals(Args.getInstance().getBlockCacheTimeout(), 60); Assert.assertEquals(Args.getInstance().isNodeDetectEnable(), false); Assert.assertFalse(Args.getInstance().isNodeEffectiveCheckEnable()); Assert.assertEquals(Args.getInstance().getRateLimiterGlobalQps(), 1000); Assert.assertEquals(Args.getInstance().getRateLimiterGlobalIpQps(), 1000); + Assert.assertEquals(Args.getInstance().getRateLimiterGlobalApiQps(), 100); Assert.assertEquals(Args.getInstance().p2pDisable, true); Assert.assertEquals(Args.getInstance().getMaxTps(), 1000); RateLimiterInitialization rateLimiter = Args.getInstance().getRateLimiterInitialization(); Assert.assertEquals(rateLimiter.getHttpMap().size(), 1); Assert.assertEquals(rateLimiter.getRpcMap().size(), 0); } + + @Test + public void testHelpMessage() { + JCommander jCommander = JCommander.newBuilder().addObject(Args.PARAMETER).build(); + Method method; + try { + method = Args.class.getDeclaredMethod("printVersion"); + method.setAccessible(true); + method.invoke(Args.class); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + Assert.fail(); + } + Args.printHelp(jCommander); + } } diff --git a/framework/src/test/java/org/tron/common/crypto/BouncyCastleTest.java b/framework/src/test/java/org/tron/common/crypto/BouncyCastleTest.java index 4e3a78461f2..880a6623a38 100644 --- a/framework/src/test/java/org/tron/common/crypto/BouncyCastleTest.java +++ b/framework/src/test/java/org/tron/common/crypto/BouncyCastleTest.java @@ -8,6 +8,7 @@ import java.util.Arrays; import org.bouncycastle.crypto.digests.SM3Digest; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Test; import org.tron.common.crypto.sm2.SM2; import org.tron.common.utils.Sha256Hash; @@ -131,4 +132,21 @@ public void testSM2SpongySignature() throws SignatureException { byte[] address = SignUtils.signatureToAddress(hash, spongySig, false); assertEquals(spongyAddress, Hex.toHexString(Arrays.copyOfRange(address, 1, 21))); } + + @Test + public void testSignToAddress() { + String messageHash = "818e0e76976123b9b78b6076cc2b5d53e61b49ff9cf78304de688a860ce7cb95"; + String base64Sign = "G1y76mVO6TRpFwp3qOiLVzHA8uFsrDiOL7hbC2uN9qTHHiLypaW4vnQkfkoUygjo5qBd" + + "+NlYQ/mAPVWKu6K00co="; + try { + SignUtils.signatureToAddress(Hex.decode(messageHash), base64Sign, Boolean.TRUE); + } catch (Exception e) { + Assert.assertTrue(e instanceof SignatureException); + } + try { + SignUtils.signatureToAddress(Hex.decode(messageHash), base64Sign, Boolean.FALSE); + } catch (Exception e) { + Assert.assertTrue(e instanceof SignatureException); + } + } } diff --git a/framework/src/test/java/org/tron/common/logsfilter/EventParserJsonTest.java b/framework/src/test/java/org/tron/common/logsfilter/EventParserJsonTest.java index 33ab712e52b..34a8e82c424 100644 --- a/framework/src/test/java/org/tron/common/logsfilter/EventParserJsonTest.java +++ b/framework/src/test/java/org/tron/common/logsfilter/EventParserJsonTest.java @@ -7,8 +7,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.common.crypto.Hash; import org.tron.common.utils.ByteArray; import org.tron.core.Wallet; diff --git a/framework/src/test/java/org/tron/common/logsfilter/EventParserTest.java b/framework/src/test/java/org/tron/common/logsfilter/EventParserTest.java index b5339156d9a..eff644b9cd9 100644 --- a/framework/src/test/java/org/tron/common/logsfilter/EventParserTest.java +++ b/framework/src/test/java/org/tron/common/logsfilter/EventParserTest.java @@ -6,8 +6,8 @@ import java.util.List; import java.util.Map; import org.bouncycastle.util.Arrays; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.common.crypto.Hash; import org.tron.common.runtime.TvmTestUtils; import org.tron.common.utils.ByteArray; @@ -76,7 +76,7 @@ public synchronized void testEventParser() { } Assert.assertEquals(LogInfoTriggerParser.getEntrySignature(entry), eventSign); - Assert.assertEquals(Hash.sha3(LogInfoTriggerParser.getEntrySignature(entry).getBytes()), + Assert.assertArrayEquals(Hash.sha3(LogInfoTriggerParser.getEntrySignature(entry).getBytes()), topicList.get(0)); Assert.assertNotNull(entry); Map dataMap = ContractEventParserAbi.parseEventData(data, topicList, entry); diff --git a/framework/src/test/java/org/tron/common/logsfilter/TransactionLogTriggerCapsuleTest.java b/framework/src/test/java/org/tron/common/logsfilter/TransactionLogTriggerCapsuleTest.java new file mode 100644 index 00000000000..76dd6e99158 --- /dev/null +++ b/framework/src/test/java/org/tron/common/logsfilter/TransactionLogTriggerCapsuleTest.java @@ -0,0 +1,178 @@ +package org.tron.common.logsfilter; + +import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION; +import static org.tron.protos.contract.Common.ResourceCode.BANDWIDTH; + +import com.google.protobuf.ByteString; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.logsfilter.capsule.TransactionLogTriggerCapsule; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.capsule.TransactionCapsule; +import org.tron.p2p.utils.ByteArray; +import org.tron.protos.Protocol; +import org.tron.protos.contract.BalanceContract; +import org.tron.protos.contract.Common; + +public class TransactionLogTriggerCapsuleTest { + + private static final String OWNER_ADDRESS = "41548794500882809695a8a687866e76d4271a1abc"; + private static final String RECEIVER_ADDRESS = "41abd4b9367799eaa3197fecb144eb71de1e049150"; + + public TransactionCapsule transactionCapsule; + public BlockCapsule blockCapsule; + + @Before + public void setup() { + blockCapsule = new BlockCapsule(1, Sha256Hash.ZERO_HASH, + System.currentTimeMillis(), Sha256Hash.ZERO_HASH.getByteString()); + } + + @Test + public void testConstructorWithUnfreezeBalanceTrxCapsule() { + BalanceContract.UnfreezeBalanceContract.Builder builder2 = + BalanceContract.UnfreezeBalanceContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setReceiverAddress(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS))); + transactionCapsule = new TransactionCapsule(builder2.build(), + Protocol.Transaction.Contract.ContractType.UnfreezeBalanceContract); + Protocol.TransactionInfo.Builder builder = Protocol.TransactionInfo.newBuilder(); + builder.setUnfreezeAmount(TRX_PRECISION + 1000); + + + TransactionLogTriggerCapsule triggerCapsule = new TransactionLogTriggerCapsule( + transactionCapsule, blockCapsule,0,0,0, + builder.build(),0); + + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress()); + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getToAddress()); + Assert.assertEquals(TRX_PRECISION + 1000, + triggerCapsule.getTransactionLogTrigger().getAssetAmount()); + } + + + @Test + public void testConstructorWithFreezeBalanceV2TrxCapsule() { + BalanceContract.FreezeBalanceV2Contract.Builder builder2 = + BalanceContract.FreezeBalanceV2Contract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setFrozenBalance(TRX_PRECISION + 100000) + .setResource(Common.ResourceCode.BANDWIDTH); + transactionCapsule = new TransactionCapsule(builder2.build(), + Protocol.Transaction.Contract.ContractType.FreezeBalanceV2Contract); + + TransactionLogTriggerCapsule triggerCapsule = + new TransactionLogTriggerCapsule(transactionCapsule, blockCapsule); + + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress()); + Assert.assertEquals("trx", triggerCapsule.getTransactionLogTrigger().getAssetName()); + Assert.assertEquals(TRX_PRECISION + 100000, + triggerCapsule.getTransactionLogTrigger().getAssetAmount()); + } + + @Test + public void testConstructorWithUnfreezeBalanceV2TrxCapsule() { + BalanceContract.UnfreezeBalanceV2Contract.Builder builder2 = + BalanceContract.UnfreezeBalanceV2Contract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setUnfreezeBalance(TRX_PRECISION + 4000) + .setResource(Common.ResourceCode.BANDWIDTH); + transactionCapsule = new TransactionCapsule(builder2.build(), + Protocol.Transaction.Contract.ContractType.UnfreezeBalanceV2Contract); + + TransactionLogTriggerCapsule triggerCapsule = + new TransactionLogTriggerCapsule(transactionCapsule, blockCapsule); + + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress()); + Assert.assertEquals("trx", triggerCapsule.getTransactionLogTrigger().getAssetName()); + Assert.assertEquals(TRX_PRECISION + 4000, + triggerCapsule.getTransactionLogTrigger().getAssetAmount()); + } + + + @Test + public void testConstructorWithWithdrawExpireTrxCapsule() { + BalanceContract.WithdrawExpireUnfreezeContract.Builder builder2 = + BalanceContract.WithdrawExpireUnfreezeContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))); + transactionCapsule = new TransactionCapsule(builder2.build(), + Protocol.Transaction.Contract.ContractType.WithdrawExpireUnfreezeContract); + + Protocol.TransactionInfo.Builder builder = Protocol.TransactionInfo.newBuilder(); + builder.setWithdrawExpireAmount(TRX_PRECISION + 1000); + + TransactionLogTriggerCapsule triggerCapsule = new TransactionLogTriggerCapsule( + transactionCapsule, blockCapsule,0,0,0, + builder.build(),0); + + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress()); + Assert.assertEquals("trx", triggerCapsule.getTransactionLogTrigger().getAssetName()); + Assert.assertEquals(TRX_PRECISION + 1000, + triggerCapsule.getTransactionLogTrigger().getAssetAmount()); + } + + + @Test + public void testConstructorWithDelegateResourceTrxCapsule() { + BalanceContract.DelegateResourceContract.Builder builder2 = + BalanceContract.DelegateResourceContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setReceiverAddress(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS))) + .setBalance(TRX_PRECISION + 2000); + transactionCapsule = new TransactionCapsule(builder2.build(), + Protocol.Transaction.Contract.ContractType.DelegateResourceContract); + + TransactionLogTriggerCapsule triggerCapsule = + new TransactionLogTriggerCapsule(transactionCapsule, blockCapsule); + + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress()); + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getToAddress()); + Assert.assertEquals("trx", triggerCapsule.getTransactionLogTrigger().getAssetName()); + Assert.assertEquals(TRX_PRECISION + 2000, + triggerCapsule.getTransactionLogTrigger().getAssetAmount()); + } + + @Test + public void testConstructorWithUnDelegateResourceTrxCapsule() { + BalanceContract.UnDelegateResourceContract.Builder builder2 = + BalanceContract.UnDelegateResourceContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setReceiverAddress(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS))) + .setBalance(TRX_PRECISION + 10000); + transactionCapsule = new TransactionCapsule(builder2.build(), + Protocol.Transaction.Contract.ContractType.UnDelegateResourceContract); + + TransactionLogTriggerCapsule triggerCapsule = + new TransactionLogTriggerCapsule(transactionCapsule, blockCapsule); + + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress()); + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getToAddress()); + Assert.assertEquals("trx", triggerCapsule.getTransactionLogTrigger().getAssetName()); + Assert.assertEquals(TRX_PRECISION + 10000, + triggerCapsule.getTransactionLogTrigger().getAssetAmount()); + } + + @Test + public void testConstructorWithCancelAllUnfreezeTrxCapsule() { + BalanceContract.CancelAllUnfreezeV2Contract.Builder builder2 = + BalanceContract.CancelAllUnfreezeV2Contract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))); + transactionCapsule = new TransactionCapsule(builder2.build(), + Protocol.Transaction.Contract.ContractType.CancelAllUnfreezeV2Contract); + + Protocol.TransactionInfo.Builder builder = Protocol.TransactionInfo.newBuilder(); + builder.clearCancelUnfreezeV2Amount().putCancelUnfreezeV2Amount( + BANDWIDTH.name(), TRX_PRECISION + 2000); + + TransactionLogTriggerCapsule triggerCapsule = new TransactionLogTriggerCapsule( + transactionCapsule, blockCapsule,0,0,0, + builder.build(),0); + + Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress()); + Assert.assertEquals(TRX_PRECISION + 2000, + triggerCapsule.getTransactionLogTrigger().getExtMap().get(BANDWIDTH.name()).longValue()); + } + +} \ No newline at end of file diff --git a/framework/src/test/java/org/tron/common/runtime/InheritanceTest.java b/framework/src/test/java/org/tron/common/runtime/InheritanceTest.java index 3c021d715cc..4b57bc880d7 100644 --- a/framework/src/test/java/org/tron/common/runtime/InheritanceTest.java +++ b/framework/src/test/java/org/tron/common/runtime/InheritanceTest.java @@ -2,9 +2,9 @@ import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.testng.Assert; import org.tron.common.BaseTest; import org.tron.core.Constant; import org.tron.core.Wallet; @@ -25,8 +25,7 @@ public class InheritanceTest extends BaseTest { private static boolean init; static { - dbPath = "output_InheritanceTest"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; } diff --git a/framework/src/test/java/org/tron/common/runtime/InternalTransactionComplexTest.java b/framework/src/test/java/org/tron/common/runtime/InternalTransactionComplexTest.java index de2c32d2731..172ef40afa7 100644 --- a/framework/src/test/java/org/tron/common/runtime/InternalTransactionComplexTest.java +++ b/framework/src/test/java/org/tron/common/runtime/InternalTransactionComplexTest.java @@ -2,9 +2,9 @@ import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.testng.Assert; import org.tron.common.BaseTest; import org.tron.common.runtime.vm.DataWord; import org.tron.core.Constant; @@ -27,8 +27,7 @@ public class InternalTransactionComplexTest extends BaseTest { private static boolean init; static { - dbPath = "output_InternalTransactionComplexTest"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug", "--support-constant"}, + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug", "--support-constant"}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; } diff --git a/framework/src/test/java/org/tron/common/runtime/ProgramResultTest.java b/framework/src/test/java/org/tron/common/runtime/ProgramResultTest.java index 393a68a0794..a2e53dd8711 100644 --- a/framework/src/test/java/org/tron/common/runtime/ProgramResultTest.java +++ b/framework/src/test/java/org/tron/common/runtime/ProgramResultTest.java @@ -9,9 +9,9 @@ import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.testng.Assert; import org.tron.common.BaseTest; import org.tron.common.runtime.vm.DataWord; import org.tron.core.Constant; @@ -44,8 +44,7 @@ public class ProgramResultTest extends BaseTest { private static boolean init; static { - dbPath = "output_InternalTransactionComplexTest"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug", "--support-constant"}, + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug", "--support-constant"}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; TRANSFER_TO = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; @@ -281,30 +280,31 @@ public void successAndFailResultTest() List internalTransactionsList = runtime.getResult() .getInternalTransactions(); Assert.assertEquals(internalTransactionsList.get(0).getValue(), 10); - Assert.assertEquals(internalTransactionsList.get(0).getSender(), aContract); - Assert.assertEquals( + Assert.assertArrayEquals(internalTransactionsList.get(0).getSender(), aContract); + Assert.assertArrayEquals( new DataWord(internalTransactionsList.get(0).getTransferToAddress()).getLast20Bytes(), new DataWord(bContract).getLast20Bytes()); Assert.assertEquals(internalTransactionsList.get(0).getNote(), "create"); Assert.assertFalse(internalTransactionsList.get(0).isRejected()); Assert.assertEquals(internalTransactionsList.get(1).getValue(), 5); - Assert.assertEquals(internalTransactionsList.get(1).getSender(), aContract); - Assert.assertEquals( + Assert.assertArrayEquals(internalTransactionsList.get(1).getSender(), aContract); + Assert.assertArrayEquals( new DataWord(internalTransactionsList.get(1).getTransferToAddress()).getLast20Bytes(), new DataWord(bContract).getLast20Bytes()); Assert.assertEquals(internalTransactionsList.get(1).getNote(), "call"); Assert.assertFalse(internalTransactionsList.get(1).isRejected()); Assert.assertEquals(internalTransactionsList.get(2).getValue(), 0); - Assert.assertEquals(internalTransactionsList.get(2).getSender(), aContract); - Assert.assertEquals( + Assert.assertArrayEquals(internalTransactionsList.get(2).getSender(), aContract); + Assert.assertArrayEquals( new DataWord(internalTransactionsList.get(2).getTransferToAddress()).getLast20Bytes(), new DataWord(bContract).getLast20Bytes()); Assert.assertEquals(internalTransactionsList.get(2).getNote(), "call"); Assert.assertFalse(internalTransactionsList.get(2).isRejected()); Assert.assertEquals(internalTransactionsList.get(3).getValue(), 1); - Assert.assertEquals(new DataWord(internalTransactionsList.get(3).getSender()).getLast20Bytes(), + Assert.assertArrayEquals( + new DataWord(internalTransactionsList.get(3).getSender()).getLast20Bytes(), new DataWord(bContract).getLast20Bytes()); - Assert.assertEquals(internalTransactionsList.get(3).getTransferToAddress(), cContract); + Assert.assertArrayEquals(internalTransactionsList.get(3).getTransferToAddress(), cContract); Assert.assertEquals(internalTransactionsList.get(3).getNote(), "call"); Assert.assertFalse(internalTransactionsList.get(3).isRejected()); checkTransactionInfo(traceSuccess, trx1, null, internalTransactionsList); @@ -326,31 +326,31 @@ public void successAndFailResultTest() List internalTransactionsListFail = runtime.getResult() .getInternalTransactions(); Assert.assertEquals(internalTransactionsListFail.get(0).getValue(), 10); - Assert.assertEquals(internalTransactionsListFail.get(0).getSender(), aContract); - Assert.assertEquals( + Assert.assertArrayEquals(internalTransactionsListFail.get(0).getSender(), aContract); + Assert.assertArrayEquals( new DataWord(internalTransactionsListFail.get(0).getTransferToAddress()).getLast20Bytes(), new DataWord(bContract2).getLast20Bytes()); Assert.assertEquals(internalTransactionsListFail.get(0).getNote(), "create"); Assert.assertTrue(internalTransactionsListFail.get(0).isRejected()); Assert.assertEquals(internalTransactionsListFail.get(1).getValue(), 5); - Assert.assertEquals(internalTransactionsListFail.get(1).getSender(), aContract); - Assert.assertEquals( + Assert.assertArrayEquals(internalTransactionsListFail.get(1).getSender(), aContract); + Assert.assertArrayEquals( new DataWord(internalTransactionsListFail.get(1).getTransferToAddress()).getLast20Bytes(), new DataWord(bContract2).getLast20Bytes()); Assert.assertEquals(internalTransactionsListFail.get(1).getNote(), "call"); Assert.assertTrue(internalTransactionsListFail.get(1).isRejected()); Assert.assertEquals(internalTransactionsListFail.get(2).getValue(), 0); - Assert.assertEquals(internalTransactionsListFail.get(2).getSender(), aContract); - Assert.assertEquals( + Assert.assertArrayEquals(internalTransactionsListFail.get(2).getSender(), aContract); + Assert.assertArrayEquals( new DataWord(internalTransactionsListFail.get(2).getTransferToAddress()).getLast20Bytes(), new DataWord(bContract2).getLast20Bytes()); Assert.assertEquals(internalTransactionsListFail.get(2).getNote(), "call"); Assert.assertTrue(internalTransactionsListFail.get(2).isRejected()); Assert.assertEquals(internalTransactionsListFail.get(3).getValue(), 1); - Assert.assertEquals( + Assert.assertArrayEquals( new DataWord(internalTransactionsListFail.get(3).getSender()).getLast20Bytes(), new DataWord(bContract2).getLast20Bytes()); - Assert.assertEquals(internalTransactionsListFail.get(3).getTransferToAddress(), cContract); + Assert.assertArrayEquals(internalTransactionsListFail.get(3).getTransferToAddress(), cContract); Assert.assertEquals(internalTransactionsListFail.get(3).getNote(), "call"); Assert.assertTrue(internalTransactionsListFail.get(3).isRejected()); checkTransactionInfo(traceFailed, trx2, null, internalTransactionsListFail); @@ -501,9 +501,10 @@ public void suicideResultTest() .assertEquals(dbManager.getAccountStore().get(Hex.decode(TRANSFER_TO)).getBalance(), 1000); Assert.assertNull(dbManager.getAccountStore().get(suicideContract)); Assert.assertEquals(internalTransactionsList.get(0).getValue(), 1000); - Assert.assertEquals(new DataWord(internalTransactionsList.get(0).getSender()).getLast20Bytes(), + Assert.assertArrayEquals(new DataWord( + internalTransactionsList.get(0).getSender()).getLast20Bytes(), new DataWord(suicideContract).getLast20Bytes()); - Assert.assertEquals(internalTransactionsList.get(0).getTransferToAddress(), + Assert.assertArrayEquals(internalTransactionsList.get(0).getTransferToAddress(), Hex.decode(TRANSFER_TO)); Assert.assertEquals(internalTransactionsList.get(0).getNote(), "suicide"); Assert.assertFalse(internalTransactionsList.get(0).isRejected()); @@ -546,15 +547,16 @@ public void checkTransactionInfo(TransactionTrace trace, Transaction trx, BlockC for (int i = 0; i < internalTransactionListFromProtocol.size(); i++) { Assert.assertEquals(internalTransactionListFromProtocol.get(i).getRejected(), internalTransactionsList.get(i).isRejected()); - Assert - .assertEquals(internalTransactionListFromProtocol.get(i).getCallerAddress().toByteArray(), + Assert.assertArrayEquals( + internalTransactionListFromProtocol.get(i).getCallerAddress().toByteArray(), internalTransactionsList.get(i).getSender()); - Assert.assertEquals(internalTransactionListFromProtocol.get(i).getHash().toByteArray(), + Assert.assertArrayEquals( + internalTransactionListFromProtocol.get(i).getHash().toByteArray(), internalTransactionsList.get(i).getHash()); Assert.assertEquals( new String(internalTransactionListFromProtocol.get(i).getNote().toByteArray()), internalTransactionsList.get(i).getNote()); - Assert.assertEquals( + Assert.assertArrayEquals( internalTransactionListFromProtocol.get(i).getTransferToAddress().toByteArray(), internalTransactionsList.get(i).getTransferToAddress()); List callValueInfoListFromProtocol = diff --git a/framework/src/test/java/org/tron/common/runtime/RuntimeImplTest.java b/framework/src/test/java/org/tron/common/runtime/RuntimeImplTest.java index 04b08d3a58d..0b7721a325d 100644 --- a/framework/src/test/java/org/tron/common/runtime/RuntimeImplTest.java +++ b/framework/src/test/java/org/tron/common/runtime/RuntimeImplTest.java @@ -5,9 +5,9 @@ import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.testng.Assert; import org.tron.common.BaseTest; import org.tron.core.Constant; import org.tron.core.Wallet; @@ -40,8 +40,7 @@ public class RuntimeImplTest extends BaseTest { private final long creatorTotalBalance = 3_000_000_000L; static { - dbPath = "output_RuntimeImplTest"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); callerAddress = Hex .decode(Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"); creatorAddress = Hex diff --git a/framework/src/test/java/org/tron/common/runtime/RuntimeTransferComplexTest.java b/framework/src/test/java/org/tron/common/runtime/RuntimeTransferComplexTest.java index b40b927c5ec..c9d61db9270 100644 --- a/framework/src/test/java/org/tron/common/runtime/RuntimeTransferComplexTest.java +++ b/framework/src/test/java/org/tron/common/runtime/RuntimeTransferComplexTest.java @@ -4,9 +4,9 @@ import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.testng.Assert; import org.tron.common.BaseTest; import org.tron.common.utils.WalletUtil; import org.tron.common.utils.client.utils.DataWord; @@ -32,8 +32,7 @@ public class RuntimeTransferComplexTest extends BaseTest { private static boolean init; static { - dbPath = "output_RuntimeTransferComplexTest"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; TRANSFER_TO = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/AllowTvmCompatibleEvmTest.java b/framework/src/test/java/org/tron/common/runtime/vm/AllowTvmCompatibleEvmTest.java index ffc3a44e730..ded7bb01af3 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/AllowTvmCompatibleEvmTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/AllowTvmCompatibleEvmTest.java @@ -7,9 +7,9 @@ import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.testng.Assert; import org.tron.common.runtime.TVMTestResult; import org.tron.common.runtime.TvmTestUtils; import org.tron.common.utils.WalletUtil; @@ -87,7 +87,7 @@ public void testEthRipemd160() throws ContractExeException, ReceiptCheckErrExcep factoryAddress, Hex.decode(hexInput), 0, feeLimit, manager, null); byte[] returnValue = result.getRuntime().getResult().getHReturn(); Assert.assertNull(result.getRuntime().getRuntimeError()); - Assert.assertEquals(returnValue, + Assert.assertArrayEquals(returnValue, hexToBytes("a76d892cc3522eab763529dfc84b12c080ee1" + "fe8000000000000000000000000")); } @@ -212,7 +212,7 @@ public void testBlake2f() throws ContractExeException, ReceiptCheckErrException, factoryAddress, Hex.decode(hexInput), 0, feeLimit, manager, null); byte[] returnValue = result.getRuntime().getResult().getHReturn(); Assert.assertNull(result.getRuntime().getRuntimeError()); - Assert.assertEquals(returnValue, + Assert.assertArrayEquals(returnValue, hexToBytes("ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87" + "c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923")); } @@ -258,7 +258,7 @@ public void testGasPrice() throws ContractExeException, ReceiptCheckErrException factoryAddress, Hex.decode(hexInput), 0, feeLimit, manager, null); byte[] returnValue = result.getRuntime().getResult().getHReturn(); Assert.assertNull(result.getRuntime().getRuntimeError()); - Assert.assertEquals(returnValue, + Assert.assertArrayEquals(returnValue, longTo32Bytes(manager.getDynamicPropertiesStore().getEnergyFee())); } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/AllowTvmLondonTest.java b/framework/src/test/java/org/tron/common/runtime/vm/AllowTvmLondonTest.java index 864a583050b..e93eca39092 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/AllowTvmLondonTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/AllowTvmLondonTest.java @@ -5,8 +5,8 @@ import java.util.Collections; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.common.runtime.TVMTestResult; import org.tron.common.runtime.TvmTestUtils; import org.tron.common.utils.WalletUtil; @@ -74,7 +74,7 @@ public void testBaseFee() throws ContractExeException, ReceiptCheckErrException, factoryAddress, Hex.decode(hexInput), 0, feeLimit, manager, null); byte[] returnValue = result.getRuntime().getResult().getHReturn(); Assert.assertNull(result.getRuntime().getRuntimeError()); - Assert.assertEquals(returnValue, + Assert.assertArrayEquals(returnValue, longTo32Bytes(manager.getDynamicPropertiesStore().getEnergyFee())); } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeOutOfTimeTest.java b/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeOutOfTimeTest.java index a0c87da01c6..afac8cd7d22 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeOutOfTimeTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeOutOfTimeTest.java @@ -67,10 +67,9 @@ public class BandWidthRuntimeOutOfTimeTest extends BaseTest { private static boolean init; static { - dbPath = "output_bandwidth_runtime_out_of_time_test"; Args.setParam( new String[]{ - "--output-directory", dbPath, + "--output-directory", dbPath(), "--storage-db-directory", dbDirectory, "--storage-index-directory", indexDirectory, "-w", diff --git a/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeOutOfTimeWithCheckTest.java b/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeOutOfTimeWithCheckTest.java index 37167988f34..7203388f815 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeOutOfTimeWithCheckTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeOutOfTimeWithCheckTest.java @@ -68,10 +68,9 @@ public class BandWidthRuntimeOutOfTimeWithCheckTest extends BaseTest { private static boolean init; static { - dbPath = "output_bandwidth_runtime_out_of_time_with_check_test"; Args.setParam( new String[]{ - "--output-directory", dbPath, + "--output-directory", dbPath(), "--storage-db-directory", dbDirectory, "--storage-index-directory", indexDirectory, "-w", diff --git a/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeTest.java b/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeTest.java index 20e8e11535a..40c5908c2dd 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeTest.java @@ -59,10 +59,9 @@ public class BandWidthRuntimeTest extends BaseTest { @BeforeClass public static void init() { - dbPath = "output_bandwidth_runtime_test"; Args.setParam( new String[]{ - "--output-directory", dbPath, + "--output-directory", dbPath(), "--storage-db-directory", dbDirectory, "--storage-index-directory", indexDirectory, "-w" diff --git a/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeWithCheckTest.java b/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeWithCheckTest.java index 0e7f79eb42f..e359e7eab1a 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeWithCheckTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/BandWidthRuntimeWithCheckTest.java @@ -70,10 +70,9 @@ public class BandWidthRuntimeWithCheckTest extends BaseTest { private static boolean init; static { - dbPath = "output_bandwidth_runtime_with_check_test"; Args.setParam( new String[]{ - "--output-directory", dbPath, + "--output-directory", dbPath(), "--storage-db-directory", dbDirectory, "--storage-index-directory", indexDirectory, "-w" diff --git a/framework/src/test/java/org/tron/common/runtime/vm/BatchSendTest.java b/framework/src/test/java/org/tron/common/runtime/vm/BatchSendTest.java index a5c397e54c2..5ada5612fce 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/BatchSendTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/BatchSendTest.java @@ -39,8 +39,7 @@ public class BatchSendTest extends BaseTest { private static final AccountCapsule ownerCapsule; static { - dbPath = "output_BatchSendTest"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; TRANSFER_TO = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; diff --git a/framework/src/test/java/org/tron/common/runtime/vm/BatchValidateSignContractTest.java b/framework/src/test/java/org/tron/common/runtime/vm/BatchValidateSignContractTest.java index 524c40ee8fb..d094f1a3d05 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/BatchValidateSignContractTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/BatchValidateSignContractTest.java @@ -6,8 +6,8 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.tuple.Pair; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.common.crypto.ECKey; import org.tron.common.crypto.Hash; import org.tron.common.utils.StringUtil; @@ -73,7 +73,7 @@ public void staticCallTest() { .add(StringUtil.encode58Check(TransactionTrace.convertToTronAddress(new byte[20]))); ret = validateMultiSign(hash, signatures, addresses); Assert.assertEquals(ret.getValue().length, 32); - Assert.assertEquals(ret.getValue(), new byte[32]); + Assert.assertArrayEquals(ret.getValue(), new byte[32]); System.gc(); // force triggering full gc to avoid timeout for next test } @@ -119,7 +119,7 @@ public void correctionTest() { List incorrectSigns = new ArrayList<>(signatures); incorrectSigns.remove(incorrectSigns.size() - 1); ret = validateMultiSign(hash, incorrectSigns, addresses); - Assert.assertEquals(ret.getValue(), DataWord.ZERO().getData()); + Assert.assertArrayEquals(ret.getValue(), DataWord.ZERO().getData()); System.gc(); // force triggering full gc to avoid timeout for next test } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/ChargeTest.java b/framework/src/test/java/org/tron/common/runtime/vm/ChargeTest.java index 600b81750da..c158b2e400f 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/ChargeTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/ChargeTest.java @@ -2,9 +2,9 @@ import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.testng.Assert; import org.tron.common.BaseTest; import org.tron.common.runtime.TVMTestResult; import org.tron.common.runtime.TvmTestUtils; @@ -27,8 +27,7 @@ public class ChargeTest extends BaseTest { private long totalBalance = 100_000_000_000_000L; static { - dbPath = "output_ChargeTest"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/Create2Test.java b/framework/src/test/java/org/tron/common/runtime/vm/Create2Test.java index 90bd07c605a..01dc69be280 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/Create2Test.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/Create2Test.java @@ -8,8 +8,8 @@ import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.common.runtime.TVMTestResult; import org.tron.common.runtime.TvmTestUtils; import org.tron.common.runtime.VmStateTestUtil; @@ -182,7 +182,7 @@ public void testCreate2() byte[] expectedContract = generateContractAddress2(address, new DataWord(salt).getData(), Hex.decode(testCode)); // check deployed contract - Assert.assertEquals(actualContract, expectedContract); + Assert.assertArrayEquals(actualContract, expectedContract); // trigger deployed contract String methodToTrigger = "plusOne()"; @@ -193,7 +193,8 @@ public void testCreate2() .triggerContractAndReturnTvmTestResult(Hex.decode(OWNER_ADDRESS), actualContract, Hex.decode(hexInput), 0, fee, manager, null); Assert.assertNull(result.getRuntime().getRuntimeError()); - Assert.assertEquals(result.getRuntime().getResult().getHReturn(), new DataWord(i).getData()); + Assert.assertArrayEquals(result.getRuntime().getResult().getHReturn(), + new DataWord(i).getData()); } testJsonRpc(actualContract, loop); } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/CreateContractSuicideTest.java b/framework/src/test/java/org/tron/common/runtime/vm/CreateContractSuicideTest.java index 9fe5ac1eed1..917c3dec030 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/CreateContractSuicideTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/CreateContractSuicideTest.java @@ -3,8 +3,8 @@ import java.util.Arrays; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.common.runtime.Runtime; import org.tron.common.runtime.TvmTestUtils; import org.tron.core.config.Parameter.ForkBlockVersionEnum; diff --git a/framework/src/test/java/org/tron/common/runtime/vm/EnergyWhenAssertStyleTest.java b/framework/src/test/java/org/tron/common/runtime/vm/EnergyWhenAssertStyleTest.java index aec3f2322a6..8b985d4bb1d 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/EnergyWhenAssertStyleTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/EnergyWhenAssertStyleTest.java @@ -2,9 +2,9 @@ import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.testng.Assert; import org.tron.common.BaseTest; import org.tron.common.runtime.TVMTestResult; import org.tron.common.runtime.TvmTestUtils; @@ -32,8 +32,7 @@ public class EnergyWhenAssertStyleTest extends BaseTest { private long totalBalance = 30_000_000_000_000L; static { - dbPath = "output_EnergyWhenAssertStyleTest"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/EnergyWhenRequireStyleTest.java b/framework/src/test/java/org/tron/common/runtime/vm/EnergyWhenRequireStyleTest.java index 2356a649e82..19231b225f1 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/EnergyWhenRequireStyleTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/EnergyWhenRequireStyleTest.java @@ -2,9 +2,9 @@ import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.testng.Assert; import org.tron.common.BaseTest; import org.tron.common.runtime.TVMTestResult; import org.tron.common.runtime.TvmTestUtils; @@ -28,8 +28,7 @@ public class EnergyWhenRequireStyleTest extends BaseTest { private long totalBalance = 30_000_000_000_000L; static { - dbPath = "output_EnergyWhenRequireStyleTest"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/EnergyWhenSendAndTransferTest.java b/framework/src/test/java/org/tron/common/runtime/vm/EnergyWhenSendAndTransferTest.java index 40af27612df..009b332324b 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/EnergyWhenSendAndTransferTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/EnergyWhenSendAndTransferTest.java @@ -2,9 +2,9 @@ import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.testng.Assert; import org.tron.common.BaseTest; import org.tron.common.runtime.TVMTestResult; import org.tron.common.runtime.TvmTestUtils; @@ -27,8 +27,7 @@ public class EnergyWhenSendAndTransferTest extends BaseTest { private long totalBalance = 30_000_000_000_000L; static { - dbPath = "output_EnergyWhenSendAndTransferTest"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/EnergyWhenTimeoutStyleTest.java b/framework/src/test/java/org/tron/common/runtime/vm/EnergyWhenTimeoutStyleTest.java index c2dc1d524ad..2559b43a020 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/EnergyWhenTimeoutStyleTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/EnergyWhenTimeoutStyleTest.java @@ -2,9 +2,9 @@ import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.testng.Assert; import org.tron.common.BaseTest; import org.tron.common.runtime.TVMTestResult; import org.tron.common.runtime.TvmTestUtils; @@ -29,8 +29,7 @@ public class EnergyWhenTimeoutStyleTest extends BaseTest { private long totalBalance = 30_000_000_000_000L; static { - dbPath = "output_CPUTimeTest"; - Args.setParam(new String[]{"--output-directory", dbPath}, + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/ExtCodeHashTest.java b/framework/src/test/java/org/tron/common/runtime/vm/ExtCodeHashTest.java index d8c8a23a8ee..d2ad875e4b0 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/ExtCodeHashTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/ExtCodeHashTest.java @@ -4,8 +4,8 @@ import java.util.Arrays; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.common.runtime.TVMTestResult; import org.tron.common.runtime.TvmTestUtils; import org.tron.common.utils.WalletUtil; diff --git a/framework/src/test/java/org/tron/common/runtime/vm/FreezeTest.java b/framework/src/test/java/org/tron/common/runtime/vm/FreezeTest.java index 600000e6535..e1459637e19 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/FreezeTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/FreezeTest.java @@ -7,7 +7,6 @@ import static org.tron.protos.contract.Common.ResourceCode.ENERGY; import com.google.protobuf.ByteString; -import java.io.File; import java.util.Arrays; import java.util.function.Consumer; import lombok.extern.slf4j.Slf4j; @@ -15,7 +14,9 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.tron.common.application.TronApplicationContext; import org.tron.common.runtime.Runtime; import org.tron.common.runtime.RuntimeImpl; @@ -23,7 +24,6 @@ import org.tron.common.runtime.TvmTestUtils; import org.tron.common.utils.Commons; import org.tron.common.utils.FastByteComparisons; -import org.tron.common.utils.FileUtil; import org.tron.common.utils.StringUtil; import org.tron.common.utils.WalletUtil; import org.tron.common.utils.client.utils.AbiUtil; @@ -121,7 +121,8 @@ public class FreezeTest { private static final String userCStr = "27juXSbMvL6pb8VgmKRgW6ByCfw5RqZjUuo"; private static final byte[] userC = Commons.decode58Check(userCStr); - private static String dbPath; + @Rule + public final TemporaryFolder temporaryFolder = new TemporaryFolder(); private static TronApplicationContext context; private static Manager manager; private static byte[] owner; @@ -129,8 +130,8 @@ public class FreezeTest { @Before public void init() throws Exception { - dbPath = "output_" + FreezeTest.class.getName(); - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", + temporaryFolder.newFolder().toString(), "--debug"}, Constant.TEST_CONF); context = new TronApplicationContext(DefaultConfig.class); manager = context.getBean(Manager.class); owner = Hex.decode(Wallet.getAddressPreFixString() @@ -1042,10 +1043,5 @@ public void destroy() { VMConfig.initVmHardFork(false); Args.clearParam(); context.destroy(); - if (FileUtil.deleteDir(new File(dbPath))) { - logger.info("Release resources successful."); - } else { - logger.error("Release resources failure."); - } } } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/FreezeV2Test.java b/framework/src/test/java/org/tron/common/runtime/vm/FreezeV2Test.java index 49ea2a390c8..25856c9ae51 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/FreezeV2Test.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/FreezeV2Test.java @@ -9,7 +9,6 @@ import static org.tron.protos.contract.Common.ResourceCode.ENERGY; import com.google.protobuf.ByteString; -import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -19,7 +18,9 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.tron.common.application.TronApplicationContext; import org.tron.common.runtime.Runtime; import org.tron.common.runtime.RuntimeImpl; @@ -28,7 +29,6 @@ import org.tron.common.runtime.VmStateTestUtil; import org.tron.common.utils.Commons; import org.tron.common.utils.FastByteComparisons; -import org.tron.common.utils.FileUtil; import org.tron.common.utils.StringUtil; import org.tron.common.utils.WalletUtil; import org.tron.common.utils.client.utils.AbiUtil; @@ -158,7 +158,8 @@ public class FreezeV2Test { private static final String userCStr = "27juXSbMvL6pb8VgmKRgW6ByCfw5RqZjUuo"; private static final byte[] userC = Commons.decode58Check(userCStr); - private static String dbPath; + @Rule + public final TemporaryFolder temporaryFolder = new TemporaryFolder(); private static TronApplicationContext context; private static Manager manager; private static byte[] owner; @@ -168,8 +169,8 @@ public class FreezeV2Test { @Before public void init() throws Exception { - dbPath = "output_" + FreezeV2Test.class.getName(); - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", + temporaryFolder.newFolder().toString(), "--debug"}, Constant.TEST_CONF); context = new TronApplicationContext(DefaultConfig.class); manager = context.getBean(Manager.class); chainBaseManager = context.getBean(ChainBaseManager.class); @@ -851,20 +852,20 @@ private TVMTestResult unDelegateResource( acquiredBalance = res == 0 ? oldReceiver.getAcquiredDelegatedFrozenV2BalanceForBandwidth() : oldReceiver.getAcquiredDelegatedFrozenV2BalanceForEnergy(); + long unDelegateMaxUsage; if (res == 0) { - long unDelegateMaxUsage = (long) (amount / TRX_PRECISION + unDelegateMaxUsage = (long) (amount / TRX_PRECISION * ((double) (dynamicStore.getTotalNetLimit()) / dynamicStore.getTotalNetWeight())); transferUsage = (long) (oldReceiver.getNetUsage() * ((double) (amount) / oldReceiver.getAllFrozenBalanceForBandwidth())); - transferUsage = Math.min(unDelegateMaxUsage, transferUsage); } else { - long unDelegateMaxUsage = (long) (amount / TRX_PRECISION + unDelegateMaxUsage = (long) (amount / TRX_PRECISION * ((double) (dynamicStore.getTotalEnergyCurrentLimit()) / dynamicStore.getTotalEnergyWeight())); transferUsage = (long) (oldReceiver.getEnergyUsage() * ((double) (amount) / oldReceiver.getAllFrozenBalanceForEnergy())); - transferUsage = Math.min(unDelegateMaxUsage, transferUsage); } + transferUsage = Math.min(unDelegateMaxUsage, transferUsage); } DelegatedResourceStore delegatedResourceStore = manager.getDelegatedResourceStore(); @@ -1009,28 +1010,20 @@ private TVMTestResult suicide(byte[] callerAddr, byte[] contractAddr, byte[] inh newInheritor.getFrozenBalance() - oldInheritorFrozenBalance); if (oldInheritor != null) { if (oldContract.getNetUsage() > 0) { - long expectedNewNetUsage = - bandwidthProcessor.unDelegateIncrease( - oldInheritor, - oldContract, - oldContract.getNetUsage(), - Common.ResourceCode.BANDWIDTH, - now); + bandwidthProcessor.unDelegateIncrease(oldInheritor, oldContract, oldContract.getNetUsage(), + Common.ResourceCode.BANDWIDTH, now); Assert.assertEquals( - expectedNewNetUsage, newInheritor.getNetUsage() - oldInheritorBandwidthUsage); - Assert.assertEquals(chainBaseManager.getHeadSlot(), newInheritor.getLatestConsumeTime()); + oldInheritor.getNetUsage(), newInheritor.getNetUsage() - oldInheritorBandwidthUsage); + Assert.assertEquals( + ChainBaseManager.getInstance().getHeadSlot(), newInheritor.getLatestConsumeTime()); } if (oldContract.getEnergyUsage() > 0) { - long expectedNewEnergyUsage = - energyProcessor.unDelegateIncrease( - oldInheritor, - oldContract, - oldContract.getEnergyUsage(), - Common.ResourceCode.ENERGY, - now); + energyProcessor.unDelegateIncrease(oldInheritor, oldContract, + oldContract.getEnergyUsage(), Common.ResourceCode.ENERGY, now); Assert.assertEquals( - expectedNewEnergyUsage, newInheritor.getEnergyUsage() - oldInheritorEnergyUsage); - Assert.assertEquals(chainBaseManager.getHeadSlot(), + oldInheritor.getEnergyUsage(), newInheritor.getEnergyUsage() - oldInheritorEnergyUsage); + Assert.assertEquals( + ChainBaseManager.getInstance().getHeadSlot(), newInheritor.getLatestConsumeTimeForEnergy()); } } @@ -1059,10 +1052,5 @@ public void destroy() { VMConfig.initVmHardFork(false); Args.clearParam(); context.destroy(); - if (FileUtil.deleteDir(new File(dbPath))) { - logger.info("Release resources successful."); - } else { - logger.error("Release resources failure."); - } } } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/InternalTransactionCallTest.java b/framework/src/test/java/org/tron/common/runtime/vm/InternalTransactionCallTest.java index 18a279f8292..75a8f32186c 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/InternalTransactionCallTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/InternalTransactionCallTest.java @@ -1,18 +1,19 @@ package org.tron.common.runtime.vm; -import java.io.File; +import java.io.IOException; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; import org.junit.After; +import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; -import org.testng.Assert; +import org.junit.rules.TemporaryFolder; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.application.TronApplicationContext; import org.tron.common.runtime.Runtime; import org.tron.common.runtime.TvmTestUtils; -import org.tron.common.utils.FileUtil; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.config.DefaultConfig; @@ -33,7 +34,8 @@ public class InternalTransactionCallTest { private Manager dbManager; private TronApplicationContext context; private RepositoryImpl repository; - private String dbPath = "output_InternalTransactionCallTest"; + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); private String OWNER_ADDRESS; private Application AppT; @@ -41,9 +43,10 @@ public class InternalTransactionCallTest { * Init data. */ @Before - public void init() { + public void init() throws IOException { Args.clearParam(); - Args.setParam(new String[]{"--output-directory", dbPath, "--support-constant", "--debug"}, + Args.setParam(new String[]{"--output-directory", + temporaryFolder.newFolder().toString(), "--support-constant", "--debug"}, Constant.TEST_CONF); context = new TronApplicationContext(DefaultConfig.class); @@ -356,11 +359,5 @@ public byte[] deployBContractAndGetItsAddress() public void destroy() { context.destroy(); Args.clearParam(); - if (FileUtil.deleteDir(new File(dbPath))) { - logger.info("Release resources successful."); - } else { - logger.warn("Release resources failure."); - } - } } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/IsContractTest.java b/framework/src/test/java/org/tron/common/runtime/vm/IsContractTest.java index 540a30a240f..94561e856f1 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/IsContractTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/IsContractTest.java @@ -3,8 +3,8 @@ import java.util.Arrays; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.common.runtime.TVMTestResult; import org.tron.common.runtime.TvmTestUtils; import org.tron.common.utils.StringUtil; diff --git a/framework/src/test/java/org/tron/common/runtime/vm/IsSRCandidateTest.java b/framework/src/test/java/org/tron/common/runtime/vm/IsSRCandidateTest.java index 3cec683ed63..f6116dbe97d 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/IsSRCandidateTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/IsSRCandidateTest.java @@ -3,8 +3,8 @@ import java.util.Collections; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.common.runtime.InternalTransaction; import org.tron.common.runtime.TvmTestUtils; import org.tron.common.utils.StringUtil; diff --git a/framework/src/test/java/org/tron/common/runtime/vm/IstanbulTest.java b/framework/src/test/java/org/tron/common/runtime/vm/IstanbulTest.java index 85fb918376d..1613eab53cd 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/IstanbulTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/IstanbulTest.java @@ -1,8 +1,8 @@ package org.tron.common.runtime.vm; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.common.runtime.TVMTestResult; import org.tron.common.runtime.TvmTestUtils; import org.tron.common.utils.WalletUtil; diff --git a/framework/src/test/java/org/tron/common/runtime/vm/MemoryTest.java b/framework/src/test/java/org/tron/common/runtime/vm/MemoryTest.java index 0966d86710a..b6e9cfe109c 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/MemoryTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/MemoryTest.java @@ -25,8 +25,8 @@ import java.util.Arrays; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.core.vm.program.Memory; @Slf4j diff --git a/framework/src/test/java/org/tron/common/runtime/vm/OperationsTest.java b/framework/src/test/java/org/tron/common/runtime/vm/OperationsTest.java index 965c7e0ce1a..be031d7c00b 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/OperationsTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/OperationsTest.java @@ -2,7 +2,6 @@ import static org.junit.Assert.assertEquals; -import java.io.File; import java.util.List; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -16,7 +15,6 @@ import org.tron.common.BaseTest; import org.tron.common.parameter.CommonParameter; import org.tron.common.runtime.InternalTransaction; -import org.tron.common.utils.FileUtil; import org.tron.core.Constant; import org.tron.core.config.args.Args; import org.tron.core.exception.ContractValidateException; @@ -42,8 +40,7 @@ public class OperationsTest extends BaseTest { @BeforeClass public static void init() { - dbPath = "output_operations_test"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); CommonParameter.getInstance().setDebug(true); VMConfig.initAllowTvmTransferTrc10(1); VMConfig.initAllowTvmConstantinople(1); @@ -58,7 +55,6 @@ public static void destroy() { ConfigLoader.disable = false; VMConfig.initVmHardFork(false); Args.clearParam(); - FileUtil.deleteDir(new File(dbPath)); VMConfig.initAllowTvmTransferTrc10(0); VMConfig.initAllowTvmConstantinople(0); VMConfig.initAllowTvmSolidity059(0); diff --git a/framework/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsTest.java b/framework/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsTest.java index b4365f02338..dce2cc7d105 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsTest.java @@ -106,8 +106,7 @@ public class PrecompiledContractsTest extends BaseTest { private static final long latestTimestamp = 1_000_000L; static { - dbPath = "output_PrecompiledContracts_test"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; WITNESS_ADDRESS = Wallet.getAddressPreFixString() + WITNESS_ADDRESS_BASE; diff --git a/framework/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsVerifyProofTest.java b/framework/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsVerifyProofTest.java index d97be9581b7..833ed6b0ac3 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsVerifyProofTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/PrecompiledContractsVerifyProofTest.java @@ -25,13 +25,13 @@ import org.tron.core.capsule.PedersenHashCapsule; import org.tron.core.config.args.Args; import org.tron.core.exception.ZksnarkException; -import org.tron.core.services.http.FullNodeHttpApiService; import org.tron.core.vm.PrecompiledContracts.MerkleHash; import org.tron.core.vm.PrecompiledContracts.VerifyBurnProof; import org.tron.core.vm.PrecompiledContracts.VerifyMintProof; import org.tron.core.vm.PrecompiledContracts.VerifyTransferProof; import org.tron.core.zen.ShieldedTRC20ParametersBuilder; import org.tron.core.zen.ShieldedTRC20ParametersBuilder.ShieldedTRC20ParametersType; +import org.tron.core.zen.ZksnarkInitService; import org.tron.core.zen.address.DiversifierT; import org.tron.core.zen.address.ExpandedSpendingKey; import org.tron.core.zen.address.FullViewingKey; @@ -58,13 +58,12 @@ public class PrecompiledContractsVerifyProofTest extends BaseTest { @BeforeClass public static void init() { - dbPath = "output_PrecompiledContracts_VerifyProof_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, "config-test.conf"); + Args.setParam(new String[]{"--output-directory", dbPath()}, "config-test.conf"); DEFAULT_OVK = ByteArray .fromHexString("030c8c2bc59fb3eb8afb047a8ea4b028743d23e7d38c6fa30908358431e2314d"); SHIELDED_CONTRACT_ADDRESS = WalletClient.decodeFromBase58Check(SHIELDED_CONTRACT_ADDRESS_STR); PUBLIC_TO_ADDRESS = WalletClient.decodeFromBase58Check(PUBLIC_TO_ADDRESS_STR); - FullNodeHttpApiService.librustzcashInitZksnarkParams(); + ZksnarkInitService.librustzcashInitZksnarkParams(); } @Test diff --git a/framework/src/test/java/org/tron/common/runtime/vm/RepositoryTest.java b/framework/src/test/java/org/tron/common/runtime/vm/RepositoryTest.java index 390b1396337..5c38ed90a3c 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/RepositoryTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/RepositoryTest.java @@ -3,10 +3,10 @@ import java.util.Arrays; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import org.testng.Assert; import org.tron.common.BaseTest; import org.tron.common.parameter.CommonParameter; import org.tron.common.runtime.Runtime; @@ -34,8 +34,7 @@ public class RepositoryTest extends BaseTest { private Repository rootRepository; static { - dbPath = "output_DepostitTest"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; } @@ -194,7 +193,6 @@ public void loopCallTest() String params1 = Hex.toHexString(new DataWord(bAddress).getData()) + "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000" + "00000000000000000000000000000000000000002"; - System.err.println(params1); byte[] triggerData = TvmTestUtils .parseAbi("callBcallARevert(address,uint256,uint256)", params1); @@ -215,12 +213,10 @@ public void loopCallTest() .triggerContractAndReturnTvmTestResult(Hex.decode(OWNER_ADDRESS), aAddress, checkN2Data, 0, fee, dbManager, null); - System.out.println(Hex.toHexString(checkN1.getRuntime().getResult().getHReturn())); - System.out.println(Hex.toHexString(checkN2.getRuntime().getResult().getHReturn())); - Assert.assertEquals(checkN1.getRuntime().getResult().getHReturn(), + Assert.assertArrayEquals(checkN1.getRuntime().getResult().getHReturn(), new DataWord(1).getData()); - Assert.assertEquals(checkN2.getRuntime().getResult().getHReturn(), + Assert.assertArrayEquals(checkN2.getRuntime().getResult().getHReturn(), new DataWord(0).getData()); // trigger contractA @@ -240,12 +236,9 @@ public void loopCallTest() checkN2 = TvmTestUtils .triggerContractAndReturnTvmTestResult(Hex.decode(OWNER_ADDRESS), aAddress, checkN2Data, 0, fee, dbManager, null); - System.out.println(Hex.toHexString(checkN1.getRuntime().getResult().getHReturn())); - System.out.println(Hex.toHexString(checkN2.getRuntime().getResult().getHReturn())); - Assert.assertEquals(checkN1.getRuntime().getResult().getHReturn(), + Assert.assertArrayEquals(checkN1.getRuntime().getResult().getHReturn(), new DataWord(100).getData()); - Assert - .assertEquals(checkN2.getRuntime().getResult().getHReturn(), + Assert.assertArrayEquals(checkN2.getRuntime().getResult().getHReturn(), new DataWord(1000).getData()); CommonParameter.setENERGY_LIMIT_HARD_FORK(false); } @@ -369,12 +362,10 @@ public void loopCallTestOldVersion() .triggerContractAndReturnTvmTestResult(Hex.decode(OWNER_ADDRESS), aAddress, checkN2Data, 0, fee, dbManager, null); - System.out.println(Hex.toHexString(checkN1.getRuntime().getResult().getHReturn())); - System.out.println(Hex.toHexString(checkN2.getRuntime().getResult().getHReturn())); - Assert.assertEquals(checkN1.getRuntime().getResult().getHReturn(), + Assert.assertArrayEquals(checkN1.getRuntime().getResult().getHReturn(), new DataWord(1).getData()); - Assert.assertEquals(checkN2.getRuntime().getResult().getHReturn(), + Assert.assertArrayEquals(checkN2.getRuntime().getResult().getHReturn(), new DataWord(2).getData()); // trigger contractA @@ -394,12 +385,10 @@ public void loopCallTestOldVersion() checkN2 = TvmTestUtils .triggerContractAndReturnTvmTestResult(Hex.decode(OWNER_ADDRESS), aAddress, checkN2Data, 0, fee, dbManager, null); - System.out.println(Hex.toHexString(checkN1.getRuntime().getResult().getHReturn())); - System.out.println(Hex.toHexString(checkN2.getRuntime().getResult().getHReturn())); - Assert.assertEquals(checkN1.getRuntime().getResult().getHReturn(), + Assert.assertArrayEquals(checkN1.getRuntime().getResult().getHReturn(), new DataWord(100).getData()); Assert - .assertEquals(checkN2.getRuntime().getResult().getHReturn(), + .assertArrayEquals(checkN2.getRuntime().getResult().getHReturn(), new DataWord(1000).getData()); CommonParameter.setENERGY_LIMIT_HARD_FORK(false); } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/RewardBalanceTest.java b/framework/src/test/java/org/tron/common/runtime/vm/RewardBalanceTest.java index 3b1021885e7..bf76310fafa 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/RewardBalanceTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/RewardBalanceTest.java @@ -4,8 +4,8 @@ import lombok.extern.slf4j.Slf4j; import org.apache.tuweni.bytes.Bytes32; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.common.runtime.InternalTransaction; import org.tron.common.runtime.TvmTestUtils; import org.tron.common.utils.Base58; diff --git a/framework/src/test/java/org/tron/common/runtime/vm/StorageTest.java b/framework/src/test/java/org/tron/common/runtime/vm/StorageTest.java index fcef572ea99..8ae04761ac3 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/StorageTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/StorageTest.java @@ -3,9 +3,9 @@ import java.util.Arrays; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; -import org.testng.Assert; import org.tron.common.parameter.CommonParameter; import org.tron.common.runtime.TVMTestResult; import org.tron.common.runtime.TvmTestUtils; diff --git a/framework/src/test/java/org/tron/common/runtime/vm/TimeBenchmarkTest.java b/framework/src/test/java/org/tron/common/runtime/vm/TimeBenchmarkTest.java index 2c04b302c49..8104a689cfa 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/TimeBenchmarkTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/TimeBenchmarkTest.java @@ -2,10 +2,10 @@ import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import org.testng.Assert; import org.tron.common.BaseTest; import org.tron.common.runtime.TVMTestResult; import org.tron.common.runtime.TvmTestUtils; @@ -29,8 +29,7 @@ public class TimeBenchmarkTest extends BaseTest { private long totalBalance = 30_000_000_000_000L; static { - dbPath = "output_TimeBenchmarkTest"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/TransferFailedEnergyTest.java b/framework/src/test/java/org/tron/common/runtime/vm/TransferFailedEnergyTest.java index 8a3bbbbeede..dbc9147de7f 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/TransferFailedEnergyTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/TransferFailedEnergyTest.java @@ -6,8 +6,8 @@ import lombok.Data; import lombok.ToString; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.common.runtime.ProgramResult; import org.tron.common.runtime.TVMTestResult; import org.tron.common.runtime.TvmTestUtils; @@ -383,12 +383,12 @@ private void checkResult(TestCase testCase, byte[] factoryAddress) factoryAddress, Hex.decode(hexInput), 0, fee, manager, null); ProgramResult programResult = result.getRuntime().getResult(); ReceiptCapsule receiptCapsule = result.getReceipt(); - Assert.assertEquals(receiptCapsule.getResult(), testCase.getReceiptResult(), - testCase.getMethod()); + Assert.assertEquals(testCase.getMethod(), + receiptCapsule.getResult(), testCase.getReceiptResult()); if (testCase.allEnergy) { - Assert.assertEquals(programResult.getEnergyUsed(), 1000000, testCase.getMethod()); + Assert.assertEquals(testCase.getMethod(), programResult.getEnergyUsed(), 1000000); } else { - Assert.assertTrue(programResult.getEnergyUsed() < allEnergy, testCase.getMethod()); + Assert.assertTrue(testCase.getMethod(), programResult.getEnergyUsed() < allEnergy); } } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java b/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java index 24255f26aed..a6659b0b4f6 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/TransferToAccountTest.java @@ -61,8 +61,7 @@ public class TransferToAccountTest extends BaseTest { private WorldStateCallBack worldStateCallBack; static { - dbPath = "output_TransferToAccountTest"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; TRANSFER_TO = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/TransferTokenTest.java b/framework/src/test/java/org/tron/common/runtime/vm/TransferTokenTest.java index bc9a60a9704..0509cad1dc7 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/TransferTokenTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/TransferTokenTest.java @@ -44,8 +44,7 @@ public class TransferTokenTest extends BaseTest { static { - dbPath = "output_TransferTokenTest"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; TRANSFER_TO = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; } @@ -132,7 +131,7 @@ public void TransferTokenTest() triggerCallValue, feeLimit, tokenValue, id); runtime = TvmTestUtils.processTransactionAndReturnRuntime(transaction, dbManager, null); - org.testng.Assert.assertNull(runtime.getRuntimeError()); + Assert.assertNull(runtime.getRuntimeError()); Assert.assertEquals(100 + tokenValue - 9, dbManager.getAccountStore().get(contractAddress).getAssetV2MapForTest() .get(String.valueOf(id)).longValue()); @@ -157,7 +156,7 @@ public void TransferTokenTest() triggerData2, triggerCallValue, feeLimit, 0, id); runtime = TvmTestUtils.processTransactionAndReturnRuntime(transaction2, dbManager, null); - org.testng.Assert.assertNull(runtime.getRuntimeError()); + Assert.assertNull(runtime.getRuntimeError()); Assert.assertEquals(100 + tokenValue - 9 + 9, dbManager.getAccountStore().get(Hex.decode(TRANSFER_TO)).getAssetV2MapForTest() .get(String.valueOf(id)).longValue()); diff --git a/framework/src/test/java/org/tron/common/runtime/vm/VMContractTestBase.java b/framework/src/test/java/org/tron/common/runtime/vm/VMContractTestBase.java index 777166a0bc0..ee49bdca7f6 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/VMContractTestBase.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/VMContractTestBase.java @@ -1,13 +1,14 @@ package org.tron.common.runtime.vm; -import java.io.File; +import java.io.IOException; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; import org.junit.After; import org.junit.Before; +import org.junit.Rule; +import org.junit.rules.TemporaryFolder; import org.tron.common.application.TronApplicationContext; import org.tron.common.runtime.Runtime; -import org.tron.common.utils.FileUtil; import org.tron.consensus.dpos.DposSlot; import org.tron.consensus.dpos.MaintenanceManager; import org.tron.core.ChainBaseManager; @@ -26,8 +27,8 @@ @Slf4j public class VMContractTestBase { - - protected String dbPath; + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); protected Runtime runtime; protected Manager manager; protected Repository rootRepository; @@ -50,9 +51,9 @@ public class VMContractTestBase { } @Before - public void init() { - dbPath = "output_" + this.getClass().getName(); - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + public void init() throws IOException { + Args.setParam(new String[]{"--output-directory", + temporaryFolder.newFolder().toString(), "--debug"}, Constant.TEST_CONF); context = new TronApplicationContext(DefaultConfig.class); // TRdmP9bYvML7dGUX9Rbw2kZrE2TayPZmZX - 41abd4b9367799eaa3197fecb144eb71de1e049abc @@ -77,10 +78,5 @@ public void init() { public void destroy() { Args.clearParam(); context.destroy(); - if (FileUtil.deleteDir(new File(dbPath))) { - logger.info("Release resources successful."); - } else { - logger.error("Release resources failure."); - } } } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/VMTestBase.java b/framework/src/test/java/org/tron/common/runtime/vm/VMTestBase.java index 1ceee84d634..18209543f62 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/VMTestBase.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/VMTestBase.java @@ -1,13 +1,15 @@ package org.tron.common.runtime.vm; -import java.io.File; +import java.io.IOException; + import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; import org.junit.After; import org.junit.Before; +import org.junit.Rule; +import org.junit.rules.TemporaryFolder; import org.tron.common.application.TronApplicationContext; import org.tron.common.runtime.Runtime; -import org.tron.common.utils.FileUtil; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.config.DefaultConfig; @@ -23,15 +25,17 @@ public class VMTestBase { protected Manager manager; protected TronApplicationContext context; - protected String dbPath; protected Repository rootRepository; protected String OWNER_ADDRESS; protected Runtime runtime; + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + @Before - public void init() { - dbPath = "output_" + this.getClass().getName(); - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + public void init() throws IOException { + Args.setParam(new String[]{"--output-directory", + temporaryFolder.newFolder().toString(), "--debug"}, Constant.TEST_CONF); context = new TronApplicationContext(DefaultConfig.class); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; manager = context.getBean(Manager.class); @@ -45,11 +49,6 @@ public void init() { public void destroy() { Args.clearParam(); context.destroy(); - if (FileUtil.deleteDir(new File(dbPath))) { - logger.info("Release resources successful."); - } else { - logger.error("Release resources failure."); - } } } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/ValidateMultiSignContractTest.java b/framework/src/test/java/org/tron/common/runtime/vm/ValidateMultiSignContractTest.java index e6ef013bd85..a688f5f9a29 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/ValidateMultiSignContractTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/ValidateMultiSignContractTest.java @@ -8,9 +8,9 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.tuple.Pair; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.testng.Assert; import org.tron.common.BaseTest; import org.tron.common.crypto.ECKey; import org.tron.common.crypto.Hash; @@ -37,8 +37,7 @@ public class ValidateMultiSignContractTest extends BaseTest { private static final byte[] longData; static { - dbPath = "output_ValidateMultiSignContract_test"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); longData = new byte[1000000]; Arrays.fill(longData, (byte) 2); } @@ -60,7 +59,7 @@ public void testAddressNonExist() { signs.add(Hex.toHexString(sign)); //Address non exist - Assert.assertEquals( + Assert.assertArrayEquals( validateMultiSign(StringUtil.encode58Check(key.getAddress()), 1, hash, signs) .getValue(), DataWord.ZERO().getData()); } @@ -120,21 +119,21 @@ public void testDifferentCase() { signs.add(Hex.toHexString(key1.sign(toSign).toByteArray())); signs.add(Hex.toHexString(key2.sign(toSign).toByteArray())); - Assert.assertEquals( + Assert.assertArrayEquals( validateMultiSign(StringUtil.encode58Check(key.getAddress()), permissionId, data, signs) .getValue(), DataWord.ONE().getData()); //weight not enough signs = new ArrayList<>(); signs.add(Hex.toHexString(key1.sign(toSign).toByteArray())); - Assert.assertEquals( + Assert.assertArrayEquals( validateMultiSign(StringUtil.encode58Check(key.getAddress()), permissionId, data, signs) .getValue(), DataWord.ZERO().getData()); //put wrong sign signs = new ArrayList<>(); signs.add(Hex.toHexString(key1.sign(toSign).toByteArray())); - Assert.assertEquals( + Assert.assertArrayEquals( validateMultiSign(StringUtil.encode58Check(key.getAddress()), permissionId, data, signs) .getValue(), DataWord.ZERO().getData()); @@ -142,7 +141,7 @@ public void testDifferentCase() { signs.add(Hex.toHexString(key1.sign(toSign).toByteArray())); signs.add(Hex.toHexString(new ECKey().sign(toSign).toByteArray())); - Assert.assertEquals( + Assert.assertArrayEquals( validateMultiSign(StringUtil.encode58Check(key.getAddress()), permissionId, data, signs) .getValue(), DataWord.ZERO().getData()); } diff --git a/framework/src/test/java/org/tron/common/runtime/vm/VoteTest.java b/framework/src/test/java/org/tron/common/runtime/vm/VoteTest.java index 52d46b27390..2596dce72c2 100644 --- a/framework/src/test/java/org/tron/common/runtime/vm/VoteTest.java +++ b/framework/src/test/java/org/tron/common/runtime/vm/VoteTest.java @@ -19,7 +19,9 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.tron.common.application.TronApplicationContext; import org.tron.common.parameter.CommonParameter; import org.tron.common.runtime.Runtime; @@ -267,7 +269,8 @@ private static Consumer getSmallerConsumer(long expected) { return getConsumer("<", expected); } - private static String dbPath; + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); private static TronApplicationContext context; private static Manager manager; private static MaintenanceManager maintenanceManager; @@ -280,8 +283,8 @@ private static Consumer getSmallerConsumer(long expected) { @Before public void init() throws Exception { - dbPath = "output_" + VoteTest.class.getName(); - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", + temporaryFolder.newFolder().toString(), "--debug"}, Constant.TEST_CONF); CommonParameter.getInstance().setCheckFrozenTime(0); context = new TronApplicationContext(DefaultConfig.class); manager = context.getBean(Manager.class); @@ -318,11 +321,6 @@ public void destroy() { VMConfig.initVmHardFork(false); Args.clearParam(); context.destroy(); - if (FileUtil.deleteDir(new File(dbPath))) { - logger.info("Release resources successful."); - } else { - logger.error("Release resources failure."); - } } private byte[] deployContract(String contractName, String abi, String code) throws Exception { diff --git a/framework/src/test/java/org/tron/common/storage/leveldb/LevelDbDataSourceImplTest.java b/framework/src/test/java/org/tron/common/storage/leveldb/LevelDbDataSourceImplTest.java index eed995f12b5..50a55d24a0f 100644 --- a/framework/src/test/java/org/tron/common/storage/leveldb/LevelDbDataSourceImplTest.java +++ b/framework/src/test/java/org/tron/common/storage/leveldb/LevelDbDataSourceImplTest.java @@ -26,7 +26,10 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; import java.io.File; +import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -37,7 +40,11 @@ import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; import org.junit.Test; +import org.junit.contrib.java.lang.system.ExpectedSystemExit; +import org.junit.rules.TemporaryFolder; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; import org.tron.common.utils.PublicMethod; @@ -48,7 +55,8 @@ @Slf4j public class LevelDbDataSourceImplTest { - private static final String dbPath = "output-levelDb-test"; + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); private static LevelDbDataSourceImpl dataSourceTest; private byte[] value1 = "10000".getBytes(); @@ -65,23 +73,23 @@ public class LevelDbDataSourceImplTest { private byte[] key5 = "00000005aa".getBytes(); private byte[] key6 = "00000006aa".getBytes(); + @Rule + public final ExpectedSystemExit exit = ExpectedSystemExit.none(); + /** * Release resources. */ @AfterClass public static void destroy() { Args.clearParam(); - if (FileUtil.deleteDir(new File(dbPath))) { - logger.info("Release resources successful."); - } else { - logger.info("Release resources failure."); - } } @Before - public void initDb() { - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); - dataSourceTest = new LevelDbDataSourceImpl(dbPath + File.separator, "test_levelDb"); + public void initDb() throws IOException { + Args.setParam(new String[]{"--output-directory", + temporaryFolder.newFolder().toString()}, Constant.TEST_CONF); + dataSourceTest = new LevelDbDataSourceImpl( + Args.getInstance().getOutputDirectory() + File.separator, "test_levelDb"); } @Test @@ -107,6 +115,13 @@ public void testReset() { Args.getInstance().getOutputDirectory(), "test_reset"); dataSource.resetDb(); assertEquals(0, dataSource.allKeys().size()); + assertEquals("LEVELDB", dataSource.getEngine()); + assertEquals("test_reset", dataSource.getName()); + assertEquals(Sets.newHashSet(), dataSource.getlatestValues(0)); + assertEquals(Collections.emptyMap(), dataSource.getNext(key1, 0)); + assertEquals(new ArrayList<>(), dataSource.getKeysNext(key1, 0)); + assertEquals(Sets.newHashSet(), dataSource.getValuesNext(key1, 0)); + assertEquals(Sets.newHashSet(), dataSource.getlatestValues(0)); dataSource.closeDB(); } @@ -332,4 +347,24 @@ public void prefixQueryTest() { dataSource.resetDb(); dataSource.closeDB(); } + + @Test + public void initDbTest() { + exit.expectSystemExitWithStatus(1); + makeExceptionDb("test_initDb"); + LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl( + Args.getInstance().getOutputDirectory(), "test_initDb"); + dataSource.initDB(); + dataSource.closeDB(); + } + + private void makeExceptionDb(String dbName) { + LevelDbDataSourceImpl dataSource = new LevelDbDataSourceImpl( + Args.getInstance().getOutputDirectory(), "test_initDb"); + dataSource.initDB(); + dataSource.closeDB(); + FileUtil.saveData(dataSource.getDbPath().toString() + "/CURRENT", + "...", Boolean.FALSE); + } + } diff --git a/framework/src/test/java/org/tron/common/storage/leveldb/RocksDbDataSourceImplTest.java b/framework/src/test/java/org/tron/common/storage/leveldb/RocksDbDataSourceImplTest.java index f0ceb7fcac4..ed37c1e4bcd 100644 --- a/framework/src/test/java/org/tron/common/storage/leveldb/RocksDbDataSourceImplTest.java +++ b/framework/src/test/java/org/tron/common/storage/leveldb/RocksDbDataSourceImplTest.java @@ -8,7 +8,10 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; import java.io.File; +import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -18,9 +21,12 @@ import lombok.extern.slf4j.Slf4j; import org.junit.AfterClass; import org.junit.Assert; -import org.junit.Before; import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Rule; import org.junit.Test; +import org.junit.contrib.java.lang.system.ExpectedSystemExit; +import org.junit.rules.TemporaryFolder; import org.tron.common.storage.rocksdb.RocksDbDataSourceImpl; import org.tron.common.utils.ByteArray; import org.tron.common.utils.FileUtil; @@ -32,7 +38,8 @@ @Slf4j public class RocksDbDataSourceImplTest { - private static final String dbPath = "output-Rocks-test"; + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); private static RocksDbDataSourceImpl dataSourceTest; private byte[] value1 = "10000".getBytes(); @@ -48,30 +55,23 @@ public class RocksDbDataSourceImplTest { private byte[] key5 = "00000005aa".getBytes(); private byte[] key6 = "00000006aa".getBytes(); + @Rule + public final ExpectedSystemExit exit = ExpectedSystemExit.none(); + /** * Release resources. */ @AfterClass public static void destroy() { - String directory = Args.getInstance().getStorage().getDbDirectory(); Args.clearParam(); - if (FileUtil.deleteDir(new File(dbPath))) { - logger.info("Release resources successful."); - } else { - logger.info("Release resources failure."); - } - - if (FileUtil.deleteDir(new File(dbPath + directory))) { - logger.info("Release resources successful."); - } else { - logger.info("Release resources failure."); - } } @BeforeClass - public static void initDb() { - Args.setParam(new String[]{"--output-directory", dbPath}, "config-test-dbbackup.conf"); - dataSourceTest = new RocksDbDataSourceImpl(dbPath + File.separator, "test_rocksDb"); + public static void initDb() throws IOException { + Args.setParam(new String[]{"--output-directory", + temporaryFolder.newFolder().toString()}, "config-test-dbbackup.conf"); + dataSourceTest = new RocksDbDataSourceImpl( + Args.getInstance().getOutputDirectory() + File.separator, "test_rocksDb"); } @Test @@ -97,6 +97,13 @@ public void testReset() { Args.getInstance().getOutputDirectory(), "test_reset"); dataSource.resetDb(); assertEquals(0, dataSource.allKeys().size()); + assertEquals("ROCKSDB", dataSource.getEngine()); + assertEquals("test_reset", dataSource.getName()); + assertEquals(Sets.newHashSet(), dataSource.getlatestValues(0)); + assertEquals(Collections.emptyMap(), dataSource.getNext(key1, 0)); + assertEquals(new ArrayList<>(), dataSource.getKeysNext(key1, 0)); + assertEquals(Sets.newHashSet(), dataSource.getValuesNext(key1, 0)); + assertEquals(Sets.newHashSet(), dataSource.getlatestValues(0)); dataSource.closeDB(); } @@ -382,4 +389,23 @@ public void prefixQueryTest() { dataSource.resetDb(); dataSource.closeDB(); } + + @Test + public void initDbTest() { + exit.expectSystemExitWithStatus(1); + makeExceptionDb("test_initDb"); + RocksDbDataSourceImpl dataSource = new RocksDbDataSourceImpl( + Args.getInstance().getOutputDirectory(), "test_initDb"); + dataSource.initDB(); + dataSource.closeDB(); + } + + private void makeExceptionDb(String dbName) { + RocksDbDataSourceImpl dataSource = new RocksDbDataSourceImpl( + Args.getInstance().getOutputDirectory(), "test_initDb"); + dataSource.initDB(); + dataSource.closeDB(); + FileUtil.saveData(dataSource.getDbPath().toString() + "/CURRENT", + "...", Boolean.FALSE); + } } diff --git a/framework/src/test/java/org/tron/common/utils/client/utils/HttpMethed.java b/framework/src/test/java/org/tron/common/utils/client/utils/HttpMethed.java index 0d117dd4a45..ee872be6330 100644 --- a/framework/src/test/java/org/tron/common/utils/client/utils/HttpMethed.java +++ b/framework/src/test/java/org/tron/common/utils/client/utils/HttpMethed.java @@ -2,6 +2,7 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.google.common.collect.Lists; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonObject; @@ -22,7 +23,7 @@ import org.apache.http.params.CoreConnectionPNames; import org.apache.http.util.EntityUtils; import org.junit.Assert; -import org.testng.collections.Lists; +import org.springframework.mock.web.MockHttpServletRequest; import org.tron.api.GrpcAPI; import org.tron.common.utils.ByteArray; import org.tron.common.utils.ByteUtil; @@ -4876,4 +4877,11 @@ public static HttpResponse getTransactionFromPending(String httpNode, String txi } return response; } + + public static MockHttpServletRequest createRequest(String method) { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setMethod(method); + request.setCharacterEncoding("UTF-8"); + return request; + } } diff --git a/framework/src/test/java/org/tron/core/BandwidthProcessorTest.java b/framework/src/test/java/org/tron/core/BandwidthProcessorTest.java index 69501c4e393..300c202e11a 100755 --- a/framework/src/test/java/org/tron/core/BandwidthProcessorTest.java +++ b/framework/src/test/java/org/tron/core/BandwidthProcessorTest.java @@ -47,8 +47,7 @@ public class BandwidthProcessorTest extends BaseTest { static { - dbPath = "output_bandwidth_processor_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); ASSET_NAME = "test_token"; ASSET_NAME_V2 = "2"; OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; diff --git a/framework/src/test/java/org/tron/core/EnergyProcessorTest.java b/framework/src/test/java/org/tron/core/EnergyProcessorTest.java index da0493e2026..1e9064cb998 100755 --- a/framework/src/test/java/org/tron/core/EnergyProcessorTest.java +++ b/framework/src/test/java/org/tron/core/EnergyProcessorTest.java @@ -24,8 +24,7 @@ public class EnergyProcessorTest extends BaseTest { private static final String USER_ADDRESS; static { - dbPath = "energy_processor_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); ASSET_NAME = "test_token"; CONTRACT_PROVIDER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; diff --git a/framework/src/test/java/org/tron/core/ForkControllerTest.java b/framework/src/test/java/org/tron/core/ForkControllerTest.java index 20a28f9b619..74e651b3c1d 100644 --- a/framework/src/test/java/org/tron/core/ForkControllerTest.java +++ b/framework/src/test/java/org/tron/core/ForkControllerTest.java @@ -1,16 +1,16 @@ package org.tron.core; import com.google.protobuf.ByteString; -import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.List; - import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.tron.common.application.TronApplicationContext; -import org.tron.common.utils.FileUtil; import org.tron.common.utils.ForkController; import org.tron.core.capsule.BlockCapsule; import org.tron.core.config.DefaultConfig; @@ -24,12 +24,14 @@ public class ForkControllerTest { private static DynamicPropertiesStore dynamicPropertiesStore; private static final ForkController forkController = ForkController.instance(); private static TronApplicationContext context; - private static final String dbPath = "output_fork_test"; + @Rule + public final TemporaryFolder temporaryFolder = new TemporaryFolder(); private static long ENERGY_LIMIT_BLOCK_NUM = 4727890L; @Before - public void init() { - Args.setParam(new String[]{"-d", dbPath, "-w"}, Constant.TEST_CONF); + public void init() throws IOException { + Args.setParam(new String[]{"-d", + temporaryFolder.newFolder().toString(), "-w"}, Constant.TEST_CONF); context = new TronApplicationContext(DefaultConfig.class); dynamicPropertiesStore = context.getBean(DynamicPropertiesStore.class); chainBaseManager = context.getBean(ChainBaseManager.class); @@ -255,7 +257,6 @@ private byte[] getBytes(int i) { public void removeDb() { Args.clearParam(); context.destroy(); - FileUtil.deleteDir(new File(dbPath)); } } diff --git a/framework/src/test/java/org/tron/core/ShieldWalletTest.java b/framework/src/test/java/org/tron/core/ShieldWalletTest.java new file mode 100644 index 00000000000..5bc2a31c9d0 --- /dev/null +++ b/framework/src/test/java/org/tron/core/ShieldWalletTest.java @@ -0,0 +1,383 @@ +package org.tron.core; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.tron.core.zen.ZksnarkInitService.librustzcashInitZksnarkParams; + +import java.math.BigInteger; +import javax.annotation.Resource; +import org.junit.Assert; +import org.junit.Test; +import org.tron.api.GrpcAPI.PrivateParameters; +import org.tron.api.GrpcAPI.PrivateParametersWithoutAsk; +import org.tron.api.GrpcAPI.PrivateShieldedTRC20Parameters; +import org.tron.api.GrpcAPI.PrivateShieldedTRC20ParametersWithoutAsk; +import org.tron.api.GrpcAPI.ShieldedAddressInfo; +import org.tron.api.GrpcAPI.ShieldedTRC20Parameters; +import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; +import org.tron.core.capsule.TransactionCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.exception.ContractExeException; +import org.tron.core.services.http.JsonFormat; +import org.tron.core.services.http.JsonFormat.ParseException; + + +public class ShieldWalletTest extends BaseTest { + + @Resource + private Wallet wallet; + + static { + Args.setParam(new String[] {"-d", dbPath()}, Constant.TEST_CONF); + } + + @Test + public void testCreateShieldedTransaction1() { + librustzcashInitZksnarkParams(); + String transactionStr1 = new String(ByteArray.fromHexString( + "0x7b0a20202020227472616e73706172656e745f66726f6d5f61646472657373223a202234433930413" + + "73241433344414546324536383932343545463430303839443634314345414337373433323433414233" + + "31333136303030222c0a202020202266726f6d5f616d6f756e74223a203130303030303030302c0a202" + + "02020226f766b223a223566643165636466643637396232616461333337623235306231303234373138" + + "6633316439636237316361653664666363396131613637626134373033643863222c0a2020202022736" + + "869656c6465645f7265636569766573223a205b0a20202020202020207b0a2020202020202020202020" + + "20226e6f7465223a207b0a202020202020202020202020202020202276616c7565223a2039303030303" + + "030302c0a20202020202020202020202020202020227061796d656e745f61646472657373223a20227a" + + "74726f6e3179616d336a723270746d79706c707030747978387974707a36736a64786364657a306a333" + + "36673636d656a76376e6863346171336d766b687275726772777671653932636a6c68356b3367222c0a" + + "202020202020202020202020202020202272636d223a202237323330353362636266656364663564613" + + "63663313861623033373634373665663330386336316237616265383931623263303165393033626362" + + "3837633065222c0a20202020202020202020202020202020226d656d6f223a20223232323232220a202" + + "0202020202020202020207d0a20202020202020207d0a202020205d0a7d")); + PrivateParameters.Builder builder1 = PrivateParameters.newBuilder(); + try { + JsonFormat.merge(transactionStr1, builder1, false); + } catch (ParseException e) { + Assert.fail(); + } + + try { + TransactionCapsule transactionCapsule = wallet.createShieldedTransaction(builder1.build()); + Assert.assertNotNull(transactionCapsule); + } catch (Exception e) { + Assert.fail(); + } + } + + @Test + public void testCreateShieldedTransaction2() { + librustzcashInitZksnarkParams(); + String transactionStr2 = new String(ByteArray.fromHexString( + "7b0a202020202261736b223a20223938666430333136376632333437623534643737323338343137663" + + "6373038643537323939643938376362613838353564653037626532346236316464653064222c0a2020" + + "2020226e736b223a2022643063623330653764306634653435333535363134333463303462616339316" + + "63039643230653664366234363361623031626534663531386230363839653039222c0a20202020226f" + + "766b223a202235666431656364666436373962326164613333376232353062313032343731386633316" + + "439636237316361653664666363396131613637626134373033643863222c0a2020202022736869656c" + + "6465645f7370656e6473223a205b0a20202020202020207b200a090909226e6f7465223a207b0a20202" + + "0202020202020202020202020202276616c7565223a2039303030303030302c0a202020202020202020" + + "20202020202020227061796d656e745f61646472657373223a20227a74726f6e3179616d336a7232707" + + "46d79706c707030747978387974707a36736a64786364657a306a33336673636d656a76376e68633461" + + "71336d766b687275726772777671653932636a6c68356b3367222c0a202020202020202020202020202" + + "020202272636d223a202237323330353362636266656364663564613636633138616230333736343736" + + "656633303863363162376162653839316232633031653930336263623837633065222c0a20202020202" + + "020202020202020202020226d656d6f223a20223232323232220a2020202020202020202020207d2c0a" + + "20202020202020202020202022616c706861223a2022323936656531633532633933663734306433616" + + "23162373265366463663561626231643666343965643865646236663334656633666462366537366335" + + "353063222c0a20202020202020202020202022766f7563686572223a207b0a202020202020202020202" + + "0202274726565223a207b0a20202020202020202020202020202020226c656674223a207b0a20202020" + + "2020202020202020202020202020202022636f6e74656e74223a2022346565653236313963343862613" + + "26264303235303235363330636430313362616361663337653961323162323965333938393735623763" + + "653864363436613265220a202020202020202020202020202020207d2c0a20202020202020202020202" + + "020202020227269676874223a207b0a202020202020202020202020202020202020202022636f6e7465" + + "6e74223a202235333863326139313537313333356334666138383866396234336239666164643931633" + + "334666366326265666130333931353932613564366535343539623537220a2020202020202020202020" + + "20202020207d0a2020202020202020202020207d2c0a202020202020202020202020227274223a20226" + + "33539376436633235663131623938613638303034343838393138386638613934616237393265353432" + + "32313461386636346632363334616535346535353531220a20202020202020207d2c0a2020202020202" + + "020202020202270617468223a2022323032306232656564303331643464366134663032613039376638" + + "30623534636331353431643431363363366236663539373166383862366534316433356335333831343" + + "23031323933356631346236373635303962383165623439656632356633393236396564373233303932" + + "33386234633134353830333534346236343664636136326432306531663334623033346434613363643" + + "23835353765323930376562663939306339313866363465636235306139346630316436666461356361" + + "35633765663732323032386537623834316463626334376363656236396437636238643934323435666" + + "23763623262613361376136626331386631336639343566376462643665326132306135313232633038" + + "66663963313631643963613666633436323037333339366337643764333865386565343863646233626" + + "56137653232333031333465643661323064326531363432633961343632323239323839653562306533" + + "62376639303038653033303163626239333338356565306532316461323534353037336362353832303" + + "13664363235323936383937316138336461383532316436353338326536316630313736363436643737" + + "31633931353238653332373665653435333833653461323066656530653532383032636230633436623" + + "16562346433373663363236393766343735396636633839313766613335323537313230326664373738" + + "66643731323230346336393337643738663432363835663834623433616433623762303066383132383" + + "53636326638356336613638656631316436326164316133656530383530323030373639353537626336" + + "38326231626633303836343666643062323265363438653862396539386635376532396635616634306" + + "63665646238333365326334393230303865656162306331336162643630363965363331303139376266" + + "38306639633165613664653738666431396362616532346434613532306536636633303233323038643" + + "56661343365356131306431313630356163373433306261316635643831666231623638643239613634" + + "30343035373637373439653834313532373637333230366163613834343864383236336535343764356" + + "66632393530653265643338333965393938643331636263366163396664353762633630303262313539" + + "32313632306364316338646266366533616363376138303433396263343936326366323562396463653" + + "76338393666336135626437303830336663356130653333636630303230366564623136643031393037" + + "62373539393737643736353064616437653365633034396166316133643837353338306236393763383" + + "63263396563356435316332303165613636373566393535316565623964666161613932343762633938" + + "35383237306433643361346335616661373137376139383464356564316265323435313230643661636" + + "46564663935663630386530396661353366623433646364303939303437353732366335313331323130" + + "63396535636165616239376630653634326632306264373462323561616362393233373861383731626" + + "63237643232356366633236626163613334346131656133356664643934353130663364313537303832" + + "63323031623737646163346432346662373235386333633532383730346335393433306236333037313" + + "86265633438363432313833373032316366373564616236353132306563363737313134633237323036" + + "66356465626331633165643636663935653262313838356461356237626533643733366231646539383" + + "53739343733303438323034373737633837373661336231653639623733613632666137303166613466" + + "37613632383264396165653263376136623832653739333764373038316332336332306261343962363" + + "53966626430623733333432313165613661396439646631383563373537653730616138316461353632" + + "66623931326238346634396263653732323034336666353435376631336239323662363164663535326" + + "43465343032656536646331343633663939613533356639613731333433393236346435623631366232" + + "30376239396162646333373330393931636339323734373237643764383264323863623739346564626" + + "33730333462346630303533666637633462363830343434323064366336333961633234623436626431" + + "39333431633931623133666463616233313538316464616637663134313133333661323731663364306" + + "16135323831333230386163396366396333393165336664343238393164323732333861383161386135" + + "63316433613732623162636265613863663434613538636537333839363133323039313264383262326" + + "33262636132333166373165666366363137333766626630613038626566613034313632313561656566" + + "35336538626236643233333930613230653131306465363563393037623964656134616530626438336" + + "13462306135316265613137353634366136346331326234633966393331623263623331623439323064" + + "38323833333836656632656630376562646262343338336331326137333961393533613464366530643" + + "66662313133396134303336643639336266626236633230666665396663303366313862313736633939" + + "38383036343339666630626238616431393361666462323762326363626338383835363931366464383" + + "03465333432303831376465333661623264353766656230373736333462636137373831396338653062" + + "64323938633034663666656430653661383363633133353663613135353230346565653236313963343" + + "86261326264303235303235363330636430313362616361663337653961323162323965333938393735" + + "62376365386436343661326530313030303030303030303030303030220a20202020202020207d0a202" + + "020205d2c0a2020202022736869656c6465645f7265636569766573223a205b0a20202020202020207b" + + "0a202020202020202020202020226e6f7465223a207b0a2020202020202020202020202020202022766" + + "16c7565223a2038303030303030302c0a20202020202020202020202020202020227061796d656e745f" + + "61646472657373223a20227a74726f6e31356b657a70736d71303568336d616a6e6c7a6834306772796" + + "a6d676d3630783265686a7967633771387336376d6c753835376375747177613334386e76706765706e" + + "35786b336735727278222c0a202020202020202020202020202020202272636d223a202237323330353" + + "36263626665636466356461363663313861623033373634373665663330386336316237616265383931" + + "6232633031653930336263623837633065222c0a20202020202020202020202020202020226d656d6f2" + + "23a2022313131313131313131220a2020202020202020202020207d0a20202020202020207d0a202020" + + "205d2c0a202020202276697369626c6522203a20747275650a7d")); + PrivateParameters.Builder builder2 = PrivateParameters.newBuilder(); + try { + JsonFormat.merge(transactionStr2, builder2, true); + } catch (ParseException e) { + Assert.fail(); + } + + try { + TransactionCapsule transactionCapsule = wallet.createShieldedTransaction(builder2.build()); + Assert.assertNotNull(transactionCapsule); + } catch (Exception e) { + Assert.fail(); + } + } + + @Test + public void testCreateShieldedTransactionWithoutSpendAuthSig() { + librustzcashInitZksnarkParams(); + String transactionStr3 = new String(ByteArray.fromHexString( + "7b0a2020202022616b223a2022373161643638633466353035373464356164333735343863626538363" + + "63031663732393662393161306362303535353733313462373830383437323730326465222c0a202020" + + "20226e736b223a202264306362333065376430663465343533353536313433346330346261633931663" + + "039643230653664366234363361623031626534663531386230363839653039222c0a20202020226f76" + + "6b223a20223566643165636466643637396232616461333337623235306231303234373138663331643" + + "9636237316361653664666363396131613637626134373033643863222c0a2020202022736869656c64" + + "65645f7370656e6473223a205b0a20202020202020207b0a202020202020202020202020226e6f74652" + + "23a207b0a202020202020202020202020202020202276616c7565223a2039303030303030302c0a2020" + + "2020202020202020202020202020227061796d656e745f61646472657373223a20227a74726f6e31796" + + "16d336a723270746d79706c707030747978387974707a36736a64786364657a306a33336673636d656a" + + "76376e6863346171336d766b687275726772777671653932636a6c68356b3367222c0a2020202020202" + + "02020202020202020202272636d223a2022373233303533626362666563646635646136366331386162" + + "30333736343736656633303863363162376162653839316232633031653930336263623837633065222" + + "c0a20202020202020202020202020202020226d656d6f223a20223232323232220a2020202020202020" + + "202020207d2c0a20202020202020202020202022616c706861223a20223239366565316335326339336" + + "63734306433616231623732653664636635616262316436663439656438656462366633346566336664" + + "62366537366335353063222c0a20202020202020202020202022766f7563686572223a207b0a2020202" + + "02020202020202020202020202274726565223a207b0a20202020202020202020202020202020202020" + + "20226c656674223a207b0a20202020202020202020202020202020202020202020202022636f6e74656" + + "e74223a2022346565653236313963343862613262643032353032353633306364303133626163616633" + + "37653961323162323965333938393735623763653864363436613265220a20202020202020202020202" + + "020202020202020207d2c0a2020202020202020202020202020202020202020227269676874223a207b" + + "0a20202020202020202020202020202020202020202020202022636f6e74656e74223a2022353338633" + + "26139313537313333356334666138383866396234336239666164643931633334666366326265666130" + + "333931353932613564366535343539623537220a20202020202020202020202020202020202020207d0" + + "a202020202020202020202020202020207d2c0a20202020202020202020202020202020227274223a20" + + "22633539376436633235663131623938613638303034343838393138386638613934616237393265353" + + "43232313461386636346632363334616535346535353531220a2020202020202020202020207d2c0a20" + + "20202020202020202020202270617468223a20223230323062326565643033316434643661346630326" + + "13039376638306235346363313534316434313633633662366635393731663838623665343164333563" + + "35333831343230313239333566313462363736353039623831656234396566323566333932363965643" + + "73233303932333862346331343538303335343462363436646361363264323065316633346230333464" + + "34613363643238353537653239303765626639393063393138663634656362353061393466303164366" + + "66461356361356337656637323230323865376238343164636263343763636562363964376362386439" + + "34323435666237636232626133613761366263313866313366393435663764626436653261323061353" + + "13232633038666639633136316439636136666334363230373333393663376437643338653865653438" + + "63646233626561376532323330313334656436613230643265313634326339613436323232393238396" + + "53562306533623766393030386530333031636262393333383565653065323164613235343530373363" + + "62353832303136643632353239363839373161383364613835323164363533383265363166303137363" + + "63436643737316339313532386533323736656534353338336534613230666565306535323830326362" + + "30633436623165623464333736633632363937663437353966366338393137666133353235373132303" + + "26664373738666437313232303463363933376437386634323638356638346234336164336237623030" + + "66383132383536363266383563366136386566313164363261643161336565303835303230303736393" + + "53537626336383262316266333038363436666430623232653634386538623965393866353765323966" + + "35616634306636656462383333653263343932303038656561623063313361626436303639653633313" + + "03139376266383066396331656136646537386664313963626165323464346135323065366366333032" + + "33323038643566613433653561313064313136303561633734333062613166356438316662316236386" + + "43239613634303430353736373734396538343135323736373332303661636138343438643832363365" + + "35343764356666323935306532656433383339653939386433316362633661633966643537626336303" + + "03262313539323136323063643163386462663665336163633761383034333962633439363263663235" + + "62396463653763383936663361356264373038303366633561306533336366303032303665646231366" + + "43031393037623735393937376437363530646164376533656330343961663161336438373533383062" + + "36393763383632633965633564353163323031656136363735663935353165656239646661616139323" + + "43762633938353832373064336433613463356166613731373761393834643565643162653234353132" + + "30643661636465646639356636303865303966613533666234336463643039393034373537323663353" + + "13331323130633965356361656162393766306536343266323062643734623235616163623932333738" + + "61383731626632376432323563666332366261636133343461316561333566646439343531306633643" + + "13537303832633230316237376461633464323466623732353863336335323837303463353934333062" + + "36333037313862656334383634323138333730323163663735646162363531323065633637373131346" + + "33237323036663564656263316331656436366639356532623138383564613562376265336437333662" + + "31646539383537393437333034383230343737376338373736613362316536396237336136326661373" + + "03166613466376136323832643961656532633761366238326537393337643730383163323363323062" + + "61343962363539666264306237333334323131656136613964396466313835633735376537306161383" + + "16461353632666239313262383466343962636537323230343366663534353766313362393236623631" + + "64663535326434653430326565366463313436336639396135333566396137313334333932363464356" + + "23631366232303762393961626463333733303939316363393237343732376437643832643238636237" + + "39346564626337303334623466303035336666376334623638303434343230643663363339616332346" + + "23436626431393334316339316231336664636162333135383164646166376631343131333336613237" + + "31663364306161353238313332303861633963663963333931653366643432383931643237323338613" + + "83161386135633164336137326231626362656138636634346135386365373338393631333230393132" + + "64383262326332626361323331663731656663663631373337666266306130386265666130343136323" + + "13561656566353365386262366432333339306132306531313064653635633930376239646561346165" + + "30626438336134623061353162656131373536343661363463313262346339663933316232636233316" + + "23439323064383238333338366566326566303765626462623433383363313261373339613935336134" + + "64366530643666623131333961343033366436393362666262366332306666653966633033663138623" + + "13736633939383830363433396666306262386164313933616664623237623263636263383838353639" + + "31366464383034653334323038313764653336616232643537666562303737363334626361373738313" + + "96338653062643239386330346636666564306536613833636331333536636131353532303465656532" + + "36313963343862613262643032353032353633306364303133626163616633376539613231623239653" + + "3393839373562376365386436343661326530313030303030303030303030303030220a202020202020" + + "20207d0a202020205d2c0a2020202022736869656c6465645f7265636569766573223a205b0a2020202" + + "0202020207b0a202020202020202020202020226e6f7465223a207b0a20202020202020202020202020" + + "2020202276616c7565223a2038303030303030302c0a202020202020202020202020202020202270617" + + "96d656e745f61646472657373223a20227a74726f6e31356b657a70736d71303568336d616a6e6c7a68" + + "34306772796a6d676d3630783265686a7967633771387336376d6c753835376375747177613334386e7" + + "6706765706e35786b336735727278222c0a202020202020202020202020202020202272636d223a2022" + + "37323330353362636266656364663564613636633138616230333736343736656633303863363162376" + + "162653839316232633031653930336263623837633065222c0a20202020202020202020202020202020" + + "226d656d6f223a2022313131313131313131220a2020202020202020202020207d0a202020202020202" + + "07d0a202020205d2c0a202020202276697369626c65223a20747275650a7d")); + PrivateParametersWithoutAsk.Builder builder3 = PrivateParametersWithoutAsk.newBuilder(); + try { + JsonFormat.merge(transactionStr3, builder3, false); + } catch (ParseException e) { + Assert.fail(); + } + + try { + TransactionCapsule transactionCapsule = wallet.createShieldedTransactionWithoutSpendAuthSig( + builder3.build()); + Assert.assertNotNull(transactionCapsule); + } catch (Exception e) { + Assert.fail(); + } + } + + @Test + public void testGetNewShieldedAddress() { + librustzcashInitZksnarkParams(); + try { + ShieldedAddressInfo shieldedAddressInfo = wallet.getNewShieldedAddress(); + Assert.assertNotNull(shieldedAddressInfo); + } catch (Exception e) { + Assert.fail(); + } + } + + @Test + public void testCreateShieldedContractParameters() throws ContractExeException { + librustzcashInitZksnarkParams(); + Args.getInstance().setFullNodeAllowShieldedTransactionArgs(true); + Wallet wallet1 = spy(new Wallet()); + + doReturn(BigInteger.valueOf(1).toByteArray()) + .when(wallet1).getShieldedContractScalingFactor( + ByteArray.fromHexString("4144007979359ECAC395BBD3CEF8060D3DF2DC3F01")); + String parameter = new String(ByteArray.fromHexString( + "7b0a202020202261736b223a22633235313365396533303834393439333262643832653063653533363" + + "63264313734323164393062373261383437316130613132623835353261333336653032222c0a202020" + + "20226e736b223a223463366266336464346130363433643230623632386637653435393830633565313" + + "8376630376135316436663365383661616631616239313663303765623064222c0a20202020226f766b" + + "223a2231376135386439613530353864613665343263613132636432383964306136616131363962393" + + "236633138653139626361353138623864366638363734653433222c0a202020202266726f6d5f616d6f" + + "756e74223a22313030222c0a2020202022736869656c6465645f7265636569766573223a5b0a2020202" + + "0202020207b0a202020202020202020202020226e6f7465223a7b0a2020202020202020202020202020" + + "20202276616c7565223a3130302c0a20202020202020202020202020202020227061796d656e745f616" + + "46472657373223a227a74726f6e317939397536656a71656e757076666b70356736713679716b703061" + + "34346334386374613064643567656a7471613476323768716132636768667664786e6d6e65683671717" + + "1303366613735222c0a202020202020202020202020202020202272636d223a22313662366635653430" + + "34343461623765656162313161653636313363323766333531313739373165666138376237313536306" + + "235383133383239633933393064220a2020202020202020202020207d0a20202020202020207d0a2020" + + "20205d2c0a2020202022736869656c6465645f54524332305f636f6e74726163745f616464726573732" + + "23a22343134343030373937393335394543414333393542424433434546383036304433444632444333" + + "463031220a7d")); + PrivateShieldedTRC20Parameters.Builder builder = PrivateShieldedTRC20Parameters.newBuilder(); + try { + JsonFormat.merge(parameter, builder, false); + } catch (ParseException e) { + Assert.fail(); + } + + try { + ShieldedTRC20Parameters shieldedTRC20Parameters = wallet1.createShieldedContractParameters( + builder.build()); + Assert.assertNotNull(shieldedTRC20Parameters); + } catch (Exception e) { + Assert.fail(); + } + } + + @Test + public void testCreateShieldedContractParametersWithoutAsk() throws ContractExeException { + librustzcashInitZksnarkParams(); + Args.getInstance().setFullNodeAllowShieldedTransactionArgs(true); + + Wallet wallet1 = spy(new Wallet()); + doReturn(BigInteger.valueOf(1).toByteArray()) + .when(wallet1).getShieldedContractScalingFactor( + ByteArray.fromHexString("4144007979359ECAC395BBD3CEF8060D3DF2DC3F01")); + String parameter = new String(ByteArray.fromHexString( + "7b0a2020202022616b223a2230656261373361343865323934396561356461613133626365663466646" + + "633613561613966336232363830363763663831313233333938613833386665336363222c0a20202020" + + "226e736b223a22346336626633646434613036343364323062363238663765343539383063356531383" + + "76630376135316436663365383661616631616239313663303765623064222c0a20202020226f766b22" + + "3a223137613538643961353035386461366534326361313263643238396430613661613136396239323" + + "6633138653139626361353138623864366638363734653433222c0a202020202266726f6d5f616d6f75" + + "6e74223a22313030222c0a2020202022736869656c6465645f7265636569766573223a5b0a202020202" + + "02020207b0a202020202020202020202020226e6f7465223a7b0a202020202020202020202020202020" + + "202276616c7565223a3130302c0a20202020202020202020202020202020227061796d656e745f61646" + + "472657373223a227a74726f6e317939397536656a71656e757076666b70356736713679716b70306134" + + "346334386374613064643567656a7471613476323768716132636768667664786e6d6e6568367171713" + + "03366613735222c0a202020202020202020202020202020202272636d223a2231366236663565343034" + + "34346162376565616231316165363631336332376633353131373937316566613837623731353630623" + + "5383133383239633933393064220a2020202020202020202020207d0a20202020202020207d0a202020" + + "205d2c0a2020202022736869656c6465645f54524332305f636f6e74726163745f61646472657373223" + + "a2234313434303037393739333539454341433339354242443343454638303630443344463244433346" + + "3031220a7d")); + PrivateShieldedTRC20ParametersWithoutAsk.Builder builder = + PrivateShieldedTRC20ParametersWithoutAsk.newBuilder(); + try { + JsonFormat.merge(parameter, builder, false); + } catch (ParseException e) { + Assert.fail(); + } + + try { + ShieldedTRC20Parameters shieldedTRC20Parameters = + wallet1.createShieldedContractParametersWithoutAsk(builder.build()); + Assert.assertNotNull(shieldedTRC20Parameters); + } catch (Exception e) { + Assert.fail(); + } + } +} diff --git a/framework/src/test/java/org/tron/core/ShieldedTRC20BuilderTest.java b/framework/src/test/java/org/tron/core/ShieldedTRC20BuilderTest.java index e7fefd5e121..ff30537ee7a 100644 --- a/framework/src/test/java/org/tron/core/ShieldedTRC20BuilderTest.java +++ b/framework/src/test/java/org/tron/core/ShieldedTRC20BuilderTest.java @@ -37,10 +37,10 @@ import org.tron.core.exception.ContractExeException; import org.tron.core.exception.ContractValidateException; import org.tron.core.exception.ZksnarkException; -import org.tron.core.services.http.FullNodeHttpApiService; import org.tron.core.vm.PrecompiledContracts.VerifyBurnProof; import org.tron.core.vm.PrecompiledContracts.VerifyMintProof; import org.tron.core.vm.PrecompiledContracts.VerifyTransferProof; +import org.tron.core.zen.ZksnarkInitService; import org.tron.core.zen.address.DiversifierT; import org.tron.core.zen.address.ExpandedSpendingKey; import org.tron.core.zen.address.FullViewingKey; @@ -64,12 +64,11 @@ public class ShieldedTRC20BuilderTest extends BaseTest { private static final byte[] PUBLIC_TO_ADDRESS; static { - dbPath = "output_Shielded_TRC20_Api_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, "config-test-mainnet.conf"); + Args.setParam(new String[]{"--output-directory", dbPath()}, "config-test-mainnet.conf"); SHIELDED_CONTRACT_ADDRESS = WalletClient.decodeFromBase58Check(SHIELDED_CONTRACT_ADDRESS_STR); DEFAULT_OVK = ByteArray .fromHexString("030c8c2bc59fb3eb8afb047a8ea4b028743d23e7d38c6fa30908358431e2314d"); - FullNodeHttpApiService.librustzcashInitZksnarkParams(); + ZksnarkInitService.librustzcashInitZksnarkParams(); PUBLIC_TO_ADDRESS = WalletClient.decodeFromBase58Check(PUBLIC_TO_ADDRESS_STR); } diff --git a/framework/src/test/java/org/tron/core/StorageMarketTest.java b/framework/src/test/java/org/tron/core/StorageMarketTest.java index 1c471032861..8b6e90e1c67 100644 --- a/framework/src/test/java/org/tron/core/StorageMarketTest.java +++ b/framework/src/test/java/org/tron/core/StorageMarketTest.java @@ -24,8 +24,7 @@ public class StorageMarketTest extends BaseTest { private static StorageMarket storageMarket; static { - dbPath = "output_storage_market_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; } diff --git a/framework/src/test/java/org/tron/core/WalletTest.java b/framework/src/test/java/org/tron/core/WalletTest.java index 15b51f51edf..357a2d2ca08 100644 --- a/framework/src/test/java/org/tron/core/WalletTest.java +++ b/framework/src/test/java/org/tron/core/WalletTest.java @@ -39,9 +39,12 @@ import org.junit.Ignore; import org.junit.Test; import org.tron.api.GrpcAPI; +import org.tron.api.GrpcAPI.AccountNetMessage; import org.tron.api.GrpcAPI.AssetIssueList; import org.tron.api.GrpcAPI.BlockList; import org.tron.api.GrpcAPI.ExchangeList; +import org.tron.api.GrpcAPI.NumberMessage; +import org.tron.api.GrpcAPI.PricesResponseMessage; import org.tron.api.GrpcAPI.ProposalList; import org.tron.common.BaseTest; import org.tron.common.crypto.ECKey; @@ -128,6 +131,7 @@ public class WalletTest extends BaseTest { private static Transaction transaction4; private static Transaction transaction5; private static AssetIssueCapsule Asset1; + private static AssetIssueCapsule Asset2; private static final String OWNER_ADDRESS; private static final String RECEIVER_ADDRESS; @@ -135,8 +139,7 @@ public class WalletTest extends BaseTest { private static boolean init; static { - dbPath = "output_wallet_test"; - Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; } @@ -234,11 +237,11 @@ private void addTransactionInfoToStore(Transaction transaction) { private static Transaction getBuildTransaction( TransferContract transferContract, long transactionTimestamp, long refBlockNum) { return Transaction.newBuilder().setRawData( - Transaction.raw.newBuilder().setTimestamp(transactionTimestamp) - .setRefBlockNum(refBlockNum) - .addContract( - Contract.newBuilder().setType(ContractType.TransferContract) - .setParameter(Any.pack(transferContract)).build()).build()) + Transaction.raw.newBuilder().setTimestamp(transactionTimestamp) + .setRefBlockNum(refBlockNum) + .addContract( + Contract.newBuilder().setType(ContractType.TransferContract) + .setParameter(Any.pack(transferContract)).build()).build()) .build(); } @@ -287,18 +290,26 @@ private void addBlockToStore(Block block) { private static Block getBuildBlock(long timestamp, long num, long witnessId, String witnessAddress, Transaction transaction, Transaction transactionNext) { return Block.newBuilder().setBlockHeader(BlockHeader.newBuilder().setRawData( - raw.newBuilder().setTimestamp(timestamp).setNumber(num).setWitnessId(witnessId) - .setWitnessAddress(ByteString.copyFrom(ByteArray.fromHexString(witnessAddress))) - .build()).build()).addTransactions(transaction).addTransactions(transactionNext) + raw.newBuilder().setTimestamp(timestamp).setNumber(num).setWitnessId(witnessId) + .setWitnessAddress(ByteString.copyFrom(ByteArray.fromHexString(witnessAddress))) + .build()).build()).addTransactions(transaction).addTransactions(transactionNext) .build(); } private void buildAssetIssue() { AssetIssueContract.Builder builder = AssetIssueContract.newBuilder(); + builder.setOwnerAddress(ByteString.copyFromUtf8("Address1")); builder.setName(ByteString.copyFromUtf8("Asset1")); Asset1 = new AssetIssueCapsule(builder.build()); chainBaseManager.getAssetIssueStore().put(Asset1.createDbKey(), Asset1); + + AssetIssueContract.Builder builder2 = AssetIssueContract.newBuilder(); + builder2.setOwnerAddress(ByteString.copyFromUtf8("Address2")); + builder2.setName(ByteString.copyFromUtf8("Asset2")); + builder2.setId("id2"); + Asset2 = new AssetIssueCapsule(builder2.build()); + chainBaseManager.getAssetIssueV2Store().put(Asset2.getId().getBytes(), Asset2); } private void buildProposal() { @@ -498,6 +509,52 @@ public void getPaginatedAssetIssueList() { } } + @Test + public void testGetAssetIssueByAccount() { + buildAssetIssue(); + // + AssetIssueList assetIssueList = wallet.getAssetIssueByAccount( + ByteString.copyFromUtf8("Address1")); + Assert.assertEquals(1, assetIssueList.getAssetIssueCount()); + } + + @Test + public void testGetAssetIssueList() { + buildAssetIssue(); + // + AssetIssueList assetIssueList = wallet.getAssetIssueList(); + Assert.assertEquals(1, assetIssueList.getAssetIssueCount()); + } + + @Test + public void testGetAssetIssueListByName() { + buildAssetIssue(); + // + AssetIssueList assetIssueList = wallet.getAssetIssueListByName( + ByteString.copyFromUtf8("Asset1")); + Assert.assertEquals(1, assetIssueList.getAssetIssueCount()); + } + + @Test + public void testGetAssetIssueById() { + buildAssetIssue(); + // + AssetIssueContract assetIssueContract = wallet.getAssetIssueById("id2"); + Assert.assertNotNull(assetIssueContract); + } + + @Test + public void testGetAccountNet() { + ByteString addressByte = ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)); + AccountCapsule accountCapsule = + new AccountCapsule(Protocol.Account.newBuilder().setAddress(addressByte).build()); + accountCapsule.setBalance(1000_000_000L); + dbManager.getChainBaseManager().getAccountStore() + .put(accountCapsule.createDbKey(), accountCapsule); + AccountNetMessage accountNetMessage = wallet.getAccountNet(addressByte); + Assert.assertNotNull(accountNetMessage); + } + @Test public void getPaginatedProposalList() { buildProposal(); @@ -531,6 +588,16 @@ public void getPaginatedProposalList() { } + @Test + public void testGetProposalById() { + buildProposal(); + // + Proposal proposal = wallet.getProposalById(ByteString.copyFrom(ByteArray.fromLong(1L))); + Assert.assertNotNull(proposal); + proposal = wallet.getProposalById(ByteString.copyFrom(ByteArray.fromLong(3L))); + Assert.assertNull(proposal); + } + @Test public void getPaginatedExchangeList() { buildExchange(); @@ -541,6 +608,24 @@ public void getPaginatedExchangeList() { exchangeList.getExchangesList().get(1).getCreatorAddress().toStringUtf8()); } + @Test + public void testGetExchangeById() { + buildExchange(); + // + Exchange exchange = wallet.getExchangeById(ByteString.copyFrom(ByteArray.fromLong(1L))); + Assert.assertNotNull(exchange); + exchange = wallet.getExchangeById(ByteString.copyFrom(ByteArray.fromLong(3L))); + Assert.assertNull(exchange); + } + + @Test + public void testGetExchangeList() { + buildExchange(); + // + ExchangeList exchangeList = wallet.getExchangeList(); + Assert.assertEquals(2, exchangeList.getExchangesCount()); + } + @Test public void getBlock() { GrpcAPI.BlockReq req = GrpcAPI.BlockReq.getDefaultInstance(); @@ -567,6 +652,12 @@ public void getBlock() { assertEquals(block, wallet.getBlock(req)); } + @Test + public void testGetNextMaintenanceTime() { + NumberMessage numberMessage = wallet.getNextMaintenanceTime(); + Assert.assertEquals(0, numberMessage.getNum()); + } + //@Test public void testChainParameters() { @@ -651,8 +742,8 @@ public void testGetDelegatedResourceAccountIndex() { } private Any getDelegatedContractForCpu(String ownerAddress, String receiverAddress, - long frozenBalance, - long duration) { + long frozenBalance, + long duration) { return Any.pack( BalanceContract.FreezeBalanceContract.newBuilder() .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(ownerAddress))) @@ -688,13 +779,13 @@ private void freezeCpuForOwner() { } private Any getDelegateContractForBandwidth(String ownerAddress, String receiveAddress, - long unfreezeBalance) { + long unfreezeBalance) { return getLockedDelegateContractForBandwidth(ownerAddress, receiveAddress, unfreezeBalance, false); } private Any getLockedDelegateContractForBandwidth(String ownerAddress, String receiveAddress, - long unfreezeBalance, boolean lock) { + long unfreezeBalance, boolean lock) { return Any.pack(BalanceContract.DelegateResourceContract.newBuilder() .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(ownerAddress))) .setReceiverAddress(ByteString.copyFrom(ByteArray.fromHexString(receiveAddress))) @@ -895,8 +986,8 @@ public void testGetCanWithdrawUnfreezeAmount() { @Test public void testGetMemoFeePrices() { - String memeFeeList = wallet.getMemoFeePrices(); - Assert.assertEquals("0:0", memeFeeList); + PricesResponseMessage memeFeeList = wallet.getMemoFeePrices(); + Assert.assertEquals("0:0", memeFeeList.getPrices()); } @Test @@ -914,7 +1005,7 @@ public void testGetAccountById() { chainBaseManager.getAccountIdIndexStore().put(ownerCapsule); Protocol.Account account = wallet.getAccountById( Protocol.Account.newBuilder().setAccountId(ByteString.copyFromUtf8("1001")).build()); - Assert.assertEquals(ownerCapsule.getAddress(),account.getAddress()); + Assert.assertEquals(ownerCapsule.getAddress(), account.getAddress()); } @Test @@ -932,18 +1023,18 @@ public void testGetAssetIssueByName() { String assetName = "My_asset"; String id = "10001"; AssetIssueCapsule assetCapsule = new AssetIssueCapsule(ByteArray.fromHexString(OWNER_ADDRESS), - id,assetName,"abbr", 1_000_000_000_000L,6); + id, assetName, "abbr", 1_000_000_000_000L, 6); chainBaseManager.getAssetIssueStore().put(assetCapsule.createDbKey(), assetCapsule); chainBaseManager.getAssetIssueV2Store().put(assetCapsule.createDbV2Key(), assetCapsule); try { AssetIssueContract assetIssue = wallet.getAssetIssueByName(ByteString.copyFromUtf8(assetName)); - Assert.assertEquals(ByteString.copyFromUtf8(assetName),assetIssue.getName()); - Assert.assertEquals(id,assetIssue.getId()); + Assert.assertEquals(ByteString.copyFromUtf8(assetName), assetIssue.getName()); + Assert.assertEquals(id, assetIssue.getId()); chainBaseManager.getDynamicPropertiesStore().saveAllowSameTokenName(1); assetIssue = wallet.getAssetIssueByName(ByteString.copyFromUtf8(assetName)); - Assert.assertEquals(ByteString.copyFromUtf8(assetName),assetIssue.getName()); - Assert.assertEquals(id,assetIssue.getId()); + Assert.assertEquals(ByteString.copyFromUtf8(assetName), assetIssue.getName()); + Assert.assertEquals(id, assetIssue.getId()); } catch (NonUniqueObjectException e) { Assert.fail(e.getMessage()); } @@ -1072,5 +1163,48 @@ public void testListNodes() { GrpcAPI.NodeList nodeList = wallet.listNodes(); assertEquals(0, nodeList.getNodesList().size()); } + + /** + * We calculate the size of the structure and conclude that + * delegate_balance = 1000_000L; => 277 + * delegate_balance = 1000_000_000L; => 279 + * delegate_balance = 1000_000_000_000L => 280 + * + * We initialize account information as follows + * account balance = 1000_000_000_000L + * account frozen_balance = 1000_000_000L + * + * then estimateConsumeBandWidthSize cost 279 + * + * so we have following result: + * TransactionUtil.estimateConsumeBandWidthSize( + * dynamicStore,ownerCapsule.getBalance()) ===> false + * TransactionUtil.estimateConsumeBandWidthSize( + * dynamicStore,ownerCapsule.getFrozenV2BalanceForBandwidth()) ===> true + * + * This test case is used to verify the above conclusions + */ + @Test + public void testGetCanDelegatedMaxSizeBandWidth123() { + long frozenBalance = 1000_000_000L; + AccountCapsule ownerCapsule = + dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); + ownerCapsule.addFrozenBalanceForBandwidthV2(frozenBalance); + ownerCapsule.setNetUsage(0L); + ownerCapsule.setEnergyUsage(0L); + dbManager.getDynamicPropertiesStore().saveTotalNetWeight(0L); + dbManager.getDynamicPropertiesStore().saveTotalEnergyWeight(0L); + dbManager.getDynamicPropertiesStore().addTotalNetWeight( + frozenBalance / TRX_PRECISION + 43100000000L); + dbManager.getAccountStore().put(ownerCapsule.getAddress().toByteArray(), ownerCapsule); + + GrpcAPI.CanDelegatedMaxSizeResponseMessage message = wallet.getCanDelegatedMaxSize( + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), + BANDWIDTH.getNumber()); + Assert.assertEquals(frozenBalance / TRX_PRECISION - 279, + message.getMaxSize() / TRX_PRECISION); + chainBaseManager.getDynamicPropertiesStore().saveMaxDelegateLockPeriod(DELEGATE_PERIOD / 3000); + } + } diff --git a/framework/src/test/java/org/tron/core/actuator/AccountPermissionUpdateActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/AccountPermissionUpdateActuatorTest.java index 888e13f1ae6..69bac08c3e6 100644 --- a/framework/src/test/java/org/tron/core/actuator/AccountPermissionUpdateActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/AccountPermissionUpdateActuatorTest.java @@ -1,7 +1,7 @@ package org.tron.core.actuator; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.fail; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; import com.google.protobuf.Any; import com.google.protobuf.ByteString; @@ -52,8 +52,7 @@ public class AccountPermissionUpdateActuatorTest extends BaseTest { private static final String KEY_ADDRESS_INVALID = "bbbb"; static { - dbPath = "output_account_permission_update_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; WITNESS_ADDRESS = Wallet.getAddressPreFixString() + "8CFC572CC20CA18B636BDD93B4FB15EA84CC2B4E"; KEY_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; diff --git a/framework/src/test/java/org/tron/core/actuator/ActuatorConstantTest.java b/framework/src/test/java/org/tron/core/actuator/ActuatorConstantTest.java index 3ad6aa1d6dd..b8c2bd4fef9 100644 --- a/framework/src/test/java/org/tron/core/actuator/ActuatorConstantTest.java +++ b/framework/src/test/java/org/tron/core/actuator/ActuatorConstantTest.java @@ -17,8 +17,7 @@ public class ActuatorConstantTest extends BaseTest { */ @BeforeClass public static void init() { - dbPath = "output_actuatorConstant_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); } @Test diff --git a/framework/src/test/java/org/tron/core/actuator/AssetIssueActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/AssetIssueActuatorTest.java index 17cf0e2286c..77c24c28797 100755 --- a/framework/src/test/java/org/tron/core/actuator/AssetIssueActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/AssetIssueActuatorTest.java @@ -1,6 +1,6 @@ package org.tron.core.actuator; -import static org.testng.Assert.fail; +import static org.junit.Assert.fail; import com.google.protobuf.Any; import com.google.protobuf.ByteString; @@ -47,8 +47,7 @@ public class AssetIssueActuatorTest extends BaseTest { private static long endTime = 0; static { - dbPath = "output_assetIssue_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ADDRESS_SECOND = Wallet .getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; diff --git a/framework/src/test/java/org/tron/core/actuator/CancelAllUnfreezeV2ActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/CancelAllUnfreezeV2ActuatorTest.java index fcc545a0fc2..fc2dad88420 100644 --- a/framework/src/test/java/org/tron/core/actuator/CancelAllUnfreezeV2ActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/CancelAllUnfreezeV2ActuatorTest.java @@ -35,8 +35,7 @@ public class CancelAllUnfreezeV2ActuatorTest extends BaseTest { private static final long initBalance = 10_000_000_000L; static { - dbPath = "output_cancel_all_unfreeze_v2_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ACCOUNT_INVALID = diff --git a/framework/src/test/java/org/tron/core/actuator/ClearABIContractActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/ClearABIContractActuatorTest.java index 1f6571e8868..3a23151f6bc 100644 --- a/framework/src/test/java/org/tron/core/actuator/ClearABIContractActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/ClearABIContractActuatorTest.java @@ -43,8 +43,7 @@ public class ClearABIContractActuatorTest extends BaseTest { private static final ABI TARGET_ABI = ABI.getDefaultInstance(); static { - dbPath = "output_clearabicontract_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_NOTEXIST = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; diff --git a/framework/src/test/java/org/tron/core/actuator/CreateAccountActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/CreateAccountActuatorTest.java index 11f68c0b8bb..f756f3dd087 100755 --- a/framework/src/test/java/org/tron/core/actuator/CreateAccountActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/CreateAccountActuatorTest.java @@ -1,6 +1,6 @@ package org.tron.core.actuator; -import static org.testng.Assert.fail; +import static org.junit.Assert.fail; import com.google.protobuf.Any; import com.google.protobuf.ByteString; @@ -32,8 +32,7 @@ public class CreateAccountActuatorTest extends BaseTest { private static final String INVALID_ACCOUNT_ADDRESS; static { - dbPath = "output_CreateAccount_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS_FIRST = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_SECOND = diff --git a/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java index b71f67ccbed..61d4ab6e2a4 100644 --- a/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java @@ -1,6 +1,9 @@ package org.tron.core.actuator; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -25,6 +28,7 @@ import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.DelegatedResourceAccountIndexCapsule; import org.tron.core.capsule.DelegatedResourceCapsule; +import org.tron.core.capsule.TransactionCapsule; import org.tron.core.capsule.TransactionResultCapsule; import org.tron.core.config.args.Args; import org.tron.core.exception.ContractExeException; @@ -33,6 +37,7 @@ import org.tron.core.state.WorldStateQueryInstance; import org.tron.core.state.store.DynamicPropertiesStateStore; import org.tron.core.store.DynamicPropertiesStore; +import org.tron.protos.Protocol; import org.tron.protos.Protocol.AccountType; import org.tron.protos.Protocol.Transaction.Result.code; import org.tron.protos.contract.AssetIssueContractOuterClass; @@ -46,13 +51,12 @@ public class DelegateResourceActuatorTest extends BaseTest { private static final String RECEIVER_ADDRESS; private static final String OWNER_ADDRESS_INVALID = "aaaa"; private static final String OWNER_ACCOUNT_INVALID; - private static final long initBalance = 10_000_000_000L; + private static final long initBalance = 1000_000_000_000L; @Resource private WorldStateCallBack worldStateCallBack; static { - dbPath = "output_delegate_resource_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ACCOUNT_INVALID = @@ -65,6 +69,7 @@ public class DelegateResourceActuatorTest extends BaseTest { @Before public void createAccountCapsule() { worldStateCallBack.setExecute(true); + dbManager.getDynamicPropertiesStore().saveTotalNetWeight(0L); dbManager.getDynamicPropertiesStore().saveUnfreezeDelayDays(1L); dbManager.getDynamicPropertiesStore().saveAllowNewResourceModel(1L); @@ -192,7 +197,8 @@ public void testDelegateResourceWithNoFreeze() { actuator.execute(ret); fail("cannot run here."); } catch (ContractValidateException e) { - assertEquals("delegateBalance must be less than available FreezeBandwidthV2 balance", + assertEquals( + "delegateBalance must be less than or equal to available FreezeBandwidthV2 balance", e.getMessage()); } catch (ContractExeException e) { fail(); @@ -206,7 +212,7 @@ public void testDelegateResourceWithNoFreeze() { fail("cannot run here."); } catch (ContractValidateException e) { assertEquals( - "delegateBalance must be less than available FreezeEnergyV2 balance", + "delegateBalance must be less than or equal to available FreezeEnergyV2 balance", e.getMessage()); } catch (ContractExeException e) { fail(e.getMessage()); @@ -235,7 +241,8 @@ public void testDelegateBandwidthWithUsage() { actuator.execute(ret); fail("cannot run here."); } catch (ContractValidateException e) { - assertEquals("delegateBalance must be less than available FreezeBandwidthV2 balance", + assertEquals( + "delegateBalance must be less than or equal to available FreezeBandwidthV2 balance", e.getMessage()); } catch (ContractExeException e) { fail(e.getMessage()); @@ -265,7 +272,7 @@ public void testDelegateCpuWithUsage() { fail("cannot run here."); } catch (ContractValidateException e) { assertEquals( - "delegateBalance must be less than available FreezeEnergyV2 balance", + "delegateBalance must be less than or equal to available FreezeEnergyV2 balance", e.getMessage()); } catch (ContractExeException e) { fail(e.getMessage()); @@ -443,9 +450,9 @@ public void testLockedDelegateResourceForBandwidth() { .get(DelegatedResourceCapsule .createDbKeyV2(ByteArray.fromHexString(OWNER_ADDRESS), ByteArray.fromHexString(RECEIVER_ADDRESS), true)); - Assert.assertNull(delegatedResourceCapsule); - Assert.assertNotNull(lockedResourceCapsule); - Assert.assertNotEquals(0, lockedResourceCapsule.getExpireTimeForBandwidth()); + assertNull(delegatedResourceCapsule); + assertNotNull(lockedResourceCapsule); + assertNotEquals(0, lockedResourceCapsule.getExpireTimeForBandwidth()); assertEquals(delegateBalance, lockedResourceCapsule.getFrozenBalanceForBandwidth()); long totalNetWeightAfter = dbManager.getDynamicPropertiesStore().getTotalNetWeight(); assertEquals(totalNetWeightBefore, totalNetWeightAfter); @@ -698,7 +705,8 @@ public void delegateLessThanZero() { actuator.execute(ret); fail("cannot run here."); } catch (ContractValidateException e) { - assertEquals("delegateBalance must be more than 1TRX", e.getMessage()); + assertEquals("delegateBalance must be greater than or equal to 1 TRX", + e.getMessage()); } catch (ContractExeException e) { fail(e.getMessage()); } @@ -736,7 +744,8 @@ public void delegateMoreThanBalance() { actuator.execute(ret); fail("cannot run here."); } catch (ContractValidateException e) { - assertEquals("delegateBalance must be less than available FreezeBandwidthV2 balance", + assertEquals( + "delegateBalance must be less than or equal to available FreezeBandwidthV2 balance", e.getMessage()); } catch (ContractExeException e) { fail(e.getMessage()); @@ -859,6 +868,62 @@ private Any getErrorContract() { ); } + + /** + * We calculate the size of the structure and conclude that + * delegate_balance = 1000_000L; => 277 + * delegate_balance = 1000_000_000L; => 279 + * delegate_balance = 1000_000_000_000L => 280 + * + * We initialize account information as follows + * account balance = 1000_000_000_000L + * account frozen_balance = 1000_000_000L + * + * then estimateConsumeBandWidthSize cost 279 + * + * so we have following result: + * TransactionUtil.estimateConsumeBandWidthSize( + * dynamicStore,ownerCapsule.getBalance()) ===> false + * TransactionUtil.estimateConsumeBandWidthSize( + * dynamicStore,ownerCapsule.getFrozenV2BalanceForBandwidth()) ===> true + * + * This test case is used to verify the above conclusions + */ + @Test + public void testDelegateResourceNoFreeze123() { + long frozenBalance = 1000_000_000L; + AccountCapsule ownerCapsule = + dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); + ownerCapsule.addFrozenBalanceForBandwidthV2(frozenBalance); + dbManager.getDynamicPropertiesStore().addTotalNetWeight( + frozenBalance / TRX_PRECISION + 43100000000L); + dbManager.getAccountStore().put(ownerCapsule.getAddress().toByteArray(), ownerCapsule); + + long delegateBalance = frozenBalance - 279 * TRX_PRECISION; + //long delegateBalance = initBalance; + DelegateResourceActuator actuator = new DelegateResourceActuator(); + TransactionCapsule transactionCapsule = new TransactionCapsule( + getDelegateContractForBandwidth(OWNER_ADDRESS, RECEIVER_ADDRESS, delegateBalance), + Protocol.Transaction.Contract.ContractType.DelegateResourceContract + ); + transactionCapsule.setTransactionCreate(true); + actuator.setChainBaseManager(dbManager.getChainBaseManager()).setAny( + getDelegateContractForBandwidth(OWNER_ADDRESS, RECEIVER_ADDRESS, delegateBalance)); + actuator.setTx(transactionCapsule); + + boolean bSuccess = true; + try { + actuator.validate(); + } catch (ContractValidateException e) { + assertEquals( + "delegateBalance must be less than or equal to available FreezeBandwidthV2 balance", + e.getMessage()); + bSuccess = false; + } + Assert.assertEquals(true, bSuccess); + } + + private WorldStateQueryInstance getQueryInstance() { Assert.assertNotNull(worldStateCallBack.getTrie()); worldStateCallBack.clear(); diff --git a/framework/src/test/java/org/tron/core/actuator/ExchangeCreateActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/ExchangeCreateActuatorTest.java index f37016845d4..807d0e1be02 100644 --- a/framework/src/test/java/org/tron/core/actuator/ExchangeCreateActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/ExchangeCreateActuatorTest.java @@ -1,6 +1,6 @@ package org.tron.core.actuator; -import static org.testng.Assert.fail; +import static org.junit.Assert.fail; import com.google.protobuf.Any; import com.google.protobuf.ByteString; @@ -40,8 +40,7 @@ public class ExchangeCreateActuatorTest extends BaseTest { private static final String OWNER_ADDRESS_NOACCOUNT; static { - dbPath = "output_ExchangeCreate_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS_FIRST = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_SECOND = diff --git a/framework/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java index 49a80fd3253..6268c226c7e 100644 --- a/framework/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/ExchangeInjectActuatorTest.java @@ -1,6 +1,6 @@ package org.tron.core.actuator; -import static org.testng.Assert.fail; +import static org.junit.Assert.fail; import static org.tron.core.config.Parameter.ChainSymbol.TRX_SYMBOL_BYTES; import com.google.protobuf.Any; @@ -41,8 +41,7 @@ public class ExchangeInjectActuatorTest extends BaseTest { private static final String OWNER_ADDRESS_NOACCOUNT; static { - dbPath = "output_ExchangeInject_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS_FIRST = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_SECOND = diff --git a/framework/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java index dad6b24e03e..02107427cad 100644 --- a/framework/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/ExchangeTransactionActuatorTest.java @@ -1,6 +1,6 @@ package org.tron.core.actuator; -import static org.testng.Assert.fail; +import static org.junit.Assert.fail; import static org.tron.core.config.Parameter.ChainSymbol.TRX_SYMBOL_BYTES; import com.google.protobuf.Any; @@ -42,8 +42,7 @@ public class ExchangeTransactionActuatorTest extends BaseTest { private static final String OWNER_ADDRESS_NOACCOUNT; static { - dbPath = "output_ExchangeTransaction_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS_FIRST = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_SECOND = diff --git a/framework/src/test/java/org/tron/core/actuator/ExchangeWithdrawActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/ExchangeWithdrawActuatorTest.java index ad08b49c9ee..6844925288e 100644 --- a/framework/src/test/java/org/tron/core/actuator/ExchangeWithdrawActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/ExchangeWithdrawActuatorTest.java @@ -1,6 +1,6 @@ package org.tron.core.actuator; -import static org.testng.Assert.fail; +import static org.junit.Assert.fail; import static org.tron.core.config.Parameter.ChainSymbol.TRX_SYMBOL_BYTES; import com.google.protobuf.Any; @@ -42,8 +42,7 @@ public class ExchangeWithdrawActuatorTest extends BaseTest { private static final String OWNER_ADDRESS_NOACCOUNT; static { - dbPath = "output_ExchangeWithdraw_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS_FIRST = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_SECOND = diff --git a/framework/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java index 64e741d3f9d..690d530a227 100644 --- a/framework/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/FreezeBalanceActuatorTest.java @@ -49,8 +49,7 @@ public class FreezeBalanceActuatorTest extends BaseTest { private WorldStateCallBack worldStateCallBack; static { - dbPath = "output_freeze_balance_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ACCOUNT_INVALID = @@ -151,7 +150,7 @@ public void testFreezeBalanceForBandwidth() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule owner = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -167,10 +166,8 @@ public void testFreezeBalanceForBandwidth() { Assert.assertEquals(owner.getFrozenBalance(), frozenBalance); Assert.assertEquals(frozenBalance, owner.getTronPower()); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -186,7 +183,7 @@ public void testFreezeBalanceForEnergy() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule owner = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -203,10 +200,8 @@ public void testFreezeBalanceForEnergy() { Assert.assertEquals(frozenBalance, owner.getEnergyFrozenBalance()); Assert.assertEquals(frozenBalance, owner.getTronPower()); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -236,9 +231,9 @@ public void testFreezeDelegatedBalanceForBandwidthWithContractAddress() { actuator.validate(); actuator.execute(ret); } catch (ContractValidateException e) { - Assert.assertEquals(e.getMessage(), "Do not allow delegate resources to contract addresses"); + Assert.assertEquals("Do not allow delegate resources to contract addresses", e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } } @@ -257,7 +252,7 @@ public void testFreezeDelegatedBalanceForBandwidth() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule owner = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -310,9 +305,8 @@ public void testFreezeDelegatedBalanceForBandwidth() { Assert .assertEquals(0, delegatedResourceAccountIndexCapsuleOwner.getFromAccountsList().size()); Assert.assertEquals(1, delegatedResourceAccountIndexCapsuleOwner.getToAccountsList().size()); - Assert.assertEquals(true, - delegatedResourceAccountIndexCapsuleOwner.getToAccountsList() - .contains(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS)))); + Assert.assertTrue(delegatedResourceAccountIndexCapsuleOwner.getToAccountsList() + .contains(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS)))); delegatedResourceAccountIndexCapsuleOwner = queryInstance.getDelegatedResourceAccountIndex( ByteArray.fromHexString(OWNER_ADDRESS)); @@ -332,9 +326,8 @@ public void testFreezeDelegatedBalanceForBandwidth() { Assert .assertEquals(1, delegatedResourceAccountIndexCapsuleReceiver.getFromAccountsList().size()); - Assert.assertEquals(true, - delegatedResourceAccountIndexCapsuleReceiver.getFromAccountsList() - .contains(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)))); + Assert.assertTrue(delegatedResourceAccountIndexCapsuleReceiver.getFromAccountsList() + .contains(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)))); delegatedResourceAccountIndexCapsuleReceiver = queryInstance.getDelegatedResourceAccountIndex( ByteArray.fromHexString(RECEIVER_ADDRESS)); @@ -346,10 +339,8 @@ public void testFreezeDelegatedBalanceForBandwidth() { .contains(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)))); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -431,7 +422,7 @@ public void testFreezeDelegatedBalanceForCpuSameNameTokenActive() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule owner = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -466,9 +457,8 @@ public void testFreezeDelegatedBalanceForCpuSameNameTokenActive() { Assert .assertEquals(0, delegatedResourceAccountIndexCapsuleOwner.getFromAccountsList().size()); Assert.assertEquals(1, delegatedResourceAccountIndexCapsuleOwner.getToAccountsList().size()); - Assert.assertEquals(true, - delegatedResourceAccountIndexCapsuleOwner.getToAccountsList() - .contains(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS)))); + Assert.assertTrue(delegatedResourceAccountIndexCapsuleOwner.getToAccountsList() + .contains(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS)))); DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsuleReceiver = dbManager .getDelegatedResourceAccountIndexStore().get(ByteArray.fromHexString(RECEIVER_ADDRESS)); @@ -477,14 +467,11 @@ public void testFreezeDelegatedBalanceForCpuSameNameTokenActive() { Assert .assertEquals(1, delegatedResourceAccountIndexCapsuleReceiver.getFromAccountsList().size()); - Assert.assertEquals(true, - delegatedResourceAccountIndexCapsuleReceiver.getFromAccountsList() - .contains(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)))); + Assert.assertTrue(delegatedResourceAccountIndexCapsuleReceiver.getFromAccountsList() + .contains(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)))); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -502,7 +489,7 @@ public void testFreezeDelegatedBalanceForCpuSameNameTokenClose() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule owner = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); Assert.assertEquals(owner.getBalance(), initBalance - frozenBalance @@ -522,10 +509,8 @@ public void testFreezeDelegatedBalanceForCpuSameNameTokenClose() { Assert.assertEquals(totalEnergyWeightBefore + frozenBalance / 1000_000L, totalEnergyWeightAfter); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -543,10 +528,9 @@ public void freezeLessThanZero() { fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("frozenBalance must be positive", e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } } @@ -564,10 +548,10 @@ public void freezeMoreThanBalance() { actuator.execute(ret); fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); - Assert.assertEquals("frozenBalance must be less than accountBalance", e.getMessage()); + Assert.assertEquals( + "frozenBalance must be less than or equal to accountBalance", e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } } @@ -586,12 +570,9 @@ public void invalidOwnerAddress() { fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); - Assert.assertEquals("Invalid address", e.getMessage()); - } catch (ContractExeException e) { - Assert.assertTrue(e instanceof ContractExeException); + Assert.fail(); } } @@ -610,11 +591,10 @@ public void invalidOwnerAccount() { actuator.execute(ret); fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("Account[" + OWNER_ACCOUNT_INVALID + "] not exists", e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } } @@ -635,11 +615,10 @@ public void durationLessThanMin() { } catch (ContractValidateException e) { long minFrozenTime = dbManager.getDynamicPropertiesStore().getMinFrozenTime(); long maxFrozenTime = dbManager.getDynamicPropertiesStore().getMaxFrozenTime(); - Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("frozenDuration must be less than " + maxFrozenTime + " days " + "and more than " + minFrozenTime + " days", e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } } @@ -659,11 +638,10 @@ public void durationMoreThanMax() { } catch (ContractValidateException e) { long minFrozenTime = dbManager.getDynamicPropertiesStore().getMinFrozenTime(); long maxFrozenTime = dbManager.getDynamicPropertiesStore().getMaxFrozenTime(); - Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("frozenDuration must be less than " + maxFrozenTime + " days " + "and more than " + minFrozenTime + " days", e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } } @@ -681,10 +659,10 @@ public void lessThan1TrxTest() { actuator.execute(ret); fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); - Assert.assertEquals("frozenBalance must be more than 1TRX", e.getMessage()); + Assert.assertEquals("frozenBalance must be greater than or equal to 1 TRX", + e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } } @@ -708,10 +686,9 @@ public void frozenNumTest() { actuator.execute(ret); fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("frozenCount must be 0 or 1", e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } } @@ -727,10 +704,8 @@ public void moreThanFrozenNumber() { try { actuator.validate(); actuator.execute(ret); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } try { actuator.validate(); @@ -738,11 +713,10 @@ public void moreThanFrozenNumber() { fail("cannot run here."); } catch (ContractValidateException e) { long maxFrozenNumber = ChainConstant.MAX_FROZEN_NUMBER; - Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("max frozen number is: " + maxFrozenNumber, e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } } @@ -783,16 +757,14 @@ public void testFreezeBalanceForEnergyWithoutOldTronPowerAfterNewResourceModel() try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule owner = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); Assert.assertEquals(-1L, owner.getInstance().getOldTronPower()); Assert.assertEquals(0L, owner.getAllTronPower()); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -816,16 +788,14 @@ public void testFreezeBalanceForEnergyWithOldTronPowerAfterNewResourceModel() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); owner = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); Assert.assertEquals(100L, owner.getInstance().getOldTronPower()); Assert.assertEquals(100L, owner.getAllTronPower()); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -849,16 +819,14 @@ public void testFreezeBalanceForTronPowerWithOldTronPowerAfterNewResourceModel() try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); owner = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); Assert.assertEquals(100L, owner.getInstance().getOldTronPower()); Assert.assertEquals(frozenBalance + 100L, owner.getAllTronPower()); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } diff --git a/framework/src/test/java/org/tron/core/actuator/FreezeBalanceV2ActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/FreezeBalanceV2ActuatorTest.java index 57241b17900..975977a7fcc 100644 --- a/framework/src/test/java/org/tron/core/actuator/FreezeBalanceV2ActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/FreezeBalanceV2ActuatorTest.java @@ -42,8 +42,7 @@ public class FreezeBalanceV2ActuatorTest extends BaseTest { private WorldStateCallBack worldStateCallBack; static { - dbPath = "output_freeze_balance_v2_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ACCOUNT_INVALID = @@ -141,7 +140,7 @@ public void testFreezeBalanceForBandwidth() { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule owner = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -155,10 +154,8 @@ public void testFreezeBalanceForBandwidth() { Assert.assertEquals(owner.getFrozenV2BalanceForBandwidth(), frozenBalance); Assert.assertEquals(frozenBalance, owner.getTronPower()); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -173,7 +170,7 @@ public void testFreezeBalanceForEnergy() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule owner = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -188,10 +185,8 @@ public void testFreezeBalanceForEnergy() { Assert.assertEquals(0L, owner.getAllFrozenBalanceForBandwidth()); Assert.assertEquals(frozenBalance, owner.getAllFrozenBalanceForEnergy()); Assert.assertEquals(frozenBalance, owner.getTronPower()); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -209,10 +204,9 @@ public void freezeLessThanZero() { fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("frozenBalance must be positive", e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } } @@ -229,10 +223,10 @@ public void freezeMoreThanBalance() { actuator.execute(ret); fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); - Assert.assertEquals("frozenBalance must be less than accountBalance", e.getMessage()); + Assert.assertEquals("frozenBalance must be less than or equal to accountBalance", + e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } } @@ -250,12 +244,9 @@ public void invalidOwnerAddress() { fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); - Assert.assertEquals("Invalid address", e.getMessage()); - } catch (ContractExeException e) { - Assert.assertTrue(e instanceof ContractExeException); + Assert.fail(); } } @@ -273,11 +264,10 @@ public void invalidOwnerAccount() { actuator.execute(ret); fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("Account[" + OWNER_ACCOUNT_INVALID + "] not exists", e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } } @@ -294,10 +284,10 @@ public void lessThan1TrxTest() { actuator.execute(ret); fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); - Assert.assertEquals("frozenBalance must be more than 1TRX", e.getMessage()); + Assert.assertEquals("frozenBalance must be greater than or equal to 1 TRX", + e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } } @@ -312,10 +302,8 @@ public void moreThanFrozenNumber() { try { actuator.validate(); actuator.execute(ret); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } try { actuator.validate(); @@ -323,11 +311,9 @@ public void moreThanFrozenNumber() { fail("cannot run here."); } catch (ContractValidateException e) { long maxFrozenNumber = ChainConstant.MAX_FROZEN_NUMBER; - Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("max frozen number is: " + maxFrozenNumber, e.getMessage()); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } } @@ -367,16 +353,14 @@ public void testFreezeBalanceForEnergyWithoutOldTronPowerAfterNewResourceModel() try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule owner = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); Assert.assertEquals(-1L, owner.getInstance().getOldTronPower()); Assert.assertEquals(0L, owner.getAllTronPower()); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -384,7 +368,6 @@ public void testFreezeBalanceForEnergyWithoutOldTronPowerAfterNewResourceModel() @Test public void testFreezeBalanceForEnergyWithOldTronPowerAfterNewResourceModel() { long frozenBalance = 1_000_000_000L; - long duration = 3; FreezeBalanceV2Actuator actuator = new FreezeBalanceV2Actuator(); ChainBaseManager chainBaseManager = dbManager.getChainBaseManager(); chainBaseManager.getDynamicPropertiesStore().saveUnfreezeDelayDays(1L); @@ -401,7 +384,7 @@ public void testFreezeBalanceForEnergyWithOldTronPowerAfterNewResourceModel() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); owner = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -412,10 +395,8 @@ public void testFreezeBalanceForEnergyWithOldTronPowerAfterNewResourceModel() { Assert.assertEquals(100L, owner.getInstance().getOldTronPower()); Assert.assertEquals(100L, owner.getAllTronPower()); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -438,7 +419,7 @@ public void testFreezeBalanceForTronPowerWithOldTronPowerAfterNewResourceModel() try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); owner = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -452,10 +433,8 @@ public void testFreezeBalanceForTronPowerWithOldTronPowerAfterNewResourceModel() Assert.assertEquals(100L, owner.getInstance().getOldTronPower()); Assert.assertEquals(100L, owner.getTronPower()); Assert.assertEquals(frozenBalance + 100, owner.getAllTronPower()); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } diff --git a/framework/src/test/java/org/tron/core/actuator/MarketCancelOrderActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/MarketCancelOrderActuatorTest.java index a9daf0871b1..b5c3427f529 100644 --- a/framework/src/test/java/org/tron/core/actuator/MarketCancelOrderActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/MarketCancelOrderActuatorTest.java @@ -1,7 +1,5 @@ package org.tron.core.actuator; -import static org.testng.Assert.fail; - import com.google.protobuf.Any; import com.google.protobuf.ByteString; import java.util.List; @@ -53,8 +51,7 @@ public class MarketCancelOrderActuatorTest extends BaseTest { private static final String TRX = "_"; static { - dbPath = "output_MarketCancelOrder_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS_FIRST = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_SECOND = @@ -192,7 +189,7 @@ public void invalidOwnerAddress() { try { actuator.validate(); - fail("Invalid address"); + Assert.fail("Invalid address"); } catch (ContractValidateException e) { Assert.assertEquals("Invalid address", e.getMessage()); } @@ -212,7 +209,7 @@ public void notExistAccount() { try { actuator.validate(); - fail("Account does not exist!"); + Assert.fail("Account does not exist!"); } catch (ContractValidateException e) { Assert.assertEquals("Account does not exist!", e.getMessage()); } @@ -231,7 +228,7 @@ public void notExistOrder() { OWNER_ADDRESS_FIRST, orderId)); try { actuator.validate(); - fail("orderId not exists"); + Assert.fail("orderId not exists"); } catch (ContractValidateException e) { Assert.assertEquals("orderId not exists", e.getMessage()); } @@ -265,7 +262,7 @@ public void orderNotActive() throws Exception { try { actuator.validate(); - fail("Order is not active!"); + Assert.fail("Order is not active!"); } catch (ContractValidateException e) { Assert.assertEquals("Order is not active!", e.getMessage()); } @@ -300,7 +297,7 @@ public void notBelongToTheAccount() throws Exception { try { actuator.validate(); actuator.execute(ret); - fail("Order does not belong to the account!"); + Assert.fail("Order does not belong to the account!"); } catch (ContractValidateException e) { Assert.assertEquals("Order does not belong to the account!", e.getMessage()); } catch (ContractExeException e) { @@ -342,7 +339,7 @@ public void noEnoughBalance() throws Exception { try { actuator.validate(); actuator.execute(ret); - fail("No enough balance !"); + Assert.fail("No enough balance !"); } catch (ContractValidateException e) { Assert.assertEquals("No enough balance !", e.getMessage()); } catch (ContractExeException e) { @@ -379,7 +376,7 @@ public void validateSuccess() throws Exception { try { actuator.validate(); } catch (ContractValidateException e) { - fail("validateSuccess error"); + Assert.fail("validateSuccess error"); } } diff --git a/framework/src/test/java/org/tron/core/actuator/MarketSellAssetActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/MarketSellAssetActuatorTest.java index 587a6b5aacd..0e938cdb025 100644 --- a/framework/src/test/java/org/tron/core/actuator/MarketSellAssetActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/MarketSellAssetActuatorTest.java @@ -1,6 +1,6 @@ package org.tron.core.actuator; -import static org.testng.Assert.fail; +import static org.junit.Assert.fail; import com.google.protobuf.Any; import com.google.protobuf.ByteString; @@ -53,8 +53,7 @@ public class MarketSellAssetActuatorTest extends BaseTest { private static final String TRX = "_"; static { - dbPath = "output_MarketSellAsset_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS_FIRST = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_SECOND = diff --git a/framework/src/test/java/org/tron/core/actuator/ParticipateAssetIssueActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/ParticipateAssetIssueActuatorTest.java index 0bcfbc8820f..52e5f554374 100755 --- a/framework/src/test/java/org/tron/core/actuator/ParticipateAssetIssueActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/ParticipateAssetIssueActuatorTest.java @@ -41,8 +41,7 @@ public class ParticipateAssetIssueActuatorTest extends BaseTest { private static long AMOUNT = TOTAL_SUPPLY - (1000L) / TRX_NUM * NUM; static { - dbPath = "output_participateAsset_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1234"; TO_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; TO_ADDRESS_2 = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e048892"; diff --git a/framework/src/test/java/org/tron/core/actuator/ProposalApproveActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/ProposalApproveActuatorTest.java index 484c6666941..2e8e78306a9 100644 --- a/framework/src/test/java/org/tron/core/actuator/ProposalApproveActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/ProposalApproveActuatorTest.java @@ -40,8 +40,7 @@ public class ProposalApproveActuatorTest extends BaseTest { private static final String OWNER_ADDRESS_NOACCOUNT; static { - dbPath = "output_ProposalApprove_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS_FIRST = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_SECOND = diff --git a/framework/src/test/java/org/tron/core/actuator/ProposalCreateActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/ProposalCreateActuatorTest.java index 1e95911884c..a42a4ffbe5a 100644 --- a/framework/src/test/java/org/tron/core/actuator/ProposalCreateActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/ProposalCreateActuatorTest.java @@ -38,8 +38,7 @@ public class ProposalCreateActuatorTest extends BaseTest { private static final String OWNER_ADDRESS_NOACCOUNT; static { - dbPath = "output_ProposalCreate_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS_FIRST = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_SECOND = diff --git a/framework/src/test/java/org/tron/core/actuator/ProposalDeleteActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/ProposalDeleteActuatorTest.java index 63e5758a907..dfd34cb620e 100644 --- a/framework/src/test/java/org/tron/core/actuator/ProposalDeleteActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/ProposalDeleteActuatorTest.java @@ -40,8 +40,7 @@ public class ProposalDeleteActuatorTest extends BaseTest { private static final String OWNER_ADDRESS_NOACCOUNT; static { - dbPath = "output_ProposalDelete_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS_FIRST = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_SECOND = diff --git a/framework/src/test/java/org/tron/core/actuator/SetAccountIdActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/SetAccountIdActuatorTest.java index 0b4311ca46f..e93d9ecf333 100644 --- a/framework/src/test/java/org/tron/core/actuator/SetAccountIdActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/SetAccountIdActuatorTest.java @@ -30,8 +30,7 @@ public class SetAccountIdActuatorTest extends BaseTest { private static final String OWNER_ADDRESS_INVALID = "aaaa"; static { - dbPath = "output_setaccountid_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; OWNER_ADDRESS_1 = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; } diff --git a/framework/src/test/java/org/tron/core/actuator/ShieldedTransferActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/ShieldedTransferActuatorTest.java index 5e7d33832b4..b71ba432018 100755 --- a/framework/src/test/java/org/tron/core/actuator/ShieldedTransferActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/ShieldedTransferActuatorTest.java @@ -27,8 +27,8 @@ import org.tron.core.exception.PermissionException; import org.tron.core.exception.ValidateSignatureException; import org.tron.core.exception.ZksnarkException; -import org.tron.core.services.http.FullNodeHttpApiService; import org.tron.core.zen.ZenTransactionBuilder; +import org.tron.core.zen.ZksnarkInitService; import org.tron.core.zen.address.DiversifierT; import org.tron.core.zen.address.ExpandedSpendingKey; import org.tron.core.zen.address.FullViewingKey; @@ -68,8 +68,7 @@ public class ShieldedTransferActuatorTest extends BaseTest { private Wallet wallet; static { - dbPath = "output_shield_transfer_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); ADDRESS_ONE_PRIVATE_KEY = PublicMethod.getRandomPrivateKey(); PUBLIC_ADDRESS_ONE = PublicMethod.getHexAddressByPrivateKey(ADDRESS_ONE_PRIVATE_KEY); @@ -91,7 +90,7 @@ public static void init() throws ZksnarkException { } private static void librustzcashInitZksnarkParams() { - FullNodeHttpApiService.librustzcashInitZksnarkParams(); + ZksnarkInitService.librustzcashInitZksnarkParams(); } /** diff --git a/framework/src/test/java/org/tron/core/actuator/TransferActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/TransferActuatorTest.java index 91ba02a62f9..98ac18c8808 100644 --- a/framework/src/test/java/org/tron/core/actuator/TransferActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/TransferActuatorTest.java @@ -52,8 +52,7 @@ public class TransferActuatorTest extends BaseTest { private WorldStateCallBack worldStateCallBack; static { - dbPath = "output_transfer_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; TO_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ACCOUNT_INVALID = diff --git a/framework/src/test/java/org/tron/core/actuator/TransferAssetActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/TransferAssetActuatorTest.java index 992b630f989..459566d5b2e 100755 --- a/framework/src/test/java/org/tron/core/actuator/TransferAssetActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/TransferAssetActuatorTest.java @@ -79,8 +79,7 @@ public class TransferAssetActuatorTest extends BaseTest { private WorldStateCallBack worldStateCallBack; static { - dbPath = "output_transferasset_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; TO_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a146a"; NOT_EXIT_ADDRESS = Wallet.getAddressPreFixString() + "B56446E617E924805E4D6CA021D341FEF6E2013B"; diff --git a/framework/src/test/java/org/tron/core/actuator/UnDelegateResourceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UnDelegateResourceActuatorTest.java index 82ed6865fb8..eea1a0bf9b7 100644 --- a/framework/src/test/java/org/tron/core/actuator/UnDelegateResourceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UnDelegateResourceActuatorTest.java @@ -38,8 +38,7 @@ public class UnDelegateResourceActuatorTest extends BaseTest { private static final long delegateBalance = 1_000_000_000L; static { - dbPath = "output_unDelegate_resource_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ACCOUNT_INVALID = diff --git a/framework/src/test/java/org/tron/core/actuator/UnfreezeAssetActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UnfreezeAssetActuatorTest.java index 37480713ebc..9d30f48edfd 100644 --- a/framework/src/test/java/org/tron/core/actuator/UnfreezeAssetActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UnfreezeAssetActuatorTest.java @@ -43,8 +43,7 @@ public class UnfreezeAssetActuatorTest extends BaseTest { private WorldStateCallBack worldStateCallBack; static { - dbPath = "output_unfreeze_asset_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; diff --git a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java index 734c37dbe05..5364618eb30 100644 --- a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceActuatorTest.java @@ -48,8 +48,7 @@ public class UnfreezeBalanceActuatorTest extends BaseTest { private WorldStateCallBack worldStateCallBack; static { - dbPath = "output_unfreeze_balance_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ACCOUNT_INVALID = @@ -124,8 +123,8 @@ public void testUnfreezeBalanceForBandwidth() { AccountCapsule accountCapsule = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); accountCapsule.setFrozen(frozenBalance, now); - Assert.assertEquals(accountCapsule.getFrozenBalance(), frozenBalance); - Assert.assertEquals(accountCapsule.getTronPower(), frozenBalance); + Assert.assertEquals(frozenBalance, accountCapsule.getFrozenBalance()); + Assert.assertEquals(frozenBalance, accountCapsule.getTronPower()); dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); UnfreezeBalanceActuator actuator = new UnfreezeBalanceActuator(); @@ -138,13 +137,13 @@ public void testUnfreezeBalanceForBandwidth() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule owner = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); Assert.assertEquals(owner.getBalance(), initBalance + frozenBalance); - Assert.assertEquals(owner.getFrozenBalance(), 0); - Assert.assertEquals(owner.getTronPower(), 0L); + Assert.assertEquals(0, owner.getFrozenBalance()); + Assert.assertEquals(0L, owner.getTronPower()); WorldStateQueryInstance instance = getQueryInstance(); Assert.assertEquals(owner.getBalance(), instance.getAccount(owner.createDbKey()).getBalance()); @@ -163,10 +162,8 @@ public void testUnfreezeBalanceForBandwidth() { stateStore.getTotalNetWeight() + frozenBalance / 1000_000L); } - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -234,12 +231,12 @@ public void testUnfreezeSelfAndOthersForBandwidth() { DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(instance); Assert.assertEquals(1, stateStore.getTotalNetWeight()); Assert.assertEquals(1, afterWeight1); - Assert.assertEquals(ret1.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret1.getInstance().getRet()); } catch (ContractValidateException e) { logger.error("ContractValidateException", e); - Assert.assertFalse(e instanceof ContractValidateException); + Assert.fail(); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } UnfreezeBalanceActuator actuator = new UnfreezeBalanceActuator(); @@ -255,11 +252,9 @@ public void testUnfreezeSelfAndOthersForBandwidth() { DynamicPropertiesStateStore stateStore = new DynamicPropertiesStateStore(instance); Assert.assertEquals(0, stateStore.getTotalNetWeight()); Assert.assertEquals(0, afterWeight); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } dbManager.getDynamicPropertiesStore().saveAllowNewReward(0); } @@ -273,8 +268,8 @@ public void testUnfreezeBalanceForEnergy() { AccountCapsule accountCapsule = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); accountCapsule.setFrozenForEnergy(frozenBalance, now); - Assert.assertEquals(accountCapsule.getAllFrozenBalanceForEnergy(), frozenBalance); - Assert.assertEquals(accountCapsule.getTronPower(), frozenBalance); + Assert.assertEquals(frozenBalance, accountCapsule.getAllFrozenBalanceForEnergy()); + Assert.assertEquals(frozenBalance, accountCapsule.getTronPower()); dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); UnfreezeBalanceActuator actuator = new UnfreezeBalanceActuator(); @@ -286,20 +281,18 @@ public void testUnfreezeBalanceForEnergy() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule owner = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); Assert.assertEquals(owner.getBalance(), initBalance + frozenBalance); - Assert.assertEquals(owner.getEnergyFrozenBalance(), 0); - Assert.assertEquals(owner.getTronPower(), 0L); + Assert.assertEquals(0, owner.getEnergyFrozenBalance()); + Assert.assertEquals(0L, owner.getTronPower()); long totalEnergyWeightAfter = dbManager.getDynamicPropertiesStore().getTotalEnergyWeight(); Assert.assertEquals(totalEnergyWeightBefore, totalEnergyWeightAfter + frozenBalance / 1000_000L); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -358,7 +351,7 @@ public void testUnfreezeDelegatedBalanceForBandwidth() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule ownerResult = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -410,10 +403,8 @@ public void testUnfreezeDelegatedBalanceForBandwidth() { Assert.assertEquals(0, delegatedResourceAccountIndexCapsuleReceiver.getFromAccountsList().size()); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -477,17 +468,18 @@ public void testUnfreezeDelegatedBalanceForBandwidthWithDeletedReceiver() { actuator.execute(ret); Assert.fail(); } catch (ContractValidateException e) { - Assert.assertEquals(e.getMessage(), - "Receiver Account[a0abd4b9367799eaa3197fecb144eb71de1e049150] does not exist"); + Assert.assertEquals( + "Receiver Account[a0abd4b9367799eaa3197fecb144eb71de1e049150] does not exist", + e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } dbManager.getDynamicPropertiesStore().saveAllowTvmConstantinople(1); try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule ownerResult = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -511,11 +503,8 @@ public void testUnfreezeDelegatedBalanceForBandwidthWithDeletedReceiver() { Assert.assertEquals(0, delegatedResourceAccountIndexCapsuleReceiver.getFromAccountsList().size()); - } catch (ContractValidateException e) { - logger.error("", e); - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -590,10 +579,11 @@ public void testUnfreezeDelegatedBalanceForBandwidthWithRecreatedReceiver() { actuator.execute(ret); Assert.fail(); } catch (ContractValidateException e) { - Assert.assertEquals(e.getMessage(), - "AcquiredDelegatedFrozenBalanceForBandwidth[10] < delegatedBandwidth[1000000000]"); + Assert.assertEquals( + "AcquiredDelegatedFrozenBalanceForBandwidth[10] < delegatedBandwidth[1000000000]", + e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } dbManager.getDynamicPropertiesStore().saveAllowShieldedTransaction(1); @@ -601,7 +591,7 @@ public void testUnfreezeDelegatedBalanceForBandwidthWithRecreatedReceiver() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule ownerResult = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -696,10 +686,9 @@ public void testUnfreezeDelegatedBalanceForBandwidthSameTokenNameClose() { actuator.execute(ret); fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("no frozenBalance(BANDWIDTH)", e.getMessage()); } catch (ContractExeException e) { - Assert.assertTrue(e instanceof ContractExeException); + Assert.fail(); } } @@ -736,7 +725,7 @@ public void testUnfreezeDelegatedBalanceForCpu() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule ownerResult = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -747,11 +736,8 @@ public void testUnfreezeDelegatedBalanceForCpu() { Assert.assertEquals(0L, ownerResult.getTronPower()); Assert.assertEquals(0L, ownerResult.getDelegatedFrozenBalanceForEnergy()); Assert.assertEquals(0L, receiverResult.getAllFrozenBalanceForEnergy()); - } catch (ContractValidateException e) { - logger.error("", e); - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -792,10 +778,11 @@ public void testUnfreezeDelegatedBalanceForCpuWithDeletedReceiver() { actuator.execute(ret); Assert.fail(); } catch (ContractValidateException e) { - Assert.assertEquals(e.getMessage(), - "Receiver Account[a0abd4b9367799eaa3197fecb144eb71de1e049150] does not exist"); + Assert.assertEquals( + "Receiver Account[a0abd4b9367799eaa3197fecb144eb71de1e049150] does not exist", + e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } dbManager.getDynamicPropertiesStore().saveAllowTvmConstantinople(1); @@ -803,17 +790,15 @@ public void testUnfreezeDelegatedBalanceForCpuWithDeletedReceiver() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule ownerResult = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); Assert.assertEquals(initBalance + frozenBalance, ownerResult.getBalance()); Assert.assertEquals(0L, ownerResult.getTronPower()); Assert.assertEquals(0L, ownerResult.getDelegatedFrozenBalanceForEnergy()); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -867,10 +852,11 @@ public void testUnfreezeDelegatedBalanceForCpuWithRecreatedReceiver() { actuator.execute(ret); Assert.fail(); } catch (ContractValidateException e) { - Assert.assertEquals(e.getMessage(), - "AcquiredDelegatedFrozenBalanceForEnergy[10] < delegatedEnergy[1000000000]"); + Assert.assertEquals( + "AcquiredDelegatedFrozenBalanceForEnergy[10] < delegatedEnergy[1000000000]", + e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } dbManager.getDynamicPropertiesStore().saveAllowShieldedTransaction(1); @@ -879,7 +865,7 @@ public void testUnfreezeDelegatedBalanceForCpuWithRecreatedReceiver() { try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule ownerResult = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); @@ -888,9 +874,7 @@ public void testUnfreezeDelegatedBalanceForCpuWithRecreatedReceiver() { Assert.assertEquals(0L, ownerResult.getDelegatedFrozenBalanceForEnergy()); receiver = dbManager.getAccountStore().get(receiver.createDbKey()); Assert.assertEquals(0, receiver.getAcquiredDelegatedFrozenBalanceForEnergy()); - } catch (ContractValidateException e) { - Assert.fail(); - } catch (ContractExeException e) { + } catch (ContractValidateException | ContractExeException e) { Assert.fail(); } } @@ -914,12 +898,9 @@ public void invalidOwnerAddress() { fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); - Assert.assertEquals("Invalid address", e.getMessage()); - } catch (ContractExeException e) { - Assert.assertTrue(e instanceof ContractExeException); + Assert.fail(); } } @@ -942,11 +923,10 @@ public void invalidOwnerAccount() { actuator.execute(ret); fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("Account[" + OWNER_ACCOUNT_INVALID + "] does not exist", e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } } @@ -962,10 +942,9 @@ public void noFrozenBalance() { fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("no frozenBalance(BANDWIDTH)", e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } } @@ -988,17 +967,15 @@ public void notTimeToUnfreeze() { fail("cannot run here."); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); Assert.assertEquals("It's not time to unfreeze(BANDWIDTH).", e.getMessage()); } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + Assert.fail(); } } @Test public void testClearVotes() { byte[] ownerAddressBytes = ByteArray.fromHexString(OWNER_ADDRESS); - ByteString ownerAddress = ByteString.copyFrom(ownerAddressBytes); long now = System.currentTimeMillis(); dbManager.getDynamicPropertiesStore().saveLatestBlockHeaderTimestamp(now); @@ -1018,14 +995,12 @@ public void testClearVotes() { VotesCapsule votesCapsule = dbManager.getVotesStore().get(ownerAddressBytes); Assert.assertNotNull(votesCapsule); Assert.assertEquals(0, votesCapsule.getNewVotes().size()); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } // if had votes - List oldVotes = new ArrayList(); + List oldVotes = new ArrayList<>(); VotesCapsule votesCapsule = new VotesCapsule( ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), oldVotes); votesCapsule.addNewVotes(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), @@ -1039,10 +1014,8 @@ public void testClearVotes() { votesCapsule = dbManager.getVotesStore().get(ownerAddressBytes); Assert.assertNotNull(votesCapsule); Assert.assertEquals(0, votesCapsule.getNewVotes().size()); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -1121,8 +1094,8 @@ public void commonErrorCheck() { AccountCapsule accountCapsule = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); accountCapsule.setFrozen(frozenBalance, now); - Assert.assertEquals(accountCapsule.getFrozenBalance(), frozenBalance); - Assert.assertEquals(accountCapsule.getTronPower(), frozenBalance); + Assert.assertEquals(frozenBalance, accountCapsule.getFrozenBalance()); + Assert.assertEquals(frozenBalance, accountCapsule.getTronPower()); dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); @@ -1145,7 +1118,7 @@ public void testUnfreezeBalanceForEnergyWithOldTronPowerAfterNewResourceModel() accountCapsule.setFrozenForEnergy(frozenBalance, now); accountCapsule.setOldTronPower(frozenBalance); accountCapsule.addVotes(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), 100L); - Assert.assertEquals(accountCapsule.getAllFrozenBalanceForEnergy(), frozenBalance); + Assert.assertEquals(frozenBalance, accountCapsule.getAllFrozenBalanceForEnergy()); dbManager.getAccountStore().put(accountCapsule.createDbKey(), accountCapsule); UnfreezeBalanceActuator actuator = new UnfreezeBalanceActuator(); @@ -1156,16 +1129,14 @@ public void testUnfreezeBalanceForEnergyWithOldTronPowerAfterNewResourceModel() try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule owner = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); - Assert.assertEquals(owner.getVotesList().size(), 0L); + Assert.assertEquals(0L, owner.getVotesList().size()); Assert.assertEquals(owner.getInstance().getOldTronPower(), -1L); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -1191,16 +1162,14 @@ public void testUnfreezeBalanceForEnergyWithoutOldTronPowerAfterNewResourceModel try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule owner = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); - Assert.assertEquals(owner.getVotesList().size(), 1L); + Assert.assertEquals(1L, owner.getVotesList().size()); Assert.assertEquals(owner.getInstance().getOldTronPower(), -1L); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -1226,16 +1195,14 @@ public void testUnfreezeBalanceForTronPowerWithOldTronPowerAfterNewResourceModel try { actuator.validate(); actuator.execute(ret); - Assert.assertEquals(ret.getInstance().getRet(), code.SUCESS); + Assert.assertEquals(code.SUCESS, ret.getInstance().getRet()); AccountCapsule owner = dbManager.getAccountStore() .get(ByteArray.fromHexString(OWNER_ADDRESS)); - Assert.assertEquals(owner.getVotesList().size(), 0L); + Assert.assertEquals(0L, owner.getVotesList().size()); Assert.assertEquals(owner.getInstance().getOldTronPower(), -1L); - } catch (ContractValidateException e) { - Assert.assertFalse(e instanceof ContractValidateException); - } catch (ContractExeException e) { - Assert.assertFalse(e instanceof ContractExeException); + } catch (ContractValidateException | ContractExeException e) { + Assert.fail(); } } @@ -1256,13 +1223,12 @@ public void testUnfreezeBalanceForTronPowerWithOldTronPowerAfterNewResourceModel UnfreezeBalanceActuator actuator = new UnfreezeBalanceActuator(); actuator.setChainBaseManager(dbManager.getChainBaseManager()) .setAny(getContractForTronPower(OWNER_ADDRESS)); - TransactionResultCapsule ret = new TransactionResultCapsule(); try { actuator.validate(); Assert.fail(); } catch (ContractValidateException e) { - Assert.assertTrue(e instanceof ContractValidateException); + Assert.assertEquals("It's not time to unfreeze(TronPower).", e.getMessage()); } } diff --git a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceV2ActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceV2ActuatorTest.java index 0355d310e58..adee10fe97b 100644 --- a/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceV2ActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UnfreezeBalanceV2ActuatorTest.java @@ -45,8 +45,7 @@ public class UnfreezeBalanceV2ActuatorTest extends BaseTest { private WorldStateCallBack worldStateCallBack; static { - dbPath = "output_unfreeze_balance_v2_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; RECEIVER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049150"; OWNER_ACCOUNT_INVALID = @@ -702,8 +701,7 @@ public void testUnfreezeBalanceCalcUnfreezeExpireTime() { .build(); long ret = actuator.calcUnfreezeExpireTime(now); - - Assert.assertTrue(true); + Assert.assertTrue(ret > 0); } @Test diff --git a/framework/src/test/java/org/tron/core/actuator/UpdateAccountActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UpdateAccountActuatorTest.java index acbb9fb4d0b..0e385347836 100755 --- a/framework/src/test/java/org/tron/core/actuator/UpdateAccountActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UpdateAccountActuatorTest.java @@ -32,8 +32,7 @@ public class UpdateAccountActuatorTest extends BaseTest { private static final String OWNER_ADDRESS_INVALID = "aaaa"; static { - dbPath = "output_updateaccount_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; OWNER_ADDRESS_1 = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; } diff --git a/framework/src/test/java/org/tron/core/actuator/UpdateAssetActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UpdateAssetActuatorTest.java index b7583bc335b..3bdba2055af 100644 --- a/framework/src/test/java/org/tron/core/actuator/UpdateAssetActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UpdateAssetActuatorTest.java @@ -39,8 +39,7 @@ public class UpdateAssetActuatorTest extends BaseTest { private static final String URL = "tron-my.com"; static { - dbPath = "output_updateAsset_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_NOTEXIST = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; diff --git a/framework/src/test/java/org/tron/core/actuator/UpdateBrokerageActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UpdateBrokerageActuatorTest.java index 034415e0ef1..efd090b4b3a 100644 --- a/framework/src/test/java/org/tron/core/actuator/UpdateBrokerageActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UpdateBrokerageActuatorTest.java @@ -34,8 +34,7 @@ public class UpdateBrokerageActuatorTest extends BaseTest { private static final int BROKEN_AGE = 10; static { - dbPath = "output_updatebrokerageactuator_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_NOTEXIST = Wallet.getAddressPreFixString() + "1234b9367799eaa3197fecb144eb71de1e049123"; diff --git a/framework/src/test/java/org/tron/core/actuator/UpdateEnergyLimitContractActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UpdateEnergyLimitContractActuatorTest.java index 3703dc74e87..60f52b541b9 100644 --- a/framework/src/test/java/org/tron/core/actuator/UpdateEnergyLimitContractActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UpdateEnergyLimitContractActuatorTest.java @@ -47,8 +47,7 @@ public class UpdateEnergyLimitContractActuatorTest extends BaseTest { private static String OWNER_ADDRESS_NOTEXIST; static { - dbPath = "output_updateEnergyLimitContractActuator_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); } /** diff --git a/framework/src/test/java/org/tron/core/actuator/UpdateSettingContractActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/UpdateSettingContractActuatorTest.java index 0445f893983..508cee731f0 100644 --- a/framework/src/test/java/org/tron/core/actuator/UpdateSettingContractActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/UpdateSettingContractActuatorTest.java @@ -41,8 +41,7 @@ public class UpdateSettingContractActuatorTest extends BaseTest { private static final long INVALID_PERCENT = 200L; static { - dbPath = "output_updatesettingcontract_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_NOTEXIST = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; diff --git a/framework/src/test/java/org/tron/core/actuator/VoteWitnessActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/VoteWitnessActuatorTest.java index cedd147dbaa..1a152555931 100644 --- a/framework/src/test/java/org/tron/core/actuator/VoteWitnessActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/VoteWitnessActuatorTest.java @@ -51,8 +51,7 @@ public class VoteWitnessActuatorTest extends BaseTest { private static boolean consensusStart; static { - dbPath = "output_VoteWitness_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; WITNESS_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; WITNESS_ADDRESS_NOACCOUNT = diff --git a/framework/src/test/java/org/tron/core/actuator/WithdrawBalanceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/WithdrawBalanceActuatorTest.java index 7010b10657a..22a4acbb838 100644 --- a/framework/src/test/java/org/tron/core/actuator/WithdrawBalanceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/WithdrawBalanceActuatorTest.java @@ -36,8 +36,7 @@ public class WithdrawBalanceActuatorTest extends BaseTest { private static final long allowance = 32_000_000L; static { - dbPath = "output_withdraw_balance_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; diff --git a/framework/src/test/java/org/tron/core/actuator/WithdrawExpireUnfreezeActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/WithdrawExpireUnfreezeActuatorTest.java index 1544e546854..34ac0d9bbeb 100644 --- a/framework/src/test/java/org/tron/core/actuator/WithdrawExpireUnfreezeActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/WithdrawExpireUnfreezeActuatorTest.java @@ -39,8 +39,7 @@ public class WithdrawExpireUnfreezeActuatorTest extends BaseTest { private static final long allowance = 32_000_000L; static { - dbPath = "output_withdraw_expire_unfreeze_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; OWNER_ACCOUNT_INVALID = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a3456"; diff --git a/framework/src/test/java/org/tron/core/actuator/WitnessCreateActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/WitnessCreateActuatorTest.java index 721d88af2b6..0809ed2993e 100644 --- a/framework/src/test/java/org/tron/core/actuator/WitnessCreateActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/WitnessCreateActuatorTest.java @@ -36,8 +36,7 @@ public class WitnessCreateActuatorTest extends BaseTest { private static final String OWNER_ADDRESS_BALANCENOTSUFFIENT; static { - dbPath = "output_WitnessCreate_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS_FIRST = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_SECOND = diff --git a/framework/src/test/java/org/tron/core/actuator/WitnessUpdateActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/WitnessUpdateActuatorTest.java index 31ac6a3cf88..6ad6e381c5e 100644 --- a/framework/src/test/java/org/tron/core/actuator/WitnessUpdateActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/WitnessUpdateActuatorTest.java @@ -36,8 +36,7 @@ public class WitnessUpdateActuatorTest extends BaseTest { private static final String OWNER_ADDRESS_INVALID = "aaaa"; static { - dbPath = "output_WitnessUpdate_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ADDRESS_NOTEXIST = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; diff --git a/framework/src/test/java/org/tron/core/actuator/utils/ProposalUtilTest.java b/framework/src/test/java/org/tron/core/actuator/utils/ProposalUtilTest.java index 5de7771dfe2..6f4df3cba8f 100644 --- a/framework/src/test/java/org/tron/core/actuator/utils/ProposalUtilTest.java +++ b/framework/src/test/java/org/tron/core/actuator/utils/ProposalUtilTest.java @@ -32,8 +32,7 @@ public class ProposalUtilTest extends BaseTest { */ @BeforeClass public static void init() { - dbPath = "output_ProposalUtil_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); } @Test diff --git a/framework/src/test/java/org/tron/core/actuator/utils/TransactionUtilTest.java b/framework/src/test/java/org/tron/core/actuator/utils/TransactionUtilTest.java index 0baaad7c962..9d56876a4da 100644 --- a/framework/src/test/java/org/tron/core/actuator/utils/TransactionUtilTest.java +++ b/framework/src/test/java/org/tron/core/actuator/utils/TransactionUtilTest.java @@ -4,7 +4,9 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.tron.core.capsule.utils.TransactionUtil.isNumber; +import static org.tron.core.config.Parameter.ChainConstant.DELEGATE_COST_BASE_SIZE; import static org.tron.core.config.Parameter.ChainConstant.DELEGATE_PERIOD; +import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION; import static org.tron.core.utils.TransactionUtil.validAccountId; import static org.tron.core.utils.TransactionUtil.validAccountName; import static org.tron.core.utils.TransactionUtil.validAssetName; @@ -12,19 +14,27 @@ import com.google.protobuf.ByteString; import java.nio.charset.StandardCharsets; +import java.util.List; import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.tron.common.BaseTest; import org.tron.common.utils.ByteArray; +import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.TransactionCapsule; import org.tron.core.config.args.Args; +import org.tron.core.store.DynamicPropertiesStore; import org.tron.core.utils.TransactionUtil; +import org.tron.protos.Protocol; import org.tron.protos.Protocol.AccountType; - +import org.tron.protos.Protocol.Transaction; +import org.tron.protos.Protocol.Transaction.Contract.ContractType; +import org.tron.protos.contract.BalanceContract.DelegateResourceContract; @Slf4j(topic = "capsule") public class TransactionUtilTest extends BaseTest { @@ -36,10 +46,8 @@ public class TransactionUtilTest extends BaseTest { */ @BeforeClass public static void init() { - dbPath = "output_transactionUtil_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; - } @Before @@ -55,6 +63,82 @@ public void setUp() { dbManager.getAccountStore().put(ownerCapsule.getAddress().toByteArray(), ownerCapsule); } + // only for testing + public static long consumeBandWidthSize( + final TransactionCapsule transactionCapsule, + ChainBaseManager chainBaseManager) { + long bs; + + boolean supportVM = chainBaseManager.getDynamicPropertiesStore().supportVM(); + if (supportVM) { + bs = transactionCapsule.getInstance().toBuilder().clearRet().build().getSerializedSize(); + } else { + bs = transactionCapsule.getSerializedSize(); + } + + List contracts = transactionCapsule.getInstance().getRawData() + .getContractList(); + for (Transaction.Contract contract : contracts) { + if (contract.getType() == Transaction.Contract.ContractType.ShieldedTransferContract) { + continue; + } + if (supportVM) { + bs += Constant.MAX_RESULT_SIZE_IN_TX; + } + } + + return bs; + } + + // only for testing + public static long estimateConsumeBandWidthSize(final AccountCapsule ownerCapsule, + ChainBaseManager chainBaseManager) { + DelegateResourceContract.Builder builder; + if (chainBaseManager.getDynamicPropertiesStore().supportMaxDelegateLockPeriod()) { + builder = DelegateResourceContract.newBuilder() + .setLock(true) + .setLockPeriod(chainBaseManager.getDynamicPropertiesStore().getMaxDelegateLockPeriod()) + .setBalance(ownerCapsule.getFrozenV2BalanceForBandwidth()); + } else { + builder = DelegateResourceContract.newBuilder() + .setLock(true) + .setBalance(ownerCapsule.getFrozenV2BalanceForBandwidth()); + } + TransactionCapsule fakeTransactionCapsule = new TransactionCapsule(builder.build(), + ContractType.DelegateResourceContract); + long size1 = consumeBandWidthSize(fakeTransactionCapsule, chainBaseManager); + + DelegateResourceContract.Builder builder2 = DelegateResourceContract.newBuilder() + .setBalance(TRX_PRECISION); + TransactionCapsule fakeTransactionCapsule2 = new TransactionCapsule(builder2.build(), + ContractType.DelegateResourceContract); + long size2 = consumeBandWidthSize(fakeTransactionCapsule2, chainBaseManager); + long addSize = Math.max(size1 - size2, 0L); + + return DELEGATE_COST_BASE_SIZE + addSize; + } + + // only for testing + public static long estimateConsumeBandWidthSizeOld( + final AccountCapsule ownerCapsule, + ChainBaseManager chainBaseManager) { + DelegateResourceContract.Builder builder = DelegateResourceContract.newBuilder() + .setLock(true) + .setBalance(ownerCapsule.getFrozenV2BalanceForBandwidth()); + TransactionCapsule fakeTransactionCapsule = new TransactionCapsule(builder.build(), + ContractType.DelegateResourceContract); + long size1 = consumeBandWidthSize(fakeTransactionCapsule, chainBaseManager); + + DelegateResourceContract.Builder builder2 = DelegateResourceContract.newBuilder() + .setBalance(TRX_PRECISION); + TransactionCapsule fakeTransactionCapsule2 = new TransactionCapsule(builder2.build(), + ContractType.DelegateResourceContract); + long size2 = consumeBandWidthSize(fakeTransactionCapsule2, chainBaseManager); + long addSize = Math.max(size1 - size2, 0L); + + return DELEGATE_COST_BASE_SIZE + addSize; + } + @Test public void validAccountNameCheck() { StringBuilder account = new StringBuilder(); @@ -65,7 +149,6 @@ public void validAccountNameCheck() { assertTrue(validAccountName(account.toString().getBytes(StandardCharsets.UTF_8))); account.append('z'); assertFalse(validAccountName(account.toString().getBytes(StandardCharsets.UTF_8))); - } @Test @@ -147,7 +230,7 @@ public void isNumberCheck() { public void testEstimateConsumeBandWidthSize() { AccountCapsule ownerCapsule = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); - long estimateConsumeBandWidthSize = TransactionUtil.estimateConsumeBandWidthSize(ownerCapsule, + long estimateConsumeBandWidthSize = estimateConsumeBandWidthSize(ownerCapsule, dbManager.getChainBaseManager()); assertEquals(275L, estimateConsumeBandWidthSize); chainBaseManager.getDynamicPropertiesStore().saveMaxDelegateLockPeriod(DELEGATE_PERIOD / 3000); @@ -159,10 +242,193 @@ public void testEstimateConsumeBandWidthSize2() { chainBaseManager.getDynamicPropertiesStore().saveMaxDelegateLockPeriod(864000L); AccountCapsule ownerCapsule = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); - long estimateConsumeBandWidthSize = TransactionUtil.estimateConsumeBandWidthSize(ownerCapsule, + long estimateConsumeBandWidthSize = estimateConsumeBandWidthSize(ownerCapsule, dbManager.getChainBaseManager()); assertEquals(277L, estimateConsumeBandWidthSize); chainBaseManager.getDynamicPropertiesStore().saveMaxDelegateLockPeriod(DELEGATE_PERIOD / 3000); } + + @Test + public void testEstimateConsumeBandWidthSizeOld() { + dbManager.getDynamicPropertiesStore().saveAllowCreationOfContracts(1L); + ChainBaseManager chainBaseManager = dbManager.getChainBaseManager(); + long balance = 1000_000L; + + AccountCapsule ownerCapsule = new AccountCapsule(ByteString.copyFromUtf8("owner"), + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), Protocol.AccountType.Normal, + balance); + ownerCapsule.addFrozenBalanceForBandwidthV2(balance); + dbManager.getAccountStore().put(ownerCapsule.createDbKey(), ownerCapsule); + ownerCapsule = dbManager.getAccountStore().get(ByteArray.fromHexString(OWNER_ADDRESS)); + long estimateConsumeBandWidthSize1 = estimateConsumeBandWidthSizeOld( + ownerCapsule, chainBaseManager); + Assert.assertEquals(277, estimateConsumeBandWidthSize1); + + balance = 1000_000_000L; + ownerCapsule = new AccountCapsule(ByteString.copyFromUtf8("owner"), + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), Protocol.AccountType.Normal, + balance); + ownerCapsule.addFrozenBalanceForBandwidthV2(balance); + dbManager.getAccountStore().put(ownerCapsule.createDbKey(), ownerCapsule); + long estimateConsumeBandWidthSize2 = estimateConsumeBandWidthSizeOld( + ownerCapsule, chainBaseManager); + Assert.assertEquals(279, estimateConsumeBandWidthSize2); + + balance = 1000_000_000_000L; + ownerCapsule = new AccountCapsule(ByteString.copyFromUtf8("owner"), + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), Protocol.AccountType.Normal, + balance); + ownerCapsule.addFrozenBalanceForBandwidthV2(balance); + dbManager.getAccountStore().put(ownerCapsule.createDbKey(), ownerCapsule); + long estimateConsumeBandWidthSize3 = estimateConsumeBandWidthSizeOld( + ownerCapsule, chainBaseManager); + Assert.assertEquals(280, estimateConsumeBandWidthSize3); + + balance = 1000_000_000_000_000L; + ownerCapsule = new AccountCapsule(ByteString.copyFromUtf8("owner"), + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), Protocol.AccountType.Normal, + balance); + ownerCapsule.addFrozenBalanceForBandwidthV2(balance); + dbManager.getAccountStore().put(ownerCapsule.createDbKey(), ownerCapsule); + long estimateConsumeBandWidthSize4 = estimateConsumeBandWidthSizeOld( + ownerCapsule, chainBaseManager); + Assert.assertEquals(282, estimateConsumeBandWidthSize4); + } + + + @Test + public void testEstimateConsumeBandWidthSizeNew() { + long balance = 1000_000L; + DynamicPropertiesStore dps = chainBaseManager.getDynamicPropertiesStore(); + long estimateConsumeBandWidthSize1 = TransactionUtil.estimateConsumeBandWidthSize(dps, balance); + Assert.assertEquals(277, estimateConsumeBandWidthSize1); + + balance = 1000_000_000L; + long estimateConsumeBandWidthSize2 = TransactionUtil.estimateConsumeBandWidthSize(dps, balance); + Assert.assertEquals(279, estimateConsumeBandWidthSize2); + + balance = 1000_000_000_000L; + long estimateConsumeBandWidthSize3 = TransactionUtil.estimateConsumeBandWidthSize(dps, balance); + Assert.assertEquals(280, estimateConsumeBandWidthSize3); + + balance = 1000_000_000_000_000L; + long estimateConsumeBandWidthSize4 = TransactionUtil.estimateConsumeBandWidthSize(dps, balance); + Assert.assertEquals(282, estimateConsumeBandWidthSize4); + } + + + @Test + public void testEstimateConsumeBandWidthSize3() { + dbManager.getDynamicPropertiesStore().saveAllowCreationOfContracts(1L); + ChainBaseManager chainBaseManager = dbManager.getChainBaseManager(); + DynamicPropertiesStore dps = chainBaseManager.getDynamicPropertiesStore(); + long balance = 1000_000L; + + AccountCapsule ownerCapsule; + long estimateConsumeBandWidthSizeOld; + long estimateConsumeBandWidthSizeNew; + + for (int i = 0; i < 100; i++) { + // old value is + ownerCapsule = new AccountCapsule(ByteString.copyFromUtf8("owner"), + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), Protocol.AccountType.Normal, + balance); + ownerCapsule.addFrozenBalanceForBandwidthV2(balance); + dbManager.getAccountStore().put(ownerCapsule.createDbKey(), ownerCapsule); + estimateConsumeBandWidthSizeOld = estimateConsumeBandWidthSizeOld( + ownerCapsule, chainBaseManager); + + // new value is + estimateConsumeBandWidthSizeNew = TransactionUtil.estimateConsumeBandWidthSize(dps, balance); + + System.out.println("balance:" + + balance + + ", estimateConsumeBandWidthSizeOld:" + + estimateConsumeBandWidthSizeOld + + ", estimateConsumeBandWidthSizeNew:" + + estimateConsumeBandWidthSizeNew); + // new value assert equal to old value + Assert.assertEquals(estimateConsumeBandWidthSizeOld, estimateConsumeBandWidthSizeNew); + + // balance accumulated + balance = balance * 10; + if (balance < 0) { + break; + } + } + + } + + @Test + public void estimateConsumeBandWidthSizePositive() { + DynamicPropertiesStore dps = chainBaseManager.getDynamicPropertiesStore(); + long balance = 100; + DelegateResourceContract.Builder builder = + DelegateResourceContract.newBuilder() + .setLock(true) + .setBalance(balance); + DelegateResourceContract.Builder builder2 = + DelegateResourceContract.newBuilder() + .setBalance(TRX_PRECISION); + + long expected = DELEGATE_COST_BASE_SIZE + Math.max( + builder.build().getSerializedSize() - builder2.build().getSerializedSize(), 0L); + long actual = TransactionUtil.estimateConsumeBandWidthSize(dps, balance); + Assert.assertEquals(expected, actual); + } + + @Test + public void estimateConsumeBandWidthSizeBoundary() { + DynamicPropertiesStore dps = chainBaseManager.getDynamicPropertiesStore(); + long balance = TRX_PRECISION; + DelegateResourceContract.Builder builder = + DelegateResourceContract.newBuilder() + .setLock(true) + .setBalance(balance); + DelegateResourceContract.Builder builder2 = + DelegateResourceContract.newBuilder() + .setBalance(TRX_PRECISION); + + long expected = DELEGATE_COST_BASE_SIZE + Math.max( + builder.build().getSerializedSize() - builder2.build().getSerializedSize(), 0L); + long actual = TransactionUtil.estimateConsumeBandWidthSize(dps, balance); + Assert.assertEquals(expected, actual); + } + + @Test + public void estimateConsumeBandWidthSizeEdge() { + DynamicPropertiesStore dps = chainBaseManager.getDynamicPropertiesStore(); + long balance = TRX_PRECISION + 1; + DelegateResourceContract.Builder builder = + DelegateResourceContract.newBuilder() + .setLock(true) + .setBalance(balance); + DelegateResourceContract.Builder builder2 = + DelegateResourceContract.newBuilder() + .setBalance(TRX_PRECISION); + + long expected = DELEGATE_COST_BASE_SIZE + Math.max( + builder.build().getSerializedSize() - builder2.build().getSerializedSize(), 0L); + long actual = TransactionUtil.estimateConsumeBandWidthSize(dps, balance); + Assert.assertEquals(expected, actual); + } + + @Test + public void estimateConsumeBandWidthSizeCorner() { + DynamicPropertiesStore dps = chainBaseManager.getDynamicPropertiesStore(); + long balance = Long.MAX_VALUE; + DelegateResourceContract.Builder builder = + DelegateResourceContract.newBuilder() + .setLock(true) + .setBalance(balance); + DelegateResourceContract.Builder builder2 = + DelegateResourceContract.newBuilder() + .setBalance(TRX_PRECISION); + + long expected = DELEGATE_COST_BASE_SIZE + Math.max( + builder.build().getSerializedSize() - builder2.build().getSerializedSize(), 0L); + long actual = TransactionUtil.estimateConsumeBandWidthSize(dps, balance); + Assert.assertEquals(expected, actual); + } } diff --git a/framework/src/test/java/org/tron/core/actuator/vm/ProgramTraceListenerTest.java b/framework/src/test/java/org/tron/core/actuator/vm/ProgramTraceListenerTest.java index 7cd1b41f5a5..089711219f8 100644 --- a/framework/src/test/java/org/tron/core/actuator/vm/ProgramTraceListenerTest.java +++ b/framework/src/test/java/org/tron/core/actuator/vm/ProgramTraceListenerTest.java @@ -1,6 +1,6 @@ package org.tron.core.actuator.vm; -import java.io.File; +import java.io.IOException; import java.lang.reflect.Field; import java.util.List; import java.util.Map; @@ -8,9 +8,10 @@ import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; +import org.junit.ClassRule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.tron.common.runtime.vm.DataWord; -import org.tron.common.utils.FileUtil; import org.tron.core.Constant; import org.tron.core.config.args.Args; import org.tron.core.db.TransactionStoreTest; @@ -20,7 +21,8 @@ @Slf4j(topic = "VM") public class ProgramTraceListenerTest { - private static final String dbPath = "output_programTraceListener_test"; + @ClassRule + public static TemporaryFolder temporaryFolder = new TemporaryFolder(); private static final int WORD_SIZE = 32; private ProgramTraceListener traceListener; @@ -30,15 +32,15 @@ public class ProgramTraceListenerTest { private DataWord storageWordValue = new DataWord(3); @BeforeClass - public static void init() { - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + public static void init() throws IOException { + Args.setParam(new String[]{"--output-directory", + temporaryFolder.newFolder().toString(), "--debug"}, Constant.TEST_CONF); } @AfterClass public static void destroy() { Args.clearParam(); - FileUtil.deleteDir(new File(dbPath)); } private void invokeProgramTraceListener(ProgramTraceListener traceListener) { diff --git a/framework/src/test/java/org/tron/core/actuator/vm/ProgramTraceTest.java b/framework/src/test/java/org/tron/core/actuator/vm/ProgramTraceTest.java index c9c4966e208..46be28deed0 100644 --- a/framework/src/test/java/org/tron/core/actuator/vm/ProgramTraceTest.java +++ b/framework/src/test/java/org/tron/core/actuator/vm/ProgramTraceTest.java @@ -1,14 +1,15 @@ package org.tron.core.actuator.vm; -import java.io.File; +import java.io.IOException; import java.math.BigInteger; import java.util.List; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; +import org.junit.ClassRule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.tron.common.runtime.vm.DataWord; -import org.tron.common.utils.FileUtil; import org.tron.core.Constant; import org.tron.core.config.args.Args; import org.tron.core.vm.trace.Op; @@ -16,17 +17,19 @@ import org.tron.core.vm.trace.ProgramTrace; public class ProgramTraceTest { - private static final String dbPath = "output_programTrace_test"; + + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); @BeforeClass - public static void init() { - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + public static void init() throws IOException { + Args.setParam(new String[]{"--output-directory", + temporaryFolder.newFolder().toString(), "--debug"}, Constant.TEST_CONF); } @AfterClass public static void destroy() { Args.clearParam(); - FileUtil.deleteDir(new File(dbPath)); } @Test diff --git a/framework/src/test/java/org/tron/core/capsule/AccountCapsuleTest.java b/framework/src/test/java/org/tron/core/capsule/AccountCapsuleTest.java index 65aab3e9e7a..de72b4be276 100644 --- a/framework/src/test/java/org/tron/core/capsule/AccountCapsuleTest.java +++ b/framework/src/test/java/org/tron/core/capsule/AccountCapsuleTest.java @@ -36,8 +36,7 @@ public class AccountCapsuleTest extends BaseTest { static AccountCapsule accountCapsule; static { - dbPath = "output_accountCapsule_test"; - Args.setParam(new String[]{"-d", dbPath, "-w"}, Constant.TEST_CONF); + Args.setParam(new String[]{"-d", dbPath(), "-w"}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "a06a17a49648a8ad32055c06f60fa14ae46df91234"; } diff --git a/framework/src/test/java/org/tron/core/capsule/BlockCapsuleTest.java b/framework/src/test/java/org/tron/core/capsule/BlockCapsuleTest.java index 88d67c3a632..3c86d893895 100644 --- a/framework/src/test/java/org/tron/core/capsule/BlockCapsuleTest.java +++ b/framework/src/test/java/org/tron/core/capsule/BlockCapsuleTest.java @@ -1,16 +1,18 @@ package org.tron.core.capsule; import com.google.protobuf.ByteString; -import java.io.File; +import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; - +import java.util.List; import lombok.extern.slf4j.Slf4j; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; +import org.junit.ClassRule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.tron.common.utils.ByteArray; -import org.tron.common.utils.FileUtil; import org.tron.common.utils.LocalWitnesses; import org.tron.common.utils.PublicMethod; import org.tron.common.utils.Sha256Hash; @@ -33,18 +35,18 @@ public class BlockCapsuleTest { .fromHexString("9938a342238077182498b464ac0292229938a342238077182498b464ac029222"))), 1234, ByteString.copyFrom("1234567".getBytes())); - private static String dbPath = "output_bloackcapsule_test"; + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); @BeforeClass - public static void init() { - Args.setParam(new String[]{"-d", dbPath}, + public static void init() throws IOException { + Args.setParam(new String[]{"-d", temporaryFolder.newFolder().toString()}, Constant.TEST_CONF); } @AfterClass public static void removeDb() { Args.clearParam(); - FileUtil.deleteDir(new File(dbPath)); } @Test @@ -146,4 +148,20 @@ public void testGetTimeStamp() { Assert.assertEquals(1234L, blockCapsule0.getTimeStamp()); } + @Test + public void testConcurrentToString() throws InterruptedException { + List threadList = new ArrayList<>(); + int n = 10; + for (int i = 0; i < n; i++) { + threadList.add(new Thread(() -> blockCapsule0.toString())); + } + for (int i = 0; i < n; i++) { + threadList.get(i).start(); + } + for (int i = 0; i < n; i++) { + threadList.get(i).join(); + } + Assert.assertTrue(true); + } + } diff --git a/framework/src/test/java/org/tron/core/capsule/ExchangeCapsuleTest.java b/framework/src/test/java/org/tron/core/capsule/ExchangeCapsuleTest.java index 48479287eab..791767a952f 100644 --- a/framework/src/test/java/org/tron/core/capsule/ExchangeCapsuleTest.java +++ b/framework/src/test/java/org/tron/core/capsule/ExchangeCapsuleTest.java @@ -15,8 +15,7 @@ public class ExchangeCapsuleTest extends BaseTest { static { - dbPath = "output_exchange_capsule_test_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); } /** diff --git a/framework/src/test/java/org/tron/core/capsule/TransactionCapsuleTest.java b/framework/src/test/java/org/tron/core/capsule/TransactionCapsuleTest.java index c9d593daf66..fcb2a4fbfd5 100644 --- a/framework/src/test/java/org/tron/core/capsule/TransactionCapsuleTest.java +++ b/framework/src/test/java/org/tron/core/capsule/TransactionCapsuleTest.java @@ -2,10 +2,10 @@ import com.google.protobuf.ByteString; import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.testng.Assert; import org.tron.common.BaseTest; import org.tron.common.utils.StringUtil; import org.tron.core.Constant; @@ -46,8 +46,7 @@ public class TransactionCapsuleTest extends BaseTest { @BeforeClass public static void init() { - dbPath = "output_transactioncapsule_test"; - Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "03702350064AD5C1A8AA6B4D74B051199CFF8EA7"; /*TO_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; OWNER_ACCOUNT_NOT_Exist = diff --git a/framework/src/test/java/org/tron/core/capsule/VotesCapsuleTest.java b/framework/src/test/java/org/tron/core/capsule/VotesCapsuleTest.java index 467d801996e..64bb660ab9a 100644 --- a/framework/src/test/java/org/tron/core/capsule/VotesCapsuleTest.java +++ b/framework/src/test/java/org/tron/core/capsule/VotesCapsuleTest.java @@ -1,15 +1,16 @@ package org.tron.core.capsule; import com.google.protobuf.ByteString; -import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import lombok.extern.slf4j.Slf4j; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.BeforeClass; +import org.junit.ClassRule; import org.junit.Test; -import org.testng.Assert; -import org.tron.common.utils.FileUtil; +import org.junit.rules.TemporaryFolder; import org.tron.common.utils.StringUtil; import org.tron.core.Constant; import org.tron.core.Wallet; @@ -21,7 +22,8 @@ @Slf4j public class VotesCapsuleTest { - private static String dbPath = "output_votesCapsule_test"; + @ClassRule + public static TemporaryFolder temporaryFolder = new TemporaryFolder(); private static final String OWNER_ADDRESS; private static List oldVotes; @@ -31,15 +33,15 @@ public class VotesCapsuleTest { } @BeforeClass - public static void init() { - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); + public static void init() throws IOException { + Args.setParam(new String[]{"--output-directory", + temporaryFolder.newFolder().toString(), "--debug"}, Constant.TEST_CONF); } @AfterClass public static void destroy() { Args.clearParam(); - FileUtil.deleteDir(new File(dbPath)); } @Test diff --git a/framework/src/test/java/org/tron/core/capsule/utils/AssetUtilTest.java b/framework/src/test/java/org/tron/core/capsule/utils/AssetUtilTest.java index 8d56c1a5f21..2b07d7d7952 100644 --- a/framework/src/test/java/org/tron/core/capsule/utils/AssetUtilTest.java +++ b/framework/src/test/java/org/tron/core/capsule/utils/AssetUtilTest.java @@ -24,8 +24,7 @@ public class AssetUtilTest extends BaseTest { static { - dbPath = "output_AssetUtil_test"; - Args.setParam(new String[] {"-d", dbPath, "-w"}, Constant.TEST_CONF); + Args.setParam(new String[] {"-d", dbPath(), "-w"}, Constant.TEST_CONF); } public static byte[] randomBytes(int length) { diff --git a/framework/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java b/framework/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java index 3d30dabf031..3437eb0ea42 100644 --- a/framework/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java +++ b/framework/src/test/java/org/tron/core/capsule/utils/ExchangeProcessorTest.java @@ -15,8 +15,7 @@ public class ExchangeProcessorTest extends BaseTest { private static ExchangeProcessor processor; static { - dbPath = "output_buy_exchange_processor_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); } /** diff --git a/framework/src/test/java/org/tron/core/config/args/ArgsTest.java b/framework/src/test/java/org/tron/core/config/args/ArgsTest.java index 143e10706aa..13e272d1e13 100644 --- a/framework/src/test/java/org/tron/core/config/args/ArgsTest.java +++ b/framework/src/test/java/org/tron/core/config/args/ArgsTest.java @@ -16,8 +16,16 @@ package org.tron.core.config.args; import com.google.common.collect.Lists; +import com.typesafe.config.Config; +import com.typesafe.config.ConfigMergeable; +import com.typesafe.config.ConfigOrigin; +import com.typesafe.config.ConfigRenderOptions; +import com.typesafe.config.ConfigValue; +import com.typesafe.config.ConfigValueType; import io.grpc.internal.GrpcUtil; import io.grpc.netty.NettyServerBuilder; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Arrays; import lombok.extern.slf4j.Slf4j; import org.junit.After; @@ -28,7 +36,10 @@ import org.tron.common.utils.ByteArray; import org.tron.common.utils.LocalWitnesses; import org.tron.common.utils.PublicMethod; +import org.tron.common.utils.ReflectUtils; import org.tron.core.Constant; +import org.tron.core.config.Configuration; +import org.tron.core.net.peer.PeerManager; @Slf4j public class ArgsTest { @@ -44,7 +55,7 @@ public void destroy() { @Test public void get() { - Args.setParam(new String[]{"-w"}, Constant.TEST_CONF); + Args.setParam(new String[] {"-w"}, Constant.TEST_CONF); CommonParameter parameter = Args.getInstance(); @@ -55,7 +66,7 @@ public void get() { localWitnesses.initWitnessAccountAddress(true); Args.setLocalWitnesses(localWitnesses); address = ByteArray.toHexString(Args.getLocalWitnesses() - .getWitnessAccountAddress(CommonParameter.getInstance().isECKeyCryptoEngine())); + .getWitnessAccountAddress(CommonParameter.getInstance().isECKeyCryptoEngine())); Assert.assertEquals(0, parameter.getBackupPriority()); @@ -112,5 +123,35 @@ public void get() { ByteArray.toHexString(Args.getLocalWitnesses() .getWitnessAccountAddress(CommonParameter.getInstance().isECKeyCryptoEngine()))); } + + @Test + public void testIpFromLibP2p() + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Args.setParam(new String[] {"-w"}, Constant.TEST_CONF); + CommonParameter parameter = Args.getInstance(); + + String configuredBindIp = parameter.getNodeDiscoveryBindIp(); + String configuredExternalIp = parameter.getNodeExternalIp(); + Assert.assertEquals("127.0.0.1", configuredBindIp); + Assert.assertEquals("46.168.1.1", configuredExternalIp); + + Config config = Configuration.getByFileName(null, Constant.TEST_CONF); + Config config2 = config.withoutPath(Constant.NODE_DISCOVERY_BIND_IP); + Config config3 = config2.withoutPath(Constant.NODE_DISCOVERY_EXTERNAL_IP); + + CommonParameter.getInstance().setNodeDiscoveryBindIp(null); + CommonParameter.getInstance().setNodeExternalIp(null); + + Method method1 = Args.class.getDeclaredMethod("bindIp", Config.class); + method1.setAccessible(true); + method1.invoke(Args.class, config3); + + Method method2 = Args.class.getDeclaredMethod("externalIp", Config.class); + method2.setAccessible(true); + method2.invoke(Args.class, config3); + + Assert.assertNotEquals(configuredBindIp, parameter.getNodeDiscoveryBindIp()); + Assert.assertNotEquals(configuredExternalIp, parameter.getNodeExternalIp()); + } } diff --git a/framework/src/test/java/org/tron/core/config/args/DynamicArgsTest.java b/framework/src/test/java/org/tron/core/config/args/DynamicArgsTest.java index 2ca95239ad7..2a3af9c440e 100644 --- a/framework/src/test/java/org/tron/core/config/args/DynamicArgsTest.java +++ b/framework/src/test/java/org/tron/core/config/args/DynamicArgsTest.java @@ -1,13 +1,15 @@ package org.tron.core.config.args; import java.io.File; +import java.io.IOException; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.tron.common.application.TronApplicationContext; import org.tron.common.parameter.CommonParameter; -import org.tron.common.utils.FileUtil; import org.tron.common.utils.ReflectUtils; import org.tron.core.Constant; import org.tron.core.config.DefaultConfig; @@ -17,11 +19,12 @@ public class DynamicArgsTest { protected TronApplicationContext context; private DynamicArgs dynamicArgs; - private String dbPath = "output-dynamic-config-test"; + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); @Before - public void init() { - Args.setParam(new String[]{"--output-directory", dbPath}, + public void init() throws IOException { + Args.setParam(new String[]{"--output-directory", temporaryFolder.newFolder().toString()}, Constant.TEST_CONF); context = new TronApplicationContext(DefaultConfig.class); dynamicArgs = context.getBean(DynamicArgs.class); @@ -32,7 +35,6 @@ public void init() { public void destroy() { Args.clearParam(); context.destroy(); - FileUtil.deleteDir(new File(dbPath)); } @Test diff --git a/framework/src/test/java/org/tron/core/db/AbiStoreTest.java b/framework/src/test/java/org/tron/core/db/AbiStoreTest.java new file mode 100644 index 00000000000..0cb134c50ce --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/AbiStoreTest.java @@ -0,0 +1,61 @@ +package org.tron.core.db; + +import static org.tron.common.utils.PublicMethod.jsonStr2Abi; + +import com.google.protobuf.ByteString; +import javax.annotation.Resource; +import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; +import org.tron.core.Constant; +import org.tron.core.capsule.AbiCapsule; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.store.AbiStore; +import org.tron.core.store.AccountIndexStore; +import org.tron.protos.Protocol.AccountType; +import org.tron.protos.contract.SmartContractOuterClass; + +public class AbiStoreTest extends BaseTest { + + @Resource + private AbiStore abiStore; + + private static final byte[] contractAddr = Hex.decode( + "41000000000000000000000000000000000000dEaD"); + + private static final SmartContractOuterClass.SmartContract.ABI SOURCE_ABI = jsonStr2Abi( + "[{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\"" + + ":\"constructor\"}]"); + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath() + }, + Constant.TEST_CONF + ); + } + + @Test + public void testPut() { + abiStore.put(contractAddr, new AbiCapsule(SOURCE_ABI)); + Assert.assertEquals(abiStore.has(contractAddr), Boolean.TRUE); + } + + @Test + public void testGet() { + abiStore.put(contractAddr, new AbiCapsule(SOURCE_ABI)); + AbiCapsule abiCapsule = abiStore.get(contractAddr); + Assert.assertEquals(abiCapsule.getInstance(), SOURCE_ABI); + } + + @Test + public void testGetTotalAbi() { + abiStore.put(contractAddr, new AbiCapsule(SOURCE_ABI)); + Assert.assertEquals(abiStore.getTotalABIs(), 1); + } +} \ No newline at end of file diff --git a/framework/src/test/java/org/tron/core/db/AccountAssetStoreTest.java b/framework/src/test/java/org/tron/core/db/AccountAssetStoreTest.java new file mode 100644 index 00000000000..48c24d98af1 --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/AccountAssetStoreTest.java @@ -0,0 +1,138 @@ +package org.tron.core.db; + +import com.google.common.primitives.Longs; +import com.google.protobuf.ByteString; + +import java.util.Map; +import javax.annotation.Resource; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.AssetIssueCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.store.AccountAssetStore; +import org.tron.core.store.AccountStore; +import org.tron.protos.Protocol; +import org.tron.protos.contract.AssetIssueContractOuterClass; + +public class AccountAssetStoreTest extends BaseTest { + + private static final byte[] ASSET_KEY = "20000".getBytes(); + private static AccountCapsule ownerCapsule; + + private static String OWNER_ADDRESS = Wallet.getAddressPreFixString() + + "abd4b9367799eaa3197fecb144eb71de1e049abc"; + private static final long TOTAL_SUPPLY = 1000_000_000L; + private static final int TRX_NUM = 10; + private static final int NUM = 1; + private static final long START_TIME = 1; + private static final long END_TIME = 2; + private static final int VOTE_SCORE = 2; + private static final String DESCRIPTION = "TRX"; + private static final String URL = "https://tron.network"; + + @Resource + private AccountAssetStore accountAssetStore; + + @Resource + private AccountStore accountStore; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath(), + }, + Constant.TEST_CONF + ); + } + + @Before + public void init() { + accountAssetStore.put(ASSET_KEY, Longs.toByteArray(200L)); + + ownerCapsule = + new AccountCapsule( + ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)), + ByteString.copyFromUtf8("owner"), + Protocol.AccountType.AssetIssue); + } + + + private long createAsset(String tokenName) { + long id = chainBaseManager.getDynamicPropertiesStore().getTokenIdNum() + 1; + chainBaseManager.getDynamicPropertiesStore().saveTokenIdNum(id); + AssetIssueContractOuterClass.AssetIssueContract assetIssueContract = + AssetIssueContractOuterClass.AssetIssueContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))) + .setName(ByteString.copyFrom(ByteArray.fromString(tokenName))) + .setId(Long.toString(id)) + .setTotalSupply(TOTAL_SUPPLY) + .setTrxNum(TRX_NUM) + .setNum(NUM) + .setStartTime(START_TIME) + .setEndTime(END_TIME) + .setVoteScore(VOTE_SCORE) + .setDescription(ByteString.copyFrom(ByteArray.fromString(DESCRIPTION))) + .setUrl(ByteString.copyFrom(ByteArray.fromString(URL))) + .build(); + AssetIssueCapsule assetIssueCapsule = new AssetIssueCapsule(assetIssueContract); + chainBaseManager.getAssetIssueV2Store() + .put(assetIssueCapsule.createDbV2Key(), assetIssueCapsule); + try { + ownerCapsule.addAssetV2(ByteArray.fromString(String.valueOf(id)), TOTAL_SUPPLY); + } catch (Exception e) { + e.printStackTrace(); + } + accountStore.put(ownerCapsule.getAddress().toByteArray(), ownerCapsule); + return id; + } + + @Test + public void testPut() { + byte[] key = "10000".getBytes(); + accountAssetStore.put(key, Longs.toByteArray(100L)); + byte[] bytes = accountAssetStore.get(key); + Assert.assertEquals(100L, Longs.fromByteArray(bytes)); + } + + @Test + public void testGet() { + byte[] bytes = accountAssetStore.get(ASSET_KEY); + Assert.assertEquals(200L, Longs.fromByteArray(bytes)); + } + + @Test + public void testGetAccountAssets() { + long assetKey = createAsset("testToken1"); + AccountCapsule accountCapsule = accountStore.get(ownerCapsule.getAddress().toByteArray()); + long assetValue = accountCapsule.getAssetV2(String.valueOf(assetKey)); + Assert.assertEquals(assetValue, TOTAL_SUPPLY); + } + + @Test + public void testGetAllAssets() { + long assetKey1 = createAsset("testToken1"); + long assetKey2 = createAsset("testToken2"); + AccountCapsule accountCapsule = accountStore.get(ownerCapsule.getAddress().toByteArray()); + + Map allAssets = accountAssetStore.getAllAssets(accountCapsule.getInstance()); + Long assetValue1 = allAssets.get(String.valueOf(assetKey1)); + Assert.assertNotNull(assetValue1); + + Long assetV1 = accountCapsule.getAssetV2(String.valueOf(assetKey1)); + Assert.assertEquals(assetValue1, assetV1); + + Long assetValue2 = allAssets.get(String.valueOf(assetKey2)); + Assert.assertNotNull(assetValue2); + + Long assetV2 = accountCapsule.getAssetV2(String.valueOf(assetKey2)); + Assert.assertEquals(assetValue1, assetV2); + } + +} diff --git a/framework/src/test/java/org/tron/core/db/AccountIdIndexStoreTest.java b/framework/src/test/java/org/tron/core/db/AccountIdIndexStoreTest.java index fa31b2fd451..9033e90481c 100644 --- a/framework/src/test/java/org/tron/core/db/AccountIdIndexStoreTest.java +++ b/framework/src/test/java/org/tron/core/db/AccountIdIndexStoreTest.java @@ -34,8 +34,7 @@ public class AccountIdIndexStoreTest extends BaseTest { private static AccountCapsule accountCapsule4; static { - dbPath = "output_AccountIndexStore_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); } diff --git a/framework/src/test/java/org/tron/core/db/AccountIndexStoreTest.java b/framework/src/test/java/org/tron/core/db/AccountIndexStoreTest.java index 0b449addc41..a4dc848b749 100755 --- a/framework/src/test/java/org/tron/core/db/AccountIndexStoreTest.java +++ b/framework/src/test/java/org/tron/core/db/AccountIndexStoreTest.java @@ -23,10 +23,9 @@ public class AccountIndexStoreTest extends BaseTest { private static byte[] accountName = TransactionStoreTest.randomBytes(32); static { - dbPath = "output_AccountIndexStore_test"; Args.setParam( new String[]{ - "--output-directory", dbPath, + "--output-directory", dbPath(), "--storage-db-directory", dbDirectory, "--storage-index-directory", indexDirectory }, diff --git a/framework/src/test/java/org/tron/core/db/AccountStoreTest.java b/framework/src/test/java/org/tron/core/db/AccountStoreTest.java index f199b371f9d..9249a3358dc 100755 --- a/framework/src/test/java/org/tron/core/db/AccountStoreTest.java +++ b/framework/src/test/java/org/tron/core/db/AccountStoreTest.java @@ -36,10 +36,9 @@ public class AccountStoreTest extends BaseTest { private static boolean init; static { - dbPath = "output_AccountStore_test"; Args.setParam( new String[]{ - "--output-directory", dbPath, + "--output-directory", dbPath(), "--storage-db-directory", dbDirectory, "--storage-index-directory", indexDirectory }, diff --git a/framework/src/test/java/org/tron/core/db/AccountTraceStoreTest.java b/framework/src/test/java/org/tron/core/db/AccountTraceStoreTest.java new file mode 100644 index 00000000000..aa87f903ad3 --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/AccountTraceStoreTest.java @@ -0,0 +1,57 @@ +package org.tron.core.db; + +import com.google.common.primitives.Bytes; +import com.google.common.primitives.Longs; +import com.google.protobuf.ByteString; +import javax.annotation.Resource; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; +import org.tron.core.Constant; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.exception.BadItemException; +import org.tron.core.exception.ItemNotFoundException; +import org.tron.core.store.AccountIndexStore; +import org.tron.core.store.AccountTraceStore; +import org.tron.protos.Protocol.AccountType; + +public class AccountTraceStoreTest extends BaseTest { + + @Resource + private AccountTraceStore accountTraceStore; + private static byte[] address = TransactionStoreTest.randomBytes(32); + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath() + }, + Constant.TEST_CONF + ); + } + + + @Test + public void testRecordBalanceWithBlock() throws BadItemException, ItemNotFoundException { + accountTraceStore.recordBalanceWithBlock(address,1,9999); + Assert.assertNotNull(accountTraceStore.get(Bytes.concat(address, + Longs.toByteArray(1L ^ Long.MAX_VALUE)))); + } + + @Test + public void testGetPrevBalance() { + accountTraceStore.recordBalanceWithBlock(address,2,9999); + Pair pair = accountTraceStore.getPrevBalance(address,2); + Assert.assertEquals((long)pair.getKey(),2L); + Assert.assertEquals((long)pair.getValue(), 0L); + byte[] address2 = TransactionStoreTest.randomBytes(21); + accountTraceStore.recordBalanceWithBlock(address2,3,99); + Pair pair2 = accountTraceStore.getPrevBalance(address2, 3); + Assert.assertEquals((long)pair2.getKey(),3L); + Assert.assertEquals((long)pair2.getValue(), 99L); + } +} \ No newline at end of file diff --git a/framework/src/test/java/org/tron/core/db/AssetIssueStoreTest.java b/framework/src/test/java/org/tron/core/db/AssetIssueStoreTest.java new file mode 100644 index 00000000000..34a4a8507d6 --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/AssetIssueStoreTest.java @@ -0,0 +1,90 @@ +package org.tron.core.db; + +import com.google.protobuf.ByteString; +import javax.annotation.Resource; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; +import org.tron.core.Constant; +import org.tron.core.capsule.AssetIssueCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.store.AssetIssueStore; +import org.tron.protos.contract.AssetIssueContractOuterClass; + +public class AssetIssueStoreTest extends BaseTest { + + private static final String NAME = "test-asset"; + private static final long TOTAL_SUPPLY = 10000L; + private static final int TRX_NUM = 10000; + private static final int NUM = 100000; + private static final String DESCRIPTION = "myCoin"; + private static final String URL = "tron.network"; + + @Resource + private AssetIssueStore assetIssueStore; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath(), + }, + Constant.TEST_CONF + ); + } + + @Before + public void init() { + long id = dbManager.getDynamicPropertiesStore().getTokenIdNum() + 1; + AssetIssueCapsule assetIssueCapsule = createAssetIssue(id, NAME); + assetIssueStore.put(assetIssueCapsule.createDbKey(), assetIssueCapsule); + } + + private AssetIssueCapsule createAssetIssue(long id, String name) { + dbManager.getDynamicPropertiesStore().saveTokenIdNum(id); + AssetIssueContractOuterClass.AssetIssueContract assetIssueContract = + AssetIssueContractOuterClass.AssetIssueContract.newBuilder() + .setName(ByteString.copyFrom(ByteArray.fromString(name))).setId(Long.toString(id)) + .setTotalSupply(TOTAL_SUPPLY) + .setTrxNum(TRX_NUM).setNum(NUM).setStartTime(1).setEndTime(100).setVoteScore(2) + .setDescription(ByteString.copyFrom(ByteArray.fromString(DESCRIPTION))) + .setUrl(ByteString.copyFrom(ByteArray.fromString(URL))).build(); + AssetIssueCapsule assetIssueCapsule = new AssetIssueCapsule(assetIssueContract); + return assetIssueCapsule; + } + + @Test + public void testPut() { + long id = dbManager.getDynamicPropertiesStore().getTokenIdNum() + 1; + String issueName = "test-asset2"; + AssetIssueCapsule assetIssueCapsule = createAssetIssue(id, issueName); + assetIssueStore.put(assetIssueCapsule.createDbKey(), assetIssueCapsule); + AssetIssueCapsule assetIssueCapsule1 = assetIssueStore.get(ByteArray.fromString(issueName)); + + Assert.assertNotNull(assetIssueCapsule1); + Assert.assertEquals(issueName, new String(assetIssueCapsule1.getName().toByteArray())); + } + + @Test + public void testGet() { + AssetIssueCapsule assetIssueCapsule = assetIssueStore.get(ByteArray.fromString(NAME)); + Assert.assertNotNull(assetIssueCapsule); + Assert.assertEquals(NAME, new String(assetIssueCapsule.getName().toByteArray())); + Assert.assertEquals(TOTAL_SUPPLY, assetIssueCapsule.getInstance().getTotalSupply()); + } + + @Test + public void testDelete() { + long id = dbManager.getDynamicPropertiesStore().getTokenIdNum() + 1; + String issueName = "test-asset-delete"; + AssetIssueCapsule assetIssueCapsule = createAssetIssue(id, issueName); + assetIssueStore.put(assetIssueCapsule.createDbKey(), assetIssueCapsule); + AssetIssueCapsule assetIssueCapsule1 = assetIssueStore.get(ByteArray.fromString(issueName)); + Assert.assertNotNull(assetIssueCapsule1); + assetIssueStore.delete(assetIssueCapsule1.createDbKey()); + AssetIssueCapsule assetIssueCapsule2 = assetIssueStore.get(ByteArray.fromString(issueName)); + Assert.assertNull(assetIssueCapsule2); + + } +} diff --git a/framework/src/test/java/org/tron/core/db/AssetIssueV2StoreTest.java b/framework/src/test/java/org/tron/core/db/AssetIssueV2StoreTest.java new file mode 100644 index 00000000000..e92027e3a28 --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/AssetIssueV2StoreTest.java @@ -0,0 +1,91 @@ +package org.tron.core.db; + +import com.google.protobuf.ByteString; +import javax.annotation.Resource; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.capsule.AssetIssueCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.store.AssetIssueV2Store; +import org.tron.protos.contract.AssetIssueContractOuterClass; + + +public class AssetIssueV2StoreTest extends BaseTest { + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath(), + }, + Constant.TEST_CONF + ); + } + + private AssetIssueCapsule assetIssueCapsule; + + @Resource + private AssetIssueV2Store assetIssueV2Store; + + @Before + public void init() { + String firstTokenId = "abc"; + assetIssueCapsule = + new AssetIssueCapsule( + AssetIssueContractOuterClass.AssetIssueContract.newBuilder() + .setName(ByteString.copyFrom(firstTokenId.getBytes())) + .build()); + assetIssueCapsule.setId(String.valueOf(1L)); + assetIssueV2Store + .put(assetIssueCapsule.createDbV2Key(), assetIssueCapsule); + } + + @Test + public void testPut() { + String firstTokenId = "efg"; + assetIssueCapsule = + new AssetIssueCapsule( + AssetIssueContractOuterClass.AssetIssueContract.newBuilder() + .setName(ByteString.copyFrom(firstTokenId.getBytes())) + .build()); + assetIssueCapsule.setId(String.valueOf(2L)); + assetIssueV2Store + .put(assetIssueCapsule.createDbV2Key(), assetIssueCapsule); + AssetIssueCapsule assetIssueCapsule = + assetIssueV2Store.get(this.assetIssueCapsule.createDbV2Key()); + Assert.assertNotNull(assetIssueCapsule); + String assetName = new String(assetIssueCapsule.getName().toByteArray()); + Assert.assertEquals(firstTokenId, assetName); + } + + @Test + public void testGet() { + AssetIssueCapsule assetIssueCapsule1 = assetIssueV2Store.get(assetIssueCapsule.createDbV2Key()); + Assert.assertNotNull(assetIssueCapsule1); + String assetName = new String(assetIssueCapsule1.getName().toByteArray()); + Assert.assertEquals("abc", assetName); + } + + @Test + public void testDelete() { + String firstTokenId = "hij"; + assetIssueCapsule = + new AssetIssueCapsule( + AssetIssueContractOuterClass.AssetIssueContract.newBuilder() + .setName(ByteString.copyFrom(firstTokenId.getBytes())) + .build()); + assetIssueCapsule.setId(String.valueOf(2L)); + assetIssueV2Store + .put(assetIssueCapsule.createDbV2Key(), assetIssueCapsule); + AssetIssueCapsule assetIssueCapsule = + assetIssueV2Store.get(this.assetIssueCapsule.createDbV2Key()); + Assert.assertNotNull(assetIssueCapsule); + + assetIssueV2Store.delete(assetIssueCapsule.createDbV2Key()); + AssetIssueCapsule assetIssueCapsule1 = + assetIssueV2Store.get(this.assetIssueCapsule.createDbV2Key()); + Assert.assertNull(assetIssueCapsule1); + } +} diff --git a/framework/src/test/java/org/tron/core/db/BalanceTraceStoreTest.java b/framework/src/test/java/org/tron/core/db/BalanceTraceStoreTest.java new file mode 100644 index 00000000000..82547a997da --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/BalanceTraceStoreTest.java @@ -0,0 +1,131 @@ +package org.tron.core.db; + +import static org.junit.Assert.assertEquals; +import static org.tron.protos.Protocol.Transaction.Contract.ContractType.TransferContract; +import static org.tron.protos.Protocol.Transaction.Result.contractResult.SUCCESS; + +import com.google.protobuf.ByteString; +import java.util.Arrays; +import javax.annotation.Resource; +import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; +import org.tron.core.Constant; +import org.tron.core.capsule.BlockBalanceTraceCapsule; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.capsule.TransactionCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.store.BalanceTraceStore; +import org.tron.protos.Protocol; +import org.tron.protos.contract.BalanceContract; + + +public class BalanceTraceStoreTest extends BaseTest { + + @Resource + private BalanceTraceStore balanceTraceStoreUnderTest; + + private static final byte[] contractAddr = Hex.decode( + "41000000000000000000000000000000000000dEaD"); + + BlockCapsule blockCapsule = new BlockCapsule(Protocol.Block.newBuilder().setBlockHeader( + Protocol.BlockHeader.newBuilder().setRawData(Protocol.BlockHeader.raw.newBuilder() + .setParentHash(ByteString.copyFrom(ByteArray.fromHexString( + "0304f784e4e7bae517bcab94c3e0c9214fb4ac7ff9d7d5a937d1f40031f87b81"))))).build()); + final TransactionCapsule transactionCapsule = + new TransactionCapsule(Protocol.Transaction.newBuilder().build()); + BalanceContract.TransactionBalanceTrace transactionBalanceTrace = + BalanceContract.TransactionBalanceTrace.newBuilder() + .setTransactionIdentifier(transactionCapsule.getTransactionId().getByteString()) + .setType(TransferContract.name()) + .setStatus(SUCCESS.name()) + .build(); + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath() + }, + Constant.TEST_CONF + ); + } + + @Before + public void clear() { + balanceTraceStoreUnderTest.resetCurrentTransactionTrace(); + balanceTraceStoreUnderTest.resetCurrentBlockTrace(); + } + + + @Test + public void testSetCurrentTransactionId() throws Exception { + balanceTraceStoreUnderTest.setCurrentBlockId(blockCapsule); + balanceTraceStoreUnderTest.setCurrentTransactionId(transactionCapsule); + Assert.assertEquals(balanceTraceStoreUnderTest.getCurrentTransactionId(), + transactionCapsule.getTransactionId()); + } + + @Test + public void testSetCurrentBlockId() { + balanceTraceStoreUnderTest.setCurrentBlockId(blockCapsule); + Assert.assertEquals(blockCapsule.getBlockId(), balanceTraceStoreUnderTest.getCurrentBlockId()); + } + + @Test + public void testResetCurrentTransactionTrace() { + balanceTraceStoreUnderTest.setCurrentBlockId(blockCapsule); + balanceTraceStoreUnderTest.setCurrentTransactionId(transactionCapsule); + balanceTraceStoreUnderTest.resetCurrentTransactionTrace(); + balanceTraceStoreUnderTest.resetCurrentBlockTrace(); + Assert.assertNotNull(balanceTraceStoreUnderTest.getCurrentTransactionId()); + Assert.assertNull(balanceTraceStoreUnderTest.getCurrentTransactionBalanceTrace()); + } + + @Test + public void testInitCurrentBlockBalanceTrace() { + balanceTraceStoreUnderTest.initCurrentBlockBalanceTrace(blockCapsule); + Assert.assertNull(balanceTraceStoreUnderTest.getCurrentBlockId()); + } + + @Test + public void testInitCurrentTransactionBalanceTrace() { + balanceTraceStoreUnderTest.setCurrentBlockId(blockCapsule); + balanceTraceStoreUnderTest.initCurrentTransactionBalanceTrace(transactionCapsule); + Assert.assertEquals(blockCapsule.getBlockId(), balanceTraceStoreUnderTest.getCurrentBlockId()); + Assert.assertNull(balanceTraceStoreUnderTest.getCurrentTransactionId()); + } + + @Test + public void testUpdateCurrentTransactionStatus() { + balanceTraceStoreUnderTest.setCurrentBlockId(blockCapsule); + balanceTraceStoreUnderTest.updateCurrentTransactionStatus(""); + Assert.assertNull(balanceTraceStoreUnderTest.getCurrentTransactionBalanceTrace()); + } + + @Test + public void testGetBlockBalanceTrace() throws Exception { + BlockBalanceTraceCapsule blockBalanceTraceCapsule = new BlockBalanceTraceCapsule(blockCapsule); + balanceTraceStoreUnderTest.put(ByteArray.fromLong(blockCapsule.getNum()), + blockBalanceTraceCapsule); + final BlockBalanceTraceCapsule result = + balanceTraceStoreUnderTest.getBlockBalanceTrace(blockCapsule.getBlockId()); + assertEquals(Arrays.toString(result.getData()), + Arrays.toString(blockBalanceTraceCapsule.getData())); + } + + @Test + public void testGetTransactionBalanceTrace() throws Exception { + BlockBalanceTraceCapsule blockBalanceTraceCapsule = new BlockBalanceTraceCapsule(blockCapsule); + blockBalanceTraceCapsule.addTransactionBalanceTrace(transactionBalanceTrace); + balanceTraceStoreUnderTest.put(ByteArray.fromLong(blockCapsule.getNum()), + blockBalanceTraceCapsule); + final BalanceContract.TransactionBalanceTrace result = + balanceTraceStoreUnderTest.getTransactionBalanceTrace(blockCapsule.getBlockId(), + transactionCapsule.getTransactionId()); + Assert.assertEquals(result.getStatus(),"SUCCESS"); + } + +} \ No newline at end of file diff --git a/framework/src/test/java/org/tron/core/db/BandwidthPriceHistoryLoaderTest.java b/framework/src/test/java/org/tron/core/db/BandwidthPriceHistoryLoaderTest.java index 4c7af2b31fe..298b9f40235 100644 --- a/framework/src/test/java/org/tron/core/db/BandwidthPriceHistoryLoaderTest.java +++ b/framework/src/test/java/org/tron/core/db/BandwidthPriceHistoryLoaderTest.java @@ -11,16 +11,17 @@ import static org.tron.core.utils.ProposalUtil.ProposalType.TRANSACTION_FEE; import static org.tron.core.utils.ProposalUtil.ProposalType.WITNESS_127_PAY_PER_BLOCK; -import java.io.File; +import java.io.IOException; import java.util.HashMap; import java.util.Map; import lombok.extern.slf4j.Slf4j; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.tron.common.application.TronApplicationContext; -import org.tron.common.utils.FileUtil; import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.capsule.ProposalCapsule; @@ -36,7 +37,8 @@ public class BandwidthPriceHistoryLoaderTest { private static ChainBaseManager chainBaseManager; private static TronApplicationContext context; - private static final String dbPath = "output-BandwidthPriceHistoryLoaderTest-test"; + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); private static long t1; private static long price1; private static long t2; @@ -47,8 +49,9 @@ public class BandwidthPriceHistoryLoaderTest { // Note, here use @Before and @After instead of @BeforeClass and @AfterClass, // because it needs to initialize DB before the single test every time @Before - public void init() { - Args.setParam(new String[] {"--output-directory", dbPath}, Constant.TEST_CONF); + public void init() throws IOException { + Args.setParam(new String[] {"--output-directory", + temporaryFolder.newFolder().toString()}, Constant.TEST_CONF); context = new TronApplicationContext(DefaultConfig.class); chainBaseManager = context.getBean(ChainBaseManager.class); } @@ -57,11 +60,6 @@ public void init() { public void destroy() { Args.clearParam(); context.destroy(); - if (FileUtil.deleteDir(new File(dbPath))) { - logger.info("Release resources successful."); - } else { - logger.info("Release resources failure."); - } } public void initDB() { diff --git a/framework/src/test/java/org/tron/core/db/BlockStoreTest.java b/framework/src/test/java/org/tron/core/db/BlockStoreTest.java index cdf8dbcc29c..4f706a97dcf 100644 --- a/framework/src/test/java/org/tron/core/db/BlockStoreTest.java +++ b/framework/src/test/java/org/tron/core/db/BlockStoreTest.java @@ -11,8 +11,7 @@ public class BlockStoreTest extends BaseTest { static { - dbPath = "output-blockStore-test"; - Args.setParam(new String[]{"--output-directory", dbPath}, + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); } diff --git a/framework/src/test/java/org/tron/core/db/ByteArrayWrapperTest.java b/framework/src/test/java/org/tron/core/db/ByteArrayWrapperTest.java index ef4a60ca1da..fdf5877b87c 100644 --- a/framework/src/test/java/org/tron/core/db/ByteArrayWrapperTest.java +++ b/framework/src/test/java/org/tron/core/db/ByteArrayWrapperTest.java @@ -1,8 +1,8 @@ package org.tron.core.db; import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.common.utils.ByteArray; @Slf4j diff --git a/framework/src/test/java/org/tron/core/db/CodeStoreTest.java b/framework/src/test/java/org/tron/core/db/CodeStoreTest.java new file mode 100644 index 00000000000..59bfba2236a --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/CodeStoreTest.java @@ -0,0 +1,74 @@ +package org.tron.core.db; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import javax.annotation.Resource; +import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; +import org.tron.core.Constant; +import org.tron.core.capsule.CodeCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.store.CodeStore; + +public class CodeStoreTest extends BaseTest { + + private static final byte[] contractAddr1 = Hex.decode( + "41000000000000000000000000000000000000dEaD"); + private static final byte[] contractAddr2 = Hex.decode( + "41000000000000000000000000000000000000dEbD"); + private static final byte[] contractAddr3 = Hex.decode( + "41000000000000000000000000000000000000dEcD"); + + private static String codeString = + "608060405234801561001057600080fd5b50d3801561001d57600080fd5b50d28015" + + "61002a57600080fd5b50600436106100495760003560e01c806385bb7d69146100555761004a565b5b61" + + "0052610073565b50005b61005d610073565b60405161006a91906100b9565b60405180910390f35b6000" + + "80600090505b60028110156100a657808261009091906100d4565b915060018161009f91906100d4565b" + + "905061007b565b5090565b6100b38161012a565b82525050565b60006020820190506100ce6000830184" + + "6100aa565b92915050565b60006100df8261012a565b91506100ea8361012a565b9250827fffffffffff" + + "ffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561011f5761011e61013456" + + "5b5b828201905092915050565b6000819050919050565b7f4e487b710000000000000000000000000000" + + "0000000000000000000000000000600052601160045260246000fdfea26474726f6e58221220f3d01983" + + "23c67293b97323c101e294e6d2cac7fb29555292675277e11c275a4b64736f6c63430008060033"; + private static final CodeCapsule codeCapsule = new CodeCapsule(ByteArray + .fromHexString(codeString)); + + @Resource + private CodeStore codeStore; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath() + }, + Constant.TEST_CONF + ); + } + + @Test + public void testGet() { + codeStore.put(contractAddr1, codeCapsule); + final CodeCapsule result = codeStore.get(contractAddr1); + assertEquals(result.toString(), Arrays.toString(ByteArray.fromHexString(codeString))); + } + + @Test + public void testGetTotalCodes() throws Exception { + codeStore.put(contractAddr1, codeCapsule); + codeStore.put(codeCapsule.getCodeHash().getBytes(), codeCapsule); + final long result = codeStore.getTotalCodes(); + assertEquals(2L, result); + } + + @Test + public void testFindCodeByHash() { + codeStore.put(codeCapsule.getCodeHash().getBytes(), codeCapsule); + final byte[] result = codeStore.findCodeByHash(codeCapsule.getCodeHash().getBytes()); + assertEquals(Arrays.toString(result), Arrays.toString(ByteArray.fromHexString(codeString))); + } +} \ No newline at end of file diff --git a/framework/src/test/java/org/tron/core/db/ContractStoreTest.java b/framework/src/test/java/org/tron/core/db/ContractStoreTest.java new file mode 100644 index 00000000000..391a2013636 --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/ContractStoreTest.java @@ -0,0 +1,101 @@ +package org.tron.core.db; + +import com.google.protobuf.ByteString; +import javax.annotation.Resource; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.capsule.ContractCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.store.ContractStore; +import org.tron.protos.contract.SmartContractOuterClass; + +public class ContractStoreTest extends BaseTest { + + private static final String SMART_CONTRACT_NAME = "smart_contract_test"; + private static final String CONTRACT_ADDRESS = "111111"; + private static final long SOURCE_ENERGY_LIMIT = 10L; + private static String OWNER_ADDRESS; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath(), + }, + Constant.TEST_CONF + ); + } + + @Resource + private ContractStore contractStore; + + @Before + public void init() { + SmartContractOuterClass.SmartContract.Builder contract = + createContract(CONTRACT_ADDRESS, SMART_CONTRACT_NAME); + contractStore.put( + ByteArray.fromHexString(CONTRACT_ADDRESS), + new ContractCapsule(contract.build())); + } + + private SmartContractOuterClass.SmartContract.Builder createContract( + String contractAddress, String contractName) { + OWNER_ADDRESS = + Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; + SmartContractOuterClass.SmartContract.Builder builder = + SmartContractOuterClass.SmartContract.newBuilder(); + builder.setName(contractName); + builder.setOriginAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS))); + builder.setContractAddress(ByteString.copyFrom(ByteArray.fromHexString(contractAddress))); + builder.setOriginEnergyLimit(SOURCE_ENERGY_LIMIT); + return builder; + } + + @Test + public void testGet() { + ContractCapsule contractCapsule = contractStore.get(ByteArray.fromHexString(CONTRACT_ADDRESS)); + byte[] originAddressByte = contractCapsule.getOriginAddress(); + String address = ByteArray.toHexString(originAddressByte); + Assert.assertEquals(OWNER_ADDRESS, address); + } + + @Test + public void testPut() { + String contractAddress = "22222222"; + String contractName = "test_contract_name"; + SmartContractOuterClass.SmartContract.Builder contract = + createContract(contractAddress, contractName); + + contractStore.put( + ByteArray.fromHexString(contractAddress), + new ContractCapsule(contract.build())); + + ContractCapsule contractCapsule = contractStore.get(ByteArray.fromHexString(contractAddress)); + Assert.assertNotNull(contractCapsule); + String name = contractCapsule.getInstance().getName(); + Assert.assertEquals(contractName, name); + } + + @Test + public void testDelete() { + String contractAddress = "3333333"; + String contractName = "test_contract_name3333"; + SmartContractOuterClass.SmartContract.Builder contract = + createContract(contractAddress, contractName); + contractStore.put( + ByteArray.fromHexString(contractAddress), + new ContractCapsule(contract.build())); + ContractCapsule contractCapsule = contractStore.get(ByteArray.fromHexString(contractAddress)); + Assert.assertNotNull(contractCapsule); + String name = contractCapsule.getInstance().getName(); + Assert.assertEquals(contractName, name); + + contractStore.delete(ByteArray.fromHexString(contractAddress)); + ContractCapsule contractCapsule2 = contractStore.get(ByteArray.fromHexString(contractAddress)); + Assert.assertNull(contractCapsule2); + } +} diff --git a/framework/src/test/java/org/tron/core/db/DelegatedResourceAccountIndexStoreTest.java b/framework/src/test/java/org/tron/core/db/DelegatedResourceAccountIndexStoreTest.java new file mode 100644 index 00000000000..fd5932603e3 --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/DelegatedResourceAccountIndexStoreTest.java @@ -0,0 +1,150 @@ +package org.tron.core.db; + +import com.google.common.primitives.Bytes; +import com.google.protobuf.ByteString; +import java.util.Collections; +import javax.annotation.Resource; +import org.junit.Assert; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.DecodeUtil; +import org.tron.core.Constant; +import org.tron.core.capsule.DelegatedResourceAccountIndexCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.store.DelegatedResourceAccountIndexStore; + + +public class DelegatedResourceAccountIndexStoreTest extends BaseTest { + + @Resource + private DelegatedResourceAccountIndexStore delegatedResourceAccountIndexStore; + + String owner1 = DecodeUtil.addressPreFixString + "548794500882809695a8a687866e76d4271a1abc"; + private static final byte[] FROM_PREFIX = {0x01}; + private static final byte[] TO_PREFIX = {0x02}; + private static final byte[] V2_FROM_PREFIX = {0x03}; + private static final byte[] V2_TO_PREFIX = {0x04}; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath() + }, + Constant.TEST_CONF + ); + } + + @Test + public void testGet() { + delegatedResourceAccountIndexStore.put(ByteArray.fromHexString(owner1), + new DelegatedResourceAccountIndexCapsule(ByteString.copyFrom("testGet".getBytes()))); + final DelegatedResourceAccountIndexCapsule result = + delegatedResourceAccountIndexStore.get(ByteArray.fromHexString(owner1)); + Assert.assertNotNull(result); + Assert.assertEquals(result.getAccount(), ByteString.copyFrom("testGet".getBytes())); + } + + @Test + public void testConvert() { + DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsule = + new DelegatedResourceAccountIndexCapsule(ByteString.copyFrom("testConvert".getBytes())); + delegatedResourceAccountIndexCapsule.setAllFromAccounts( + Collections.singletonList(ByteString.copyFrom("testConvertFrom".getBytes()))); + delegatedResourceAccountIndexCapsule.setAllToAccounts( + Collections.singletonList(ByteString.copyFrom("testConvertTo".getBytes()))); + delegatedResourceAccountIndexStore.put(ByteArray.fromHexString(owner1), + delegatedResourceAccountIndexCapsule); + delegatedResourceAccountIndexStore.convert(ByteArray.fromHexString(owner1)); + DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsule1 = + delegatedResourceAccountIndexStore.get(Bytes.concat(FROM_PREFIX, + ByteArray.fromHexString(owner1), "testConvertTo".getBytes())); + DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsule2 = + delegatedResourceAccountIndexStore.get(Bytes.concat(TO_PREFIX, + "testConvertTo".getBytes(), ByteArray.fromHexString(owner1))); + Assert.assertNotNull(delegatedResourceAccountIndexCapsule1); + Assert.assertNotNull(delegatedResourceAccountIndexCapsule2); + } + + @Test + public void testDelegate() throws Exception { + delegatedResourceAccountIndexStore.delegate("testDelegateFrom".getBytes(), + "testDelegateTo".getBytes(),1L); + DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsule1 = + delegatedResourceAccountIndexStore.get(Bytes.concat(FROM_PREFIX, + "testDelegateFrom".getBytes(), "testDelegateTo".getBytes())); + DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsule2 = + delegatedResourceAccountIndexStore.get(Bytes.concat(TO_PREFIX, "testDelegateTo".getBytes(), + "testDelegateFrom".getBytes())); + Assert.assertNotNull(delegatedResourceAccountIndexCapsule1); + Assert.assertEquals(delegatedResourceAccountIndexCapsule1.getTimestamp(),1); + Assert.assertNotNull(delegatedResourceAccountIndexCapsule2); + Assert.assertEquals(delegatedResourceAccountIndexCapsule2.getTimestamp(),1); + } + + @Test + public void testDelegateV2() { + delegatedResourceAccountIndexStore.delegateV2("testDelegatev2From".getBytes(), + "testDelegatev2To".getBytes(),2L); + DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsule1 = + delegatedResourceAccountIndexStore.get(Bytes.concat(V2_FROM_PREFIX, + "testDelegatev2From".getBytes(), "testDelegatev2To".getBytes())); + DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsule2 = + delegatedResourceAccountIndexStore.get(Bytes.concat(V2_TO_PREFIX, + "testDelegatev2To".getBytes(), "testDelegatev2From".getBytes())); + Assert.assertNotNull(delegatedResourceAccountIndexCapsule1); + Assert.assertEquals(delegatedResourceAccountIndexCapsule1.getTimestamp(),2); + Assert.assertNotNull(delegatedResourceAccountIndexCapsule2); + Assert.assertEquals(delegatedResourceAccountIndexCapsule2.getTimestamp(),2); + } + + @Test + public void testUnDelegate() throws Exception { + delegatedResourceAccountIndexStore.delegate("testDelegateFrom".getBytes(), + "testDelegateTo".getBytes(),1L); + delegatedResourceAccountIndexStore.unDelegate("testDelegateFrom".getBytes(), + "testDelegateTo".getBytes()); + DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsule1 = + delegatedResourceAccountIndexStore.get(Bytes.concat(FROM_PREFIX, + "testDelegateFrom".getBytes(), "testDelegateTo".getBytes())); + DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsule2 = + delegatedResourceAccountIndexStore.get(Bytes.concat(TO_PREFIX, + "testDelegateTo".getBytes(), "testDelegateFrom".getBytes())); + Assert.assertNull(delegatedResourceAccountIndexCapsule1); + Assert.assertNull(delegatedResourceAccountIndexCapsule2); + } + + @Test + public void testUnDelegateV2() { + delegatedResourceAccountIndexStore.delegateV2("testDelegateFrom".getBytes(), + "testDelegateTo".getBytes(),1L); + delegatedResourceAccountIndexStore.unDelegateV2("testDelegateFrom".getBytes(), + "testDelegateTo".getBytes()); + DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsule1 = + delegatedResourceAccountIndexStore.get(Bytes.concat(V2_FROM_PREFIX, + "testDelegateFrom".getBytes(), "testDelegateTo".getBytes())); + DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsule2 = + delegatedResourceAccountIndexStore.get(Bytes.concat(V2_TO_PREFIX, + "testDelegateTo".getBytes(), "testDelegateFrom".getBytes())); + Assert.assertNull(delegatedResourceAccountIndexCapsule1); + Assert.assertNull(delegatedResourceAccountIndexCapsule2); + } + + @Test + public void testGetIndex() throws Exception { + DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsule = + delegatedResourceAccountIndexStore.getIndex("testGetIndex".getBytes()); + Assert.assertNotNull(delegatedResourceAccountIndexCapsule); + Assert.assertNotNull(delegatedResourceAccountIndexCapsule.getFromAccountsList()); + Assert.assertNotNull(delegatedResourceAccountIndexCapsule.getToAccountsList()); + } + + @Test + public void testGetV2Index() { + DelegatedResourceAccountIndexCapsule delegatedResourceAccountIndexCapsule = + delegatedResourceAccountIndexStore.getV2Index("testGetV2Index".getBytes()); + Assert.assertNotNull(delegatedResourceAccountIndexCapsule); + Assert.assertNotNull(delegatedResourceAccountIndexCapsule.getFromAccountsList()); + Assert.assertNotNull(delegatedResourceAccountIndexCapsule.getToAccountsList()); + } +} \ No newline at end of file diff --git a/framework/src/test/java/org/tron/core/db/DelegatedResourceStoreTest.java b/framework/src/test/java/org/tron/core/db/DelegatedResourceStoreTest.java new file mode 100644 index 00000000000..8878ff0dcf3 --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/DelegatedResourceStoreTest.java @@ -0,0 +1,71 @@ +package org.tron.core.db; + +import com.google.protobuf.ByteString; +import javax.annotation.Resource; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; +import org.tron.core.Constant; +import org.tron.core.capsule.DelegatedResourceCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.store.DelegatedResourceStore; + +public class DelegatedResourceStoreTest extends BaseTest { + private static final long BALANCE = 1_000_000; + private static final long EXPIRE_TIME = 1000L; + private static final String OWNER_ADDRESS = "111111111111"; + private static final String RECEIVER_ADDRESS = "222222222222"; + private static DelegatedResourceCapsule delegatedResourceCapsule; + + @Resource + private DelegatedResourceStore delegatedResourceStore; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath(), + }, + Constant.TEST_CONF + ); + } + + @Before + public void init() { + delegatedResourceCapsule = create(OWNER_ADDRESS); + delegatedResourceStore.put(delegatedResourceCapsule.createDbKey(), + delegatedResourceCapsule); + } + + @Test + public void testGet() { + DelegatedResourceCapsule delegatedResource = delegatedResourceStore + .get(delegatedResourceCapsule.createDbKey()); + Assert.assertNotNull(delegatedResource); + Assert.assertEquals(delegatedResourceCapsule.getFrom(), delegatedResource.getFrom()); + } + + @Test + public void testPut() { + DelegatedResourceCapsule delegatedResourceCapsule = create("333333333333"); + byte[] key = delegatedResourceCapsule.createDbKey(); + delegatedResourceStore.put(key, delegatedResourceCapsule); + + DelegatedResourceCapsule delegatedResourceCapsule1 = delegatedResourceStore.get(key); + Assert.assertNotNull(delegatedResourceCapsule1); + Assert.assertEquals(BALANCE, delegatedResourceCapsule1.getFrozenBalanceForEnergy()); + } + + public DelegatedResourceCapsule create(String address) { + byte[] ownerAddress = ByteArray.fromHexString(address); + byte[] receiverAddress = ByteArray.fromHexString(RECEIVER_ADDRESS); + DelegatedResourceCapsule delegatedResourceCapsule = new DelegatedResourceCapsule( + ByteString.copyFrom(ownerAddress), + ByteString.copyFrom(receiverAddress)); + + delegatedResourceCapsule.setFrozenBalanceForEnergy(BALANCE, EXPIRE_TIME); + return delegatedResourceCapsule; + } + +} diff --git a/framework/src/test/java/org/tron/core/db/DelegationStoreTest.java b/framework/src/test/java/org/tron/core/db/DelegationStoreTest.java new file mode 100644 index 00000000000..d63015ae064 --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/DelegationStoreTest.java @@ -0,0 +1,71 @@ +package org.tron.core.db; + +import javax.annotation.Resource; +import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; +import org.tron.core.Constant; +import org.tron.core.capsule.BytesCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.store.DelegationStore; + + +public class DelegationStoreTest extends BaseTest { + + private static final String OWNER_ADDRESS = "11111111111"; + private static final long CYCLE = 100; + private static final long VALUE = 10_000_000; + + @Resource + private DelegationStore delegationStore; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath(), + }, + Constant.TEST_CONF + ); + } + + @Before + public void init() { + create(); + } + + public void create() { + byte[] key = buildRewardKey(CYCLE, ByteArray.fromHexString(OWNER_ADDRESS)); + delegationStore.put(key, new BytesCapsule(ByteArray + .fromLong(VALUE))); + } + + private byte[] buildRewardKey(long cycle, byte[] address) { + return (cycle + "-" + Hex.toHexString(address) + "-reward").getBytes(); + } + + @Test + public void testGet() { + byte[] key = buildRewardKey(CYCLE, ByteArray.fromHexString(OWNER_ADDRESS)); + BytesCapsule bytesCapsule = delegationStore.get(key); + Assert.assertNotNull(bytesCapsule); + long actualValue = ByteArray.toLong(bytesCapsule.getData()); + Assert.assertEquals(VALUE, actualValue); + } + + @Test + public void testPut() { + long value = 20_000_000; + byte[] key = buildRewardKey(CYCLE, ByteArray.fromHexString("2222222222222")); + delegationStore.put(key, new BytesCapsule(ByteArray + .fromLong(20_000_000))); + + BytesCapsule bytesCapsule = delegationStore.get(key); + Assert.assertNotNull(bytesCapsule); + long actualValue = ByteArray.toLong(bytesCapsule.getData()); + Assert.assertEquals(value, actualValue); + } + +} diff --git a/framework/src/test/java/org/tron/core/db/EnergyPriceHistoryLoaderTest.java b/framework/src/test/java/org/tron/core/db/EnergyPriceHistoryLoaderTest.java index ca115bed2bd..995d9e01ecb 100644 --- a/framework/src/test/java/org/tron/core/db/EnergyPriceHistoryLoaderTest.java +++ b/framework/src/test/java/org/tron/core/db/EnergyPriceHistoryLoaderTest.java @@ -36,8 +36,7 @@ public class EnergyPriceHistoryLoaderTest extends BaseTest { private static long price5 = 140L; static { - dbPath = "output-EnergyPriceHistoryLoaderTest-test"; - Args.setParam(new String[] {"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[] {"--output-directory", dbPath()}, Constant.TEST_CONF); } public void initDB() { diff --git a/framework/src/test/java/org/tron/core/db/ExchangeStoreTest.java b/framework/src/test/java/org/tron/core/db/ExchangeStoreTest.java new file mode 100644 index 00000000000..f48ac11301d --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/ExchangeStoreTest.java @@ -0,0 +1,62 @@ +package org.tron.core.db; + +import com.google.protobuf.ByteString; +import java.util.List; +import javax.annotation.Resource; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.capsule.ExchangeCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.store.ExchangeStore; +import org.tron.protos.Protocol; + +public class ExchangeStoreTest extends BaseTest { + + @Resource + private ExchangeStore exchangeStore; + private byte[] exchangeKey1; + private byte[] exchangeKey2; + + static { + Args.setParam( + new String[] { + "--output-directory", dbPath() + }, + Constant.TEST_CONF + ); + } + + @Before + public void init() { + Protocol.Exchange.Builder builder = Protocol.Exchange.newBuilder(); + builder.setExchangeId(1L).setCreatorAddress(ByteString.copyFromUtf8("Address1")); + ExchangeCapsule exchangeCapsule = new ExchangeCapsule(builder.build()); + exchangeKey1 = exchangeCapsule.createDbKey(); + chainBaseManager.getExchangeStore().put(exchangeKey1, exchangeCapsule); + builder.setExchangeId(2L).setCreatorAddress(ByteString.copyFromUtf8("Address2")); + exchangeCapsule = new ExchangeCapsule(builder.build()); + exchangeKey2 = exchangeCapsule.createDbKey(); + chainBaseManager.getExchangeStore().put(exchangeKey2, exchangeCapsule); + } + + + @Test + public void testGet() throws Exception { + final ExchangeCapsule result = exchangeStore.get(exchangeKey1); + Assert.assertNotNull(result); + Assert.assertEquals(result.getID(), 1); + } + + @Test + public void testGetAllExchanges() { + List exchangeCapsuleList = exchangeStore.getAllExchanges(); + ExchangeCapsule exchangeCapsule1 = exchangeCapsuleList.get(0); + ExchangeCapsule exchangeCapsule2 = exchangeCapsuleList.get(1); + Assert.assertEquals(exchangeCapsuleList.size(), 2); + Assert.assertEquals(exchangeCapsule1.getCreatorAddress(), ByteString.copyFromUtf8("Address1")); + Assert.assertEquals(exchangeCapsule2.getCreatorAddress(), ByteString.copyFromUtf8("Address2")); + } +} diff --git a/framework/src/test/java/org/tron/core/db/ExchangeV2StoreTest.java b/framework/src/test/java/org/tron/core/db/ExchangeV2StoreTest.java new file mode 100644 index 00000000000..2b1e2ea31ea --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/ExchangeV2StoreTest.java @@ -0,0 +1,44 @@ +package org.tron.core.db; + +import com.google.protobuf.ByteString; +import javax.annotation.Resource; +import org.junit.Assert; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.capsule.ExchangeCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.store.ExchangeV2Store; +import org.tron.protos.Protocol; + +public class ExchangeV2StoreTest extends BaseTest { + + @Resource + private ExchangeV2Store exchangeV2Store; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath() + }, + Constant.TEST_CONF + ); + } + + @Test + public void testGet() throws Exception { + byte[] key = putToExchangeV2(); + final ExchangeCapsule result = exchangeV2Store.get(key); + Assert.assertNotNull(result); + Assert.assertEquals(result.getID(), 1); + } + + private byte[] putToExchangeV2() { + Protocol.Exchange.Builder builder = Protocol.Exchange.newBuilder().setExchangeId(1L) + .setCreatorAddress(ByteString.copyFromUtf8("Address1")); + ExchangeCapsule exchangeCapsule = new ExchangeCapsule(builder.build()); + byte[] exchangeKey1 = exchangeCapsule.createDbKey(); + exchangeV2Store.put(exchangeKey1, exchangeCapsule); + return exchangeKey1; + } +} diff --git a/framework/src/test/java/org/tron/core/db/IncrementalMerkleTreeStoreTest.java b/framework/src/test/java/org/tron/core/db/IncrementalMerkleTreeStoreTest.java new file mode 100644 index 00000000000..643f86d3fe5 --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/IncrementalMerkleTreeStoreTest.java @@ -0,0 +1,51 @@ +package org.tron.core.db; + +import javax.annotation.Resource; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.capsule.IncrementalMerkleTreeCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.store.IncrementalMerkleTreeStore; + +public class IncrementalMerkleTreeStoreTest extends BaseTest { + + private static final byte[] incrementalMerkleTreeData = {10, 0}; + + @Resource + private IncrementalMerkleTreeStore incrementalMerkleTreeStore; + + static { + Args.setParam( + new String[] { + "--output-directory", dbPath() + }, + Constant.TEST_CONF + ); + } + + @Before + public void init() { + incrementalMerkleTreeStore.put("Address1".getBytes(), new IncrementalMerkleTreeCapsule( + incrementalMerkleTreeData)); + } + + @Test + public void testGet() throws Exception { + final IncrementalMerkleTreeCapsule result = + incrementalMerkleTreeStore.get("Address1".getBytes()); + Assert.assertNotNull(result); + Assert.assertEquals(result.getInstance(), new IncrementalMerkleTreeCapsule( + incrementalMerkleTreeData).getInstance()); + } + + @Test + public void testContain() throws Exception { + final boolean result1 = incrementalMerkleTreeStore.contain("Address1".getBytes()); + final boolean result2 = incrementalMerkleTreeStore.contain("Address2".getBytes()); + Assert.assertTrue(result1); + Assert.assertFalse(result2); + } +} diff --git a/framework/src/test/java/org/tron/core/db/KhaosDatabaseTest.java b/framework/src/test/java/org/tron/core/db/KhaosDatabaseTest.java index 87a38927be1..72214c6743e 100644 --- a/framework/src/test/java/org/tron/core/db/KhaosDatabaseTest.java +++ b/framework/src/test/java/org/tron/core/db/KhaosDatabaseTest.java @@ -1,5 +1,6 @@ package org.tron.core.db; +import com.google.common.collect.Lists; import com.google.protobuf.ByteString; import java.lang.ref.Reference; import java.lang.ref.WeakReference; @@ -7,9 +8,7 @@ import javax.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; -import org.junit.BeforeClass; import org.junit.Test; -import org.testng.collections.Lists; import org.tron.common.BaseTest; import org.tron.common.parameter.CommonParameter; import org.tron.common.utils.ByteArray; @@ -32,14 +31,9 @@ public class KhaosDatabaseTest extends BaseTest { private KhaosDatabase khaosDatabase; static { - dbPath = "output-khaosDatabase-test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); } - @BeforeClass - public static void init() { - Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); - } @Test public void testStartBlock() { diff --git a/framework/src/test/java/org/tron/core/db/ManagerTest.java b/framework/src/test/java/org/tron/core/db/ManagerTest.java index 2c51250d757..bd79f7d9776 100755 --- a/framework/src/test/java/org/tron/core/db/ManagerTest.java +++ b/framework/src/test/java/org/tron/core/db/ManagerTest.java @@ -7,8 +7,9 @@ import static org.tron.core.exception.BadBlockException.TypeEnum.CALC_MERKLE_ROOT_FAILED; import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import com.google.protobuf.ByteString; -import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -21,13 +22,13 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; -import org.testng.collections.Sets; +import org.junit.rules.TemporaryFolder; import org.tron.common.application.TronApplicationContext; import org.tron.common.crypto.ECKey; import org.tron.common.runtime.RuntimeImpl; import org.tron.common.utils.ByteArray; -import org.tron.common.utils.FileUtil; import org.tron.common.utils.JsonUtil; import org.tron.common.utils.LocalWitnesses; import org.tron.common.utils.PublicMethod; @@ -100,7 +101,8 @@ public class ManagerTest extends BlockGenerate { private static DposSlot dposSlot; private static TronApplicationContext context; private static BlockCapsule blockCapsule2; - private static String dbPath = "output_manager_test"; + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); private static AtomicInteger port = new AtomicInteger(0); private static String accountAddress = Wallet.getAddressPreFixString() + "548794500882809695a8a687866e76d4271a1abc"; @@ -108,8 +110,9 @@ public class ManagerTest extends BlockGenerate { private LocalWitnesses localWitnesses; @Before - public void init() { - Args.setParam(new String[]{"-d", dbPath, "-w"}, Constant.TEST_CONF); + public void init() throws IOException { + Args.setParam(new String[]{"-d", + temporaryFolder.newFolder().toString(), "-w"}, Constant.TEST_CONF); Args.getInstance().setNodeListenPort(10000 + port.incrementAndGet()); context = new TronApplicationContext(DefaultConfig.class); @@ -157,7 +160,6 @@ public void init() { public void removeDb() { Args.clearParam(); context.destroy(); - FileUtil.deleteDir(new File(dbPath)); } @Test @@ -579,14 +581,24 @@ public void pushSwitchFork() AccountResourceInsufficientException, EventBloomException { String key = "f31db24bfbd1a2ef19beddca0a0fa37632eded9ac666a05d3bd925f01dde1f62"; + String key2 = "c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4"; byte[] privateKey = ByteArray.fromHexString(key); final ECKey ecKey = ECKey.fromPrivate(privateKey); byte[] address = ecKey.getAddress(); - + WitnessCapsule sr1 = new WitnessCapsule( + ByteString.copyFrom(address), "www.tron.net/first"); + sr1.setVoteCount(1000000000L); + byte[] privateKey2 = ByteArray.fromHexString(key2); + final ECKey ecKey2 = ECKey.fromPrivate(privateKey2); + byte[] address2 = ecKey2.getAddress(); + WitnessCapsule sr2 = new WitnessCapsule( + ByteString.copyFrom(address2), "www.tron.net/second"); + sr2.setVoteCount(100000L); + chainManager.getWitnessStore().put(address, sr1); WitnessCapsule witnessCapsule = new WitnessCapsule(ByteString.copyFrom(address)); chainManager.getWitnessScheduleStore().saveActiveWitnesses(new ArrayList<>()); chainManager.addWitness(ByteString.copyFrom(address)); - + List witnessStandby1 = chainManager.getWitnessStore().getWitnessStandby(); Block block = getSignedBlock(witnessCapsule.getAddress(), 1533529947843L, privateKey); dbManager.pushBlock(new BlockCapsule(block)); @@ -623,6 +635,9 @@ public void pushSwitchFork() } catch (Exception e) { Assert.assertTrue(e instanceof Exception); } + chainManager.getWitnessStore().put(address, sr2); + List witnessStandby2 = chainManager.getWitnessStore().getWitnessStandby(); + Assert.assertNotEquals(witnessStandby1, witnessStandby2); } diff --git a/framework/src/test/java/org/tron/core/db/MarketAccountStoreTest.java b/framework/src/test/java/org/tron/core/db/MarketAccountStoreTest.java new file mode 100644 index 00000000000..51bf1c5d7fc --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/MarketAccountStoreTest.java @@ -0,0 +1,37 @@ +package org.tron.core.db; + +import com.google.protobuf.ByteString; +import javax.annotation.Resource; +import org.junit.Assert; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.capsule.MarketAccountOrderCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.store.MarketAccountStore; + +public class MarketAccountStoreTest extends BaseTest { + + @Resource + private MarketAccountStore marketAccountStore; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath() + }, + Constant.TEST_CONF + ); + } + + @Test + public void testGet() throws Exception { + String address = "Address1"; + marketAccountStore.put(address.getBytes(), + new MarketAccountOrderCapsule(ByteString.copyFrom(address.getBytes()))); + final MarketAccountOrderCapsule result = marketAccountStore.get(address.getBytes()); + Assert.assertNotNull(result); + Assert.assertEquals(result.getOwnerAddress(), ByteString.copyFrom(address.getBytes())); + } + +} diff --git a/framework/src/test/java/org/tron/core/db/MarketOrderStoreTest.java b/framework/src/test/java/org/tron/core/db/MarketOrderStoreTest.java new file mode 100644 index 00000000000..33126783e9a --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/MarketOrderStoreTest.java @@ -0,0 +1,47 @@ +package org.tron.core.db; + +import com.google.protobuf.ByteString; +import javax.annotation.Resource; +import org.junit.Assert; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.capsule.MarketOrderCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.store.MarketOrderStore; +import org.tron.protos.Protocol; + +public class MarketOrderStoreTest extends BaseTest { + + @Resource + private MarketOrderStore marketOrderStore; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath() + }, + Constant.TEST_CONF + ); + } + + @Test + public void testGet() throws Exception { + byte[] orderId = "testGet".getBytes(); + marketOrderStore.put(orderId, + new MarketOrderCapsule(Protocol.MarketOrder.newBuilder() + .setOrderId(ByteString.copyFrom(orderId)) + .setSellTokenId(ByteString.copyFrom("addr1".getBytes())) + .setSellTokenQuantity(200L) + .setBuyTokenId(ByteString.copyFrom("addr2".getBytes())) + .setBuyTokenQuantity(100L) + .build())); + final MarketOrderCapsule result = marketOrderStore.get(orderId); + Assert.assertNotNull(result); + Assert.assertEquals(new String(result.getSellTokenId()), "addr1"); + Assert.assertEquals(result.getSellTokenQuantity(), 200L); + Assert.assertEquals(new String(result.getBuyTokenId()), "addr2"); + Assert.assertEquals(result.getBuyTokenQuantity(), 100L); + } + +} diff --git a/framework/src/test/java/org/tron/core/db/MarketPairPriceToOrderStoreTest.java b/framework/src/test/java/org/tron/core/db/MarketPairPriceToOrderStoreTest.java index f90b5712c56..1f453cb9b41 100755 --- a/framework/src/test/java/org/tron/core/db/MarketPairPriceToOrderStoreTest.java +++ b/framework/src/test/java/org/tron/core/db/MarketPairPriceToOrderStoreTest.java @@ -23,8 +23,7 @@ public class MarketPairPriceToOrderStoreTest extends BaseTest { static { - dbPath = "output-MarketPairPriceToOrderStore-test"; - Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); } @After diff --git a/framework/src/test/java/org/tron/core/db/MarketPairToPriceStoreTest.java b/framework/src/test/java/org/tron/core/db/MarketPairToPriceStoreTest.java new file mode 100644 index 00000000000..adf315bb92e --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/MarketPairToPriceStoreTest.java @@ -0,0 +1,83 @@ +package org.tron.core.db; + +import static org.junit.Assert.assertEquals; + +import javax.annotation.Resource; +import org.junit.Assert; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; +import org.tron.core.Constant; +import org.tron.core.capsule.BytesCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.store.MarketPairPriceToOrderStore; +import org.tron.core.store.MarketPairToPriceStore; + +public class MarketPairToPriceStoreTest extends BaseTest { + + @Resource + private MarketPairToPriceStore marketPairToPriceStore; + + @Resource + private MarketPairPriceToOrderStore marketPairPriceToOrderStore; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath() + }, + Constant.TEST_CONF + ); + } + + @Test + public void testGet() throws Exception { + marketPairToPriceStore.put("testGet".getBytes(), new BytesCapsule( + ByteArray.fromString("11.0"))); + final BytesCapsule result = marketPairToPriceStore.get("testGet".getBytes()); + Assert.assertNotNull(result); + Assert.assertEquals(new String(result.getData()), "11.0"); + } + + @Test + public void testGetPriceNum() { + marketPairToPriceStore.put("testGetPriceNum".getBytes(), new BytesCapsule( + ByteArray.fromLong(100))); + final long result = marketPairToPriceStore.getPriceNum("testGetPriceNum".getBytes()); + assertEquals(100L, result); + assertEquals(0L, marketPairToPriceStore.getPriceNum("testGetPriceNum1".getBytes())); + } + + @Test + public void testGetPriceNumByTokenId() { + marketPairToPriceStore.setPriceNum("tokenId1".getBytes(), "tokenId2".getBytes(),99); + final long result = + marketPairToPriceStore.getPriceNum("tokenId1".getBytes(), "tokenId2".getBytes()); + assertEquals(99L, result); + assertEquals(0L, marketPairToPriceStore.getPriceNum("tokenId2".getBytes(), + "tokenId1".getBytes())); + } + + @Test + public void testSetPriceNum() { + marketPairToPriceStore.setPriceNum("testSetPriceNum1".getBytes(), 98L); + long result = marketPairToPriceStore.getPriceNum("testSetPriceNum1".getBytes()); + assertEquals(result, 98); + } + + @Test + public void testSetPriceNumByToken() { + marketPairToPriceStore.setPriceNum("token3".getBytes(), "token4".getBytes(), 97L); + long result = marketPairToPriceStore.getPriceNum("token3".getBytes(), "token4".getBytes()); + assertEquals(result, 97); + } + + @Test + public void testAddNewPriceKey() { + marketPairToPriceStore + .addNewPriceKey("token5".getBytes(), "token6".getBytes(), marketPairPriceToOrderStore); + long result = marketPairToPriceStore.getPriceNum("token5".getBytes(), "token6".getBytes()); + assertEquals(1, result); + } + +} diff --git a/framework/src/test/java/org/tron/core/db/NullifierStoreTest.java b/framework/src/test/java/org/tron/core/db/NullifierStoreTest.java index 5ed2f967a15..6070182a5c1 100644 --- a/framework/src/test/java/org/tron/core/db/NullifierStoreTest.java +++ b/framework/src/test/java/org/tron/core/db/NullifierStoreTest.java @@ -7,7 +7,6 @@ import org.junit.BeforeClass; import org.junit.Test; import org.tron.common.BaseTest; -import org.tron.common.application.Application; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.BytesCapsule; @@ -21,16 +20,13 @@ public class NullifierStoreTest extends BaseTest { private static final byte[] TRX_TWO = randomBytes(32); private static final byte[] TRX_TWO_NEW = randomBytes(32); @Resource - public Application AppT; - @Resource private NullifierStore nullifierStore; private static BytesCapsule nullifier1; private static BytesCapsule nullifier2; private static BytesCapsule nullifier2New; static { - dbPath = "output_NullifierStore_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); } diff --git a/framework/src/test/java/org/tron/core/db/ProposalStoreTest.java b/framework/src/test/java/org/tron/core/db/ProposalStoreTest.java new file mode 100644 index 00000000000..b08402d33a0 --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/ProposalStoreTest.java @@ -0,0 +1,72 @@ +package org.tron.core.db; + +import static org.junit.Assert.assertThrows; + +import com.google.protobuf.ByteString; +import java.util.List; + +import javax.annotation.Resource; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.capsule.ProposalCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.exception.ItemNotFoundException; +import org.tron.core.store.ProposalStore; +import org.tron.protos.Protocol; + +public class ProposalStoreTest extends BaseTest { + + @Resource + private ProposalStore proposalStore; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath() + }, + Constant.TEST_CONF + ); + } + + @Before + public void init() { + Protocol.Proposal.Builder builder = Protocol.Proposal.newBuilder() + .setProposalId(1L).putParameters(1,99).setState(Protocol.Proposal.State.PENDING) + .setProposerAddress(ByteString.copyFromUtf8("Address1")); + proposalStore.put("1".getBytes(), new ProposalCapsule(builder.build())); + builder.setProposalId(2L).setState(Protocol.Proposal.State.APPROVED).setProposerAddress( + ByteString.copyFromUtf8("Address2")); + proposalStore.put("2".getBytes(), new ProposalCapsule(builder.build())); + } + + @Test + public void testGet() throws Exception { + final ProposalCapsule result = proposalStore.get("1".getBytes()); + Assert.assertNotNull(result); + Assert.assertEquals(result.getID(),1); + Assert.assertEquals(result.getProposalAddress(), ByteString.copyFromUtf8("Address1")); + assertThrows(ItemNotFoundException.class, + () -> proposalStore.get("testGet1".getBytes())); + } + + @Test + public void testGetAllProposals() { + final List result = proposalStore.getAllProposals(); + Assert.assertEquals(result.size(), 2); + Assert.assertEquals(result.get(0).getID(), 1); + Assert.assertEquals(result.get(0).getProposalAddress(), ByteString.copyFromUtf8("Address1")); + } + + @Test + public void testGetSpecifiedProposals() { + final List result = + proposalStore.getSpecifiedProposals(Protocol.Proposal.State.PENDING, 1); + Assert.assertEquals(result.size(), 1); + Assert.assertEquals(result.get(0).getID(), 1); + Assert.assertEquals(result.get(0).getProposalAddress(), ByteString.copyFromUtf8("Address1")); + } + +} diff --git a/framework/src/test/java/org/tron/core/db/TransactionExpireTest.java b/framework/src/test/java/org/tron/core/db/TransactionExpireTest.java index f9b1a6c44e0..5243405b7e6 100644 --- a/framework/src/test/java/org/tron/core/db/TransactionExpireTest.java +++ b/framework/src/test/java/org/tron/core/db/TransactionExpireTest.java @@ -1,50 +1,50 @@ package org.tron.core.db; import com.google.protobuf.ByteString; -import java.io.File; -import java.lang.reflect.Array; +import java.io.IOException; import java.util.Arrays; - import lombok.extern.slf4j.Slf4j; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.tron.api.GrpcAPI; import org.tron.api.GrpcAPI.Return.response_code; +import org.tron.api.GrpcAPI.TransactionApprovedList; import org.tron.common.application.TronApplicationContext; import org.tron.common.parameter.CommonParameter; import org.tron.common.utils.ByteArray; -import org.tron.common.utils.FileUtil; import org.tron.common.utils.LocalWitnesses; import org.tron.common.utils.PublicMethod; import org.tron.common.utils.Sha256Hash; -import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.BlockCapsule; import org.tron.core.capsule.TransactionCapsule; -import org.tron.core.capsule.WitnessCapsule; import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; -import org.tron.core.store.WitnessScheduleStore; import org.tron.protos.Protocol; +import org.tron.protos.Protocol.Transaction; import org.tron.protos.Protocol.Transaction.Contract.ContractType; import org.tron.protos.contract.BalanceContract.TransferContract; @Slf4j public class TransactionExpireTest { - private String dbPath = "output_expire_test"; + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); private TronApplicationContext context; private Wallet wallet; private Manager dbManager; private BlockCapsule blockCapsule; @Before - public void init() { - Args.setParam(new String[] {"--output-directory", dbPath}, Constant.TEST_CONF); + public void init() throws IOException { + Args.setParam(new String[] {"--output-directory", + temporaryFolder.newFolder().toString()}, Constant.TEST_CONF); CommonParameter.PARAMETER.setMinEffectiveConnection(0); context = new TronApplicationContext(DefaultConfig.class); @@ -77,11 +77,6 @@ private void initLocalWitness() { public void removeDb() { Args.clearParam(); context.destroy(); - if (FileUtil.deleteDir(new File(dbPath))) { - logger.info("Release resources successful."); - } else { - logger.info("Release resources failure."); - } } @Test @@ -105,4 +100,48 @@ public void testExpireTransaction() { GrpcAPI.Return result = wallet.broadcastTransaction(transactionCapsule.getInstance()); Assert.assertEquals(response_code.TRANSACTION_EXPIRATION_ERROR, result.getCode()); } + + @Test + public void testTransactionApprovedList() { + byte[] address = Args.getLocalWitnesses() + .getWitnessAccountAddress(CommonParameter.getInstance().isECKeyCryptoEngine()); + TransferContract transferContract = TransferContract.newBuilder() + .setAmount(1L) + .setOwnerAddress(ByteString.copyFrom(address)) + .setToAddress(ByteString.copyFrom(ByteArray.fromHexString( + (Wallet.getAddressPreFixString() + "A389132D6639FBDA4FBC8B659264E6B7C90DB086")))) + .build(); + TransactionCapsule transactionCapsule = + new TransactionCapsule(transferContract, ContractType.TransferContract); + transactionCapsule.setReference(blockCapsule.getNum(), blockCapsule.getBlockId().getBytes()); + transactionCapsule.sign(ByteArray.fromHexString(Args.getLocalWitnesses().getPrivateKey())); + + TransactionApprovedList transactionApprovedList = wallet.getTransactionApprovedList( + transactionCapsule.getInstance()); + Assert.assertTrue( + transactionApprovedList.getResult().getMessage().contains("Account does not exist!")); + + ByteString addressByte = ByteString.copyFrom(address); + AccountCapsule accountCapsule = + new AccountCapsule(Protocol.Account.newBuilder().setAddress(addressByte).build()); + accountCapsule.setBalance(1000_000_000L); + dbManager.getChainBaseManager().getAccountStore() + .put(accountCapsule.createDbKey(), accountCapsule); + transactionApprovedList = wallet.getTransactionApprovedList(transactionCapsule.getInstance()); + Assert.assertEquals("", transactionApprovedList.getResult().getMessage()); + + byte[] randomSig = org.tron.keystore.Wallet.generateRandomBytes(64); + Transaction transaction = transactionCapsule.getInstance().toBuilder().clearSignature() + .addSignature(ByteString.copyFrom(randomSig)).build(); + transactionApprovedList = wallet.getTransactionApprovedList(transaction); + Assert.assertEquals(TransactionApprovedList.Result.response_code.SIGNATURE_FORMAT_ERROR, + transactionApprovedList.getResult().getCode()); + + randomSig = org.tron.keystore.Wallet.generateRandomBytes(65); + transaction = transactionCapsule.getInstance().toBuilder().clearSignature() + .addSignature(ByteString.copyFrom(randomSig)).build(); + transactionApprovedList = wallet.getTransactionApprovedList(transaction); + Assert.assertEquals(TransactionApprovedList.Result.response_code.COMPUTE_ADDRESS_ERROR, + transactionApprovedList.getResult().getCode()); + } } diff --git a/framework/src/test/java/org/tron/core/db/TransactionHistoryTest.java b/framework/src/test/java/org/tron/core/db/TransactionHistoryTest.java index 812f19922ca..eef168938b2 100644 --- a/framework/src/test/java/org/tron/core/db/TransactionHistoryTest.java +++ b/framework/src/test/java/org/tron/core/db/TransactionHistoryTest.java @@ -24,10 +24,9 @@ public class TransactionHistoryTest extends BaseTest { private static TransactionInfoCapsule transactionInfoCapsule; static { - dbPath = "output_TransactionHistoryStore_test"; Args.setParam( new String[]{ - "--output-directory", dbPath, + "--output-directory", dbPath(), "--storage-db-directory", dbDirectory, "--storage-index-directory", indexDirectory }, diff --git a/framework/src/test/java/org/tron/core/db/TransactionRetStoreTest.java b/framework/src/test/java/org/tron/core/db/TransactionRetStoreTest.java index 04478f2c261..b8aebe00aac 100644 --- a/framework/src/test/java/org/tron/core/db/TransactionRetStoreTest.java +++ b/framework/src/test/java/org/tron/core/db/TransactionRetStoreTest.java @@ -32,8 +32,8 @@ public class TransactionRetStoreTest extends BaseTest { private static TransactionRetCapsule transactionRetCapsule; static { - dbPath = "output_TransactionRetStore_test"; - Args.setParam(new String[]{"--output-directory", dbPath, "--storage-db-directory", dbDirectory, + Args.setParam(new String[]{"--output-directory", dbPath(), + "--storage-db-directory", dbDirectory, "--storage-index-directory", indexDirectory}, Constant.TEST_CONF); } diff --git a/framework/src/test/java/org/tron/core/db/TransactionStoreTest.java b/framework/src/test/java/org/tron/core/db/TransactionStoreTest.java index f51a8744c74..1edc4aca756 100644 --- a/framework/src/test/java/org/tron/core/db/TransactionStoreTest.java +++ b/framework/src/test/java/org/tron/core/db/TransactionStoreTest.java @@ -50,9 +50,7 @@ public class TransactionStoreTest extends BaseTest { */ @BeforeClass public static void init() { - dbPath = "output_TransactionStore_test"; - Args.setParam(new String[]{"--output-directory", dbPath, "--storage-db-directory", - dbDirectory, "--storage-index-directory", indexDirectory, "-w"}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath(), "-w"}, Constant.TEST_CONF); } /** diff --git a/framework/src/test/java/org/tron/core/db/TransactionTraceTest.java b/framework/src/test/java/org/tron/core/db/TransactionTraceTest.java index 553eb46a725..161fbea9569 100644 --- a/framework/src/test/java/org/tron/core/db/TransactionTraceTest.java +++ b/framework/src/test/java/org/tron/core/db/TransactionTraceTest.java @@ -60,10 +60,9 @@ public class TransactionTraceTest extends BaseTest { private static boolean init; static { - dbPath = "output_TransactionTrace_test"; Args.setParam( new String[]{ - "--output-directory", dbPath, + "--output-directory", dbPath(), "--storage-db-directory", dbDirectory, "--storage-index-directory", indexDirectory, "-w", diff --git a/framework/src/test/java/org/tron/core/db/TreeBlockIndexStoreTest.java b/framework/src/test/java/org/tron/core/db/TreeBlockIndexStoreTest.java new file mode 100644 index 00000000000..19d1329e580 --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/TreeBlockIndexStoreTest.java @@ -0,0 +1,52 @@ +package org.tron.core.db; + +import javax.annotation.Resource; +import org.junit.Assert; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; +import org.tron.core.Constant; +import org.tron.core.capsule.BytesCapsule; +import org.tron.core.config.args.Args; +import org.tron.core.exception.ItemNotFoundException; +import org.tron.core.store.TreeBlockIndexStore; + +public class TreeBlockIndexStoreTest extends BaseTest { + + @Resource + private TreeBlockIndexStore treeBlockIndexStore; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath() + }, + Constant.TEST_CONF + ); + } + + @Test + public void testPut() throws ItemNotFoundException { + treeBlockIndexStore.put(1L, "testPut".getBytes()); + byte[] result = treeBlockIndexStore.get(1L); + Assert.assertEquals(new String(result),"testPut"); + } + + @Test + public void testGetByNum() throws Exception { + treeBlockIndexStore.put(2L, "testGetByNum".getBytes()); + byte[] result = treeBlockIndexStore.get(2L); + Assert.assertEquals(new String(result),"testGetByNum"); + Assert.assertThrows(ItemNotFoundException.class, () -> treeBlockIndexStore.get(0L)); + } + + @Test + public void testGet() throws Exception { + treeBlockIndexStore.put(3L, "testGet".getBytes()); + final BytesCapsule result = treeBlockIndexStore.get(ByteArray.fromLong(3L)); + Assert.assertEquals(new String(result.getData()),"testGet"); + Assert.assertThrows(ItemNotFoundException.class, () -> treeBlockIndexStore + .get(ByteArray.fromLong(0L))); + } + +} diff --git a/framework/src/test/java/org/tron/core/db/TronDatabaseTest.java b/framework/src/test/java/org/tron/core/db/TronDatabaseTest.java new file mode 100644 index 00000000000..f38f55df64d --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/TronDatabaseTest.java @@ -0,0 +1,101 @@ +package org.tron.core.db; + +import com.google.protobuf.InvalidProtocolBufferException; +import java.io.IOException; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.rocksdb.RocksDB; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; +import org.tron.core.exception.BadItemException; +import org.tron.core.exception.ItemNotFoundException; + +public class TronDatabaseTest extends TronDatabase { + + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); + + static { + RocksDB.loadLibrary(); + } + + @BeforeClass + public static void initArgs() throws IOException { + Args.setParam(new String[]{"-d", temporaryFolder.newFolder().toString()}, Constant.TEST_CONF); + } + + @AfterClass + public static void destroy() { + Args.clearParam(); + } + + @Override + public void put(byte[] key, String item) { + + } + + @Override + public void delete(byte[] key) { + + } + + @Override + public String get(byte[] key) { + return "test"; + } + + @Override + public boolean has(byte[] key) { + return false; + } + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void TestInit() { + TronDatabaseTest db = new TronDatabaseTest(); + Assert.assertNull(db.getDbSource()); + Assert.assertNull(db.getDbName()); + } + + @Test + public void TestIterator() { + TronDatabaseTest db = new TronDatabaseTest(); + thrown.expect(UnsupportedOperationException.class); + db.iterator(); + } + + @Test + public void TestIsNotEmpty() { + TronDatabaseTest db = new TronDatabaseTest(); + thrown.expect(UnsupportedOperationException.class); + db.isNotEmpty(); + } + + @Test + public void TestGetUnchecked() { + TronDatabaseTest db = new TronDatabaseTest(); + Assert.assertNull(db.getUnchecked("test".getBytes())); + } + + @Test + public void TestClose() { + TronDatabaseTest db = new TronDatabaseTest(); + db.close(); + } + + @Test + public void TestGetFromRoot() throws + InvalidProtocolBufferException, BadItemException, ItemNotFoundException { + TronDatabaseTest db = new TronDatabaseTest(); + Assert.assertEquals(db.getFromRoot("test".getBytes()), + "test"); + } +} diff --git a/framework/src/test/java/org/tron/core/db/TxCacheDBInitTest.java b/framework/src/test/java/org/tron/core/db/TxCacheDBInitTest.java new file mode 100644 index 00000000000..b976cf5f2da --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/TxCacheDBInitTest.java @@ -0,0 +1,103 @@ +package org.tron.core.db; + +import java.io.IOException; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.tron.common.application.TronApplicationContext; +import org.tron.common.utils.ByteArray; +import org.tron.core.Constant; +import org.tron.core.capsule.BytesCapsule; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.store.DynamicPropertiesStore; +import org.tron.keystore.Wallet; + +@Slf4j +public class TxCacheDBInitTest { + + private static TronApplicationContext context; + + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); + + private final byte[][] hash = new byte[140000][64]; + + @AfterClass + public static void destroy() { + context.destroy(); + Args.clearParam(); + } + + /** + * Init data. + */ + @BeforeClass + public static void init() throws IOException { + Args.setParam(new String[]{"--output-directory", temporaryFolder.newFolder().toString(), + "--p2p-disable", "true"}, Constant.TEST_CONF); + context = new TronApplicationContext(DefaultConfig.class); + } + + @Test + public void reload() { + TransactionCache db = context.getBean(TransactionCache.class); + db.initCache(); + putTransaction(); + DefaultListableBeanFactory defaultListableBeanFactory = + (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory(); + queryTransaction(); + db.close(); + defaultListableBeanFactory.destroySingleton("transactionCache"); + db = new TransactionCache("transactionCache", + context.getBean(RecentTransactionStore.class), + context.getBean(DynamicPropertiesStore.class)); + db.initCache(); + defaultListableBeanFactory.registerSingleton("transactionCache",db); + queryTransaction(); + db.close(); + defaultListableBeanFactory.destroySingleton("transactionCache"); + db = new TransactionCache("transactionCache", + context.getBean(RecentTransactionStore.class), + context.getBean(DynamicPropertiesStore.class)); + DynamicPropertiesStore dynamicPropertiesStore = context.getBean(DynamicPropertiesStore.class); + dynamicPropertiesStore.saveLatestBlockHeaderNumber(1); + defaultListableBeanFactory.registerSingleton("transactionCache",db); + db.initCache(); + Assert.assertFalse(db.has(hash[65538])); + } + + private void putTransaction() { + TransactionCache db = context.getBean(TransactionCache.class); + for (int i = 1; i < 140000; i++) { + hash[i] = Wallet.generateRandomBytes(64); + db.put(hash[i], new BytesCapsule(ByteArray.fromLong(i))); + } + } + + private void queryTransaction() { + TransactionCache db = context.getBean(TransactionCache.class); + // [1,65537] are expired + for (int i = 1; i < 65538; i++) { + try { + Assert.assertFalse("index = " + i, db.has(hash[i])); + } catch (Exception e) { + Assert.fail("transaction should be expired index = " + i); + } + } + // [65538,140000] are in cache + for (int i = 65538; i < 140000; i++) { + try { + Assert.assertTrue("index = " + i, db.has(hash[i])); + } catch (Exception e) { + Assert.fail("transaction should not be expired index = " + i); + } + } + } + +} \ No newline at end of file diff --git a/framework/src/test/java/org/tron/core/db/TxCacheDBTest.java b/framework/src/test/java/org/tron/core/db/TxCacheDBTest.java index 8b1724248a0..55557cf51b5 100644 --- a/framework/src/test/java/org/tron/core/db/TxCacheDBTest.java +++ b/framework/src/test/java/org/tron/core/db/TxCacheDBTest.java @@ -1,11 +1,9 @@ package org.tron.core.db; -import javax.annotation.Resource; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.tron.common.BaseTest; -import org.tron.common.application.Application; import org.tron.common.utils.ByteArray; import org.tron.core.Constant; import org.tron.core.capsule.BytesCapsule; @@ -13,8 +11,6 @@ import org.tron.keystore.Wallet; public class TxCacheDBTest extends BaseTest { - @Resource - private Application appT; /** * Init data. @@ -23,8 +19,7 @@ public class TxCacheDBTest extends BaseTest { public static void init() { String dbDirectory = "db_TransactionCache_test"; String indexDirectory = "index_TransactionCache_test"; - dbPath = "output_TransactionCache_test"; - Args.setParam(new String[]{"--output-directory", dbPath, "--storage-db-directory", + Args.setParam(new String[]{"--output-directory", dbPath(), "--storage-db-directory", dbDirectory, "--storage-index-directory", indexDirectory, "-w"}, Constant.TEST_CONF); } diff --git a/framework/src/test/java/org/tron/core/db/VotesStoreTest.java b/framework/src/test/java/org/tron/core/db/VotesStoreTest.java index 9e5cd7c0098..48d4d1324db 100755 --- a/framework/src/test/java/org/tron/core/db/VotesStoreTest.java +++ b/framework/src/test/java/org/tron/core/db/VotesStoreTest.java @@ -19,8 +19,7 @@ public class VotesStoreTest extends BaseTest { static { - dbPath = "output-votesStore-test"; - Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); } @Resource diff --git a/framework/src/test/java/org/tron/core/db/WitnessScheduleStoreTest.java b/framework/src/test/java/org/tron/core/db/WitnessScheduleStoreTest.java new file mode 100644 index 00000000000..7588b1c7add --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/WitnessScheduleStoreTest.java @@ -0,0 +1,105 @@ +package org.tron.core.db; + +import com.google.protobuf.ByteString; +import java.util.Arrays; +import java.util.List; +import javax.annotation.Resource; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; +import org.tron.core.store.WitnessScheduleStore; + +public class WitnessScheduleStoreTest extends BaseTest { + + @Resource + private WitnessScheduleStore witnessScheduleStore; + private static final String KEY1 = "41f08012b4881c320eb40b80f1228731898824e09d"; + private static final String KEY2 = "41df309fef25b311e7895562bd9e11aab2a58816d2"; + private static final String KEY3 = "41F8C7ACC4C08CF36CA08FC2A61B1F5A7C8DEA7BEC"; + + private static final String CURRENT_KEY1 = "411D7ABA13EA199A63D1647E58E39C16A9BB9DA689"; + private static final String CURRENT_KEY2 = "410694981B116304ED21E05896FB16A6BC2E91C92C"; + private static final String CURRENT_KEY3 = "411155D10415FAC16A8F4CB2F382CE0E0F0A7E64CC"; + + private static List witnessAddresses; + private static List currentShuffledWitnesses; + + + static { + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); + } + + @Before + public void init() { + witnessAddresses = Arrays.asList( + getByteString(KEY1), + getByteString(KEY2), + getByteString(KEY3) + ); + + currentShuffledWitnesses = Arrays.asList( + getByteString(CURRENT_KEY1), + getByteString(CURRENT_KEY2), + getByteString(CURRENT_KEY3) + ); + } + + private ByteString getByteString(String address) { + return ByteString.copyFrom( + ByteArray.fromHexString(address)); + } + + @Test + public void tetSaveActiveWitnesses() { + witnessScheduleStore.saveActiveWitnesses(witnessAddresses); + List activeWitnesses = witnessScheduleStore.getActiveWitnesses(); + Assert.assertNotNull(activeWitnesses); + Assert.assertEquals(3, activeWitnesses.size()); + ByteString firstWitness = activeWitnesses.get(0); + Assert.assertEquals(getByteString(KEY1), firstWitness); + } + + @Test + public void testGetActiveWitnesses() { + witnessScheduleStore.saveActiveWitnesses(witnessAddresses); + List activeWitnesses = witnessScheduleStore.getActiveWitnesses(); + Assert.assertNotNull(activeWitnesses); + Assert.assertEquals(3, activeWitnesses.size()); + ByteString firstWitness = activeWitnesses.get(0); + ByteString secondWitness = activeWitnesses.get(1); + ByteString thirdWitness = activeWitnesses.get(2); + Assert.assertEquals(getByteString(KEY1), firstWitness); + Assert.assertEquals(getByteString(KEY2), secondWitness); + Assert.assertEquals(getByteString(KEY3), thirdWitness); + } + + @Test + public void testSaveCurrentShuffledWitnesses() { + witnessScheduleStore.saveCurrentShuffledWitnesses(currentShuffledWitnesses); + List currentWitnesses = witnessScheduleStore.getCurrentShuffledWitnesses(); + Assert.assertNotNull(currentWitnesses); + Assert.assertEquals(3, currentWitnesses.size()); + ByteString firstWitness = currentWitnesses.get(0); + Assert.assertEquals(getByteString(CURRENT_KEY1), firstWitness); + } + + @Test + public void GetCurrentShuffledWitnesses() { + witnessScheduleStore.saveCurrentShuffledWitnesses(currentShuffledWitnesses); + List currentWitnesses = witnessScheduleStore.getCurrentShuffledWitnesses(); + Assert.assertNotNull(currentWitnesses); + Assert.assertEquals(3, currentWitnesses.size()); + ByteString firstWitness = currentWitnesses.get(0); + ByteString secondWitness = currentWitnesses.get(1); + ByteString thirdWitness = currentWitnesses.get(2); + Assert.assertEquals(getByteString(CURRENT_KEY1), firstWitness); + Assert.assertEquals(getByteString(CURRENT_KEY2), secondWitness); + Assert.assertEquals(getByteString(CURRENT_KEY3), thirdWitness); + } + +} diff --git a/framework/src/test/java/org/tron/core/db/WitnessStoreTest.java b/framework/src/test/java/org/tron/core/db/WitnessStoreTest.java index fd91e7da72a..3190e226689 100755 --- a/framework/src/test/java/org/tron/core/db/WitnessStoreTest.java +++ b/framework/src/test/java/org/tron/core/db/WitnessStoreTest.java @@ -15,8 +15,7 @@ public class WitnessStoreTest extends BaseTest { static { - dbPath = "output-witnessStore-test"; - Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); } @Resource diff --git a/framework/src/test/java/org/tron/core/db/api/AssetUpdateHelperTest.java b/framework/src/test/java/org/tron/core/db/api/AssetUpdateHelperTest.java index 714198bde51..ed18b1be97d 100644 --- a/framework/src/test/java/org/tron/core/db/api/AssetUpdateHelperTest.java +++ b/framework/src/test/java/org/tron/core/db/api/AssetUpdateHelperTest.java @@ -27,8 +27,7 @@ public class AssetUpdateHelperTest extends BaseTest { private static boolean init; static { - dbPath = "output_AssetUpdateHelperTest_test"; - Args.setParam(new String[]{"-d", dbPath, "-w"}, "config-test-index.conf"); + Args.setParam(new String[]{"-d", dbPath(), "-w"}, "config-test-index.conf"); Args.getInstance().setSolidityNode(true); } diff --git a/framework/src/test/java/org/tron/core/db/backup/BackupDbUtilTest.java b/framework/src/test/java/org/tron/core/db/backup/BackupDbUtilTest.java index 4ddbd88d338..0153faeab71 100644 --- a/framework/src/test/java/org/tron/core/db/backup/BackupDbUtilTest.java +++ b/framework/src/test/java/org/tron/core/db/backup/BackupDbUtilTest.java @@ -34,8 +34,10 @@ public class BackupDbUtilTest extends BaseTest { String bak2Path; int frequency; + private static final String dbPath; + static { - dbPath = "output-BackupDbUtilTest"; + dbPath = dbPath(); Args.setParam( new String[]{ "--output-directory", dbPath, diff --git a/framework/src/test/java/org/tron/core/db2/ChainbaseTest.java b/framework/src/test/java/org/tron/core/db2/ChainbaseTest.java index 86e3bfefe6b..ee9813be633 100644 --- a/framework/src/test/java/org/tron/core/db2/ChainbaseTest.java +++ b/framework/src/test/java/org/tron/core/db2/ChainbaseTest.java @@ -1,18 +1,19 @@ package org.tron.core.db2; -import java.io.File; +import java.io.IOException; import java.util.HashMap; import java.util.Map; import lombok.extern.slf4j.Slf4j; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.rocksdb.RocksDB; import org.tron.common.storage.leveldb.LevelDbDataSourceImpl; import org.tron.common.storage.rocksdb.RocksDbDataSourceImpl; import org.tron.common.utils.ByteArray; -import org.tron.common.utils.FileUtil; import org.tron.core.Constant; import org.tron.core.config.args.Args; import org.tron.core.db.common.DbSourceInter; @@ -24,7 +25,8 @@ @Slf4j public class ChainbaseTest { - private static final String dbPath = "output-chainbase-test"; + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); private Chainbase chainbase = null; private final byte[] value0 = "00000".getBytes(); @@ -61,17 +63,13 @@ public class ChainbaseTest { @AfterClass public static void destroy() { Args.clearParam(); - if (FileUtil.deleteDir(new File(dbPath))) { - logger.info("Release resources successful."); - } else { - logger.info("Release resources failure."); - } } @Before - public void initDb() { + public void initDb() throws IOException { RocksDB.loadLibrary(); - Args.setParam(new String[] {"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[] {"--output-directory", + temporaryFolder.newFolder().toString()}, Constant.TEST_CONF); } @Test diff --git a/framework/src/test/java/org/tron/core/db2/SnapshotImplTest.java b/framework/src/test/java/org/tron/core/db2/SnapshotImplTest.java new file mode 100644 index 00000000000..aab6f656b1f --- /dev/null +++ b/framework/src/test/java/org/tron/core/db2/SnapshotImplTest.java @@ -0,0 +1,201 @@ +package org.tron.core.db2; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.io.File; +import java.lang.reflect.Constructor; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.tron.common.application.Application; +import org.tron.common.application.ApplicationFactory; +import org.tron.common.application.TronApplicationContext; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.db2.core.Snapshot; +import org.tron.core.db2.core.SnapshotImpl; +import org.tron.core.db2.core.SnapshotManager; +import org.tron.core.db2.core.SnapshotRoot; + +public class SnapshotImplTest { + private RevokingDbWithCacheNewValueTest.TestRevokingTronStore tronDatabase; + private TronApplicationContext context; + private Application appT; + private SnapshotManager revokingDatabase; + + @Before + public void init() { + Args.setParam(new String[]{"-d", "output_revokingStore_test"}, Constant.TEST_CONF); + context = new TronApplicationContext(DefaultConfig.class); + appT = ApplicationFactory.create(context); + + tronDatabase = new RevokingDbWithCacheNewValueTest.TestRevokingTronStore( + "testSnapshotRoot-testMerge"); + revokingDatabase = context.getBean(SnapshotManager.class); + revokingDatabase.enable(); + revokingDatabase.add(tronDatabase.getRevokingDB()); + } + + @After + public void removeDb() { + Args.clearParam(); + context.destroy(); + FileUtil.deleteDir(new File("output_revokingStore_test")); + + tronDatabase.close(); + revokingDatabase.shutdown(); + } + + /** + * linklist is: from -> root + * root:key1=>value1, key2=>value2 + * from:key3=>value3, key4=>value4 + * after construct, getSnapshotImplIns(root); + * from: key1=>value1, key2=>value2, key3=>value3, key4=>value4 + * from: get key1 or key2, traverse 0 times + */ + @Test + public void testMergeRoot() { + // linklist is: from -> root + SnapshotRoot root = new SnapshotRoot(tronDatabase.getDb()); + //root.setOptimized(true); + + root.put("key1".getBytes(), "value1".getBytes()); + root.put("key2".getBytes(), "value2".getBytes()); + SnapshotImpl from = getSnapshotImplIns(root); + from.put("key3".getBytes(), "value3".getBytes()); + from.put("key4".getBytes(), "value4".getBytes()); + + byte[] s1 = from.get("key1".getBytes()); + assertEquals(new String("value1".getBytes()), new String(s1)); + byte[] s2 = from.get("key2".getBytes()); + assertEquals(new String("value2".getBytes()), new String(s2)); + } + + /** + * linklist is: from2 -> from -> root + * root: + * from:key1=>value1, key2=>value2 + * from2:key3=>value3,key4=>value4 + * before merge: from2.mergeAhead(from); + * from2: get key1 or key2, traverse 1 times + * after merge + * from2:key1=>value1, key2=>value2, value3=>value3,key4=>value4 + * from2: get key1 or key2, traverse 0 times + * + */ + @Test + public void testMergeAhead() { + + // linklist is: from2 -> from -> root + SnapshotRoot root = new SnapshotRoot(tronDatabase.getDb()); + SnapshotImpl from = getSnapshotImplIns(root); + from.put("key1".getBytes(), "value1".getBytes()); + from.put("key2".getBytes(), "value2".getBytes()); + + SnapshotImpl from2 = getSnapshotImplIns(from); + from2.put("key3".getBytes(), "value3".getBytes()); + from2.put("key4".getBytes(), "value4".getBytes()); + + /* + // before merge get data in from is success,traverse 0 times + byte[] s1 = from.get("key1".getBytes()); + assertEquals(new String("value1".getBytes()), new String(s1)); + byte[] s2 = from.get("key2".getBytes()); + assertEquals(new String("value2".getBytes()), new String(s2)); + // before merge get data in from2 is success, traverse 0 times + byte[] s3 = from2.get("key3".getBytes()); + assertEquals(new String("value3".getBytes()), new String(s3)); + byte[] s4 = from2.get("key4".getBytes()); + assertEquals(new String("value4".getBytes()), new String(s4)); + */ + + // before merge from2 get data is success, traverse 1 times + byte[] s11 = from2.get("key1".getBytes()); + assertEquals(new String("value1".getBytes()), new String(s11)); + byte[] s12 = from2.get("key2".getBytes()); + assertEquals(new String("value2".getBytes()), new String(s12)); + // this can not get key3 and key4 + assertNull(from.get("key3".getBytes())); + assertNull(from.get("key4".getBytes())); + + // do mergeAhead + from2.mergeAhead(from); + /* + // after merge get data in from is success, traverse 0 times + s1 = from.get("key1".getBytes()); + assertEquals(new String("value1".getBytes()), new String(s1)); + s2 = from.get("key2".getBytes()); + assertEquals(new String("value2".getBytes()), new String(s2)); + + // after merge get data in from2 is success, traverse 0 times + s3 = from2.get("key3".getBytes()); + assertEquals(new String("value3".getBytes()), new String(s3)); + s4 = from2.get("key4".getBytes()); + assertEquals(new String("value4".getBytes()), new String(s4)); + */ + + // after merge from2 get data is success, traverse 0 times + byte[] s1 = from2.get("key1".getBytes()); + assertEquals(new String("value1".getBytes()), new String(s1)); + byte[] s2 = from2.get("key2".getBytes()); + assertEquals(new String("value2".getBytes()), new String(s2)); + + // this can not get key3 and key4 + assertNull(from.get("key3".getBytes())); + assertNull(from.get("key4".getBytes())); + } + + /** + * from: key1=>value1, key2=>value2, key3=>value31 + * from2: key3=>value32,key4=>value4 + * after merge: from2.mergeAhead(from); + * from2: key1=>value1, key2=>value2, key3=>value32, key4=>value4 + */ + @Test + public void testMergeOverride() { + // linklist is: from2 -> from -> root + SnapshotRoot root = new SnapshotRoot(tronDatabase.getDb()); + SnapshotImpl from = getSnapshotImplIns(root); + from.put("key1".getBytes(), "value1".getBytes()); + from.put("key2".getBytes(), "value2".getBytes()); + from.put("key3".getBytes(), "value31".getBytes()); + + SnapshotImpl from2 = getSnapshotImplIns(from); + from2.put("key3".getBytes(), "value32".getBytes()); + from2.put("key4".getBytes(), "value4".getBytes()); + // do mergeAhead + from2.mergeAhead(from); + + // after merge from2 get data is success, traverse 0 times + byte[] s1 = from2.get("key1".getBytes()); + assertEquals(new String("value1".getBytes()), new String(s1)); + byte[] s2 = from2.get("key2".getBytes()); + assertEquals(new String("value2".getBytes()), new String(s2)); + byte[] s3 = from2.get("key3".getBytes()); + assertEquals(new String("value32".getBytes()), new String(s3)); + byte[] s4 = from2.get("key4".getBytes()); + assertEquals(new String("value4".getBytes()), new String(s4)); + } + + /** + * The constructor of SnapshotImpl is not public + * so reflection is used to construct the object here. + */ + private SnapshotImpl getSnapshotImplIns(Snapshot snapshot) { + Class clazz = SnapshotImpl.class; + try { + Constructor constructor = clazz.getDeclaredConstructor(Snapshot.class); + constructor.setAccessible(true); + return (SnapshotImpl) constructor.newInstance(snapshot); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/framework/src/test/java/org/tron/core/db2/SnapshotRootTest.java b/framework/src/test/java/org/tron/core/db2/SnapshotRootTest.java index a483be278ff..70b4d9eff30 100644 --- a/framework/src/test/java/org/tron/core/db2/SnapshotRootTest.java +++ b/framework/src/test/java/org/tron/core/db2/SnapshotRootTest.java @@ -1,5 +1,6 @@ package org.tron.core.db2; +import com.google.common.collect.Sets; import java.io.File; import java.util.ArrayList; import java.util.Arrays; @@ -14,7 +15,6 @@ import org.junit.Before; import org.junit.Test; import org.springframework.util.CollectionUtils; -import org.testng.collections.Sets; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.application.TronApplicationContext; diff --git a/framework/src/test/java/org/tron/core/jsonrpc/BloomTest.java b/framework/src/test/java/org/tron/core/jsonrpc/BloomTest.java index 2964e24232f..19e232b0f93 100644 --- a/framework/src/test/java/org/tron/core/jsonrpc/BloomTest.java +++ b/framework/src/test/java/org/tron/core/jsonrpc/BloomTest.java @@ -6,8 +6,8 @@ import java.util.ArrayList; import java.util.List; import org.bouncycastle.util.encoders.Hex; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.common.bloom.Bloom; import org.tron.common.crypto.Hash; import org.tron.common.runtime.vm.DataWord; diff --git a/framework/src/test/java/org/tron/core/jsonrpc/BuildTransactionTest.java b/framework/src/test/java/org/tron/core/jsonrpc/BuildTransactionTest.java index 55d7c106458..578d5869e31 100644 --- a/framework/src/test/java/org/tron/core/jsonrpc/BuildTransactionTest.java +++ b/framework/src/test/java/org/tron/core/jsonrpc/BuildTransactionTest.java @@ -32,8 +32,7 @@ public class BuildTransactionTest extends BaseTest { private Wallet wallet; static { - dbPath = "output_build_transaction_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; diff --git a/framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java b/framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java index f3ad69d09a1..b3ed26b591f 100644 --- a/framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java +++ b/framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java @@ -29,6 +29,8 @@ import org.tron.core.capsule.TransactionCapsule; import org.tron.core.config.args.Args; import org.tron.core.services.NodeInfoService; +import org.tron.core.services.interfaceJsonRpcOnPBFT.JsonRpcServiceOnPBFT; +import org.tron.core.services.interfaceJsonRpcOnSolidity.JsonRpcServiceOnSolidity; import org.tron.core.services.jsonrpc.FullNodeJsonRpcHttpService; import org.tron.core.services.jsonrpc.TronJsonRpcImpl; import org.tron.core.services.jsonrpc.types.BlockResult; @@ -55,10 +57,17 @@ public class JsonrpcServiceTest extends BaseTest { @Resource private FullNodeJsonRpcHttpService fullNodeJsonRpcHttpService; + @Resource + private JsonRpcServiceOnPBFT jsonRpcServiceOnPBFT; + + @Resource + private JsonRpcServiceOnSolidity jsonRpcServiceOnSolidity; + static { - dbPath = "output_jsonrpc_service_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); CommonParameter.getInstance().setJsonRpcHttpFullNodeEnable(true); + CommonParameter.getInstance().setJsonRpcHttpPBFTNodeEnable(true); + CommonParameter.getInstance().setJsonRpcHttpSolidityNodeEnable(true); CommonParameter.getInstance().setMetricsPrometheusEnable(true); Metrics.init(); @@ -256,6 +265,7 @@ public void testGetTransactionByHash() { @Test public void testGetBlockByNumber2() { + fullNodeJsonRpcHttpService.init(Args.getInstance()); fullNodeJsonRpcHttpService.start(); JsonArray params = new JsonArray(); params.add(ByteArray.toJsonHex(blockCapsule.getNum())); @@ -290,4 +300,17 @@ public void testGetBlockByNumber2() { } } + @Test + public void testServicesInit() { + try { + jsonRpcServiceOnPBFT.init(Args.getInstance()); + jsonRpcServiceOnPBFT.start(); + jsonRpcServiceOnSolidity.init(Args.getInstance()); + jsonRpcServiceOnSolidity.start(); + } finally { + jsonRpcServiceOnPBFT.stop(); + jsonRpcServiceOnSolidity.stop(); + } + } + } diff --git a/framework/src/test/java/org/tron/core/jsonrpc/SectionBloomStoreTest.java b/framework/src/test/java/org/tron/core/jsonrpc/SectionBloomStoreTest.java index fd2b7a66d31..6e350a38999 100644 --- a/framework/src/test/java/org/tron/core/jsonrpc/SectionBloomStoreTest.java +++ b/framework/src/test/java/org/tron/core/jsonrpc/SectionBloomStoreTest.java @@ -6,8 +6,8 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.annotation.Resource; +import org.junit.Assert; import org.junit.Test; -import org.testng.Assert; import org.tron.common.BaseTest; import org.tron.common.runtime.vm.DataWord; import org.tron.common.runtime.vm.LogInfo; @@ -29,8 +29,7 @@ public class SectionBloomStoreTest extends BaseTest { SectionBloomStore sectionBloomStore; static { - dbPath = "output-sectionBloomStore-test"; - Args.setParam(new String[] {"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[] {"--output-directory", dbPath()}, Constant.TEST_CONF); } @Test diff --git a/framework/src/test/java/org/tron/core/jsonrpc/WalletCursorTest.java b/framework/src/test/java/org/tron/core/jsonrpc/WalletCursorTest.java index 05d27832e1d..d460440184c 100644 --- a/framework/src/test/java/org/tron/core/jsonrpc/WalletCursorTest.java +++ b/framework/src/test/java/org/tron/core/jsonrpc/WalletCursorTest.java @@ -30,8 +30,7 @@ public class WalletCursorTest extends BaseTest { private static boolean init; static { - dbPath = "output_wallet_cursor_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", dbPath()}, Constant.TEST_CONF); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; diff --git a/framework/src/test/java/org/tron/core/metrics/MetricsApiServiceTest.java b/framework/src/test/java/org/tron/core/metrics/MetricsApiServiceTest.java index 714faea05d9..51a46b09388 100644 --- a/framework/src/test/java/org/tron/core/metrics/MetricsApiServiceTest.java +++ b/framework/src/test/java/org/tron/core/metrics/MetricsApiServiceTest.java @@ -1,16 +1,17 @@ package org.tron.core.metrics; -import java.io.File; +import java.io.IOException; import lombok.extern.slf4j.Slf4j; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.application.TronApplicationContext; import org.tron.common.parameter.CommonParameter; -import org.tron.common.utils.FileUtil; import org.tron.core.Constant; import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; @@ -21,7 +22,8 @@ @Slf4j public class MetricsApiServiceTest { - private static String dbPath = "output-metrics"; + @ClassRule + public static TemporaryFolder temporaryFolder = new TemporaryFolder(); private static String dbDirectory = "metrics-database"; private static String indexDirectory = "metrics-index"; private static int port = 10001; @@ -32,7 +34,8 @@ public class MetricsApiServiceTest { @Before - public void init() { + public void init() throws IOException { + String dbPath = temporaryFolder.newFolder().toString(); Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); Args.setParam( @@ -52,8 +55,6 @@ public void init() { rpcApiService = context.getBean(RpcApiService.class); metricsApiService = context.getBean(MetricsApiService.class); appT.addService(rpcApiService); - appT.initServices(parameter); - appT.startServices(); appT.startup(); } @@ -105,6 +106,5 @@ public void testProcessMessage() { @After public void destroy() { context.destroy(); - FileUtil.deleteDir(new File(dbPath)); } } diff --git a/framework/src/test/java/org/tron/core/metrics/prometheus/PrometheusApiServiceTest.java b/framework/src/test/java/org/tron/core/metrics/prometheus/PrometheusApiServiceTest.java index a2a812ef30b..1c6e56cbbbe 100644 --- a/framework/src/test/java/org/tron/core/metrics/prometheus/PrometheusApiServiceTest.java +++ b/framework/src/test/java/org/tron/core/metrics/prometheus/PrometheusApiServiceTest.java @@ -55,8 +55,7 @@ public class PrometheusApiServiceTest extends BaseTest { private ChainBaseManager chainManager; static { - dbPath = "output-prometheus-metric"; - Args.setParam(new String[] {"-d", dbPath, "-w"}, Constant.TEST_CONF); + Args.setParam(new String[] {"-d", dbPath(), "-w"}, Constant.TEST_CONF); Args.getInstance().setNodeListenPort(10000 + port.incrementAndGet()); initParameter(Args.getInstance()); Metrics.init(); diff --git a/framework/src/test/java/org/tron/core/net/BaseNet.java b/framework/src/test/java/org/tron/core/net/BaseNet.java index 805f8aa76a4..7ae8b355168 100644 --- a/framework/src/test/java/org/tron/core/net/BaseNet.java +++ b/framework/src/test/java/org/tron/core/net/BaseNet.java @@ -14,13 +14,17 @@ import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.handler.timeout.WriteTimeoutHandler; import java.io.File; +import java.io.IOException; import java.util.Collection; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.rules.TemporaryFolder; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.application.TronApplicationContext; @@ -36,7 +40,8 @@ @Slf4j public class BaseNet { - private static String dbPath = "output-net"; + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); private static String dbDirectory = "net-database"; private static String indexDirectory = "net-index"; private static int port = 10000; @@ -77,14 +82,18 @@ protected void initChannel(Channel ch) throws Exception { public static void init() throws Exception { executorService.execute(() -> { logger.info("Full node running."); - Args.setParam( - new String[]{ - "--output-directory", dbPath, - "--storage-db-directory", dbDirectory, - "--storage-index-directory", indexDirectory - }, - "config.conf" - ); + try { + Args.setParam( + new String[]{ + "--output-directory", temporaryFolder.newFolder().toString(), + "--storage-db-directory", dbDirectory, + "--storage-index-directory", indexDirectory + }, + "config.conf" + ); + } catch (IOException e) { + Assert.fail("create temp db directory failed"); + } CommonParameter parameter = Args.getInstance(); parameter.setNodeListenPort(port); parameter.getSeedNode().getAddressList().clear(); @@ -93,8 +102,6 @@ public static void init() throws Exception { appT = ApplicationFactory.create(context); rpcApiService = context.getBean(RpcApiService.class); appT.addService(rpcApiService); - appT.initServices(parameter); - appT.startServices(); appT.startup(); try { Thread.sleep(2000); @@ -102,7 +109,7 @@ public static void init() throws Exception { //ignore } tronNetDelegate = context.getBean(TronNetDelegate.class); - rpcApiService.blockUntilShutdown(); + appT.blockUntilShutdown(); }); int tryTimes = 0; do { @@ -119,6 +126,5 @@ public static void destroy() { } Args.clearParam(); context.destroy(); - FileUtil.deleteDir(new File(dbPath)); } } diff --git a/framework/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java b/framework/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java index 57c27bc2382..8154d01aded 100644 --- a/framework/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java +++ b/framework/src/test/java/org/tron/core/net/messagehandler/BlockMsgHandlerTest.java @@ -41,8 +41,7 @@ public class BlockMsgHandlerTest extends BaseTest { */ @BeforeClass public static void init() { - dbPath = "output_blockmsghandler_test"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); } diff --git a/framework/src/test/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandlerTest.java b/framework/src/test/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandlerTest.java index e885741c29c..404d275276a 100644 --- a/framework/src/test/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandlerTest.java +++ b/framework/src/test/java/org/tron/core/net/messagehandler/FetchInvDataMsgHandlerTest.java @@ -1,5 +1,65 @@ package org.tron.core.net.messagehandler; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import java.lang.reflect.Field; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.TimeUnit; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; +import org.tron.common.utils.ReflectUtils; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.config.Parameter; +import org.tron.core.net.TronNetDelegate; +import org.tron.core.net.message.adv.BlockMessage; +import org.tron.core.net.message.adv.FetchInvDataMessage; +import org.tron.core.net.peer.Item; +import org.tron.core.net.peer.PeerConnection; +import org.tron.core.net.service.adv.AdvService; +import org.tron.protos.Protocol; + + + public class FetchInvDataMsgHandlerTest { + @Test + public void testProcessMessage() throws Exception { + FetchInvDataMsgHandler fetchInvDataMsgHandler = new FetchInvDataMsgHandler(); + PeerConnection peer = Mockito.mock(PeerConnection.class); + TronNetDelegate tronNetDelegate = Mockito.mock(TronNetDelegate.class); + AdvService advService = Mockito.mock(AdvService.class); + + Field field = FetchInvDataMsgHandler.class.getDeclaredField("tronNetDelegate"); + field.setAccessible(true); + field.set(fetchInvDataMsgHandler, tronNetDelegate); + + Mockito.when(tronNetDelegate.allowPBFT()).thenReturn(false); + + BlockCapsule.BlockId blockId = new BlockCapsule.BlockId(); + List blockIds = new LinkedList<>(); + blockIds.add(blockId); + + Cache advInvSpread = CacheBuilder.newBuilder().maximumSize(20000) + .expireAfterWrite(1, TimeUnit.HOURS).recordStats().build(); + Mockito.when(peer.getAdvInvSpread()).thenReturn(advInvSpread); + Mockito.when(peer.isNeedSyncFromUs()).thenReturn(true); + Mockito.when(peer.isSyncFinish()).thenReturn(false); + Mockito.when(peer.getBlockBothHave()).thenReturn(blockId); + Cache syncBlockIdCache = CacheBuilder.newBuilder() + .maximumSize(2 * Parameter.NetConstants.SYNC_FETCH_BATCH_NUM).recordStats().build(); + Mockito.when(peer.getSyncBlockIdCache()).thenReturn(syncBlockIdCache); + Mockito.when(peer.getLastSyncBlockId()).thenReturn(blockId); + BlockCapsule blockCapsule = new BlockCapsule(1, Sha256Hash.ZERO_HASH, + System.currentTimeMillis(), Sha256Hash.ZERO_HASH.getByteString()); + Mockito.when(advService.getMessage(new Item(blockId, Protocol.Inventory.InventoryType.BLOCK))) + .thenReturn(new BlockMessage(blockCapsule)); + ReflectUtils.setFieldValue(fetchInvDataMsgHandler, "advService", advService); + + fetchInvDataMsgHandler.processMessage(peer, + new FetchInvDataMessage(blockIds, Protocol.Inventory.InventoryType.BLOCK)); + Assert.assertNotNull(syncBlockIdCache.getIfPresent(blockId)); + } } diff --git a/framework/src/test/java/org/tron/core/net/messagehandler/MessageHandlerTest.java b/framework/src/test/java/org/tron/core/net/messagehandler/MessageHandlerTest.java index 215b5f495ad..7ff29b54bb7 100644 --- a/framework/src/test/java/org/tron/core/net/messagehandler/MessageHandlerTest.java +++ b/framework/src/test/java/org/tron/core/net/messagehandler/MessageHandlerTest.java @@ -3,7 +3,6 @@ import static org.mockito.Mockito.mock; import com.google.protobuf.ByteString; -import java.io.File; import java.lang.reflect.Field; import java.net.InetSocketAddress; import java.util.ArrayList; @@ -12,11 +11,12 @@ import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; +import org.junit.ClassRule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.mockito.Mockito; import org.springframework.context.ApplicationContext; import org.tron.common.application.TronApplicationContext; -import org.tron.common.utils.FileUtil; import org.tron.common.utils.ReflectUtils; import org.tron.common.utils.Sha256Hash; import org.tron.consensus.pbft.message.PbftMessage; @@ -39,13 +39,15 @@ public class MessageHandlerTest { private PeerConnection peer; private static P2pEventHandlerImpl p2pEventHandler; private static ApplicationContext ctx; - private static String dbPath = "output-message-handler-test"; + + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); @BeforeClass public static void init() throws Exception { - Args.setParam(new String[] {"--output-directory", dbPath, "--debug"}, - Constant.TEST_CONF); + Args.setParam(new String[] {"--output-directory", + temporaryFolder.newFolder().toString(), "--debug"}, Constant.TEST_CONF); context = new TronApplicationContext(DefaultConfig.class); p2pEventHandler = context.getBean(P2pEventHandlerImpl.class); ctx = (ApplicationContext) ReflectUtils.getFieldObject(p2pEventHandler, "ctx"); @@ -59,7 +61,6 @@ public static void init() throws Exception { public static void destroy() { Args.clearParam(); context.destroy(); - FileUtil.deleteDir(new File(dbPath)); } @Before diff --git a/framework/src/test/java/org/tron/core/net/messagehandler/PbftDataSyncHandlerTest.java b/framework/src/test/java/org/tron/core/net/messagehandler/PbftDataSyncHandlerTest.java new file mode 100644 index 00000000000..d1fdfaa5d90 --- /dev/null +++ b/framework/src/test/java/org/tron/core/net/messagehandler/PbftDataSyncHandlerTest.java @@ -0,0 +1,57 @@ +package org.tron.core.net.messagehandler; + +import com.alibaba.fastjson.JSON; +import com.google.protobuf.ByteString; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Map; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.ChainBaseManager; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.capsule.PbftSignCapsule; +import org.tron.core.db.PbftSignDataStore; +import org.tron.core.net.message.pbft.PbftCommitMessage; +import org.tron.core.store.DynamicPropertiesStore; +import org.tron.protos.Protocol; + +public class PbftDataSyncHandlerTest { + @Test + public void testProcessMessage() throws Exception { + PbftDataSyncHandler pbftDataSyncHandler = new PbftDataSyncHandler(); + BlockCapsule blockCapsule = new BlockCapsule(1, Sha256Hash.ZERO_HASH, + System.currentTimeMillis(), ByteString.EMPTY); + Protocol.PBFTMessage.Raw.Builder rawBuilder = Protocol.PBFTMessage.Raw.newBuilder(); + rawBuilder.setViewN(blockCapsule.getNum()) + .setEpoch(0) + .setDataType(Protocol.PBFTMessage.DataType.BLOCK) + .setMsgType(Protocol.PBFTMessage.MsgType.PREPREPARE) + .setData(blockCapsule.getBlockId().getByteString()); + Protocol.PBFTMessage.Raw raw = rawBuilder.build(); + PbftSignCapsule pbftSignCapsule = new PbftSignCapsule(raw.toByteString(), new ArrayList<>()); + PbftCommitMessage pbftCommitMessage = new PbftCommitMessage(pbftSignCapsule); + pbftDataSyncHandler.processMessage(null, pbftCommitMessage); + Assert.assertEquals(Protocol.PBFTMessage.Raw.parseFrom( + pbftCommitMessage.getPBFTCommitResult().getData()).getViewN(), 1); + + DynamicPropertiesStore dynamicPropertiesStore = Mockito.mock(DynamicPropertiesStore.class); + PbftSignDataStore pbftSignDataStore = Mockito.mock(PbftSignDataStore.class); + ChainBaseManager chainBaseManager = Mockito.mock(ChainBaseManager.class); + Mockito.when(chainBaseManager.getDynamicPropertiesStore()).thenReturn(dynamicPropertiesStore); + Mockito.when(dynamicPropertiesStore.allowPBFT()).thenReturn(true); + Mockito.when(dynamicPropertiesStore.getMaintenanceTimeInterval()).thenReturn(600L); + Mockito.when(chainBaseManager.getPbftSignDataStore()).thenReturn(pbftSignDataStore); + + Field field = PbftDataSyncHandler.class.getDeclaredField("chainBaseManager"); + field.setAccessible(true); + field.set(pbftDataSyncHandler, chainBaseManager); + + pbftDataSyncHandler.processPBFTCommitData(blockCapsule); + Field field1 = PbftDataSyncHandler.class.getDeclaredField("pbftCommitMessageCache"); + field1.setAccessible(true); + Map map = JSON.parseObject(JSON.toJSONString(field1.get(pbftDataSyncHandler)), Map.class); + Assert.assertFalse(map.containsKey(0)); + } +} diff --git a/framework/src/test/java/org/tron/core/net/messagehandler/PbftMsgHandlerTest.java b/framework/src/test/java/org/tron/core/net/messagehandler/PbftMsgHandlerTest.java new file mode 100644 index 00000000000..3fec10fc163 --- /dev/null +++ b/framework/src/test/java/org/tron/core/net/messagehandler/PbftMsgHandlerTest.java @@ -0,0 +1,121 @@ +package org.tron.core.net.messagehandler; + +import static org.mockito.Mockito.mock; + +import com.google.protobuf.ByteString; +import java.io.File; +import java.lang.reflect.Field; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Collections; +import org.bouncycastle.util.encoders.Hex; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.Mockito; +import org.tron.common.application.TronApplicationContext; +import org.tron.common.crypto.SignInterface; +import org.tron.common.crypto.SignUtils; +import org.tron.common.utils.FileUtil; +import org.tron.common.utils.PublicMethod; +import org.tron.common.utils.ReflectUtils; +import org.tron.common.utils.Sha256Hash; +import org.tron.consensus.base.Param; +import org.tron.consensus.pbft.message.PbftMessage; +import org.tron.core.Constant; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.consensus.PbftBaseImpl; +import org.tron.core.exception.P2pException; +import org.tron.core.net.TronNetService; +import org.tron.core.net.message.MessageTypes; +import org.tron.core.net.peer.PeerConnection; +import org.tron.core.net.peer.PeerManager; +import org.tron.p2p.P2pConfig; +import org.tron.p2p.base.Parameter; +import org.tron.p2p.connection.Channel; +import org.tron.protos.Protocol; + + +public class PbftMsgHandlerTest { + private static TronApplicationContext context; + private PeerConnection peer; + private static String dbPath = "output-pbft-message-handler-test"; + + + @BeforeClass + public static void init() { + Args.setParam(new String[] {"--output-directory", dbPath, "--debug"}, + Constant.TEST_CONF); + context = new TronApplicationContext(DefaultConfig.class); + + TronNetService tronNetService = context.getBean(TronNetService.class); + Parameter.p2pConfig = new P2pConfig(); + ReflectUtils.setFieldValue(tronNetService, "p2pConfig", Parameter.p2pConfig); + } + + @AfterClass + public static void destroy() { + Args.clearParam(); + context.destroy(); + FileUtil.deleteDir(new File(dbPath)); + } + + @Before + public void clearPeers() { + try { + Field field = PeerManager.class.getDeclaredField("peers"); + field.setAccessible(true); + field.set(PeerManager.class, Collections.synchronizedList(new ArrayList<>())); + } catch (NoSuchFieldException | IllegalAccessException e) { + //ignore + } + } + + @Test + public void testPbft() throws Exception { + InetSocketAddress a1 = new InetSocketAddress("127.0.0.1", 10001); + Channel c1 = mock(Channel.class); + Mockito.when(c1.getInetSocketAddress()).thenReturn(a1); + Mockito.when(c1.getInetAddress()).thenReturn(a1.getAddress()); + PeerManager.add(context, c1); + Assert.assertEquals(1, PeerManager.getPeers().size()); + Assert.assertFalse(c1.isDisconnect()); + + peer = PeerManager.getPeers().get(0); + BlockCapsule blockCapsule = new BlockCapsule(1, Sha256Hash.ZERO_HASH, + System.currentTimeMillis(), ByteString.EMPTY); + PbftMessage pbftMessage = new PbftMessage(); + Protocol.PBFTMessage.Raw.Builder rawBuilder = Protocol.PBFTMessage.Raw.newBuilder(); + Protocol.PBFTMessage.Builder builder = Protocol.PBFTMessage.newBuilder(); + rawBuilder.setViewN(blockCapsule.getNum()) + .setEpoch(0) + .setDataType(Protocol.PBFTMessage.DataType.BLOCK) + .setMsgType(Protocol.PBFTMessage.MsgType.PREPREPARE) + .setData(blockCapsule.getBlockId().getByteString()); + Protocol.PBFTMessage.Raw raw = rawBuilder.build(); + builder.setRawData(raw); + SignInterface sign = SignUtils.fromPrivate(Hex.decode(PublicMethod.getRandomPrivateKey()), + true); + builder.setSignature(ByteString.copyFrom(sign.Base64toBytes(sign.signHash( + Sha256Hash.hash(true, raw.toByteArray()))))); + Protocol.PBFTMessage message = builder.build(); + pbftMessage.setType(MessageTypes.PBFT_MSG.asByte()); + pbftMessage.setPbftMessage(message); + pbftMessage.setData(message.toByteArray()); + pbftMessage.setSwitch(blockCapsule.isSwitch()); + Param.getInstance().setPbftInterface(context.getBean(PbftBaseImpl.class)); + peer.setNeedSyncFromPeer(false); + //Mockito.doNothing().when(pbftMessage).analyzeSignature(); + try { + context.getBean(PbftMsgHandler.class).processMessage(peer, pbftMessage); + } catch (P2pException e) { + Assert.assertEquals(P2pException.TypeEnum.BAD_MESSAGE, e.getType()); + } + + Assert.assertEquals(1, PeerManager.getPeers().size()); + } +} diff --git a/framework/src/test/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandlerTest.java b/framework/src/test/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandlerTest.java index 2dbad09c655..d4ad32dd34f 100644 --- a/framework/src/test/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandlerTest.java +++ b/framework/src/test/java/org/tron/core/net/messagehandler/SyncBlockChainMsgHandlerTest.java @@ -1,7 +1,7 @@ package org.tron.core.net.messagehandler; -import java.io.File; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.InetSocketAddress; import java.util.ArrayList; @@ -9,11 +9,13 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.tron.common.application.TronApplicationContext; -import org.tron.common.utils.FileUtil; import org.tron.core.Constant; import org.tron.core.capsule.BlockCapsule; +import org.tron.core.capsule.BlockCapsule.BlockId; import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; import org.tron.core.exception.P2pException; @@ -26,12 +28,13 @@ public class SyncBlockChainMsgHandlerTest { private TronApplicationContext context; private SyncBlockChainMsgHandler handler; private PeerConnection peer; - private String dbPath = "output-sync-chain-test"; + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); @Before public void init() throws Exception { - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, - Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", + temporaryFolder.newFolder().toString(), "--debug"}, Constant.TEST_CONF); context = new TronApplicationContext(DefaultConfig.class); handler = context.getBean(SyncBlockChainMsgHandler.class); peer = context.getBean(PeerConnection.class); @@ -64,12 +67,26 @@ public void testProcessMessage() throws Exception { method.setAccessible(true); boolean f = (boolean)method.invoke(handler, peer, message); Assert.assertTrue(!f); + + Method method1 = handler.getClass().getDeclaredMethod( + "getLostBlockIds", List.class, BlockId.class); + method1.setAccessible(true); + try { + method1.invoke(handler, blockIds, new BlockCapsule.BlockId()); + } catch (InvocationTargetException e) { + Assert.assertEquals("unForkId is null", e.getTargetException().getMessage()); + } + + Method method2 = handler.getClass().getDeclaredMethod( + "getBlockIds", Long.class, BlockId.class); + method2.setAccessible(true); + List list = (List) method2.invoke(handler, 0L, new BlockCapsule.BlockId()); + Assert.assertEquals(1, list.size()); } @After public void destroy() { Args.clearParam(); - FileUtil.deleteDir(new File(dbPath)); } } diff --git a/framework/src/test/java/org/tron/core/net/messagehandler/TransactionsMsgHandlerTest.java b/framework/src/test/java/org/tron/core/net/messagehandler/TransactionsMsgHandlerTest.java new file mode 100644 index 00000000000..47ffde30ac3 --- /dev/null +++ b/framework/src/test/java/org/tron/core/net/messagehandler/TransactionsMsgHandlerTest.java @@ -0,0 +1,84 @@ +package org.tron.core.net.messagehandler; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import org.joda.time.DateTime; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.Mockito; +import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; +import org.tron.core.net.TronNetDelegate; +import org.tron.core.net.message.adv.TransactionMessage; +import org.tron.core.net.message.adv.TransactionsMessage; +import org.tron.core.net.peer.Item; +import org.tron.core.net.peer.PeerConnection; +import org.tron.core.net.service.adv.AdvService; +import org.tron.protos.Protocol; +import org.tron.protos.contract.BalanceContract; + +public class TransactionsMsgHandlerTest extends BaseTest { + @BeforeClass + public static void init() { + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, + Constant.TEST_CONF); + + } + + @Test + public void testProcessMessage() { + TransactionsMsgHandler transactionsMsgHandler = new TransactionsMsgHandler(); + try { + Assert.assertFalse(transactionsMsgHandler.isBusy()); + + transactionsMsgHandler.init(); + + PeerConnection peer = Mockito.mock(PeerConnection.class); + TronNetDelegate tronNetDelegate = Mockito.mock(TronNetDelegate.class); + AdvService advService = Mockito.mock(AdvService.class); + + Field field = TransactionsMsgHandler.class.getDeclaredField("tronNetDelegate"); + field.setAccessible(true); + field.set(transactionsMsgHandler, tronNetDelegate); + + BalanceContract.TransferContract transferContract = BalanceContract.TransferContract + .newBuilder() + .setAmount(10) + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString("121212a9cf"))) + .setToAddress(ByteString.copyFrom(ByteArray.fromHexString("232323a9cf"))).build(); + + long transactionTimestamp = DateTime.now().minusDays(4).getMillis(); + Protocol.Transaction trx = Protocol.Transaction.newBuilder().setRawData( + Protocol.Transaction.raw.newBuilder().setTimestamp(transactionTimestamp) + .setRefBlockNum(1) + .addContract( + Protocol.Transaction.Contract.newBuilder() + .setType(Protocol.Transaction.Contract.ContractType.TransferContract) + .setParameter(Any.pack(transferContract)).build()).build()) + .build(); + Map advInvRequest = new ConcurrentHashMap<>(); + Item item = new Item(new TransactionMessage(trx).getMessageId(), + Protocol.Inventory.InventoryType.TRX); + advInvRequest.put(item, 0L); + Mockito.when(peer.getAdvInvRequest()).thenReturn(advInvRequest); + + List transactionList = new ArrayList<>(); + transactionList.add(trx); + transactionsMsgHandler.processMessage(peer, new TransactionsMessage(transactionList)); + Assert.assertNull(advInvRequest.get(item)); + //Thread.sleep(10); + } catch (Exception e) { + Assert.fail(); + } finally { + transactionsMsgHandler.close(); + } + } +} diff --git a/framework/src/test/java/org/tron/core/net/peer/PeerConnectionTest.java b/framework/src/test/java/org/tron/core/net/peer/PeerConnectionTest.java new file mode 100644 index 00000000000..c0d81ca2763 --- /dev/null +++ b/framework/src/test/java/org/tron/core/net/peer/PeerConnectionTest.java @@ -0,0 +1,279 @@ +package org.tron.core.net.peer; + +import static org.mockito.Mockito.mock; + +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; +import org.tron.common.overlay.message.Message; +import org.tron.common.utils.Pair; +import org.tron.common.utils.ReflectUtils; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.net.message.adv.InventoryMessage; +import org.tron.core.net.message.handshake.HelloMessage; +import org.tron.core.net.message.keepalive.PingMessage; +import org.tron.core.net.message.keepalive.PongMessage; +import org.tron.core.net.service.adv.AdvService; +import org.tron.core.net.service.sync.SyncService; +import org.tron.p2p.connection.Channel; +import org.tron.protos.Protocol; + +public class PeerConnectionTest { + + @Test + public void testVariableDefaultValue() { + PeerConnection peerConnection = new PeerConnection(); + Assert.assertTrue(!peerConnection.isBadPeer()); + Assert.assertTrue(!peerConnection.isFetchAble()); + Assert.assertTrue(peerConnection.isIdle()); + Assert.assertTrue(!peerConnection.isRelayPeer()); + Assert.assertTrue(peerConnection.isNeedSyncFromPeer()); + Assert.assertTrue(peerConnection.isNeedSyncFromUs()); + Assert.assertTrue(!peerConnection.isSyncFinish()); + } + + @Test + public void testOnDisconnect() { + PeerConnection peerConnection = new PeerConnection(); + + SyncService syncService = mock(SyncService.class); + ReflectUtils.setFieldValue(peerConnection, "syncService", syncService); + + AdvService advService = mock(AdvService.class); + ReflectUtils.setFieldValue(peerConnection, "advService", advService); + + Item item = new Item(Sha256Hash.ZERO_HASH, Protocol.Inventory.InventoryType.TRX); + Long time = System.currentTimeMillis(); + BlockCapsule.BlockId blockId = new BlockCapsule.BlockId(); + peerConnection.getAdvInvReceive().put(item, time); + peerConnection.getAdvInvSpread().put(item, time); + peerConnection.getSyncBlockIdCache().put(item.getHash(), time); + peerConnection.getSyncBlockToFetch().add(blockId); + peerConnection.getSyncBlockRequested().put(blockId, time); + peerConnection.getSyncBlockInProcess().add(blockId); + + peerConnection.onDisconnect(); + + //Assert.assertEquals(0, peerConnection.getAdvInvReceive().size()); + //Assert.assertEquals(0, peerConnection.getAdvInvSpread().size()); + //Assert.assertEquals(0, peerConnection.getSyncBlockIdCache().size()); + Assert.assertEquals(0, peerConnection.getSyncBlockToFetch().size()); + Assert.assertEquals(0, peerConnection.getSyncBlockRequested().size()); + Assert.assertEquals(0, peerConnection.getSyncBlockInProcess().size()); + } + + @Test + public void testIsIdle() { + PeerConnection peerConnection = new PeerConnection(); + boolean f = peerConnection.isIdle(); + Assert.assertTrue(f); + + Item item = new Item(Sha256Hash.ZERO_HASH, Protocol.Inventory.InventoryType.TRX); + Long time = System.currentTimeMillis(); + peerConnection.getAdvInvRequest().put(item, time); + f = peerConnection.isIdle(); + Assert.assertTrue(!f); + + peerConnection.getAdvInvRequest().clear(); + f = peerConnection.isIdle(); + Assert.assertTrue(f); + + BlockCapsule.BlockId blockId = new BlockCapsule.BlockId(); + peerConnection.getSyncBlockRequested().put(blockId, time); + f = peerConnection.isIdle(); + Assert.assertTrue(!f); + + peerConnection.getSyncBlockRequested().clear(); + f = peerConnection.isIdle(); + Assert.assertTrue(f); + + peerConnection.setSyncChainRequested(new Pair<>(new LinkedList<>(), time)); + f = peerConnection.isIdle(); + Assert.assertTrue(!f); + } + + @Test + public void testOnConnect() { + PeerConnection peerConnection = new PeerConnection(); + SyncService syncService = mock(SyncService.class); + ReflectUtils.setFieldValue(peerConnection, "syncService", syncService); + + HelloMessage m1 = mock(HelloMessage.class); + BlockCapsule.BlockId b1 = new BlockCapsule.BlockId(Sha256Hash.ZERO_HASH, 1); + Mockito.when(m1.getHeadBlockId()).thenReturn(b1); + + HelloMessage m2 = mock(HelloMessage.class); + BlockCapsule.BlockId b2 = new BlockCapsule.BlockId(Sha256Hash.ZERO_HASH, 2); + Mockito.when(m2.getHeadBlockId()).thenReturn(b2); + + Assert.assertTrue(peerConnection.isNeedSyncFromUs()); + Assert.assertTrue(peerConnection.isNeedSyncFromPeer()); + + ReflectUtils.setFieldValue(peerConnection, "helloMessageReceive", m1); + ReflectUtils.setFieldValue(peerConnection, "helloMessageSend", m2); + peerConnection.onConnect(); + Assert.assertTrue(peerConnection.isNeedSyncFromUs()); + Assert.assertTrue(!peerConnection.isNeedSyncFromPeer()); + + peerConnection.setNeedSyncFromPeer(true); + peerConnection.setNeedSyncFromUs(true); + ReflectUtils.setFieldValue(peerConnection, "helloMessageReceive", m2); + ReflectUtils.setFieldValue(peerConnection, "helloMessageSend", m1); + peerConnection.onConnect(); + Assert.assertTrue(!peerConnection.isNeedSyncFromUs()); + Assert.assertTrue(peerConnection.isNeedSyncFromPeer()); + + peerConnection.setNeedSyncFromPeer(true); + peerConnection.setNeedSyncFromUs(true); + ReflectUtils.setFieldValue(peerConnection, "helloMessageReceive", m1); + ReflectUtils.setFieldValue(peerConnection, "helloMessageSend", m1); + peerConnection.onConnect(); + Assert.assertTrue(!peerConnection.isNeedSyncFromUs()); + Assert.assertTrue(!peerConnection.isNeedSyncFromPeer()); + } + + @Test + public void testSetChannel() { + PeerConnection peerConnection = new PeerConnection(); + + InetSocketAddress inetSocketAddress = + new InetSocketAddress("127.0.0.2", 10001); + Channel c1 = new Channel(); + ReflectUtils.setFieldValue(c1, "inetSocketAddress", inetSocketAddress); + ReflectUtils.setFieldValue(c1, "inetAddress", inetSocketAddress.getAddress()); + + List relayNodes = new ArrayList<>(); + ReflectUtils.setFieldValue(peerConnection, "relayNodes", relayNodes); + + peerConnection.setChannel(c1); + Assert.assertTrue(!peerConnection.isRelayPeer()); + + relayNodes.add(inetSocketAddress); + peerConnection.setChannel(c1); + Assert.assertTrue(peerConnection.isRelayPeer()); + } + + @Test + public void testIsSyncFinish() { + PeerConnection peerConnection = new PeerConnection(); + boolean f = peerConnection.isSyncFinish(); + Assert.assertTrue(!f); + + peerConnection.setNeedSyncFromUs(false); + f = peerConnection.isSyncFinish(); + Assert.assertTrue(!f); + + peerConnection.setNeedSyncFromPeer(false); + f = peerConnection.isSyncFinish(); + Assert.assertTrue(f); + } + + @Test + public void testCheckAndPutAdvInvRequest() { + PeerConnection peerConnection = new PeerConnection(); + Item item = new Item(Sha256Hash.ZERO_HASH, Protocol.Inventory.InventoryType.TRX); + Long time = System.currentTimeMillis(); + boolean f = peerConnection.checkAndPutAdvInvRequest(item, time); + Assert.assertTrue(f); + + f = peerConnection.checkAndPutAdvInvRequest(item, time); + Assert.assertTrue(!f); + } + + @Test + public void testEquals() { + List relayNodes = new ArrayList<>(); + + PeerConnection p1 = new PeerConnection(); + InetSocketAddress inetSocketAddress1 = + new InetSocketAddress("127.0.0.2", 10001); + Channel c1 = new Channel(); + ReflectUtils.setFieldValue(c1, "inetSocketAddress", inetSocketAddress1); + ReflectUtils.setFieldValue(c1, "inetAddress", inetSocketAddress1.getAddress()); + ReflectUtils.setFieldValue(p1, "relayNodes", relayNodes); + p1.setChannel(c1); + + PeerConnection p2 = new PeerConnection(); + InetSocketAddress inetSocketAddress2 = + new InetSocketAddress("127.0.0.2", 10002); + Channel c2 = new Channel(); + ReflectUtils.setFieldValue(c2, "inetSocketAddress", inetSocketAddress2); + ReflectUtils.setFieldValue(c2, "inetAddress", inetSocketAddress2.getAddress()); + ReflectUtils.setFieldValue(p2, "relayNodes", relayNodes); + p2.setChannel(c2); + + PeerConnection p3 = new PeerConnection(); + InetSocketAddress inetSocketAddress3 = + new InetSocketAddress("127.0.0.2", 10002); + Channel c3 = new Channel(); + ReflectUtils.setFieldValue(c3, "inetSocketAddress", inetSocketAddress3); + ReflectUtils.setFieldValue(c3, "inetAddress", inetSocketAddress3.getAddress()); + ReflectUtils.setFieldValue(p3, "relayNodes", relayNodes); + p3.setChannel(c3); + + Assert.assertTrue(p1.equals(p1)); + Assert.assertTrue(!p1.equals(p2)); + Assert.assertTrue(p2.equals(p3)); + } + + @Test + public void testHashCode() { + List relayNodes = new ArrayList<>(); + + PeerConnection p1 = new PeerConnection(); + InetSocketAddress inetSocketAddress1 = + new InetSocketAddress("127.0.0.2", 10001); + Channel c1 = new Channel(); + ReflectUtils.setFieldValue(c1, "inetSocketAddress", inetSocketAddress1); + ReflectUtils.setFieldValue(c1, "inetAddress", inetSocketAddress1.getAddress()); + ReflectUtils.setFieldValue(p1, "relayNodes", relayNodes); + p1.setChannel(c1); + + PeerConnection p2 = new PeerConnection(); + InetSocketAddress inetSocketAddress2 = + new InetSocketAddress("127.0.0.2", 10002); + Channel c2 = new Channel(); + ReflectUtils.setFieldValue(c2, "inetSocketAddress", inetSocketAddress2); + ReflectUtils.setFieldValue(c2, "inetAddress", inetSocketAddress2.getAddress()); + ReflectUtils.setFieldValue(p2, "relayNodes", relayNodes); + p2.setChannel(c2); + + PeerConnection p3 = new PeerConnection(); + InetSocketAddress inetSocketAddress3 = + new InetSocketAddress("127.0.0.2", 10002); + Channel c3 = new Channel(); + ReflectUtils.setFieldValue(c3, "inetSocketAddress", inetSocketAddress3); + ReflectUtils.setFieldValue(c3, "inetAddress", inetSocketAddress3.getAddress()); + ReflectUtils.setFieldValue(p3, "relayNodes", relayNodes); + p3.setChannel(c3); + + Assert.assertTrue(p1.hashCode() != p2.hashCode()); + Assert.assertTrue(p2.hashCode() == p3.hashCode()); + } + + @Test + public void testNeedToLog() throws Exception { + Message msg = new PingMessage(); + boolean f = PeerConnection.needToLog(msg); + Assert.assertTrue(!f); + + msg = new PongMessage(); + f = PeerConnection.needToLog(msg); + Assert.assertTrue(!f); + + msg = new InventoryMessage(new ArrayList<>(), Protocol.Inventory.InventoryType.TRX); + f = PeerConnection.needToLog(msg); + Assert.assertTrue(!f); + + msg = new InventoryMessage(new ArrayList<>(), Protocol.Inventory.InventoryType.BLOCK); + f = PeerConnection.needToLog(msg); + Assert.assertTrue(f); + } + +} diff --git a/framework/src/test/java/org/tron/core/net/peer/PeerManagerTest.java b/framework/src/test/java/org/tron/core/net/peer/PeerManagerTest.java new file mode 100644 index 00000000000..a6151da6d1c --- /dev/null +++ b/framework/src/test/java/org/tron/core/net/peer/PeerManagerTest.java @@ -0,0 +1,138 @@ +package org.tron.core.net.peer; + +import static org.mockito.Mockito.mock; + +import java.lang.reflect.Field; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.context.ApplicationContext; +import org.tron.common.utils.ReflectUtils; +import org.tron.p2p.connection.Channel; + +public class PeerManagerTest { + List relayNodes = new ArrayList<>(); + + @Test + public void testAdd() throws Exception { + Field field = PeerManager.class.getDeclaredField("peers"); + field.setAccessible(true); + field.set(PeerManager.class, Collections.synchronizedList(new ArrayList<>())); + + PeerConnection p1 = new PeerConnection(); + InetSocketAddress inetSocketAddress1 = + new InetSocketAddress("127.0.0.2", 10001); + Channel c1 = new Channel(); + ReflectUtils.setFieldValue(c1, "inetSocketAddress", inetSocketAddress1); + ReflectUtils.setFieldValue(c1, "inetAddress", inetSocketAddress1.getAddress()); + ReflectUtils.setFieldValue(p1, "relayNodes", relayNodes); + p1.setChannel(c1); + + ApplicationContext ctx = mock(ApplicationContext.class); + Mockito.when(ctx.getBean(PeerConnection.class)).thenReturn(p1); + + PeerConnection p = PeerManager.add(ctx, c1); + Assert.assertTrue(p != null); + + p = PeerManager.add(ctx, c1); + Assert.assertTrue(p == null); + } + + @Test + public void testRemove() throws Exception { + Field field = PeerManager.class.getDeclaredField("peers"); + field.setAccessible(true); + field.set(PeerManager.class, Collections.synchronizedList(new ArrayList<>())); + + PeerConnection p1 = new PeerConnection(); + InetSocketAddress inetSocketAddress1 = + new InetSocketAddress("127.0.0.2", 10001); + Channel c1 = new Channel(); + ReflectUtils.setFieldValue(c1, "inetSocketAddress", inetSocketAddress1); + ReflectUtils.setFieldValue(c1, "inetAddress", inetSocketAddress1.getAddress()); + ReflectUtils.setFieldValue(p1, "relayNodes", relayNodes); + p1.setChannel(c1); + + ApplicationContext ctx = mock(ApplicationContext.class); + Mockito.when(ctx.getBean(PeerConnection.class)).thenReturn(p1); + + PeerConnection p = PeerManager.remove(c1); + Assert.assertTrue(p == null); + + PeerManager.add(ctx, c1); + p = PeerManager.remove(c1); + Assert.assertTrue(p != null); + } + + @Test + public void testGetPeerConnection() throws Exception { + Field field = PeerManager.class.getDeclaredField("peers"); + field.setAccessible(true); + field.set(PeerManager.class, Collections.synchronizedList(new ArrayList<>())); + + PeerConnection p1 = new PeerConnection(); + InetSocketAddress inetSocketAddress1 = + new InetSocketAddress("127.0.0.2", 10001); + Channel c1 = new Channel(); + ReflectUtils.setFieldValue(c1, "inetSocketAddress", inetSocketAddress1); + ReflectUtils.setFieldValue(c1, "inetAddress", inetSocketAddress1.getAddress()); + ReflectUtils.setFieldValue(p1, "relayNodes", relayNodes); + p1.setChannel(c1); + + ApplicationContext ctx = mock(ApplicationContext.class); + Mockito.when(ctx.getBean(PeerConnection.class)).thenReturn(p1); + + PeerManager.add(ctx, c1); + PeerConnection p = PeerManager.getPeerConnection(c1); + Assert.assertTrue(p != null); + } + + @Test + public void testGetPeers() throws Exception { + Field field = PeerManager.class.getDeclaredField("peers"); + field.setAccessible(true); + field.set(PeerManager.class, Collections.synchronizedList(new ArrayList<>())); + + PeerConnection p1 = new PeerConnection(); + InetSocketAddress inetSocketAddress1 = + new InetSocketAddress("127.0.0.1", 10001); + Channel c1 = new Channel(); + ReflectUtils.setFieldValue(c1, "inetSocketAddress", inetSocketAddress1); + ReflectUtils.setFieldValue(c1, "inetAddress", inetSocketAddress1.getAddress()); + ReflectUtils.setFieldValue(p1, "relayNodes", relayNodes); + p1.setChannel(c1); + + ApplicationContext ctx = mock(ApplicationContext.class); + Mockito.when(ctx.getBean(PeerConnection.class)).thenReturn(p1); + + PeerConnection p = PeerManager.add(ctx, c1); + Assert.assertTrue(p != null); + + List peers = PeerManager.getPeers(); + Assert.assertEquals(1, peers.size()); + + PeerConnection p2 = new PeerConnection(); + InetSocketAddress inetSocketAddress2 = + new InetSocketAddress("127.0.0.2", 10001); + Channel c2 = new Channel(); + ReflectUtils.setFieldValue(c2, "inetSocketAddress", inetSocketAddress2); + ReflectUtils.setFieldValue(c2, "inetAddress", inetSocketAddress2.getAddress()); + ReflectUtils.setFieldValue(p2, "relayNodes", relayNodes); + p2.setChannel(c2); + + ApplicationContext ctx2 = mock(ApplicationContext.class); + Mockito.when(ctx2.getBean(PeerConnection.class)).thenReturn(p2); + + p = PeerManager.add(ctx2, c2); + Assert.assertTrue(p != null); + + peers = PeerManager.getPeers(); + Assert.assertEquals(2, peers.size()); + } + +} diff --git a/framework/src/test/java/org/tron/core/net/services/AdvServiceTest.java b/framework/src/test/java/org/tron/core/net/services/AdvServiceTest.java index 78db0398755..d79b54f6f45 100644 --- a/framework/src/test/java/org/tron/core/net/services/AdvServiceTest.java +++ b/framework/src/test/java/org/tron/core/net/services/AdvServiceTest.java @@ -1,42 +1,59 @@ package org.tron.core.net.services; -import com.google.common.collect.Lists; -import java.util.List; -import javax.annotation.Resource; +import static org.mockito.Mockito.mock; + +import java.io.IOException; +import java.net.InetSocketAddress; +import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; +import org.junit.ClassRule; import org.junit.Test; -import org.tron.common.BaseTest; +import org.junit.rules.TemporaryFolder; +import org.mockito.Mockito; +import org.springframework.context.ApplicationContext; +import org.tron.common.application.TronApplicationContext; import org.tron.common.parameter.CommonParameter; import org.tron.common.utils.ReflectUtils; import org.tron.common.utils.Sha256Hash; import org.tron.core.Constant; import org.tron.core.capsule.BlockCapsule; +import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; +import org.tron.core.net.P2pEventHandlerImpl; import org.tron.core.net.message.adv.BlockMessage; import org.tron.core.net.message.adv.TransactionMessage; import org.tron.core.net.peer.Item; import org.tron.core.net.peer.PeerConnection; +import org.tron.core.net.peer.PeerManager; import org.tron.core.net.service.adv.AdvService; -import org.tron.p2p.P2pEventHandler; +import org.tron.p2p.connection.Channel; import org.tron.protos.Protocol; import org.tron.protos.Protocol.Inventory.InventoryType; -public class AdvServiceTest extends BaseTest { +public class AdvServiceTest { + private static TronApplicationContext context; + private static AdvService service; + private static P2pEventHandlerImpl p2pEventHandler; + private static ApplicationContext ctx; - @Resource - private AdvService service; - @Resource - private PeerConnection peer; + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); - /** - * init context. - */ @BeforeClass - public static void init() { - dbPath = "output-adv-service-test"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, - Constant.TEST_CONF); + public static void init() throws IOException { + Args.setParam(new String[]{"--output-directory", + temporaryFolder.newFolder().toString(), "--debug"}, Constant.TEST_CONF); + context = new TronApplicationContext(DefaultConfig.class); + service = context.getBean(AdvService.class); + p2pEventHandler = context.getBean(P2pEventHandlerImpl.class); + ctx = (ApplicationContext) ReflectUtils.getFieldObject(p2pEventHandler, "ctx"); + } + + @AfterClass + public static void after() { + Args.clearParam(); + context.destroy(); } @Test @@ -66,25 +83,26 @@ private void testAddInv() { } private void testBroadcast() { + InetSocketAddress inetSocketAddress = + new InetSocketAddress("127.0.0.2", 10001); - try { - List peers = Lists.newArrayList(); - peers.add(peer); - ReflectUtils.setFieldValue(P2pEventHandler.class, "peers", peers); - BlockCapsule blockCapsule = new BlockCapsule(1, Sha256Hash.ZERO_HASH, - System.currentTimeMillis(), Sha256Hash.ZERO_HASH.getByteString()); - BlockMessage msg = new BlockMessage(blockCapsule); - service.broadcast(msg); - Item item = new Item(blockCapsule.getBlockId(), InventoryType.BLOCK); - Assert.assertNotNull(service.getMessage(item)); - peer.checkAndPutAdvInvRequest(item, System.currentTimeMillis()); - boolean res = peer.checkAndPutAdvInvRequest(item, System.currentTimeMillis()); - Assert.assertFalse(res); - } catch (NullPointerException e) { - System.out.println(e); - } - } + Channel c1 = mock(Channel.class); + Mockito.when(c1.getInetSocketAddress()).thenReturn(inetSocketAddress); + Mockito.when(c1.getInetAddress()).thenReturn(inetSocketAddress.getAddress()); + PeerConnection peer = PeerManager.add(ctx, c1); + peer.setChannel(c1); + peer.setNeedSyncFromUs(false); + peer.setNeedSyncFromPeer(false); + + BlockCapsule blockCapsule = new BlockCapsule(1, Sha256Hash.ZERO_HASH, + System.currentTimeMillis(), Sha256Hash.ZERO_HASH.getByteString()); + BlockMessage msg = new BlockMessage(blockCapsule); + service.broadcast(msg); + Item item = new Item(blockCapsule.getBlockId(), InventoryType.BLOCK); + Assert.assertNotNull(service.getMessage(item)); + Assert.assertNotNull(peer.getAdvInvSpread().getIfPresent(item)); + } private void testTrxBroadcast() { Protocol.Transaction trx = Protocol.Transaction.newBuilder().build(); diff --git a/framework/src/test/java/org/tron/core/net/services/EffectiveCheckServiceTest.java b/framework/src/test/java/org/tron/core/net/services/EffectiveCheckServiceTest.java index aa42e0fcb89..9104b087d26 100644 --- a/framework/src/test/java/org/tron/core/net/services/EffectiveCheckServiceTest.java +++ b/framework/src/test/java/org/tron/core/net/services/EffectiveCheckServiceTest.java @@ -1,14 +1,15 @@ package org.tron.core.net.services; -import java.io.File; +import java.io.IOException; import java.lang.reflect.Method; import java.net.InetSocketAddress; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.tron.common.application.TronApplicationContext; -import org.tron.common.utils.FileUtil; import org.tron.common.utils.ReflectUtils; import org.tron.core.Constant; import org.tron.core.config.DefaultConfig; @@ -21,12 +22,14 @@ public class EffectiveCheckServiceTest { protected TronApplicationContext context; private EffectiveCheckService service; - private String dbPath = "output-effective-service-test"; + + @Rule + public final TemporaryFolder temporaryFolder = new TemporaryFolder(); @Before - public void init() { - Args.setParam(new String[] {"--output-directory", dbPath, "--debug"}, - Constant.TEST_CONF); + public void init() throws IOException { + Args.setParam(new String[] {"--output-directory", + temporaryFolder.newFolder().toString(), "--debug"}, Constant.TEST_CONF); context = new TronApplicationContext(DefaultConfig.class); service = context.getBean(EffectiveCheckService.class); } @@ -35,7 +38,6 @@ public void init() { public void destroy() { Args.clearParam(); context.destroy(); - FileUtil.deleteDir(new File(dbPath)); } @Test diff --git a/framework/src/test/java/org/tron/core/net/services/HandShakeServiceTest.java b/framework/src/test/java/org/tron/core/net/services/HandShakeServiceTest.java index 4f074b2c825..e027749458f 100644 --- a/framework/src/test/java/org/tron/core/net/services/HandShakeServiceTest.java +++ b/framework/src/test/java/org/tron/core/net/services/HandShakeServiceTest.java @@ -4,7 +4,6 @@ import static org.tron.core.net.message.handshake.HelloMessage.getEndpointFromNode; import com.google.protobuf.ByteString; -import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -16,15 +15,14 @@ import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; +import org.junit.ClassRule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.mockito.Mockito; import org.springframework.context.ApplicationContext; import org.tron.common.application.TronApplicationContext; -import org.tron.common.utils.ByteArray; -import org.tron.common.utils.FileUtil; import org.tron.common.utils.ReflectUtils; import org.tron.common.utils.Sha256Hash; -import org.tron.consensus.pbft.message.PbftMessage; import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.capsule.BlockCapsule; @@ -33,7 +31,6 @@ import org.tron.core.net.P2pEventHandlerImpl; import org.tron.core.net.TronNetService; import org.tron.core.net.message.handshake.HelloMessage; -import org.tron.core.net.message.keepalive.PingMessage; import org.tron.core.net.peer.PeerConnection; import org.tron.core.net.peer.PeerManager; import org.tron.p2p.P2pConfig; @@ -51,13 +48,13 @@ public class HandShakeServiceTest { private PeerConnection peer; private static P2pEventHandlerImpl p2pEventHandler; private static ApplicationContext ctx; - private static String dbPath = "output-message-handler-test"; - + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); @BeforeClass public static void init() throws Exception { - Args.setParam(new String[] {"--output-directory", dbPath, "--debug"}, - Constant.TEST_CONF); + Args.setParam(new String[] {"--output-directory", + temporaryFolder.newFolder().toString(), "--debug"}, Constant.TEST_CONF); context = new TronApplicationContext(DefaultConfig.class); p2pEventHandler = context.getBean(P2pEventHandlerImpl.class); ctx = (ApplicationContext) ReflectUtils.getFieldObject(p2pEventHandler, "ctx"); @@ -71,7 +68,6 @@ public static void init() throws Exception { public static void destroy() { Args.clearParam(); context.destroy(); - FileUtil.deleteDir(new File(dbPath)); } @Before diff --git a/framework/src/test/java/org/tron/core/net/services/RelayServiceTest.java b/framework/src/test/java/org/tron/core/net/services/RelayServiceTest.java index a5b676d0144..777472bdc35 100644 --- a/framework/src/test/java/org/tron/core/net/services/RelayServiceTest.java +++ b/framework/src/test/java/org/tron/core/net/services/RelayServiceTest.java @@ -40,8 +40,7 @@ public class RelayServiceTest extends BaseTest { */ @BeforeClass public static void init() { - dbPath = "output-relay-service-test"; - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, + Args.setParam(new String[]{"--output-directory", dbPath(), "--debug"}, Constant.TEST_CONF); } diff --git a/framework/src/test/java/org/tron/core/net/services/SyncServiceTest.java b/framework/src/test/java/org/tron/core/net/services/SyncServiceTest.java index 4eebb7da12c..89c081eaab5 100644 --- a/framework/src/test/java/org/tron/core/net/services/SyncServiceTest.java +++ b/framework/src/test/java/org/tron/core/net/services/SyncServiceTest.java @@ -3,7 +3,6 @@ import static org.mockito.Mockito.mock; import com.google.common.cache.Cache; -import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.InetSocketAddress; @@ -13,11 +12,12 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.mockito.Mockito; import org.springframework.context.ApplicationContext; import org.tron.common.application.TronApplicationContext; -import org.tron.common.utils.FileUtil; import org.tron.common.utils.ReflectUtils; import org.tron.core.Constant; import org.tron.core.capsule.BlockCapsule; @@ -38,7 +38,8 @@ public class SyncServiceTest { private PeerConnection peer; private P2pEventHandlerImpl p2pEventHandler; private ApplicationContext ctx; - private String dbPath = "output-sync-service-test"; + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); private InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.2", 10001); @@ -50,8 +51,8 @@ public SyncServiceTest() { */ @Before public void init() throws Exception { - Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, - Constant.TEST_CONF); + Args.setParam(new String[]{"--output-directory", + temporaryFolder.newFolder().toString(), "--debug"}, Constant.TEST_CONF); context = new TronApplicationContext(DefaultConfig.class); service = context.getBean(SyncService.class); p2pEventHandler = context.getBean(P2pEventHandlerImpl.class); @@ -65,7 +66,6 @@ public void init() throws Exception { public void destroy() { Args.clearParam(); context.destroy(); - FileUtil.deleteDir(new File(dbPath)); } @Test @@ -151,6 +151,13 @@ public void testStartFetchSyncBlock() throws Exception { PeerManager.add(ctx, c1); peer = PeerManager.getPeers().get(0); + Method method1 = PeerManager.class.getDeclaredMethod("check"); + method1.setAccessible(true); + method1.invoke(PeerManager.class); + Method method2 = PeerManager.class.getDeclaredMethod("logPeerStats"); + method2.setAccessible(true); + method2.invoke(PeerManager.class); + method.invoke(service); Assert.assertTrue(peer.getSyncBlockRequested().get(blockId) == null); diff --git a/framework/src/test/java/org/tron/core/pbft/PbftApiTest.java b/framework/src/test/java/org/tron/core/pbft/PbftApiTest.java index 61ce5ec3625..9bc942d6684 100755 --- a/framework/src/test/java/org/tron/core/pbft/PbftApiTest.java +++ b/framework/src/test/java/org/tron/core/pbft/PbftApiTest.java @@ -35,8 +35,7 @@ public class PbftApiTest extends BaseTest { @BeforeClass public static void init() { - dbPath = "output_pbftAPI_test"; - Args.setParam(new String[]{"-d", dbPath, "-w"}, Constant.TEST_CONF); + Args.setParam(new String[]{"-d", dbPath(), "-w"}, Constant.TEST_CONF); } @Test @@ -59,6 +58,7 @@ public void pbftapi() throws IOException { Assert.assertTrue(dynamicPropertiesStore.getLatestBlockHeaderNumber() >= 10); commonDataBase.saveLatestPbftBlockNum(6); + httpApiOnPBFTService.init(Args.getInstance()); httpApiOnPBFTService.start(); CloseableHttpResponse response; try (CloseableHttpClient httpClient = HttpClients.createDefault()) { diff --git a/framework/src/test/java/org/tron/core/services/NodeInfoServiceTest.java b/framework/src/test/java/org/tron/core/services/NodeInfoServiceTest.java index d442a5826f7..19d0540e5e6 100644 --- a/framework/src/test/java/org/tron/core/services/NodeInfoServiceTest.java +++ b/framework/src/test/java/org/tron/core/services/NodeInfoServiceTest.java @@ -1,10 +1,14 @@ package org.tron.core.services; +import static org.mockito.Mockito.mock; + import com.alibaba.fastjson.JSON; import com.google.protobuf.ByteString; import io.grpc.ManagedChannelBuilder; +import java.net.InetSocketAddress; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; +import org.mockito.Mockito; import org.tron.api.GrpcAPI.EmptyMessage; import org.tron.api.WalletGrpc; import org.tron.api.WalletGrpc.WalletBlockingStub; @@ -13,6 +17,9 @@ import org.tron.common.utils.Sha256Hash; import org.tron.common.utils.client.Configuration; import org.tron.core.capsule.BlockCapsule; +import org.tron.core.net.P2pEventHandlerImpl; +import org.tron.core.net.peer.PeerManager; +import org.tron.p2p.connection.Channel; import org.tron.program.Version; @@ -21,12 +28,14 @@ public class NodeInfoServiceTest { private NodeInfoService nodeInfoService; private WitnessProductBlockService witnessProductBlockService; + private P2pEventHandlerImpl p2pEventHandler; private String fullnode = Configuration.getByPath("testng.conf").getStringList("fullnode.ip.list") .get(0); public NodeInfoServiceTest(TronApplicationContext context) { nodeInfoService = context.getBean("nodeInfoService", NodeInfoService.class); witnessProductBlockService = context.getBean(WitnessProductBlockService.class); + p2pEventHandler = context.getBean(P2pEventHandlerImpl.class); } public void test() { @@ -36,6 +45,15 @@ public void test() { 200, ByteString.EMPTY); witnessProductBlockService.validWitnessProductTwoBlock(blockCapsule1); witnessProductBlockService.validWitnessProductTwoBlock(blockCapsule2); + + //add peer + InetSocketAddress a1 = new InetSocketAddress("127.0.0.1", 10001); + Channel c1 = mock(Channel.class); + Mockito.when(c1.getInetSocketAddress()).thenReturn(a1); + Mockito.when(c1.getInetAddress()).thenReturn(a1.getAddress()); + p2pEventHandler.onConnect(c1); + + //test setConnectInfo NodeInfo nodeInfo = nodeInfoService.getNodeInfo(); Assert.assertEquals(nodeInfo.getConfigNodeInfo().getCodeVersion(), Version.getVersion()); Assert.assertEquals(nodeInfo.getCheatWitnessInfoMap().size(), 1); diff --git a/framework/src/test/java/org/tron/core/services/ProposalServiceTest.java b/framework/src/test/java/org/tron/core/services/ProposalServiceTest.java index 53c97f07b2a..0ba32b27f2e 100644 --- a/framework/src/test/java/org/tron/core/services/ProposalServiceTest.java +++ b/framework/src/test/java/org/tron/core/services/ProposalServiceTest.java @@ -26,8 +26,7 @@ public class ProposalServiceTest extends BaseTest { @BeforeClass public static void init() { - dbPath = "output_proposal_test"; - Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); } diff --git a/framework/src/test/java/org/tron/core/services/RpcApiServicesTest.java b/framework/src/test/java/org/tron/core/services/RpcApiServicesTest.java new file mode 100644 index 00000000000..8b45b871af7 --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/RpcApiServicesTest.java @@ -0,0 +1,1213 @@ +package org.tron.core.services; + +import static org.junit.Assert.assertNotNull; +import static org.tron.common.parameter.CommonParameter.getInstance; +import static org.tron.common.utils.client.WalletClient.decodeFromBase58Check; +import static org.tron.protos.Protocol.Transaction.Contract.ContractType.TransferContract; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.io.IOException; +import java.util.Objects; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runners.MethodSorters; +import org.tron.api.DatabaseGrpc; +import org.tron.api.DatabaseGrpc.DatabaseBlockingStub; +import org.tron.api.GrpcAPI.BlockLimit; +import org.tron.api.GrpcAPI.BlockReq; +import org.tron.api.GrpcAPI.BytesMessage; +import org.tron.api.GrpcAPI.CanDelegatedMaxSizeRequestMessage; +import org.tron.api.GrpcAPI.CanWithdrawUnfreezeAmountRequestMessage; +import org.tron.api.GrpcAPI.DelegatedResourceMessage; +import org.tron.api.GrpcAPI.DiversifierMessage; +import org.tron.api.GrpcAPI.EmptyMessage; +import org.tron.api.GrpcAPI.ExpandedSpendingKeyMessage; +import org.tron.api.GrpcAPI.GetAvailableUnfreezeCountRequestMessage; +import org.tron.api.GrpcAPI.IncomingViewingKeyDiversifierMessage; +import org.tron.api.GrpcAPI.IncomingViewingKeyMessage; +import org.tron.api.GrpcAPI.IvkDecryptAndMarkParameters; +import org.tron.api.GrpcAPI.IvkDecryptParameters; +import org.tron.api.GrpcAPI.IvkDecryptTRC20Parameters; +import org.tron.api.GrpcAPI.NumberMessage; +import org.tron.api.GrpcAPI.OvkDecryptParameters; +import org.tron.api.GrpcAPI.OvkDecryptTRC20Parameters; +import org.tron.api.GrpcAPI.PaginatedMessage; +import org.tron.api.GrpcAPI.PrivateParameters; +import org.tron.api.GrpcAPI.PrivateParametersWithoutAsk; +import org.tron.api.GrpcAPI.ViewingKeyMessage; +import org.tron.api.WalletGrpc; +import org.tron.api.WalletGrpc.WalletBlockingStub; +import org.tron.api.WalletSolidityGrpc; +import org.tron.api.WalletSolidityGrpc.WalletSolidityBlockingStub; +import org.tron.common.application.Application; +import org.tron.common.application.ApplicationFactory; +import org.tron.common.application.TronApplicationContext; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.PublicMethod; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.Constant; +import org.tron.core.Wallet; +import org.tron.core.capsule.AccountCapsule; +import org.tron.core.capsule.BlockCapsule; +import org.tron.core.capsule.TransactionCapsule; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.services.interfaceOnPBFT.RpcApiServiceOnPBFT; +import org.tron.core.services.interfaceOnSolidity.RpcApiServiceOnSolidity; +import org.tron.protos.Protocol; +import org.tron.protos.Protocol.Account; +import org.tron.protos.Protocol.Block; +import org.tron.protos.Protocol.BlockHeader.raw; +import org.tron.protos.Protocol.MarketOrderPair; +import org.tron.protos.Protocol.Transaction; +import org.tron.protos.contract.AccountContract.AccountCreateContract; +import org.tron.protos.contract.AccountContract.AccountPermissionUpdateContract; +import org.tron.protos.contract.AccountContract.AccountUpdateContract; +import org.tron.protos.contract.AccountContract.SetAccountIdContract; +import org.tron.protos.contract.AssetIssueContractOuterClass.AssetIssueContract; +import org.tron.protos.contract.AssetIssueContractOuterClass.ParticipateAssetIssueContract; +import org.tron.protos.contract.AssetIssueContractOuterClass.TransferAssetContract; +import org.tron.protos.contract.AssetIssueContractOuterClass.UnfreezeAssetContract; +import org.tron.protos.contract.AssetIssueContractOuterClass.UpdateAssetContract; +import org.tron.protos.contract.BalanceContract; +import org.tron.protos.contract.BalanceContract.AccountBalanceRequest; +import org.tron.protos.contract.BalanceContract.AccountIdentifier; +import org.tron.protos.contract.BalanceContract.BlockBalanceTrace.BlockIdentifier; +import org.tron.protos.contract.BalanceContract.CancelAllUnfreezeV2Contract; +import org.tron.protos.contract.BalanceContract.DelegateResourceContract; +import org.tron.protos.contract.BalanceContract.FreezeBalanceContract; +import org.tron.protos.contract.BalanceContract.FreezeBalanceV2Contract; +import org.tron.protos.contract.BalanceContract.UnDelegateResourceContract; +import org.tron.protos.contract.BalanceContract.UnfreezeBalanceContract; +import org.tron.protos.contract.BalanceContract.UnfreezeBalanceV2Contract; +import org.tron.protos.contract.BalanceContract.WithdrawBalanceContract; +import org.tron.protos.contract.BalanceContract.WithdrawExpireUnfreezeContract; +import org.tron.protos.contract.ExchangeContract.ExchangeCreateContract; +import org.tron.protos.contract.ExchangeContract.ExchangeInjectContract; +import org.tron.protos.contract.ExchangeContract.ExchangeTransactionContract; +import org.tron.protos.contract.ExchangeContract.ExchangeWithdrawContract; +import org.tron.protos.contract.MarketContract.MarketCancelOrderContract; +import org.tron.protos.contract.MarketContract.MarketSellAssetContract; +import org.tron.protos.contract.ProposalContract.ProposalApproveContract; +import org.tron.protos.contract.ProposalContract.ProposalCreateContract; +import org.tron.protos.contract.ProposalContract.ProposalDeleteContract; +import org.tron.protos.contract.SmartContractOuterClass.ClearABIContract; +import org.tron.protos.contract.SmartContractOuterClass.CreateSmartContract; +import org.tron.protos.contract.SmartContractOuterClass.TriggerSmartContract; +import org.tron.protos.contract.SmartContractOuterClass.UpdateEnergyLimitContract; +import org.tron.protos.contract.SmartContractOuterClass.UpdateSettingContract; +import org.tron.protos.contract.StorageContract.UpdateBrokerageContract; +import org.tron.protos.contract.WitnessContract.VoteWitnessContract; +import org.tron.protos.contract.WitnessContract.WitnessCreateContract; +import org.tron.protos.contract.WitnessContract.WitnessUpdateContract; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class RpcApiServicesTest { + private static TronApplicationContext context; + private static DatabaseBlockingStub databaseBlockingStubFull = null; + private static DatabaseBlockingStub databaseBlockingStubSolidity = null; + private static DatabaseBlockingStub databaseBlockingStubPBFT = null; + private static WalletBlockingStub blockingStubFull = null; + private static WalletSolidityBlockingStub blockingStubSolidity = null; + private static WalletSolidityBlockingStub blockingStubPBFT = null; + @ClassRule + public static TemporaryFolder temporaryFolder = new TemporaryFolder(); + private static ByteString ownerAddress; + private static ByteString sk; + private static ByteString ask; + private static ByteString nsk; + private static ByteString ovk; + private static ByteString ak; + private static ByteString nk; + private static ByteString ivk; + private static ByteString d; + + @BeforeClass + public static void init() throws IOException { + Args.setParam(new String[]{"-d", temporaryFolder.newFolder().toString()}, Constant.TEST_CONF); + String OWNER_ADDRESS = Wallet.getAddressPreFixString() + + "548794500882809695a8a687866e76d4271a1abc"; + getInstance().setRpcPort(PublicMethod.chooseRandomPort()); + getInstance().setRpcOnSolidityPort(PublicMethod.chooseRandomPort()); + getInstance().setRpcOnPBFTPort(PublicMethod.chooseRandomPort()); + String fullNode = String.format("%s:%d", getInstance().getNodeDiscoveryBindIp(), + getInstance().getRpcPort()); + String solidityNode = String.format("%s:%d", getInstance().getNodeDiscoveryBindIp(), + getInstance().getRpcOnSolidityPort()); + String pBFTNode = String.format("%s:%d", getInstance().getNodeDiscoveryBindIp(), + getInstance().getRpcOnPBFTPort()); + + ManagedChannel channelFull = ManagedChannelBuilder.forTarget(fullNode) + .usePlaintext() + .build(); + ManagedChannel channelPBFT = ManagedChannelBuilder.forTarget(pBFTNode) + .usePlaintext() + .build(); + ManagedChannel channelSolidity = ManagedChannelBuilder.forTarget(solidityNode) + .usePlaintext() + .build(); + context = new TronApplicationContext(DefaultConfig.class); + databaseBlockingStubFull = DatabaseGrpc.newBlockingStub(channelFull); + databaseBlockingStubSolidity = DatabaseGrpc.newBlockingStub(channelSolidity); + databaseBlockingStubPBFT = DatabaseGrpc.newBlockingStub(channelPBFT); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + blockingStubSolidity = WalletSolidityGrpc.newBlockingStub(channelSolidity); + blockingStubPBFT = WalletSolidityGrpc.newBlockingStub(channelPBFT); + + RpcApiService rpcApiService = context.getBean(RpcApiService.class); + RpcApiServiceOnSolidity rpcApiServiceOnSolidity = + context.getBean(RpcApiServiceOnSolidity.class); + RpcApiServiceOnPBFT rpcApiServiceOnPBFT = context.getBean(RpcApiServiceOnPBFT.class); + + Manager manager = context.getBean(Manager.class); + + ownerAddress = ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)); + AccountCapsule ownerCapsule = new AccountCapsule(ByteString.copyFromUtf8("owner"), + ownerAddress, Protocol.AccountType.Normal, 10_000_000_000L); + manager.getAccountStore().put(ownerCapsule.createDbKey(), ownerCapsule); + manager.getDynamicPropertiesStore().saveAllowShieldedTransaction(1); + manager.getDynamicPropertiesStore().saveAllowShieldedTRC20Transaction(1); + Application appTest = ApplicationFactory.create(context); + appTest.addService(rpcApiService); + appTest.addService(rpcApiServiceOnSolidity); + appTest.addService(rpcApiServiceOnPBFT); + appTest.startup(); + } + + @AfterClass + public static void destroy() { + context.close(); + Args.clearParam(); + } + + @Test + public void testGetBlockByNum() { + NumberMessage message = NumberMessage.newBuilder().setNum(0).build(); + assertNotNull(databaseBlockingStubFull.getBlockByNum(message)); + assertNotNull(databaseBlockingStubSolidity.getBlockByNum(message)); + assertNotNull(databaseBlockingStubPBFT.getBlockByNum(message)); + assertNotNull(blockingStubFull.getBlockByNum(message)); + assertNotNull(blockingStubSolidity.getBlockByNum(message)); + assertNotNull(blockingStubPBFT.getBlockByNum(message)); + + assertNotNull(blockingStubFull.getBlockByNum2(message)); + assertNotNull(blockingStubSolidity.getBlockByNum2(message)); + assertNotNull(blockingStubPBFT.getBlockByNum2(message)); + } + + @Test + public void testGetDynamicProperties() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(databaseBlockingStubFull.getDynamicProperties(message)); + assertNotNull(databaseBlockingStubSolidity.getDynamicProperties(message)); + assertNotNull(databaseBlockingStubPBFT.getDynamicProperties(message)); + } + + @Test + public void testGetAccount() { + Account account = Account.newBuilder().setAddress(ownerAddress).build(); + assertNotNull(blockingStubFull.getAccount(account)); + assertNotNull(blockingStubSolidity.getAccount(account)); + assertNotNull(blockingStubPBFT.getAccount(account)); + } + + @Test + public void testGetAccountById() { + Account account = Account.newBuilder().setAccountId(ownerAddress).build(); + assertNotNull(blockingStubFull.getAccountById(account)); + assertNotNull(blockingStubSolidity.getAccountById(account)); + assertNotNull(blockingStubPBFT.getAccountById(account)); + } + + @Test + public void testListWitnesses() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.listWitnesses(message)); + assertNotNull(blockingStubSolidity.listWitnesses(message)); + assertNotNull(blockingStubPBFT.listWitnesses(message)); + } + + @Test + public void testGetAssetIssueList() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getAssetIssueList(message)); + assertNotNull(blockingStubSolidity.getAssetIssueList(message)); + assertNotNull(blockingStubPBFT.getAssetIssueList(message)); + } + + @Test + public void testGetPaginatedAssetIssueList() { + PaginatedMessage paginatedMessage = PaginatedMessage.newBuilder() + .setOffset(0).setLimit(5).build(); + assertNotNull(blockingStubFull.getPaginatedAssetIssueList(paginatedMessage)); + assertNotNull(blockingStubSolidity.getPaginatedAssetIssueList(paginatedMessage)); + assertNotNull(blockingStubPBFT.getPaginatedAssetIssueList(paginatedMessage)); + } + + @Test + public void testGetAssetIssueByName() { + BytesMessage message = BytesMessage.newBuilder().setValue(ownerAddress).build(); + assertNotNull(blockingStubFull.getAssetIssueByName(message)); + assertNotNull(blockingStubSolidity.getAssetIssueByName(message)); + assertNotNull(blockingStubPBFT.getAssetIssueByName(message)); + } + + @Test + public void testGetAssetIssueListByName() { + BytesMessage message = BytesMessage.newBuilder().setValue(ownerAddress).build(); + assertNotNull(blockingStubFull.getAssetIssueListByName(message)); + assertNotNull(blockingStubSolidity.getAssetIssueListByName(message)); + assertNotNull(blockingStubPBFT.getAssetIssueListByName(message)); + } + + @Test + public void testGetAssetIssueById() { + BytesMessage message = BytesMessage.newBuilder().setValue(ownerAddress).build(); + assertNotNull(blockingStubFull.getAssetIssueById(message)); + assertNotNull(blockingStubSolidity.getAssetIssueById(message)); + assertNotNull(blockingStubPBFT.getAssetIssueById(message)); + } + + @Test + public void testGetBlockReference() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(databaseBlockingStubFull.getBlockReference(message)); + assertNotNull(databaseBlockingStubSolidity.getBlockReference(message)); + assertNotNull(databaseBlockingStubPBFT.getBlockReference(message)); + } + + @Test + public void testGetNowBlock() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(databaseBlockingStubFull.getNowBlock(message)); + assertNotNull(databaseBlockingStubSolidity.getNowBlock(message)); + assertNotNull(databaseBlockingStubPBFT.getNowBlock(message)); + assertNotNull(blockingStubFull.getNowBlock(message)); + assertNotNull(blockingStubSolidity.getNowBlock(message)); + assertNotNull(blockingStubPBFT.getNowBlock(message)); + + assertNotNull(blockingStubFull.getNowBlock2(message)); + assertNotNull(blockingStubSolidity.getNowBlock2(message)); + assertNotNull(blockingStubPBFT.getNowBlock2(message)); + } + + @Test + public void testGetDelegatedResource() { + DelegatedResourceMessage message = DelegatedResourceMessage.newBuilder() + .setFromAddress(ownerAddress) + .setToAddress(ownerAddress).build(); + assertNotNull(blockingStubFull.getDelegatedResource(message)); + assertNotNull(blockingStubSolidity.getDelegatedResource(message)); + assertNotNull(blockingStubPBFT.getDelegatedResource(message)); + + assertNotNull(blockingStubFull.getDelegatedResourceV2(message)); + assertNotNull(blockingStubSolidity.getDelegatedResourceV2(message)); + assertNotNull(blockingStubPBFT.getDelegatedResourceV2(message)); + } + + @Test + public void testGetDelegatedResourceAccountIndex() { + BytesMessage message = BytesMessage.newBuilder().setValue(ownerAddress).build(); + assertNotNull(blockingStubFull.getDelegatedResourceAccountIndex(message)); + assertNotNull(blockingStubSolidity.getDelegatedResourceAccountIndex(message)); + assertNotNull(blockingStubPBFT.getDelegatedResourceAccountIndex(message)); + + assertNotNull(blockingStubFull.getDelegatedResourceAccountIndexV2(message)); + assertNotNull(blockingStubSolidity.getDelegatedResourceAccountIndexV2(message)); + assertNotNull(blockingStubPBFT.getDelegatedResourceAccountIndexV2(message)); + } + + @Test + public void testGetCanDelegatedMaxSize() { + CanDelegatedMaxSizeRequestMessage message = CanDelegatedMaxSizeRequestMessage.newBuilder() + .setType(0).setOwnerAddress(ownerAddress).build(); + assertNotNull(blockingStubFull.getCanDelegatedMaxSize(message)); + assertNotNull(blockingStubSolidity.getCanDelegatedMaxSize(message)); + assertNotNull(blockingStubPBFT.getCanDelegatedMaxSize(message)); + } + + @Test + public void testGetAvailableUnfreezeCount() { + GetAvailableUnfreezeCountRequestMessage message = GetAvailableUnfreezeCountRequestMessage + .newBuilder().setOwnerAddress(ownerAddress).build(); + assertNotNull(blockingStubFull.getAvailableUnfreezeCount(message)); + assertNotNull(blockingStubSolidity.getAvailableUnfreezeCount(message)); + assertNotNull(blockingStubPBFT.getAvailableUnfreezeCount(message)); + } + + @Test + public void testGetCanWithdrawUnfreezeAmount() { + CanWithdrawUnfreezeAmountRequestMessage message = CanWithdrawUnfreezeAmountRequestMessage + .newBuilder().setOwnerAddress(ownerAddress).setTimestamp(0).build(); + assertNotNull(blockingStubFull.getCanWithdrawUnfreezeAmount(message)); + assertNotNull(blockingStubSolidity.getCanWithdrawUnfreezeAmount(message)); + assertNotNull(blockingStubPBFT.getCanWithdrawUnfreezeAmount(message)); + } + + @Test + public void testGetExchangeById() { + BytesMessage message = BytesMessage.newBuilder().setValue(ownerAddress).build(); + assertNotNull(blockingStubFull.getExchangeById(message)); + assertNotNull(blockingStubSolidity.getExchangeById(message)); + assertNotNull(blockingStubPBFT.getExchangeById(message)); + } + + @Test + public void testListExchanges() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.listExchanges(message)); + assertNotNull(blockingStubSolidity.listExchanges(message)); + assertNotNull(blockingStubPBFT.listExchanges(message)); + } + + @Test + public void testGetTransactionCountByBlockNum() { + NumberMessage message = NumberMessage.newBuilder().setNum(0).build(); + assertNotNull(blockingStubFull.getTransactionCountByBlockNum(message)); + assertNotNull(blockingStubSolidity.getTransactionCountByBlockNum(message)); + assertNotNull(blockingStubPBFT.getTransactionCountByBlockNum(message)); + } + + @Test + public void testListNodes() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.listNodes(message)); + } + + @Test + public void testGetTransactionById() { + BytesMessage message = BytesMessage.newBuilder().setValue(ownerAddress).build(); + assertNotNull(blockingStubFull.getTransactionById(message)); + assertNotNull(blockingStubSolidity.getTransactionById(message)); + assertNotNull(blockingStubPBFT.getTransactionById(message)); + } + + @Test + public void testGetTransactionInfoById() { + BytesMessage message = BytesMessage.newBuilder().setValue(ownerAddress).build(); + assertNotNull(blockingStubFull.getTransactionInfoById(message)); + assertNotNull(blockingStubSolidity.getTransactionInfoById(message)); + assertNotNull(blockingStubPBFT.getTransactionInfoById(message)); + } + + @Test + public void testGetRewardInfo() { + BytesMessage message = BytesMessage.newBuilder().setValue(ownerAddress).build(); + assertNotNull(blockingStubFull.getRewardInfo(message)); + assertNotNull(blockingStubSolidity.getRewardInfo(message)); + assertNotNull(blockingStubPBFT.getRewardInfo(message)); + } + + @Test + public void testGetBrokerageInfo() { + BytesMessage message = BytesMessage.newBuilder().setValue(ownerAddress).build(); + assertNotNull(blockingStubFull.getBrokerageInfo(message)); + assertNotNull(blockingStubSolidity.getBrokerageInfo(message)); + assertNotNull(blockingStubPBFT.getBrokerageInfo(message)); + } + + @Test + public void testGetBurnTrx() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getBurnTrx(message)); + assertNotNull(blockingStubSolidity.getBurnTrx(message)); + assertNotNull(blockingStubPBFT.getBurnTrx(message)); + } + + // @Test + // public void testGetMerkleTreeVoucherInfo() { + // OutputPoint outputPoint = OutputPoint.newBuilder().build(); + // OutputPointInfo message = OutputPointInfo.newBuilder() + // .addOutPoints(outputPoint).setBlockNum(0).build(); + // assertNotNull(blockingStubFull.getMerkleTreeVoucherInfo(message)); + // assertNotNull(blockingStubSolidity.getMerkleTreeVoucherInfo(message)); + // assertNotNull(blockingStubPBFT.getMerkleTreeVoucherInfo(message)); + // } + + @Test + public void testScanNoteByIvk() { + IvkDecryptParameters message = IvkDecryptParameters.newBuilder() + .setStartBlockIndex(0) + .setEndBlockIndex(1) + .build(); + assertNotNull(blockingStubFull.scanNoteByIvk(message)); + assertNotNull(blockingStubSolidity.scanNoteByIvk(message)); + assertNotNull(blockingStubPBFT.scanNoteByIvk(message)); + } + + @Test + public void testScanAndMarkNoteByIvk() { + IvkDecryptAndMarkParameters message = IvkDecryptAndMarkParameters.newBuilder() + .setStartBlockIndex(0) + .setEndBlockIndex(1) + .build(); + assertNotNull(blockingStubFull.scanAndMarkNoteByIvk(message)); + assertNotNull(blockingStubSolidity.scanAndMarkNoteByIvk(message)); + assertNotNull(blockingStubPBFT.scanAndMarkNoteByIvk(message)); + } + + @Test + public void test08ScanNoteByOvk() { + OvkDecryptParameters message = OvkDecryptParameters.newBuilder() + .setStartBlockIndex(0) + .setEndBlockIndex(1) + .setOvk(ovk) + .build(); + assertNotNull(blockingStubFull.scanNoteByOvk(message)); + assertNotNull(blockingStubSolidity.scanNoteByOvk(message)); + assertNotNull(blockingStubPBFT.scanNoteByOvk(message)); + } + + // @Test + // public void testIsSpend() { + // NoteParameters message = NoteParameters.newBuilder() + // .build(); + // assertNotNull(blockingStubFull.isSpend(message)); + // assertNotNull(blockingStubSolidity.isSpend(message)); + // assertNotNull(blockingStubPBFT.isSpend(message)); + // } + + @Test + public void testScanShieldedTRC20NotesByIvk() { + IvkDecryptTRC20Parameters message = IvkDecryptTRC20Parameters.newBuilder() + .setStartBlockIndex(1) + .setEndBlockIndex(10) + .build(); + assertNotNull(blockingStubFull.scanShieldedTRC20NotesByIvk(message)); + assertNotNull(blockingStubSolidity.scanShieldedTRC20NotesByIvk(message)); + assertNotNull(blockingStubPBFT.scanShieldedTRC20NotesByIvk(message)); + } + + @Test + public void testScanShieldedTRC20NotesByOvk() { + OvkDecryptTRC20Parameters message = OvkDecryptTRC20Parameters.newBuilder() + .setStartBlockIndex(1) + .setEndBlockIndex(10) + .build(); + assertNotNull(blockingStubFull.scanShieldedTRC20NotesByOvk(message)); + assertNotNull(blockingStubSolidity.scanShieldedTRC20NotesByOvk(message)); + assertNotNull(blockingStubPBFT.scanShieldedTRC20NotesByOvk(message)); + } + + // @Test + // public void testIsShieldedTRC20ContractNoteSpent() { + // NfTRC20Parameters message = NfTRC20Parameters.newBuilder().build(); + // assertNotNull(blockingStubFull.isShieldedTRC20ContractNoteSpent(message)); + // assertNotNull(blockingStubSolidity.isShieldedTRC20ContractNoteSpent(message)); + // assertNotNull(blockingStubPBFT.isShieldedTRC20ContractNoteSpent(message)); + // } + + // @Test + // public void testGetTriggerInputForShieldedTRC20Contract() { + // ShieldedTRC20TriggerContractParameters message = + // ShieldedTRC20TriggerContractParameters.newBuilder() + // .setAmount("1000") + // .build(); + // assertNotNull(blockingStubFull.getTriggerInputForShieldedTRC20Contract(message)); + // } + + @Test + public void testUpdateBrokerage() { + UpdateBrokerageContract message = UpdateBrokerageContract.newBuilder() + .setOwnerAddress(ownerAddress).setBrokerage(1).build(); + assertNotNull(blockingStubFull.updateBrokerage(message)); + } + + @Test + public void testCreateCommonTransaction() { + UpdateBrokerageContract.Builder updateBrokerageContract = UpdateBrokerageContract.newBuilder(); + updateBrokerageContract.setOwnerAddress( + ByteString.copyFrom(Objects + .requireNonNull(decodeFromBase58Check("TN3zfjYUmMFK3ZsHSsrdJoNRtGkQmZLBLz")))) + .setBrokerage(10); + Transaction.Builder transaction = Transaction.newBuilder(); + Transaction.raw.Builder raw = Transaction.raw.newBuilder(); + Transaction.Contract.Builder contract = Transaction.Contract.newBuilder(); + contract.setType(Transaction.Contract.ContractType.UpdateBrokerageContract) + .setParameter(Any.pack(updateBrokerageContract.build())); + raw.addContract(contract.build()); + transaction.setRawData(raw.build()); + assertNotNull(blockingStubFull.createCommonTransaction(transaction.build())); + } + + @Test + public void testGetTransactionInfoByBlockNum() { + NumberMessage message = NumberMessage.newBuilder().setNum(1).build(); + assertNotNull(blockingStubFull.getTransactionInfoByBlockNum(message)); + assertNotNull(blockingStubSolidity.getTransactionInfoByBlockNum(message)); + } + + @Test + public void testMarketSellAsset() { + String sellTokenId = "123"; + long sellTokenQuant = 100000000L; + String buyTokenId = "456"; + long buyTokenQuant = 200000000L; + MarketSellAssetContract message = MarketSellAssetContract.newBuilder() + .setOwnerAddress(ownerAddress) + .setBuyTokenQuantity(buyTokenQuant) + .setBuyTokenId(ByteString.copyFrom(buyTokenId.getBytes())) + .setSellTokenQuantity(sellTokenQuant) + .setSellTokenId(ByteString.copyFrom(sellTokenId.getBytes())) + .build(); + assertNotNull(blockingStubFull.marketSellAsset(message)); + } + + @Test + public void testMarketCancelOrder() { + MarketCancelOrderContract message = MarketCancelOrderContract.newBuilder() + .setOwnerAddress(ownerAddress) + .setOrderId(ByteString.copyFromUtf8("123")) + .build(); + assertNotNull(blockingStubFull.marketCancelOrder(message)); + } + + @Test + public void testGetMarketOrderByAccount() { + BytesMessage message = BytesMessage.newBuilder().setValue(ownerAddress).build(); + assertNotNull(blockingStubFull.getMarketOrderByAccount(message)); + assertNotNull(blockingStubSolidity.getMarketOrderByAccount(message)); + assertNotNull(blockingStubPBFT.getMarketOrderByAccount(message)); + } + + // @Test + // public void testGetMarketOrderById() { + // BytesMessage message = BytesMessage.newBuilder().setValue(ownerAddress).build(); + // assertNotNull(blockingStubFull.getMarketOrderById(message)); + // assertNotNull(blockingStubSolidity.getMarketOrderById(message)); + // assertNotNull(blockingStubPBFT.getMarketOrderById(message)); + // } + + @Test + public void testGetMarketPriceByPair() { + MarketOrderPair marketOrderPair = getMarketOrderPair(); + assertNotNull(blockingStubFull.getMarketPriceByPair(marketOrderPair)); + assertNotNull(blockingStubSolidity.getMarketPriceByPair(marketOrderPair)); + assertNotNull(blockingStubPBFT.getMarketPriceByPair(marketOrderPair)); + } + + @Test + public void testGetMarketOrderListByPair() { + MarketOrderPair marketOrderPair = getMarketOrderPair(); + assertNotNull(blockingStubFull.getMarketOrderListByPair(marketOrderPair)); + assertNotNull(blockingStubSolidity.getMarketOrderListByPair(marketOrderPair)); + assertNotNull(blockingStubPBFT.getMarketOrderListByPair(marketOrderPair)); + } + + private static MarketOrderPair getMarketOrderPair() { + ByteString buyTokenId = ByteString.copyFrom(Objects + .requireNonNull(ByteArray.fromString("_"))); + ByteString sellTokenId = ByteString.copyFrom(Objects + .requireNonNull(ByteArray.fromString("_"))); + return MarketOrderPair.newBuilder() + .setBuyTokenId(buyTokenId) + .setSellTokenId(sellTokenId).build(); + } + + @Test + public void testGetMarketPairList() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getMarketPairList(message)); + assertNotNull(blockingStubSolidity.getMarketPairList(message)); + assertNotNull(blockingStubPBFT.getMarketPairList(message)); + } + + @Test + public void testGetTransactionFromPending() { + BalanceContract.TransferContract tc = + BalanceContract.TransferContract.newBuilder() + .setAmount(10) + .setOwnerAddress(ByteString.copyFromUtf8("aaa")) + .setToAddress(ByteString.copyFromUtf8("bbb")) + .build(); + TransactionCapsule trx = new TransactionCapsule(tc, TransferContract); + BytesMessage message = BytesMessage.newBuilder() + .setValue(trx.getTransactionId().getByteString()).build(); + assertNotNull(blockingStubFull.getTransactionFromPending(message)); + } + + @Test + public void testGetTransactionListFromPending() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getTransactionListFromPending(message)); + } + + @Test + public void testGetPendingSize() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getPendingSize(message)); + } + + @Test + public void testGetBlock() { + BlockReq message = BlockReq.newBuilder().setIdOrNum("0").build(); + assertNotNull(blockingStubFull.getBlock(message)); + assertNotNull(blockingStubSolidity.getBlock(message)); + assertNotNull(blockingStubPBFT.getBlock(message)); + } + + @Test + public void testGetAccountBalance() { + AccountIdentifier accountIdentifier = AccountIdentifier.newBuilder() + .setAddress(ownerAddress).build(); + BlockIdentifier blockIdentifier = getBlockIdentifier(); + AccountBalanceRequest message = AccountBalanceRequest.newBuilder() + .setAccountIdentifier(accountIdentifier) + .setBlockIdentifier(blockIdentifier) + .build(); + assertNotNull(blockingStubFull.getAccountBalance(message)); + } + + @Test + public void testGetBlockBalanceTrace() { + BlockIdentifier blockIdentifier = getBlockIdentifier(); + assertNotNull(blockingStubFull.getBlockBalanceTrace(blockIdentifier)); + } + + private static BlockIdentifier getBlockIdentifier() { + Block nowBlock = blockingStubFull.getNowBlock(EmptyMessage.newBuilder().build()); + raw rawData = nowBlock.getBlockHeader().getRawData(); + BlockCapsule.BlockId blockId = + new BlockCapsule.BlockId(Sha256Hash.of(getInstance().isECKeyCryptoEngine(), + rawData.toByteArray()), + rawData.getNumber()); + return BlockIdentifier.newBuilder() + .setNumber(rawData.getNumber()) + .setHash(blockId.getByteString()) + .build(); + } + + @Test + public void testCreateTransaction() { + BalanceContract.TransferContract transferContract = BalanceContract.TransferContract + .newBuilder() + .setOwnerAddress(ownerAddress) + .setToAddress(ownerAddress) + .setAmount(1000) + .build(); + assertNotNull(blockingStubFull.createTransaction(transferContract)); + assertNotNull(blockingStubFull.createTransaction2(transferContract)); + } + + @Test + public void testGetTransactionSignWeight() { + UpdateBrokerageContract.Builder updateBrokerageContract = UpdateBrokerageContract.newBuilder(); + updateBrokerageContract.setOwnerAddress( + ByteString.copyFrom(Objects + .requireNonNull(decodeFromBase58Check("TN3zfjYUmMFK3ZsHSsrdJoNRtGkQmZLBLz")))) + .setBrokerage(10); + Transaction.Builder transaction = Transaction.newBuilder(); + Transaction.raw.Builder raw = Transaction.raw.newBuilder(); + Transaction.Contract.Builder contract = Transaction.Contract.newBuilder(); + contract.setType(Transaction.Contract.ContractType.UpdateBrokerageContract) + .setParameter(Any.pack(updateBrokerageContract.build())); + raw.addContract(contract.build()); + transaction.setRawData(raw.build()); + assertNotNull(blockingStubFull.getTransactionSignWeight(transaction.build())); + } + + @Test + public void testGetTransactionApprovedList() { + UpdateBrokerageContract.Builder updateBrokerageContract = UpdateBrokerageContract.newBuilder(); + updateBrokerageContract.setOwnerAddress( + ByteString.copyFrom(Objects + .requireNonNull(decodeFromBase58Check("TN3zfjYUmMFK3ZsHSsrdJoNRtGkQmZLBLz")))) + .setBrokerage(10); + Transaction.Builder transaction = Transaction.newBuilder(); + Transaction.raw.Builder raw = Transaction.raw.newBuilder(); + Transaction.Contract.Builder contract = Transaction.Contract.newBuilder(); + contract.setType(Transaction.Contract.ContractType.UpdateBrokerageContract) + .setParameter(Any.pack(updateBrokerageContract.build())); + raw.addContract(contract.build()); + transaction.setRawData(raw.build()); + assertNotNull(blockingStubFull.getTransactionApprovedList(transaction.build())); + } + + @Test + public void testCreateAssetIssue() { + AssetIssueContract assetIssueContract = AssetIssueContract.newBuilder() + .build(); + assertNotNull(blockingStubFull.createAssetIssue(assetIssueContract)); + assertNotNull(blockingStubFull.createAssetIssue2(assetIssueContract)); + } + + @Test + public void testUnfreezeAsset() { + UnfreezeAssetContract message = UnfreezeAssetContract.newBuilder().build(); + assertNotNull(blockingStubFull.unfreezeAsset(message)); + assertNotNull(blockingStubFull.unfreezeAsset2(message)); + } + + @Test + public void testVoteWitnessAccount() { + VoteWitnessContract message = VoteWitnessContract.newBuilder().build(); + assertNotNull(blockingStubFull.voteWitnessAccount(message)); + assertNotNull(blockingStubFull.voteWitnessAccount2(message)); + } + + @Test + public void testUpdateSetting() { + UpdateSettingContract message = UpdateSettingContract.newBuilder().build(); + assertNotNull(blockingStubFull.updateSetting(message)); + } + + @Test + public void testUpdateEnergyLimit() { + UpdateEnergyLimitContract message = UpdateEnergyLimitContract.newBuilder().build(); + assertNotNull(blockingStubFull.updateEnergyLimit(message)); + } + + @Test + public void testClearContractABI() { + ClearABIContract message = ClearABIContract.newBuilder().build(); + assertNotNull(blockingStubFull.clearContractABI(message)); + } + + @Test + public void testCreateWitness() { + WitnessCreateContract message = WitnessCreateContract.newBuilder().build(); + assertNotNull(blockingStubFull.createWitness(message)); + assertNotNull(blockingStubFull.createWitness2(message)); + } + + @Test + public void testCreateAccount() { + AccountCreateContract message = AccountCreateContract.newBuilder().build(); + assertNotNull(blockingStubFull.createAccount(message)); + assertNotNull(blockingStubFull.createAccount2(message)); + } + + @Test + public void testUpdateWitness() { + WitnessUpdateContract message = WitnessUpdateContract.newBuilder().build(); + assertNotNull(blockingStubFull.updateWitness(message)); + assertNotNull(blockingStubFull.updateWitness2(message)); + } + + @Test + public void testUpdateAccount() { + AccountUpdateContract message = AccountUpdateContract.newBuilder().build(); + assertNotNull(blockingStubFull.updateAccount(message)); + assertNotNull(blockingStubFull.updateAccount2(message)); + } + + @Test + public void testSetAccountId() { + SetAccountIdContract message = SetAccountIdContract.newBuilder().build(); + assertNotNull(blockingStubFull.setAccountId(message)); + } + + @Test + public void testUpdateAsset() { + UpdateAssetContract message = UpdateAssetContract.newBuilder().build(); + assertNotNull(blockingStubFull.updateAsset(message)); + assertNotNull(blockingStubFull.updateAsset2(message)); + } + + @Test + public void testFreezeBalance2() { + FreezeBalanceContract message = FreezeBalanceContract.newBuilder().build(); + assertNotNull(blockingStubFull.freezeBalance(message)); + assertNotNull(blockingStubFull.freezeBalance2(message)); + } + + @Test + public void testFreezeBalanceV2() { + FreezeBalanceV2Contract message = FreezeBalanceV2Contract.newBuilder().build(); + assertNotNull(blockingStubFull.freezeBalanceV2(message)); + } + + @Test + public void testUnfreezeBalance() { + UnfreezeBalanceContract message = UnfreezeBalanceContract.newBuilder().build(); + assertNotNull(blockingStubFull.unfreezeBalance(message)); + assertNotNull(blockingStubFull.unfreezeBalance2(message)); + } + + @Test + public void testUnfreezeBalanceV2() { + UnfreezeBalanceV2Contract message = UnfreezeBalanceV2Contract.newBuilder().build(); + assertNotNull(blockingStubFull.unfreezeBalanceV2(message)); + } + + @Test + public void testWithdrawBalance() { + WithdrawBalanceContract message = WithdrawBalanceContract.newBuilder().build(); + assertNotNull(blockingStubFull.withdrawBalance(message)); + assertNotNull(blockingStubFull.withdrawBalance2(message)); + } + + @Test + public void testWithdrawExpireUnfreeze() { + WithdrawExpireUnfreezeContract message = WithdrawExpireUnfreezeContract.newBuilder().build(); + assertNotNull(blockingStubFull.withdrawExpireUnfreeze(message)); + } + + @Test + public void testDelegateResource() { + DelegateResourceContract message = DelegateResourceContract.newBuilder().build(); + assertNotNull(blockingStubFull.delegateResource(message)); + } + + @Test + public void testUnDelegateResource() { + UnDelegateResourceContract message = UnDelegateResourceContract.newBuilder().build(); + assertNotNull(blockingStubFull.unDelegateResource(message)); + } + + @Test + public void testCancelAllUnfreezeV2() { + CancelAllUnfreezeV2Contract message = CancelAllUnfreezeV2Contract.newBuilder().build(); + assertNotNull(blockingStubFull.cancelAllUnfreezeV2(message)); + } + + @Test + public void testProposalCreate() { + ProposalCreateContract message = ProposalCreateContract.newBuilder().build(); + assertNotNull(blockingStubFull.proposalCreate(message)); + } + + @Test + public void testProposalApprove() { + ProposalApproveContract message = ProposalApproveContract.newBuilder().build(); + assertNotNull(blockingStubFull.proposalApprove(message)); + } + + @Test + public void testProposalDelete() { + ProposalDeleteContract message = ProposalDeleteContract.newBuilder().build(); + assertNotNull(blockingStubFull.proposalDelete(message)); + } + + @Test + public void testExchangeCreate() { + ExchangeCreateContract message = ExchangeCreateContract.newBuilder().build(); + assertNotNull(blockingStubFull.exchangeCreate(message)); + } + + @Test + public void testExchangeInject() { + ExchangeInjectContract message = ExchangeInjectContract.newBuilder().build(); + assertNotNull(blockingStubFull.exchangeInject(message)); + } + + @Test + public void testExchangeWithdraw() { + ExchangeWithdrawContract message = ExchangeWithdrawContract.newBuilder().build(); + assertNotNull(blockingStubFull.exchangeWithdraw(message)); + } + + @Test + public void testExchangeTransaction() { + ExchangeTransactionContract message = ExchangeTransactionContract.newBuilder().build(); + assertNotNull(blockingStubFull.exchangeTransaction(message)); + } + + @Test + public void testTransferAsset() { + TransferAssetContract message = TransferAssetContract.newBuilder().build(); + assertNotNull(blockingStubFull.transferAsset(message)); + assertNotNull(blockingStubFull.transferAsset2(message)); + } + + @Test + public void testParticipateAssetIssue() { + ParticipateAssetIssueContract message = ParticipateAssetIssueContract.newBuilder().build(); + assertNotNull(blockingStubFull.participateAssetIssue(message)); + assertNotNull(blockingStubFull.participateAssetIssue2(message)); + } + + @Test + public void testGetAssetIssueByAccount() { + Account message = Account.newBuilder().build(); + assertNotNull(blockingStubFull.getAssetIssueByAccount(message)); + } + + @Test + public void testGetAccountNet() { + Account message = Account.newBuilder().build(); + assertNotNull(blockingStubFull.getAccountNet(message)); + } + + @Test + public void testGetAccountResource() { + Account message = Account.newBuilder().build(); + assertNotNull(blockingStubFull.getAccountResource(message)); + } + + @Test + public void testGetBlockById() { + BytesMessage message = BytesMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getBlockById(message)); + } + + @Test + public void testGetProposalById() { + BytesMessage message = BytesMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getProposalById(message)); + } + + @Test + public void testGetBlockByLimitNext() { + BlockLimit message = BlockLimit.newBuilder().build(); + assertNotNull(blockingStubFull.getBlockByLimitNext(message)); + assertNotNull(blockingStubFull.getBlockByLimitNext2(message)); + } + + @Test + public void testGetBlockByLatestNum() { + NumberMessage message = NumberMessage.newBuilder().setNum(0).build(); + assertNotNull(blockingStubFull.getBlockByLatestNum(message)); + assertNotNull(blockingStubFull.getBlockByLatestNum2(message)); + } + + @Test + public void testDeployContract() { + CreateSmartContract message = CreateSmartContract.newBuilder().build(); + assertNotNull(blockingStubFull.deployContract(message)); + } + + @Test + public void testTotalTransaction() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.totalTransaction(message)); + } + + @Test + public void testGetNextMaintenanceTime() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getNextMaintenanceTime(message)); + } + + @Test + public void testTriggerContract() { + TriggerSmartContract message = TriggerSmartContract.newBuilder().build(); + assertNotNull(blockingStubFull.estimateEnergy(message)); + assertNotNull(blockingStubSolidity.estimateEnergy(message)); + assertNotNull(blockingStubPBFT.estimateEnergy(message)); + } + + @Test + public void testEstimateEnergy() { + TriggerSmartContract message = TriggerSmartContract.newBuilder().build(); + assertNotNull(blockingStubFull.estimateEnergy(message)); + } + + @Test + public void testTriggerConstantContract() { + TriggerSmartContract message = TriggerSmartContract.newBuilder().build(); + assertNotNull(blockingStubFull.triggerConstantContract(message)); + } + + @Test + public void testGetContract() { + BytesMessage message = BytesMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getContract(message)); + } + + @Test + public void testGetContractInfo() { + BytesMessage message = BytesMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getContractInfo(message)); + } + + @Test + public void testListProposals() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.listProposals(message)); + } + + @Test + public void testGetBandwidthPrices() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getBandwidthPrices(message)); + assertNotNull(blockingStubSolidity.getBandwidthPrices(message)); + assertNotNull(blockingStubPBFT.getBandwidthPrices(message)); + } + + @Test + public void testGetEnergyPrices() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getEnergyPrices(message)); + assertNotNull(blockingStubSolidity.getEnergyPrices(message)); + assertNotNull(blockingStubPBFT.getEnergyPrices(message)); + } + + @Test + public void testGetMemoFee() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getMemoFee(message)); + } + + @Test + public void testGetPaginatedProposalList() { + PaginatedMessage message = PaginatedMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getPaginatedProposalList(message)); + } + + @Test + public void testGetPaginatedExchangeList() { + PaginatedMessage message = PaginatedMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getPaginatedExchangeList(message)); + } + + @Test + public void testGetChainParameters() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getChainParameters(message)); + } + + @Test + public void testGetNodeInfo() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getNodeInfo(message)); + } + + @Test + public void testAccountPermissionUpdate() { + AccountPermissionUpdateContract message = AccountPermissionUpdateContract.newBuilder().build(); + assertNotNull(blockingStubFull.accountPermissionUpdate(message)); + } + + @Test + public void testCreateShieldedTransaction() { + PrivateParameters message = PrivateParameters.newBuilder().build(); + assertNotNull(blockingStubFull.createShieldedTransaction(message)); + } + + @Test + public void testCreateShieldedTransactionWithoutSpendAuthSig() { + PrivateParametersWithoutAsk message = PrivateParametersWithoutAsk.newBuilder().build(); + assertNotNull(blockingStubFull.createShieldedTransactionWithoutSpendAuthSig(message)); + } + + @Test + public void testGetNewShieldedAddress() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getNewShieldedAddress(message)); + } + + @Test + public void test01GetSpendingKey() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + BytesMessage spendingKey = blockingStubFull.getSpendingKey(message); + assertNotNull(spendingKey); + sk = spendingKey.getValue(); + } + + @Test + public void testGetRcm() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getRcm(message)); + } + + @Test + public void test02GetExpandedSpendingKey() { + BytesMessage message = BytesMessage.newBuilder().setValue(sk).build(); + ExpandedSpendingKeyMessage eskMessage = blockingStubFull.getExpandedSpendingKey(message); + assertNotNull(eskMessage); + ask = eskMessage.getAsk(); + nsk = eskMessage.getNsk(); + ovk = eskMessage.getOvk(); + } + + @Test + public void test03GetAkFromAsk() { + BytesMessage message = BytesMessage.newBuilder().setValue(ask).build(); + BytesMessage akMessage = blockingStubFull.getAkFromAsk(message); + assertNotNull(akMessage); + ak = akMessage.getValue(); + } + + @Test + public void test04GetNkFromNsk() { + BytesMessage message = BytesMessage.newBuilder().setValue(nsk).build(); + BytesMessage nkFromNsk = blockingStubFull.getNkFromNsk(message); + assertNotNull(nkFromNsk); + nk = nkFromNsk.getValue(); + } + + @Test + public void test05GetIncomingViewingKey() { + ViewingKeyMessage viewingKeyMessage = ViewingKeyMessage.newBuilder() + .setAk(ak) + .setNk(nk) + .build(); + IncomingViewingKeyMessage incomingViewingKey = blockingStubFull + .getIncomingViewingKey(viewingKeyMessage); + assertNotNull(incomingViewingKey); + ivk = incomingViewingKey.getIvk(); + } + + @Test + public void test06GetDiversifier() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + DiversifierMessage diversifier = blockingStubFull.getDiversifier(message); + assertNotNull(diversifier); + d = diversifier.getD(); + } + + @Test + public void test07GetZenPaymentAddress() { + DiversifierMessage diversifierMessage = DiversifierMessage.newBuilder().setD(d).build(); + IncomingViewingKeyMessage incomingViewingKey = IncomingViewingKeyMessage.newBuilder() + .setIvk(ivk).build(); + IncomingViewingKeyDiversifierMessage message = IncomingViewingKeyDiversifierMessage + .newBuilder() + .setD(diversifierMessage) + .setIvk(incomingViewingKey) + .build(); + assertNotNull(blockingStubFull.getZenPaymentAddress(message)); + } + + // @Test + // public void testCreateShieldNullifier() { + // NfParameters message = NfParameters + // .newBuilder().build(); + // assertNotNull(blockingStubFull.createShieldNullifier(message)); + // } + + // @Test + // public void testCreateSpendAuthSig() { + // SpendAuthSigParameters message = SpendAuthSigParameters + // .newBuilder().build(); + // assertNotNull(blockingStubFull.createSpendAuthSig(message)); + // } + + // @Test + // public void testGetShieldTransactionHash() { + // Transaction message = Transaction + // .newBuilder().build(); + // assertNotNull(blockingStubFull.getShieldTransactionHash(message)); + // } + + // @Test + // public void testCreateShieldedContractParameters() { + // PrivateShieldedTRC20Parameters message = PrivateShieldedTRC20Parameters + // .newBuilder().build(); + // assertNotNull(blockingStubFull.createShieldedContractParameters(message)); + // } + + // @Test + // public void testCreateShieldedContractParametersWithoutAsk() throws ZksnarkException { + // SpendingKey sk = SpendingKey.random(); + // ExpandedSpendingKey expsk = sk.expandedSpendingKey(); + // byte[] ovk = expsk.getOvk(); + // PrivateShieldedTRC20ParametersWithoutAsk message = PrivateShieldedTRC20ParametersWithoutAsk + // .newBuilder() + // .setOvk(ByteString.copyFrom(ovk)) + // .setFromAmount(BigInteger.valueOf(50).toString()) + // .setShieldedTRC20ContractAddress(ownerAddress) + // .build(); + // assertNotNull(blockingStubFull + // .createShieldedContractParametersWithoutAsk(message)); + // } +} diff --git a/framework/src/test/java/org/tron/core/services/WalletApiTest.java b/framework/src/test/java/org/tron/core/services/WalletApiTest.java index 3e8316666e6..0a87c348fdb 100644 --- a/framework/src/test/java/org/tron/core/services/WalletApiTest.java +++ b/framework/src/test/java/org/tron/core/services/WalletApiTest.java @@ -1,18 +1,19 @@ package org.tron.core.services; import io.grpc.ManagedChannelBuilder; -import java.io.File; +import java.io.IOException; import lombok.extern.slf4j.Slf4j; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.tron.api.GrpcAPI.EmptyMessage; import org.tron.api.WalletGrpc; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.application.TronApplicationContext; -import org.tron.common.utils.FileUtil; import org.tron.common.utils.client.Configuration; import org.tron.core.Constant; import org.tron.core.config.DefaultConfig; @@ -22,22 +23,23 @@ @Slf4j public class WalletApiTest { + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + private static TronApplicationContext context; - private static String dbPath = "output_wallet_api_test"; private String fullnode = Configuration.getByPath("testng.conf") .getStringList("fullnode.ip.list").get(0); private RpcApiService rpcApiService; private Application appT; @Before - public void init() { - Args.setParam(new String[]{ "-d", dbPath, "--p2p-disable", "true"}, Constant.TEST_CONF); + public void init() throws IOException { + Args.setParam(new String[]{ "-d", temporaryFolder.newFolder().toString(), + "--p2p-disable", "true"}, Constant.TEST_CONF); context = new TronApplicationContext(DefaultConfig.class); appT = ApplicationFactory.create(context); rpcApiService = context.getBean(RpcApiService.class); appT.addService(rpcApiService); - appT.initServices(Args.getInstance()); - appT.startServices(); appT.startup(); } @@ -55,7 +57,6 @@ public void listNodesTest() { public void destroy() { Args.clearParam(); context.destroy(); - FileUtil.deleteDir(new File(dbPath)); } } diff --git a/framework/src/test/java/org/tron/core/services/filter/HttpApiAccessFilterTest.java b/framework/src/test/java/org/tron/core/services/filter/HttpApiAccessFilterTest.java index 46449aab9c4..5f883fc8c07 100644 --- a/framework/src/test/java/org/tron/core/services/filter/HttpApiAccessFilterTest.java +++ b/framework/src/test/java/org/tron/core/services/filter/HttpApiAccessFilterTest.java @@ -17,7 +17,6 @@ import org.junit.Before; import org.junit.Test; import org.tron.common.BaseTest; -import org.tron.common.application.Application; import org.tron.common.parameter.CommonParameter; import org.tron.core.Constant; import org.tron.core.config.args.Args; @@ -27,8 +26,6 @@ public class HttpApiAccessFilterTest extends BaseTest { - @Resource - private Application appTest; @Resource private FullNodeHttpApiService httpApiService; @Resource @@ -40,8 +37,7 @@ public class HttpApiAccessFilterTest extends BaseTest { private static final CloseableHttpClient httpClient = HttpClients.createDefault(); static { - dbPath = "output_http_api_access_filter_test"; - Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); Args.getInstance().setFullNodeAllowShieldedTransactionArgs(false); } @@ -50,12 +46,10 @@ public class HttpApiAccessFilterTest extends BaseTest { */ @Before public void init() { - appTest.addService(httpApiService); - appTest.addService(httpApiOnSolidityService); - appTest.addService(httpApiOnPBFTService); - appTest.initServices(Args.getInstance()); - appTest.startServices(); - appTest.startup(); + appT.addService(httpApiService); + appT.addService(httpApiOnSolidityService); + appT.addService(httpApiOnPBFTService); + appT.startup(); } @Test diff --git a/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryGrpcInterceptorTest.java b/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryGrpcInterceptorTest.java index 4ee8fd051d0..00f2c2fc086 100644 --- a/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryGrpcInterceptorTest.java +++ b/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryGrpcInterceptorTest.java @@ -3,23 +3,23 @@ import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.StatusRuntimeException; -import java.io.File; +import java.io.IOException; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; - -import org.junit.After; +import org.junit.AfterClass; import org.junit.Assert; -import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; import org.tron.api.GrpcAPI; import org.tron.api.WalletGrpc; import org.tron.api.WalletSolidityGrpc; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.application.TronApplicationContext; -import org.tron.common.utils.FileUtil; import org.tron.common.utils.PublicMethod; import org.tron.core.ChainBaseManager; import org.tron.core.Constant; @@ -32,80 +32,79 @@ @Slf4j public class LiteFnQueryGrpcInterceptorTest { - private TronApplicationContext context; - private ManagedChannel channelFull = null; - private ManagedChannel channelpBFT = null; - private WalletGrpc.WalletBlockingStub blockingStubFull = null; - private WalletSolidityGrpc.WalletSolidityBlockingStub blockingStubSolidity = null; - private WalletSolidityGrpc.WalletSolidityBlockingStub blockingStubpBFT = null; - private RpcApiService rpcApiService; - private RpcApiServiceOnSolidity rpcApiServiceOnSolidity; - private RpcApiServiceOnPBFT rpcApiServiceOnPBFT; - private Application appTest; - private ChainBaseManager chainBaseManager; - - private String dbPath = "output_grpc_interceptor_test"; + private static TronApplicationContext context; + private static ManagedChannel channelFull = null; + private static ManagedChannel channelSolidity = null; + private static ManagedChannel channelpBFT = null; + private static WalletGrpc.WalletBlockingStub blockingStubFull = null; + private static WalletSolidityGrpc.WalletSolidityBlockingStub blockingStubSolidity = null; + private static WalletSolidityGrpc.WalletSolidityBlockingStub blockingStubpBFT = null; + private static ChainBaseManager chainBaseManager; + private static final String ERROR_MSG = + "UNAVAILABLE: this API is closed because this node is a lite fullnode"; @Rule public ExpectedException thrown = ExpectedException.none(); + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); + /** * init logic. */ - @Before - public void init() { - Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); + @BeforeClass + public static void init() throws IOException { + Args.setParam(new String[]{"-d", temporaryFolder.newFolder().toString()}, Constant.TEST_CONF); Args.getInstance().setRpcPort(PublicMethod.chooseRandomPort()); Args.getInstance().setRpcOnSolidityPort(PublicMethod.chooseRandomPort()); Args.getInstance().setRpcOnPBFTPort(PublicMethod.chooseRandomPort()); String fullnode = String.format("%s:%d", Args.getInstance().getNodeDiscoveryBindIp(), Args.getInstance().getRpcPort()); + String solidityNode = String.format("%s:%d", Args.getInstance().getNodeDiscoveryBindIp(), + Args.getInstance().getRpcOnSolidityPort()); String pBFTNode = String.format("%s:%d", Args.getInstance().getNodeDiscoveryBindIp(), - Args.getInstance().getRpcOnPBFTPort()); + Args.getInstance().getRpcOnPBFTPort()); channelFull = ManagedChannelBuilder.forTarget(fullnode) .usePlaintext() .build(); + channelSolidity = ManagedChannelBuilder.forTarget(solidityNode) + .usePlaintext() + .build(); channelpBFT = ManagedChannelBuilder.forTarget(pBFTNode) .usePlaintext() .build(); context = new TronApplicationContext(DefaultConfig.class); + context.registerShutdownHook(); blockingStubFull = WalletGrpc.newBlockingStub(channelFull); - blockingStubSolidity = WalletSolidityGrpc.newBlockingStub(channelFull); + blockingStubSolidity = WalletSolidityGrpc.newBlockingStub(channelSolidity); blockingStubpBFT = WalletSolidityGrpc.newBlockingStub(channelpBFT); - blockingStubSolidity = WalletSolidityGrpc.newBlockingStub(channelFull); - rpcApiService = context.getBean(RpcApiService.class); - rpcApiServiceOnSolidity = context.getBean(RpcApiServiceOnSolidity.class); - rpcApiServiceOnPBFT = context.getBean(RpcApiServiceOnPBFT.class); + RpcApiService rpcApiService = context.getBean(RpcApiService.class); + RpcApiServiceOnSolidity rpcOnSolidity = context.getBean(RpcApiServiceOnSolidity.class); + RpcApiServiceOnPBFT rpcApiServiceOnPBFT = context.getBean(RpcApiServiceOnPBFT.class); chainBaseManager = context.getBean(ChainBaseManager.class); - appTest = ApplicationFactory.create(context); + Application appTest = ApplicationFactory.create(context); appTest.addService(rpcApiService); - appTest.addService(rpcApiServiceOnSolidity); + appTest.addService(rpcOnSolidity); appTest.addService(rpcApiServiceOnPBFT); - appTest.initServices(Args.getInstance()); - appTest.startServices(); appTest.startup(); } /** * destroy the context. */ - @After - public void destroy() throws InterruptedException { + @AfterClass + public static void destroy() throws InterruptedException { if (channelFull != null) { channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); } + if (channelSolidity != null) { + channelSolidity.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } if (channelpBFT != null) { channelpBFT.shutdown().awaitTermination(5, TimeUnit.SECONDS); } + context.close(); Args.clearParam(); - appTest.shutdownServices(); - appTest.shutdown(); - context.destroy(); - if (FileUtil.deleteDir(new File(dbPath))) { - logger.info("Release resources successful."); - } else { - logger.info("Release resources failure."); - } } @Test @@ -113,16 +112,25 @@ public void testGrpcApiThrowStatusRuntimeException() { final GrpcAPI.NumberMessage message = GrpcAPI.NumberMessage.newBuilder().setNum(0).build(); chainBaseManager.setNodeType(ChainBaseManager.NodeType.LITE); thrown.expect(StatusRuntimeException.class); - thrown.expectMessage("UNAVAILABLE: this API is closed because this node is a lite fullnode"); + thrown.expectMessage(ERROR_MSG); blockingStubFull.getBlockByNum(message); } + @Test + public void testGrpcSolidityThrowStatusRuntimeException() { + final GrpcAPI.NumberMessage message = GrpcAPI.NumberMessage.newBuilder().setNum(0).build(); + chainBaseManager.setNodeType(ChainBaseManager.NodeType.LITE); + thrown.expect(StatusRuntimeException.class); + thrown.expectMessage(ERROR_MSG); + blockingStubSolidity.getBlockByNum(message); + } + @Test public void testpBFTGrpcApiThrowStatusRuntimeException() { final GrpcAPI.NumberMessage message = GrpcAPI.NumberMessage.newBuilder().setNum(0).build(); chainBaseManager.setNodeType(ChainBaseManager.NodeType.LITE); thrown.expect(StatusRuntimeException.class); - thrown.expectMessage("UNAVAILABLE: this API is closed because this node is a lite fullnode"); + thrown.expectMessage(ERROR_MSG); blockingStubpBFT.getBlockByNum(message); } diff --git a/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryHttpFilterTest.java b/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryHttpFilterTest.java index 5c4b955667f..5fd4711273e 100644 --- a/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryHttpFilterTest.java +++ b/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryHttpFilterTest.java @@ -19,7 +19,6 @@ import org.junit.Before; import org.junit.Test; import org.tron.common.BaseTest; -import org.tron.common.application.Application; import org.tron.core.Constant; import org.tron.core.config.args.Args; import org.tron.core.services.http.FullNodeHttpApiService; @@ -32,8 +31,6 @@ public class LiteFnQueryHttpFilterTest extends BaseTest { private final String ip = "127.0.0.1"; private int fullHttpPort; @Resource - private Application appTest; - @Resource private FullNodeHttpApiService httpApiService; @Resource private HttpApiOnSolidityService httpApiOnSolidityService; @@ -42,8 +39,7 @@ public class LiteFnQueryHttpFilterTest extends BaseTest { private final CloseableHttpClient httpClient = HttpClients.createDefault(); static { - dbPath = "output_http_filter_test"; - Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); Args.getInstance().setFullNodeAllowShieldedTransactionArgs(false); } @@ -52,12 +48,10 @@ public class LiteFnQueryHttpFilterTest extends BaseTest { */ @Before public void init() { - appTest.addService(httpApiService); - appTest.addService(httpApiOnSolidityService); - appTest.addService(httpApiOnPBFTService); - appTest.initServices(Args.getInstance()); - appTest.startServices(); - appTest.startup(); + appT.addService(httpApiService); + appT.addService(httpApiOnSolidityService); + appT.addService(httpApiOnPBFTService); + appT.startup(); } @Test diff --git a/framework/src/test/java/org/tron/core/services/filter/RpcApiAccessInterceptorTest.java b/framework/src/test/java/org/tron/core/services/filter/RpcApiAccessInterceptorTest.java index edd15fc19de..7d95c0c368a 100644 --- a/framework/src/test/java/org/tron/core/services/filter/RpcApiAccessInterceptorTest.java +++ b/framework/src/test/java/org/tron/core/services/filter/RpcApiAccessInterceptorTest.java @@ -1,28 +1,36 @@ package org.tron.core.services.filter; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.StatusRuntimeException; import io.grpc.stub.ServerCallStreamObserver; -import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; import lombok.extern.slf4j.Slf4j; import org.junit.AfterClass; -import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Rule; +import org.junit.ClassRule; import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.tron.api.GrpcAPI; +import org.junit.rules.TemporaryFolder; +import org.tron.api.GrpcAPI.BlockExtention; +import org.tron.api.GrpcAPI.BlockReq; +import org.tron.api.GrpcAPI.BytesMessage; +import org.tron.api.GrpcAPI.EmptyMessage; +import org.tron.api.GrpcAPI.NumberMessage; +import org.tron.api.GrpcAPI.TransactionIdList; import org.tron.api.WalletGrpc; import org.tron.api.WalletSolidityGrpc; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.application.TronApplicationContext; -import org.tron.common.utils.FileUtil; import org.tron.common.utils.PublicMethod; import org.tron.core.Constant; import org.tron.core.config.DefaultConfig; @@ -30,28 +38,24 @@ import org.tron.core.services.RpcApiService; import org.tron.core.services.interfaceOnPBFT.RpcApiServiceOnPBFT; import org.tron.core.services.interfaceOnSolidity.RpcApiServiceOnSolidity; +import org.tron.protos.Protocol.Transaction; @Slf4j public class RpcApiAccessInterceptorTest { private static TronApplicationContext context; - private static WalletGrpc.WalletBlockingStub blockingStubFull = null; private static WalletSolidityGrpc.WalletSolidityBlockingStub blockingStubSolidity = null; private static WalletSolidityGrpc.WalletSolidityBlockingStub blockingStubPBFT = null; - private static Application appTest; - - private static String dbPath = "output_rpc_api_access_interceptor_test"; - - @Rule - public ExpectedException thrown = ExpectedException.none(); + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); /** * init logic. */ @BeforeClass - public static void init() { - Args.setParam(new String[] {"-d", dbPath}, Constant.TEST_CONF); + public static void init() throws IOException { + Args.setParam(new String[] {"-d", temporaryFolder.newFolder().toString()}, Constant.TEST_CONF); Args.getInstance().setRpcPort(PublicMethod.chooseRandomPort()); Args.getInstance().setRpcOnSolidityPort(PublicMethod.chooseRandomPort()); Args.getInstance().setRpcOnPBFTPort(PublicMethod.chooseRandomPort()); @@ -65,7 +69,7 @@ public static void init() { ManagedChannel channelFull = ManagedChannelBuilder.forTarget(fullNode) .usePlaintext() .build(); - ManagedChannel channelpBFT = ManagedChannelBuilder.forTarget(pBFTNode) + ManagedChannel channelPBFT = ManagedChannelBuilder.forTarget(pBFTNode) .usePlaintext() .build(); ManagedChannel channelSolidity = ManagedChannelBuilder.forTarget(solidityNode) @@ -76,19 +80,17 @@ public static void init() { blockingStubFull = WalletGrpc.newBlockingStub(channelFull); blockingStubSolidity = WalletSolidityGrpc.newBlockingStub(channelSolidity); - blockingStubPBFT = WalletSolidityGrpc.newBlockingStub(channelpBFT); + blockingStubPBFT = WalletSolidityGrpc.newBlockingStub(channelPBFT); RpcApiService rpcApiService = context.getBean(RpcApiService.class); RpcApiServiceOnSolidity rpcApiServiceOnSolidity = context.getBean(RpcApiServiceOnSolidity.class); RpcApiServiceOnPBFT rpcApiServiceOnPBFT = context.getBean(RpcApiServiceOnPBFT.class); - appTest = ApplicationFactory.create(context); + Application appTest = ApplicationFactory.create(context); appTest.addService(rpcApiService); appTest.addService(rpcApiServiceOnSolidity); appTest.addService(rpcApiServiceOnPBFT); - appTest.initServices(Args.getInstance()); - appTest.startServices(); appTest.startup(); } @@ -97,15 +99,8 @@ public static void init() { */ @AfterClass public static void destroy() { + context.close(); Args.clearParam(); - appTest.shutdownServices(); - appTest.shutdown(); - context.destroy(); - if (FileUtil.deleteDir(new File(dbPath))) { - logger.info("Release resources successful."); - } else { - logger.info("Release resources failure."); - } } @Test @@ -115,59 +110,63 @@ public void testAccessDisabledFullNode() { disabledApiList.add("getblockbynum"); Args.getInstance().setDisabledApiList(disabledApiList); - final GrpcAPI.NumberMessage message = GrpcAPI.NumberMessage.newBuilder().setNum(0).build(); - thrown.expect(StatusRuntimeException.class); - thrown.expectMessage("this API is unavailable due to config"); - blockingStubFull.getBlockByNum(message); + final NumberMessage message = NumberMessage.newBuilder().setNum(0).build(); + assertThrows("this API is unavailable due to config", StatusRuntimeException.class, + () -> blockingStubFull.getBlockByNum(message)); } @Test public void testRpcApiService() { RpcApiService rpcApiService = context.getBean(RpcApiService.class); - ServerCallStreamObserverTest serverCallStreamObserverTest = new ServerCallStreamObserverTest(); - rpcApiService.getBlockCommon(GrpcAPI.BlockReq.getDefaultInstance(), - serverCallStreamObserverTest); - Assert.assertTrue("Get block Common failed!", serverCallStreamObserverTest.isReady()); + ServerCallStreamObserverTest serverCallStreamObserverTest = + new ServerCallStreamObserverTest<>(); + ServerCallStreamObserverTest serverCallStreamObserverTest1 = + new ServerCallStreamObserverTest<>(); + ServerCallStreamObserverTest serverCallStreamObserverTest2 = + new ServerCallStreamObserverTest<>(); + ServerCallStreamObserverTest serverCallStreamObserverTest3 = + new ServerCallStreamObserverTest<>(); + rpcApiService.getBlockCommon(BlockReq.getDefaultInstance(), serverCallStreamObserverTest); + assertTrue("Get block Common failed!", serverCallStreamObserverTest.isReady()); serverCallStreamObserverTest.isCancelled(); - rpcApiService.getBrokerageInfoCommon(GrpcAPI.BytesMessage.newBuilder().build(), - serverCallStreamObserverTest); - Assert.assertTrue("Get brokerage info Common failed!", - serverCallStreamObserverTest.isReady()); + rpcApiService.getBrokerageInfoCommon(BytesMessage.newBuilder().build(), + serverCallStreamObserverTest1); + assertTrue("Get brokerage info Common failed!", + serverCallStreamObserverTest1.isReady()); serverCallStreamObserverTest.isCancelled(); - rpcApiService.getBurnTrxCommon(GrpcAPI.EmptyMessage.newBuilder().build(), - serverCallStreamObserverTest); - Assert.assertTrue("Get burn trx common failed!", - serverCallStreamObserverTest.isReady()); + rpcApiService.getBurnTrxCommon(EmptyMessage.newBuilder().build(), + serverCallStreamObserverTest1); + assertTrue("Get burn trx common failed!", + serverCallStreamObserverTest1.isReady()); serverCallStreamObserverTest.isCancelled(); - rpcApiService.getPendingSizeCommon(GrpcAPI.EmptyMessage.getDefaultInstance(), - serverCallStreamObserverTest); - Assert.assertTrue("Get pending size common failed!", - serverCallStreamObserverTest.isReady()); + rpcApiService.getPendingSizeCommon(EmptyMessage.getDefaultInstance(), + serverCallStreamObserverTest1); + assertTrue("Get pending size common failed!", + serverCallStreamObserverTest1.isReady()); serverCallStreamObserverTest.isCancelled(); - rpcApiService.getRewardInfoCommon(GrpcAPI.BytesMessage.newBuilder().build(), - serverCallStreamObserverTest); - Assert.assertTrue("Get reward info common failed!", - serverCallStreamObserverTest.isReady()); + rpcApiService.getRewardInfoCommon(BytesMessage.newBuilder().build(), + serverCallStreamObserverTest1); + assertTrue("Get reward info common failed!", + serverCallStreamObserverTest1.isReady()); serverCallStreamObserverTest.isCancelled(); rpcApiService.getTransactionCountByBlockNumCommon( - GrpcAPI.NumberMessage.newBuilder().getDefaultInstanceForType(), - serverCallStreamObserverTest); - Assert.assertTrue("Get transaction count by block num failed!", - serverCallStreamObserverTest.isReady()); + NumberMessage.newBuilder().getDefaultInstanceForType(), + serverCallStreamObserverTest1); + assertTrue("Get transaction count by block num failed!", + serverCallStreamObserverTest1.isReady()); serverCallStreamObserverTest.isCancelled(); - rpcApiService.getTransactionFromPendingCommon(GrpcAPI.BytesMessage.newBuilder().build(), - serverCallStreamObserverTest); - Assert.assertTrue("Get transaction from pending failed!", - serverCallStreamObserverTest.isReady() == false); + rpcApiService.getTransactionFromPendingCommon(BytesMessage.newBuilder().build(), + serverCallStreamObserverTest2); + assertFalse("Get transaction from pending failed!", + serverCallStreamObserverTest2.isReady()); serverCallStreamObserverTest.isCancelled(); - rpcApiService.getTransactionListFromPendingCommon(GrpcAPI.EmptyMessage.newBuilder() - .getDefaultInstanceForType(), serverCallStreamObserverTest); - Assert.assertTrue("Get transaction list from pending failed!", - serverCallStreamObserverTest.isReady()); + rpcApiService.getTransactionListFromPendingCommon(EmptyMessage.newBuilder() + .getDefaultInstanceForType(), serverCallStreamObserverTest3); + assertTrue("Get transaction list from pending failed!", + serverCallStreamObserverTest3.isReady()); } - - class ServerCallStreamObserverTest extends ServerCallStreamObserver { + static class ServerCallStreamObserverTest extends ServerCallStreamObserver { Object ret; @@ -228,10 +227,9 @@ public void testAccessDisabledSolidityNode() { disabledApiList.add("getblockbynum"); Args.getInstance().setDisabledApiList(disabledApiList); - final GrpcAPI.NumberMessage message = GrpcAPI.NumberMessage.newBuilder().setNum(0).build(); - thrown.expect(StatusRuntimeException.class); - thrown.expectMessage("this API is unavailable due to config"); - blockingStubSolidity.getBlockByNum(message); + final NumberMessage message = NumberMessage.newBuilder().setNum(0).build(); + assertThrows("this API is unavailable due to config", StatusRuntimeException.class, + () -> blockingStubSolidity.getBlockByNum(message)); } @Test @@ -241,20 +239,19 @@ public void testAccessDisabledPBFTNode() { disabledApiList.add("getblockbynum"); Args.getInstance().setDisabledApiList(disabledApiList); - final GrpcAPI.NumberMessage message = GrpcAPI.NumberMessage.newBuilder().setNum(0).build(); - thrown.expect(StatusRuntimeException.class); - thrown.expectMessage("this API is unavailable due to config"); - blockingStubPBFT.getBlockByNum(message); + final NumberMessage message = NumberMessage.newBuilder().setNum(0).build(); + assertThrows("this API is unavailable due to config", StatusRuntimeException.class, + () -> blockingStubPBFT.getBlockByNum(message)); } @Test public void testAccessNoDisabled() { Args.getInstance().setDisabledApiList(Collections.emptyList()); - final GrpcAPI.NumberMessage message = GrpcAPI.NumberMessage.newBuilder().setNum(0).build(); - Assert.assertNotNull(blockingStubFull.getBlockByNum(message)); - Assert.assertNotNull(blockingStubSolidity.getBlockByNum(message)); - Assert.assertNotNull(blockingStubPBFT.getBlockByNum(message)); + final NumberMessage message = NumberMessage.newBuilder().setNum(0).build(); + assertNotNull(blockingStubFull.getBlockByNum(message)); + assertNotNull(blockingStubSolidity.getBlockByNum(message)); + assertNotNull(blockingStubPBFT.getBlockByNum(message)); } @Test @@ -263,10 +260,32 @@ public void testAccessDisabledNotIncluded() { disabledApiList.add("getaccount"); Args.getInstance().setDisabledApiList(disabledApiList); - final GrpcAPI.NumberMessage message = GrpcAPI.NumberMessage.newBuilder().setNum(0).build(); - Assert.assertNotNull(blockingStubFull.getBlockByNum(message)); - Assert.assertNotNull(blockingStubSolidity.getBlockByNum(message)); - Assert.assertNotNull(blockingStubPBFT.getBlockByNum(message)); + final NumberMessage message = NumberMessage.newBuilder().setNum(0).build(); + assertNotNull(blockingStubFull.getBlockByNum(message)); + assertNotNull(blockingStubSolidity.getBlockByNum(message)); + assertNotNull(blockingStubPBFT.getBlockByNum(message)); + } + + @Test + public void testGetBandwidthPrices() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getBandwidthPrices(message)); + assertNotNull(blockingStubSolidity.getBandwidthPrices(message)); + assertNotNull(blockingStubPBFT.getBandwidthPrices(message)); + } + + @Test + public void testGetEnergyPrices() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getEnergyPrices(message)); + assertNotNull(blockingStubSolidity.getEnergyPrices(message)); + assertNotNull(blockingStubPBFT.getEnergyPrices(message)); + } + + @Test + public void testGetMemoFee() { + EmptyMessage message = EmptyMessage.newBuilder().build(); + assertNotNull(blockingStubFull.getMemoFee(message)); } } diff --git a/framework/src/test/java/org/tron/core/services/http/BroadcastServletTest.java b/framework/src/test/java/org/tron/core/services/http/BroadcastServletTest.java index 24ec969c08b..37956e71762 100644 --- a/framework/src/test/java/org/tron/core/services/http/BroadcastServletTest.java +++ b/framework/src/test/java/org/tron/core/services/http/BroadcastServletTest.java @@ -25,7 +25,7 @@ import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; -import org.testng.annotations.Test; +import org.junit.Test; import org.tron.common.utils.FileUtil; import org.tron.core.services.http.solidity.mockito.HttpUrlStreamHandler; @@ -47,7 +47,12 @@ public class BroadcastServletTest { public static void init() { // Allows for mocking URL connections URLStreamHandlerFactory urlStreamHandlerFactory = mock(URLStreamHandlerFactory.class); - URL.setURLStreamHandlerFactory(urlStreamHandlerFactory); + try { + URL.setURLStreamHandlerFactory(urlStreamHandlerFactory); + } catch (Error e) { + logger.info("Ignore error: {}", e.getMessage()); + } + httpUrlStreamHandler = new HttpUrlStreamHandler(); given(urlStreamHandlerFactory.createURLStreamHandler("http")).willReturn(httpUrlStreamHandler); @@ -83,8 +88,6 @@ public void tearDown() { @Test public void doPostTest() throws IOException { URLStreamHandlerFactory urlStreamHandlerFactory = mock(URLStreamHandlerFactory.class); - URL.setURLStreamHandlerFactory(urlStreamHandlerFactory); - httpUrlStreamHandler = new HttpUrlStreamHandler(); given(urlStreamHandlerFactory.createURLStreamHandler("http")).willReturn(httpUrlStreamHandler); diff --git a/framework/src/test/java/org/tron/core/services/http/GetAssetIssueListServletTest.java b/framework/src/test/java/org/tron/core/services/http/GetAssetIssueListServletTest.java new file mode 100644 index 00000000000..71a2d4fa5d5 --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/http/GetAssetIssueListServletTest.java @@ -0,0 +1,82 @@ +package org.tron.core.services.http; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.Assert.fail; + +import com.alibaba.fastjson.JSONObject; +import java.io.UnsupportedEncodingException; +import javax.annotation.Resource; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; + +public class GetAssetIssueListServletTest extends BaseTest { + + @Resource + private GetAssetIssueListServlet getAssetIssueListServlet; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath(), + }, Constant.TEST_CONF + ); + } + + public MockHttpServletRequest createRequest(String contentType) { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setMethod("POST"); + request.setContentType(contentType); + request.setCharacterEncoding("UTF-8"); + return request; + } + + @Test + public void testGetAssetIssueListByJson() { + String jsonParam = "{\"visible\": true}"; + MockHttpServletRequest request = createRequest("application/json"); + request.setContent(jsonParam.getBytes()); + MockHttpServletResponse response = new MockHttpServletResponse(); + getAssetIssueListServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject.parseObject(contentAsString); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testGetAssetIssueListValue() { + MockHttpServletRequest request = createRequest("application/x-www-form-urlencoded"); + try { + String params = "visible=true"; + request.setContent(params.getBytes(UTF_8)); + MockHttpServletResponse response = new MockHttpServletResponse(); + getAssetIssueListServlet.doPost(request, response); + String contentAsString = response.getContentAsString(); + JSONObject.parseObject(contentAsString); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testGetAssetIssueListEmptyParam() { + MockHttpServletRequest request = createRequest("application/x-www-form-urlencoded"); + String params = "visible="; + request.setContent(params.getBytes(UTF_8)); + MockHttpServletResponse response = new MockHttpServletResponse(); + getAssetIssueListServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject.parseObject(contentAsString); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + +} diff --git a/framework/src/test/java/org/tron/core/services/http/GetBandwidthPricesServletTest.java b/framework/src/test/java/org/tron/core/services/http/GetBandwidthPricesServletTest.java new file mode 100644 index 00000000000..40ef8ad068f --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/http/GetBandwidthPricesServletTest.java @@ -0,0 +1,57 @@ +package org.tron.core.services.http; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.tron.common.utils.client.utils.HttpMethed.createRequest; + +import com.alibaba.fastjson.JSONObject; +import java.io.UnsupportedEncodingException; +import javax.annotation.Resource; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; + +public class GetBandwidthPricesServletTest extends BaseTest { + + @Resource + private GetBandwidthPricesServlet getBandwidthPricesServlet; + + @BeforeClass + public static void init() { + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); + } + + @Test + public void testGet() { + MockHttpServletRequest request = createRequest(HttpGet.METHOD_NAME); + MockHttpServletResponse response = new MockHttpServletResponse(); + getBandwidthPricesServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testPost() { + MockHttpServletRequest request = createRequest(HttpPost.METHOD_NAME); + try { + MockHttpServletResponse response = new MockHttpServletResponse(); + getBandwidthPricesServlet.doPost(request, response); + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } +} diff --git a/framework/src/test/java/org/tron/core/services/http/GetBrokerageServletTest.java b/framework/src/test/java/org/tron/core/services/http/GetBrokerageServletTest.java new file mode 100644 index 00000000000..ffe8cc6c22e --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/http/GetBrokerageServletTest.java @@ -0,0 +1,109 @@ +package org.tron.core.services.http; + +import com.alibaba.fastjson.JSONObject; + +import java.io.UnsupportedEncodingException; +import javax.annotation.Resource; + +import org.junit.Assert; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; + +public class GetBrokerageServletTest extends BaseTest { + + @Resource + private GetBrokerageServlet getBrokerageServlet; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath(), + }, Constant.TEST_CONF + ); + } + + public MockHttpServletRequest createRequest(String contentType) { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setMethod("POST"); + request.setContentType(contentType); + request.setCharacterEncoding("UTF-8"); + return request; + } + + @Test + public void getBrokerageValueByJsonTest() { + int expect = 20; + String jsonParam = "{\"address\": \"27VZHn9PFZwNh7o2EporxmLkpe157iWZVkh\"}"; + MockHttpServletRequest request = createRequest("application/json"); + request.setContent(jsonParam.getBytes()); + MockHttpServletResponse response = new MockHttpServletResponse(); + getBrokerageServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + int brokerage = (int)result.get("brokerage"); + Assert.assertEquals(expect, brokerage); + } catch (UnsupportedEncodingException e) { + Assert.fail(e.getMessage()); + } + } + + + @Test + public void getBrokerageByJsonUTF8Test() { + int expect = 20; + String jsonParam = "{\"address\": \"27VZHn9PFZwNh7o2EporxmLkpe157iWZVkh\"}"; + MockHttpServletRequest request = createRequest("application/json; charset=utf-8"); + request.setContent(jsonParam.getBytes()); + MockHttpServletResponse response = new MockHttpServletResponse(); + getBrokerageServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + int brokerage = (int)result.get("brokerage"); + Assert.assertEquals(expect, brokerage); + } catch (UnsupportedEncodingException e) { + Assert.fail(e.getMessage()); + } + } + + @Test + public void getBrokerageValueTest() { + int expect = 20; + MockHttpServletRequest request = createRequest("application/x-www-form-urlencoded"); + request.addParameter("address", "27VZHn9PFZwNh7o2EporxmLkpe157iWZVkh"); + MockHttpServletResponse response = new MockHttpServletResponse(); + getBrokerageServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + int brokerage = (int)result.get("brokerage"); + Assert.assertEquals(expect, brokerage); + } catch (UnsupportedEncodingException e) { + Assert.fail(e.getMessage()); + } + } + + @Test + public void getByBlankParamTest() { + int expect = 0; + MockHttpServletRequest request = createRequest("application/x-www-form-urlencoded"); + request.addParameter("address", ""); + MockHttpServletResponse response = new MockHttpServletResponse(); + getBrokerageServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + int brokerage = (int)result.get("brokerage"); + Assert.assertEquals(expect, brokerage); + String content = (String) result.get("Error"); + Assert.assertNull(content); + } catch (UnsupportedEncodingException e) { + Assert.fail(e.getMessage()); + } + } +} diff --git a/framework/src/test/java/org/tron/core/services/http/GetEnergyPricesServletTest.java b/framework/src/test/java/org/tron/core/services/http/GetEnergyPricesServletTest.java new file mode 100644 index 00000000000..34e93c557f5 --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/http/GetEnergyPricesServletTest.java @@ -0,0 +1,57 @@ +package org.tron.core.services.http; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.tron.common.utils.client.utils.HttpMethed.createRequest; + +import com.alibaba.fastjson.JSONObject; +import java.io.UnsupportedEncodingException; +import javax.annotation.Resource; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; + +public class GetEnergyPricesServletTest extends BaseTest { + + @Resource + private GetEnergyPricesServlet getEnergyPricesServlet; + + @BeforeClass + public static void init() { + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); + } + + @Test + public void testGet() { + MockHttpServletRequest request = createRequest(HttpGet.METHOD_NAME); + MockHttpServletResponse response = new MockHttpServletResponse(); + getEnergyPricesServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testPost() { + MockHttpServletRequest request = createRequest(HttpPost.METHOD_NAME); + try { + MockHttpServletResponse response = new MockHttpServletResponse(); + getEnergyPricesServlet.doPost(request, response); + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } +} diff --git a/framework/src/test/java/org/tron/core/services/http/GetMemoFeePricesServletTest.java b/framework/src/test/java/org/tron/core/services/http/GetMemoFeePricesServletTest.java new file mode 100644 index 00000000000..a954f4f4f8f --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/http/GetMemoFeePricesServletTest.java @@ -0,0 +1,57 @@ +package org.tron.core.services.http; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.tron.common.utils.client.utils.HttpMethed.createRequest; + +import com.alibaba.fastjson.JSONObject; +import java.io.UnsupportedEncodingException; +import javax.annotation.Resource; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; + +public class GetMemoFeePricesServletTest extends BaseTest { + + @Resource + private GetMemoFeePricesServlet getMemoFeePricesServlet; + + @BeforeClass + public static void init() { + Args.setParam(new String[]{"-d",dbPath()}, Constant.TEST_CONF); + } + + @Test + public void testGet() { + MockHttpServletRequest request = createRequest(HttpGet.METHOD_NAME); + MockHttpServletResponse response = new MockHttpServletResponse(); + getMemoFeePricesServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testPost() { + MockHttpServletRequest request = createRequest(HttpPost.METHOD_NAME); + try { + MockHttpServletResponse response = new MockHttpServletResponse(); + getMemoFeePricesServlet.doPost(request, response); + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } +} diff --git a/framework/src/test/java/org/tron/core/services/http/GetNowBlockServletTest.java b/framework/src/test/java/org/tron/core/services/http/GetNowBlockServletTest.java new file mode 100644 index 00000000000..3ee3d5a7052 --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/http/GetNowBlockServletTest.java @@ -0,0 +1,121 @@ +package org.tron.core.services.http; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.apache.commons.lang3.StringUtils.EMPTY; +import static org.apache.commons.lang3.StringUtils.isNotEmpty; +import static org.apache.http.entity.ContentType.APPLICATION_FORM_URLENCODED; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.alibaba.fastjson.JSONObject; +import java.io.UnsupportedEncodingException; +import javax.annotation.Resource; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; + +public class GetNowBlockServletTest extends BaseTest { + + @Resource + private GetNowBlockServlet getNowBlockServlet; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath(), + }, Constant.TEST_CONF + ); + } + + public MockHttpServletRequest createRequest(String contentType) { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setMethod("POST"); + if (isNotEmpty(contentType)) { + request.setContentType(contentType); + } + request.setCharacterEncoding("UTF-8"); + return request; + } + + @Test + public void testGetNowBlockByJson() { + String jsonParam = "{\"visible\": true}"; + MockHttpServletRequest request = createRequest("application/json"); + request.setContent(jsonParam.getBytes()); + MockHttpServletResponse response = new MockHttpServletResponse(); + getNowBlockServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("blockID")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testGetNowBlockByJson2() { + String jsonParam = "{\"visible\": true}"; + MockHttpServletRequest request = createRequest(APPLICATION_FORM_URLENCODED.getMimeType()); + request.setContent(jsonParam.getBytes()); + MockHttpServletResponse response = new MockHttpServletResponse(); + getNowBlockServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("blockID")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testGetNowBlockByEmpty() { + MockHttpServletRequest request = createRequest(APPLICATION_FORM_URLENCODED.getMimeType()); + request.setContent(EMPTY.getBytes()); + MockHttpServletResponse response = new MockHttpServletResponse(); + getNowBlockServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("blockID")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testGetNowBlockValue() { + MockHttpServletRequest request = createRequest("application/x-www-form-urlencoded"); + try { + String params = "visible=true"; + request.setContent(params.getBytes(UTF_8)); + MockHttpServletResponse response = new MockHttpServletResponse(); + getNowBlockServlet.doPost(request, response); + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("blockID")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testGetNowBlockEmptyParam() { + MockHttpServletRequest request = createRequest("application/x-www-form-urlencoded"); + String params = "visible="; + request.setContent(params.getBytes(UTF_8)); + MockHttpServletResponse response = new MockHttpServletResponse(); + getNowBlockServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("blockID")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } +} diff --git a/framework/src/test/java/org/tron/core/services/http/GetRewardServletTest.java b/framework/src/test/java/org/tron/core/services/http/GetRewardServletTest.java new file mode 100644 index 00000000000..404e154a4c3 --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/http/GetRewardServletTest.java @@ -0,0 +1,139 @@ +package org.tron.core.services.http; + +import static org.tron.common.utils.Commons.decodeFromBase58Check; + +import com.alibaba.fastjson.JSONObject; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import javax.annotation.Resource; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.BaseTest; +import org.tron.common.utils.FileUtil; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; +import org.tron.core.db.Manager; +import org.tron.core.service.MortgageService; +import org.tron.core.store.DelegationStore; + +@Slf4j +public class GetRewardServletTest extends BaseTest { + + @Resource + private Manager manager; + + @Resource + private MortgageService mortgageService; + + @Resource + private DelegationStore delegationStore; + + @Resource + GetRewardServlet getRewardServlet; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath(), + }, Constant.TEST_CONF + ); + } + + public MockHttpServletRequest createRequest(String contentType) { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setMethod("POST"); + request.setContentType(contentType); + request.setCharacterEncoding("UTF-8"); + return request; + } + + @Before + public void init() { + manager.getDynamicPropertiesStore().saveChangeDelegation(1); + byte[] sr = decodeFromBase58Check("27VZHn9PFZwNh7o2EporxmLkpe157iWZVkh"); + delegationStore.setBrokerage(0, sr, 10); + delegationStore.setWitnessVote(0, sr, 100000000); + } + + @Test + public void getRewardValueByJsonTest() { + int expect = 138181; + String jsonParam = "{\"address\": \"27VZHn9PFZwNh7o2EporxmLkpe157iWZVkh\"}"; + MockHttpServletRequest request = createRequest("application/json"); + MockHttpServletResponse response = new MockHttpServletResponse(); + request.setContent(jsonParam.getBytes()); + try { + getRewardServlet.doPost(request, response); + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + int reward = (int)result.get("reward"); + Assert.assertEquals(expect, reward); + } catch (UnsupportedEncodingException e) { + Assert.fail(e.getMessage()); + } + } + + @Test + public void getRewardByJsonUTF8Test() { + int expect = 138181; + String jsonParam = "{\"address\": \"27VZHn9PFZwNh7o2EporxmLkpe157iWZVkh\"}"; + MockHttpServletRequest request = createRequest("application/json; charset=utf-8"); + MockHttpServletResponse response = new MockHttpServletResponse(); + request.setContent(jsonParam.getBytes()); + try { + getRewardServlet.doPost(request, response); + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + int reward = (int)result.get("reward"); + Assert.assertEquals(expect, reward); + } catch (UnsupportedEncodingException e) { + Assert.fail(e.getMessage()); + } + } + + @Test + public void getRewardValueTest() { + int expect = 138181; + MockHttpServletRequest request = createRequest("application/x-www-form-urlencoded"); + MockHttpServletResponse response = new MockHttpServletResponse(); + mortgageService.payStandbyWitness(); + request.addParameter("address", "27VZHn9PFZwNh7o2EporxmLkpe157iWZVkh"); + getRewardServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + int reward = (int)result.get("reward"); + Assert.assertEquals(expect, reward); + } catch (UnsupportedEncodingException e) { + Assert.fail(e.getMessage()); + } + } + + @Test + public void getByBlankParamTest() { + MockHttpServletRequest request = createRequest("application/x-www-form-urlencoded"); + MockHttpServletResponse response = new MockHttpServletResponse(); + request.addParameter("address", ""); + GetRewardServlet getRewardServlet = new GetRewardServlet(); + getRewardServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + int reward = (int)result.get("reward"); + Assert.assertEquals(0, reward); + String content = (String) result.get("Error"); + Assert.assertNull(content); + } catch (UnsupportedEncodingException e) { + Assert.fail(e.getMessage()); + } + } + +} diff --git a/framework/src/test/java/org/tron/core/services/http/ListNodesServletTest.java b/framework/src/test/java/org/tron/core/services/http/ListNodesServletTest.java new file mode 100644 index 00000000000..1f491ca11db --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/http/ListNodesServletTest.java @@ -0,0 +1,82 @@ +package org.tron.core.services.http; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.io.UnsupportedEncodingException; +import javax.annotation.Resource; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; + +public class ListNodesServletTest extends BaseTest { + + @Resource + private ListNodesServlet listNodesServlet; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath(), + }, Constant.TEST_CONF + ); + } + + public MockHttpServletRequest createRequest(String contentType) { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setMethod("POST"); + request.setContentType(contentType); + request.setCharacterEncoding("UTF-8"); + return request; + } + + @Test + public void testListNodesByJson() { + String jsonParam = "{\"visible\": true}"; + MockHttpServletRequest request = createRequest("application/json"); + request.setContent(jsonParam.getBytes()); + MockHttpServletResponse response = new MockHttpServletResponse(); + listNodesServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + assertNotNull(contentAsString); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testListNodesValue() { + MockHttpServletRequest request = createRequest("application/x-www-form-urlencoded"); + try { + String params = "visible=true"; + request.setContent(params.getBytes(UTF_8)); + MockHttpServletResponse response = new MockHttpServletResponse(); + listNodesServlet.doPost(request, response); + String contentAsString = response.getContentAsString(); + assertNotNull(contentAsString); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testListNodesEmptyParam() { + MockHttpServletRequest request = createRequest("application/x-www-form-urlencoded"); + String params = "visible="; + request.setContent(params.getBytes(UTF_8)); + MockHttpServletResponse response = new MockHttpServletResponse(); + listNodesServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + assertNotNull(contentAsString); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + +} diff --git a/framework/src/test/java/org/tron/core/services/http/ListProposalsServletTest.java b/framework/src/test/java/org/tron/core/services/http/ListProposalsServletTest.java new file mode 100644 index 00000000000..aa3a1817a3e --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/http/ListProposalsServletTest.java @@ -0,0 +1,82 @@ +package org.tron.core.services.http; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.Assert.fail; + +import com.alibaba.fastjson.JSONObject; +import java.io.UnsupportedEncodingException; +import javax.annotation.Resource; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; + +public class ListProposalsServletTest extends BaseTest { + + @Resource + private ListProposalsServlet listProposalsServlet; + + static { + Args.setParam( + new String[]{ + "--output-directory", dbPath(), + }, Constant.TEST_CONF + ); + } + + public MockHttpServletRequest createRequest(String contentType) { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setMethod("POST"); + request.setContentType(contentType); + request.setCharacterEncoding("UTF-8"); + return request; + } + + @Test + public void testListProposalsByJson() { + String jsonParam = "{\"visible\": true}"; + MockHttpServletRequest request = createRequest("application/json"); + request.setContent(jsonParam.getBytes()); + MockHttpServletResponse response = new MockHttpServletResponse(); + listProposalsServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject.parseObject(contentAsString); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testListProposalsValue() { + MockHttpServletRequest request = createRequest("application/x-www-form-urlencoded"); + try { + String params = "visible=true"; + request.setContent(params.getBytes(UTF_8)); + MockHttpServletResponse response = new MockHttpServletResponse(); + listProposalsServlet.doPost(request, response); + String contentAsString = response.getContentAsString(); + JSONObject.parseObject(contentAsString); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testListProposalsEmptyParam() { + MockHttpServletRequest request = createRequest("application/x-www-form-urlencoded"); + String params = "visible="; + request.setContent(params.getBytes(UTF_8)); + MockHttpServletResponse response = new MockHttpServletResponse(); + listProposalsServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject.parseObject(contentAsString); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + +} diff --git a/framework/src/test/java/org/tron/core/services/http/TriggerSmartContractServletTest.java b/framework/src/test/java/org/tron/core/services/http/TriggerSmartContractServletTest.java index 8adae9b8c3d..f363b7fbefc 100644 --- a/framework/src/test/java/org/tron/core/services/http/TriggerSmartContractServletTest.java +++ b/framework/src/test/java/org/tron/core/services/http/TriggerSmartContractServletTest.java @@ -11,7 +11,6 @@ import org.junit.Test; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.tron.common.BaseTest; -import org.tron.common.application.Application; import org.tron.common.utils.ByteArray; import org.tron.common.utils.client.Configuration; import org.tron.common.utils.client.utils.HttpMethed; @@ -35,14 +34,11 @@ public class TriggerSmartContractServletTest extends BaseTest { @Resource private FullNodeHttpApiService httpApiService; - @Resource - private Application appT; @BeforeClass public static void init() throws Exception { - dbPath = "output_" + TriggerSmartContractServletTest.class.getName(); Args.setParam( - new String[]{"--output-directory", dbPath, "--debug", "--witness"}, Constant.TEST_CONF); + new String[]{"--output-directory", dbPath(), "--debug", "--witness"}, Constant.TEST_CONF); Args.getInstance().needSyncCheck = false; // build app context @@ -55,8 +51,6 @@ public void before() { appT.addService(httpApiService); // start services - appT.initServices(Args.getInstance()); - appT.startServices(); appT.startup(); // create contract for testing diff --git a/framework/src/test/java/org/tron/core/services/http/UtilTest.java b/framework/src/test/java/org/tron/core/services/http/UtilTest.java index 1f698796ba7..5d9d8092b22 100644 --- a/framework/src/test/java/org/tron/core/services/http/UtilTest.java +++ b/framework/src/test/java/org/tron/core/services/http/UtilTest.java @@ -1,27 +1,47 @@ package org.tron.core.services.http; +import com.google.protobuf.ByteString; import javax.annotation.Resource; import org.junit.Assert; +import org.junit.Before; import org.junit.Test; import org.tron.api.GrpcAPI.TransactionApprovedList; import org.tron.api.GrpcAPI.TransactionSignWeight; import org.tron.common.BaseTest; +import org.tron.common.utils.ByteArray; import org.tron.core.Constant; import org.tron.core.Wallet; +import org.tron.core.capsule.AccountCapsule; import org.tron.core.config.args.Args; import org.tron.core.utils.TransactionUtil; +import org.tron.protos.Protocol; import org.tron.protos.Protocol.Transaction; public class UtilTest extends BaseTest { + private static final String OWNER_ADDRESS; + @Resource private Wallet wallet; @Resource private TransactionUtil transactionUtil; static { - dbPath = "output_util_test"; - Args.setParam(new String[] {"-d", dbPath}, Constant.TEST_CONF); + OWNER_ADDRESS = Wallet.getAddressPreFixString() + "c076305e35aea1fe45a772fcaaab8a36e87bdb55"; + Args.setParam(new String[] {"-d", dbPath()}, Constant.TEST_CONF); + } + + @Before + public void setUp() { + byte[] owner = ByteArray.fromHexString(OWNER_ADDRESS); + AccountCapsule ownerCapsule = + new AccountCapsule( + ByteString.copyFromUtf8("owner"), + ByteString.copyFrom(owner), + Protocol.AccountType.Normal, + 10_000_000_000L); + ownerCapsule.setFrozenForBandwidth(1000000L, 1000000L); + dbManager.getAccountStore().put(ownerCapsule.getAddress().toByteArray(), ownerCapsule); } @Test @@ -108,4 +128,42 @@ public void testPackTransactionWithInvalidType() { Assert.assertEquals("Invalid transaction: no valid contract", txSignWeight.getResult().getMessage()); } + + @Test + public void testPackTransaction() { + String strTransaction = "{\n" + + " \"visible\": false,\n" + + " \"signature\": [\n" + + " \"5c23bddabccd3e4e5ebdf7d2f21dc58af9f88e0b99620374c5354e0dd9efb3a436167d95b70d2" + + "d825180bf90bc84525acb13a203f209afd5d397316f6b2c387c01\"\n" + + " ],\n" + + " \"txID\": \"fc33817936b06e50d4b6f1797e62f52d69af6c0da580a607241a9c03a48e390e\",\n" + + " \"raw_data\": {\n" + + " \"contract\": [\n" + + " {\n" + + " \"parameter\": {\n" + + " \"value\": {\n" + + " \"amount\": 10,\n" + + " \"owner_address\":\"41c076305e35aea1fe45a772fcaaab8a36e87bdb55\"," + + " \"to_address\": \"415624c12e308b03a1a6b21d9b86e3942fac1ab92b\"\n" + + " },\n" + + " \"type_url\": \"type.googleapis.com/protocol.TransferContract\"\n" + + " },\n" + + " \"type\": \"TransferContract\"\n" + + " }\n" + + " ],\n" + + " \"ref_block_bytes\": \"d8ed\",\n" + + " \"ref_block_hash\": \"2e066c3259e756f5\",\n" + + " \"expiration\": 1651906644000,\n" + + " \"timestamp\": 1651906586162\n" + + " },\n" + + " \"raw_data_hex\": \"0a02d8ed22082e066c3259e756f540a090bcea89305a65080112610a2d747970" + + "652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e74726163741230" + + "0a1541c076305e35aea1fe45a772fcaaab8a36e87bdb551215415624c12e308b03a1a6b21d9b86e3942fac1a" + + "b92b180a70b2ccb8ea8930\"\n" + + "}"; + Transaction transaction = Util.packTransaction(strTransaction, false); + TransactionSignWeight txSignWeight = transactionUtil.getTransactionSignWeight(transaction); + Assert.assertNotNull(txSignWeight); + } } diff --git a/framework/src/test/java/org/tron/core/services/http/solidity/GetTransactionByIdSolidityServletTest.java b/framework/src/test/java/org/tron/core/services/http/solidity/GetTransactionByIdSolidityServletTest.java index 06bc5f561c5..70c74e3a2a7 100644 --- a/framework/src/test/java/org/tron/core/services/http/solidity/GetTransactionByIdSolidityServletTest.java +++ b/framework/src/test/java/org/tron/core/services/http/solidity/GetTransactionByIdSolidityServletTest.java @@ -48,7 +48,11 @@ public class GetTransactionByIdSolidityServletTest { public static void init() { // Allows for mocking URL connections URLStreamHandlerFactory urlStreamHandlerFactory = mock(URLStreamHandlerFactory.class); - URL.setURLStreamHandlerFactory(urlStreamHandlerFactory); + try { + URL.setURLStreamHandlerFactory(urlStreamHandlerFactory); + } catch (Error e) { + logger.info("Ignore error: {}", e.getMessage()); + } httpUrlStreamHandler = new HttpUrlStreamHandler(); given(urlStreamHandlerFactory.createURLStreamHandler("http")).willReturn(httpUrlStreamHandler); diff --git a/framework/src/test/java/org/tron/core/services/interfaceOnPBFT/http/GetBandwidthPricesOnPBFTServletTest.java b/framework/src/test/java/org/tron/core/services/interfaceOnPBFT/http/GetBandwidthPricesOnPBFTServletTest.java new file mode 100644 index 00000000000..a8e07b743c5 --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/interfaceOnPBFT/http/GetBandwidthPricesOnPBFTServletTest.java @@ -0,0 +1,57 @@ +package org.tron.core.services.interfaceOnPBFT.http; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.tron.common.utils.client.utils.HttpMethed.createRequest; + +import com.alibaba.fastjson.JSONObject; +import java.io.UnsupportedEncodingException; +import javax.annotation.Resource; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; + +public class GetBandwidthPricesOnPBFTServletTest extends BaseTest { + + @Resource + private GetBandwidthPricesOnPBFTServlet getBandwidthPricesOnPBFTServlet; + + @BeforeClass + public static void init() { + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); + } + + @Test + public void testGet() { + MockHttpServletRequest request = createRequest(HttpGet.METHOD_NAME); + MockHttpServletResponse response = new MockHttpServletResponse(); + getBandwidthPricesOnPBFTServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testPost() { + MockHttpServletRequest request = createRequest(HttpPost.METHOD_NAME); + try { + MockHttpServletResponse response = new MockHttpServletResponse(); + getBandwidthPricesOnPBFTServlet.doPost(request, response); + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } +} diff --git a/framework/src/test/java/org/tron/core/services/interfaceOnPBFT/http/GetEnergyPricesOnPBFTServletTest.java b/framework/src/test/java/org/tron/core/services/interfaceOnPBFT/http/GetEnergyPricesOnPBFTServletTest.java new file mode 100644 index 00000000000..8785618bdbe --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/interfaceOnPBFT/http/GetEnergyPricesOnPBFTServletTest.java @@ -0,0 +1,57 @@ +package org.tron.core.services.interfaceOnPBFT.http; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.tron.common.utils.client.utils.HttpMethed.createRequest; + +import com.alibaba.fastjson.JSONObject; +import java.io.UnsupportedEncodingException; +import javax.annotation.Resource; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; + +public class GetEnergyPricesOnPBFTServletTest extends BaseTest { + + @Resource + private GetEnergyPricesOnPBFTServlet getEnergyPricesOnPBFTServlet; + + @BeforeClass + public static void init() { + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); + } + + @Test + public void testGet() { + MockHttpServletRequest request = createRequest(HttpGet.METHOD_NAME); + MockHttpServletResponse response = new MockHttpServletResponse(); + getEnergyPricesOnPBFTServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testPost() { + MockHttpServletRequest request = createRequest(HttpPost.METHOD_NAME); + try { + MockHttpServletResponse response = new MockHttpServletResponse(); + getEnergyPricesOnPBFTServlet.doPost(request, response); + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } +} diff --git a/framework/src/test/java/org/tron/core/services/interfaceOnSolidity/http/GetBandwidthPricesOnSolidityServletTest.java b/framework/src/test/java/org/tron/core/services/interfaceOnSolidity/http/GetBandwidthPricesOnSolidityServletTest.java new file mode 100644 index 00000000000..4b1ace08970 --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/interfaceOnSolidity/http/GetBandwidthPricesOnSolidityServletTest.java @@ -0,0 +1,57 @@ +package org.tron.core.services.interfaceOnSolidity.http; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.tron.common.utils.client.utils.HttpMethed.createRequest; + +import com.alibaba.fastjson.JSONObject; +import java.io.UnsupportedEncodingException; +import javax.annotation.Resource; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; + +public class GetBandwidthPricesOnSolidityServletTest extends BaseTest { + + @Resource + private GetBandwidthPricesOnSolidityServlet getBandwidthPricesOnSolidityServlet; + + @BeforeClass + public static void init() { + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); + } + + @Test + public void testGet() { + MockHttpServletRequest request = createRequest(HttpGet.METHOD_NAME); + MockHttpServletResponse response = new MockHttpServletResponse(); + getBandwidthPricesOnSolidityServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testPost() { + MockHttpServletRequest request = createRequest(HttpPost.METHOD_NAME); + try { + MockHttpServletResponse response = new MockHttpServletResponse(); + getBandwidthPricesOnSolidityServlet.doPost(request, response); + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } +} diff --git a/framework/src/test/java/org/tron/core/services/interfaceOnSolidity/http/GetEnergyPricesOnSolidityServletTest.java b/framework/src/test/java/org/tron/core/services/interfaceOnSolidity/http/GetEnergyPricesOnSolidityServletTest.java new file mode 100644 index 00000000000..6a26f9bc861 --- /dev/null +++ b/framework/src/test/java/org/tron/core/services/interfaceOnSolidity/http/GetEnergyPricesOnSolidityServletTest.java @@ -0,0 +1,57 @@ +package org.tron.core.services.interfaceOnSolidity.http; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.tron.common.utils.client.utils.HttpMethed.createRequest; + +import com.alibaba.fastjson.JSONObject; +import java.io.UnsupportedEncodingException; +import javax.annotation.Resource; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.BaseTest; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; + +public class GetEnergyPricesOnSolidityServletTest extends BaseTest { + + @Resource + private GetEnergyPricesOnSolidityServlet getEnergyPricesOnSolidityServlet; + + @BeforeClass + public static void init() { + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); + } + + @Test + public void testGet() { + MockHttpServletRequest request = createRequest(HttpGet.METHOD_NAME); + MockHttpServletResponse response = new MockHttpServletResponse(); + getEnergyPricesOnSolidityServlet.doPost(request, response); + try { + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } + + @Test + public void testPost() { + MockHttpServletRequest request = createRequest(HttpPost.METHOD_NAME); + try { + MockHttpServletResponse response = new MockHttpServletResponse(); + getEnergyPricesOnSolidityServlet.doPost(request, response); + String contentAsString = response.getContentAsString(); + JSONObject result = JSONObject.parseObject(contentAsString); + assertTrue(result.containsKey("prices")); + } catch (UnsupportedEncodingException e) { + fail(e.getMessage()); + } + } +} diff --git a/framework/src/test/java/org/tron/core/services/stop/BlockHeightStopTest.java b/framework/src/test/java/org/tron/core/services/stop/BlockHeightStopTest.java index a05cc64aad4..66a827fc55e 100644 --- a/framework/src/test/java/org/tron/core/services/stop/BlockHeightStopTest.java +++ b/framework/src/test/java/org/tron/core/services/stop/BlockHeightStopTest.java @@ -18,10 +18,4 @@ protected void check() throws Exception { Assert.assertEquals(height, dbManager.getDynamicPropertiesStore() .getLatestBlockHeaderNumberFromDB()); } - - @Override - protected void initDbPath() { - dbPath = "output-height-stop"; - } - } diff --git a/framework/src/test/java/org/tron/core/services/stop/BlockSyncCountStopTest.java b/framework/src/test/java/org/tron/core/services/stop/BlockSyncCountStopTest.java index f974a8a4272..0ac9b93f2dc 100644 --- a/framework/src/test/java/org/tron/core/services/stop/BlockSyncCountStopTest.java +++ b/framework/src/test/java/org/tron/core/services/stop/BlockSyncCountStopTest.java @@ -19,10 +19,4 @@ protected void check() throws Exception { Assert.assertEquals(sync + currentHeader, dbManager .getDynamicPropertiesStore().getLatestBlockHeaderNumberFromDB()); } - - @Override - protected void initDbPath() { - dbPath = "output-sync-stop"; - } - } diff --git a/framework/src/test/java/org/tron/core/services/stop/BlockTimeStopTest.java b/framework/src/test/java/org/tron/core/services/stop/BlockTimeStopTest.java index 2d3fde1afdb..86c32e66507 100644 --- a/framework/src/test/java/org/tron/core/services/stop/BlockTimeStopTest.java +++ b/framework/src/test/java/org/tron/core/services/stop/BlockTimeStopTest.java @@ -37,10 +37,4 @@ protected void check() throws Exception { Assert.assertTrue(cronExpression.isSatisfiedBy(new Date(chainManager .getBlockById(chainManager.getBlockIdByNum(height)).getTimeStamp()))); } - - @Override - protected void initDbPath() { - dbPath = "output-time-stop"; - } - } diff --git a/framework/src/test/java/org/tron/core/services/stop/ConditionallyStopTest.java b/framework/src/test/java/org/tron/core/services/stop/ConditionallyStopTest.java index 617e824c58f..dc3d02e7ced 100644 --- a/framework/src/test/java/org/tron/core/services/stop/ConditionallyStopTest.java +++ b/framework/src/test/java/org/tron/core/services/stop/ConditionallyStopTest.java @@ -3,6 +3,7 @@ import com.google.common.collect.Maps; import com.google.protobuf.ByteString; import java.io.File; +import java.io.IOException; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; @@ -17,7 +18,9 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.tron.common.application.TronApplicationContext; import org.tron.common.crypto.ECKey; import org.tron.common.parameter.CommonParameter; @@ -44,6 +47,8 @@ @Slf4j public abstract class ConditionallyStopTest extends BlockGenerate { + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); static ChainBaseManager chainManager; private static DposSlot dposSlot; @@ -67,14 +72,15 @@ public abstract class ConditionallyStopTest extends BlockGenerate { protected abstract void check() throws Exception; - protected abstract void initDbPath(); + protected void initDbPath() throws IOException { + dbPath = temporaryFolder.newFolder().toString(); + } @Before public void init() throws Exception { initDbPath(); - FileUtil.deleteDir(new File(dbPath)); logger.info("Full node running."); Args.setParam(new String[] {"-d", dbPath, "-w"}, Constant.TEST_CONF); Args.getInstance().setNodeListenPort(10000 + port.incrementAndGet()); @@ -108,7 +114,6 @@ public void init() throws Exception { public void destroy() { Args.clearParam(); context.destroy(); - FileUtil.deleteDir(new File(dbPath)); } private void generateBlock(Map witnessAndAccount) throws Exception { diff --git a/framework/src/test/java/org/tron/core/witness/ProposalControllerTest.java b/framework/src/test/java/org/tron/core/witness/ProposalControllerTest.java index cb502008bfc..c7b55ed4417 100644 --- a/framework/src/test/java/org/tron/core/witness/ProposalControllerTest.java +++ b/framework/src/test/java/org/tron/core/witness/ProposalControllerTest.java @@ -1,5 +1,6 @@ package org.tron.core.witness; +import com.google.common.collect.Lists; import com.google.protobuf.ByteString; import java.util.HashMap; import java.util.List; @@ -8,7 +9,6 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.testng.collections.Lists; import org.tron.common.BaseTest; import org.tron.common.utils.ByteArray; import org.tron.core.Constant; @@ -29,8 +29,7 @@ public class ProposalControllerTest extends BaseTest { private static boolean init; static { - dbPath = "output_proposal_controller_test"; - Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); } @Before diff --git a/framework/src/test/java/org/tron/core/witness/WitnessControllerTest.java b/framework/src/test/java/org/tron/core/witness/WitnessControllerTest.java index dcca6e4bc65..26e46ac138c 100644 --- a/framework/src/test/java/org/tron/core/witness/WitnessControllerTest.java +++ b/framework/src/test/java/org/tron/core/witness/WitnessControllerTest.java @@ -20,8 +20,7 @@ public class WitnessControllerTest extends BaseTest { static { - dbPath = "output_witness_controller_test"; - Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); } @Test diff --git a/framework/src/test/java/org/tron/core/zksnark/LibrustzcashTest.java b/framework/src/test/java/org/tron/core/zksnark/LibrustzcashTest.java index 55223bccb0c..67353eb24b1 100644 --- a/framework/src/test/java/org/tron/core/zksnark/LibrustzcashTest.java +++ b/framework/src/test/java/org/tron/core/zksnark/LibrustzcashTest.java @@ -50,9 +50,9 @@ import org.tron.core.config.args.Args; import org.tron.core.exception.BadItemException; import org.tron.core.exception.ZksnarkException; -import org.tron.core.services.http.FullNodeHttpApiService; import org.tron.core.zen.ZenTransactionBuilder; import org.tron.core.zen.ZenTransactionBuilder.SpendDescriptionInfo; +import org.tron.core.zen.ZksnarkInitService; import org.tron.core.zen.address.DiversifierT; import org.tron.core.zen.address.ExpandedSpendingKey; import org.tron.core.zen.address.FullViewingKey; @@ -73,10 +73,9 @@ public class LibrustzcashTest extends BaseTest { @BeforeClass public static void init() { - dbPath = "output_Librustzcash_test"; Args.setParam( new String[]{ - "--output-directory", dbPath, + "--output-directory", dbPath(), "--storage-db-directory", dbDirectory, "--storage-index-directory", indexDirectory, "-w", @@ -116,7 +115,7 @@ public static void test(byte[] K, byte[] ovk, byte[] cv, byte[] cm, byte[] epk) } public static void librustzcashInitZksnarkParams() { - FullNodeHttpApiService.librustzcashInitZksnarkParams(); + ZksnarkInitService.librustzcashInitZksnarkParams(); } @Test diff --git a/framework/src/test/java/org/tron/core/zksnark/MerkleContainerTest.java b/framework/src/test/java/org/tron/core/zksnark/MerkleContainerTest.java index 678eb137df0..183a504ee35 100644 --- a/framework/src/test/java/org/tron/core/zksnark/MerkleContainerTest.java +++ b/framework/src/test/java/org/tron/core/zksnark/MerkleContainerTest.java @@ -23,6 +23,7 @@ import org.tron.protos.Protocol.Block; import org.tron.protos.Protocol.Transaction; import org.tron.protos.Protocol.Transaction.Contract.ContractType; +import org.tron.protos.contract.ShieldContract.IncrementalMerkleTree; import org.tron.protos.contract.ShieldContract.IncrementalMerkleVoucherInfo; import org.tron.protos.contract.ShieldContract.OutputPoint; import org.tron.protos.contract.ShieldContract.OutputPointInfo; @@ -38,8 +39,7 @@ public class MerkleContainerTest extends BaseTest { static { - dbPath = "MerkleContainerTest"; - Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); } /*@Before diff --git a/framework/src/test/java/org/tron/core/zksnark/MerkleTreeTest.java b/framework/src/test/java/org/tron/core/zksnark/MerkleTreeTest.java index b635b55339c..cb70adb35a2 100644 --- a/framework/src/test/java/org/tron/core/zksnark/MerkleTreeTest.java +++ b/framework/src/test/java/org/tron/core/zksnark/MerkleTreeTest.java @@ -2,6 +2,7 @@ import com.alibaba.fastjson.JSONArray; import com.google.common.base.Charsets; +import com.google.common.collect.Lists; import com.google.common.io.Files; import com.google.protobuf.ByteString; import java.io.File; @@ -9,7 +10,6 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.testng.collections.Lists; import org.tron.common.BaseTest; import org.tron.common.utils.ByteArray; import org.tron.common.utils.ByteUtil; @@ -31,10 +31,9 @@ public class MerkleTreeTest extends BaseTest { private static boolean init; static { - dbPath = "output_ShieldedTransaction_test"; Args.setParam( new String[]{ - "--output-directory", dbPath, + "--output-directory", dbPath(), "--storage-db-directory", dbDirectory, "--storage-index-directory", indexDirectory, "-w", diff --git a/framework/src/test/java/org/tron/core/zksnark/NoteEncDecryTest.java b/framework/src/test/java/org/tron/core/zksnark/NoteEncDecryTest.java index fb054747fe6..e59060540e9 100644 --- a/framework/src/test/java/org/tron/core/zksnark/NoteEncDecryTest.java +++ b/framework/src/test/java/org/tron/core/zksnark/NoteEncDecryTest.java @@ -40,8 +40,7 @@ public class NoteEncDecryTest extends BaseTest { private Wallet wallet; static { - dbPath = "note_encdec_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, "config-localtest.conf"); + Args.setParam(new String[]{"--output-directory", dbPath()}, "config-localtest.conf"); FROM_ADDRESS = Wallet.getAddressPreFixString() + "a7d8a35b260395c14aa456297662092ba3b76fc0"; ADDRESS_ONE_PRIVATE_KEY = "7f7f701e94d4f1dd60ee5205e7ea8ee31121427210417b608a6b2e96433549a7"; } diff --git a/framework/src/test/java/org/tron/core/zksnark/SaplingNoteTest.java b/framework/src/test/java/org/tron/core/zksnark/SaplingNoteTest.java index 155e0477d65..60f6c8c0826 100644 --- a/framework/src/test/java/org/tron/core/zksnark/SaplingNoteTest.java +++ b/framework/src/test/java/org/tron/core/zksnark/SaplingNoteTest.java @@ -1,14 +1,14 @@ package org.tron.core.zksnark; import org.junit.AfterClass; +import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.testng.Assert; import org.tron.common.utils.ByteArray; import org.tron.core.config.args.Args; import org.tron.core.exception.BadItemException; import org.tron.core.exception.ZksnarkException; -import org.tron.core.services.http.FullNodeHttpApiService; +import org.tron.core.zen.ZksnarkInitService; import org.tron.core.zen.address.DiversifierT; import org.tron.core.zen.address.PaymentAddress; import org.tron.core.zen.address.SpendingKey; @@ -21,7 +21,7 @@ public class SaplingNoteTest { public static void init() { Args.setFullNodeAllowShieldedTransaction(true); // Args.getInstance().setAllowShieldedTransaction(1); - FullNodeHttpApiService.librustzcashInitZksnarkParams(); + ZksnarkInitService.librustzcashInitZksnarkParams(); } @AfterClass diff --git a/framework/src/test/java/org/tron/core/zksnark/SendCoinShieldTest.java b/framework/src/test/java/org/tron/core/zksnark/SendCoinShieldTest.java index cd7a36ab7a4..4a844c49c3c 100644 --- a/framework/src/test/java/org/tron/core/zksnark/SendCoinShieldTest.java +++ b/framework/src/test/java/org/tron/core/zksnark/SendCoinShieldTest.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONArray; import com.google.common.base.Charsets; +import com.google.common.collect.Lists; import com.google.common.io.Files; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; @@ -18,7 +19,6 @@ import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import org.testng.collections.Lists; import org.tron.api.GrpcAPI; import org.tron.common.BaseTest; import org.tron.common.parameter.CommonParameter; @@ -64,9 +64,9 @@ import org.tron.core.exception.VMIllegalException; import org.tron.core.exception.ValidateSignatureException; import org.tron.core.exception.ZksnarkException; -import org.tron.core.services.http.FullNodeHttpApiService; import org.tron.core.zen.ZenTransactionBuilder; import org.tron.core.zen.ZenTransactionBuilder.SpendDescriptionInfo; +import org.tron.core.zen.ZksnarkInitService; import org.tron.core.zen.address.DiversifierT; import org.tron.core.zen.address.ExpandedSpendingKey; import org.tron.core.zen.address.FullViewingKey; @@ -110,8 +110,7 @@ public class SendCoinShieldTest extends BaseTest { private static boolean init; static { - dbPath = "output_ShieldedTransaction_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, "config-test-mainnet.conf"); + Args.setParam(new String[]{"--output-directory", dbPath()}, "config-test-mainnet.conf"); Args.getInstance().setZenTokenId(String.valueOf(tokenId)); PUBLIC_ADDRESS_ONE = Wallet.getAddressPreFixString() + "a7d8a35b260395c14aa456297662092ba3b76fc0"; @@ -221,7 +220,7 @@ private IncrementalMerkleVoucherContainer createSimpleMerkleVoucherContainer(byt } private void librustzcashInitZksnarkParams() { - FullNodeHttpApiService.librustzcashInitZksnarkParams(); + ZksnarkInitService.librustzcashInitZksnarkParams(); } @Test diff --git a/framework/src/test/java/org/tron/core/zksnark/ShieldedReceiveTest.java b/framework/src/test/java/org/tron/core/zksnark/ShieldedReceiveTest.java index 514a5dfab76..c963a92bb9d 100755 --- a/framework/src/test/java/org/tron/core/zksnark/ShieldedReceiveTest.java +++ b/framework/src/test/java/org/tron/core/zksnark/ShieldedReceiveTest.java @@ -17,6 +17,7 @@ import org.junit.Test; import org.tron.api.GrpcAPI.BytesMessage; import org.tron.api.GrpcAPI.DecryptNotes; +import org.tron.api.GrpcAPI.DecryptNotesMarked; import org.tron.api.GrpcAPI.ReceiveNote; import org.tron.api.GrpcAPI.SpendAuthSigParameters; import org.tron.api.GrpcAPI.TransactionExtention; @@ -66,11 +67,11 @@ import org.tron.core.exception.VMIllegalException; import org.tron.core.exception.ValidateSignatureException; import org.tron.core.exception.ZksnarkException; -import org.tron.core.services.http.FullNodeHttpApiService; import org.tron.core.utils.TransactionUtil; import org.tron.core.zen.ZenTransactionBuilder; import org.tron.core.zen.ZenTransactionBuilder.ReceiveDescriptionInfo; import org.tron.core.zen.ZenTransactionBuilder.SpendDescriptionInfo; +import org.tron.core.zen.ZksnarkInitService; import org.tron.core.zen.address.DiversifierT; import org.tron.core.zen.address.ExpandedSpendingKey; import org.tron.core.zen.address.FullViewingKey; @@ -122,8 +123,7 @@ public class ShieldedReceiveTest extends BaseTest { private static boolean init; static { - dbPath = "receive_description_test"; - Args.setParam(new String[]{"--output-directory", dbPath}, "config-localtest.conf"); + Args.setParam(new String[]{"--output-directory", dbPath()}, "config-localtest.conf"); FROM_ADDRESS = Wallet.getAddressPreFixString() + "a7d8a35b260395c14aa456297662092ba3b76fc0"; ADDRESS_ONE_PRIVATE_KEY = "7f7f701e94d4f1dd60ee5205e7ea8ee31121427210417b608a6b2e96433549a7"; } @@ -142,7 +142,7 @@ public void init() { } private static void librustzcashInitZksnarkParams() { - FullNodeHttpApiService.librustzcashInitZksnarkParams(); + ZksnarkInitService.librustzcashInitZksnarkParams(); } private static byte[] randomUint256() { @@ -2378,8 +2378,8 @@ public void pushSameSkAndScanAndSpend() throws Exception { chainBaseManager.addWitness(ByteString.copyFrom(witnessAddress)); //sometimes generate block failed, try several times. - - Block block = getSignedBlock(witnessCapsule.getAddress(), 0, privateKey); + long time = System.currentTimeMillis(); + Block block = getSignedBlock(witnessCapsule.getAddress(), time, privateKey); dbManager.pushBlock(new BlockCapsule(block)); //create transactions @@ -2427,17 +2427,25 @@ public void pushSameSkAndScanAndSpend() throws Exception { Thread.sleep(500); //package transaction to block - block = getSignedBlock(witnessCapsule.getAddress(), 0, privateKey); + block = getSignedBlock(witnessCapsule.getAddress(), time + 3000, privateKey); dbManager.pushBlock(new BlockCapsule(block)); BlockCapsule blockCapsule3 = new BlockCapsule(wallet.getNowBlock()); Assert.assertEquals("blocknum != 2", 2, blockCapsule3.getNum()); + block = getSignedBlock(witnessCapsule.getAddress(), time + 6000, privateKey); + dbManager.pushBlock(new BlockCapsule(block)); + // scan note by ivk byte[] receiverIvk = incomingViewingKey.getValue(); DecryptNotes notes1 = wallet.scanNoteByIvk(0, 100, receiverIvk); Assert.assertEquals(2, notes1.getNoteTxsCount()); + // scan note by ivk and mark + DecryptNotesMarked notes3 = wallet.scanAndMarkNoteByIvk(0, 100, receiverIvk, + fullViewingKey.getAk(), fullViewingKey.getNk()); + Assert.assertEquals(2, notes3.getNoteTxsCount()); + // scan note by ovk DecryptNotes notes2 = wallet.scanNoteByOvk(0, 100, senderOvk); Assert.assertEquals(2, notes2.getNoteTxsCount()); @@ -2453,6 +2461,7 @@ public void pushSameSkAndScanAndSpend() throws Exception { outPointBuild.setIndex(i); request.addOutPoints(outPointBuild.build()); } + request.setBlockNum(1); IncrementalMerkleVoucherInfo merkleVoucherInfo = wallet .getMerkleTreeVoucherInfo(request.build()); diff --git a/framework/src/test/java/org/tron/keystore/WalletFileTest.java b/framework/src/test/java/org/tron/keystore/WalletFileTest.java index 7d584b3d8e2..c24647be322 100644 --- a/framework/src/test/java/org/tron/keystore/WalletFileTest.java +++ b/framework/src/test/java/org/tron/keystore/WalletFileTest.java @@ -2,7 +2,6 @@ import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; -import junit.framework.TestCase; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.Test; @@ -10,8 +9,7 @@ import org.tron.core.exception.CipherException; @Slf4j -public class WalletFileTest extends TestCase { - +public class WalletFileTest { @Test public void testGetAddress() throws NoSuchAlgorithmException, CipherException { @@ -19,10 +17,59 @@ public void testGetAddress() throws NoSuchAlgorithmException, CipherException { SecureRandom.getInstance("NativePRNG"),true)); WalletFile walletFile2 = Wallet.createStandard("", SignUtils.getGeneratedRandomSign( SecureRandom.getInstance("NativePRNG"),true)); - Assert.assertTrue(!walletFile1.getAddress().equals(walletFile2.getAddress())); - Assert.assertTrue(!walletFile1.getCrypto().equals(walletFile2.getCrypto())); - Assert.assertTrue(!walletFile1.getId().equals(walletFile2.getId())); - Assert.assertTrue(walletFile1.getVersion() == walletFile2.getVersion()); + WalletFile walletFile3 = (WalletFile) getSame(walletFile1); + Assert.assertNotEquals(walletFile1.getAddress(), walletFile2.getAddress()); + Assert.assertNotEquals(walletFile1.getCrypto(), walletFile2.getCrypto()); + Assert.assertNotEquals(walletFile1.getId(), walletFile2.getId()); + Assert.assertEquals(walletFile1.getVersion(), walletFile2.getVersion()); + Assert.assertNotEquals(walletFile1, walletFile2); + Assert.assertEquals(walletFile1, walletFile3); + Assert.assertNotEquals(walletFile1, null); + Assert.assertNotEquals(walletFile2, new Object()); + Assert.assertNotEquals(0, walletFile1.hashCode()); + + WalletFile.CipherParams cipherParams = new WalletFile.CipherParams(); + WalletFile.CipherParams cipherParams1 = new WalletFile.CipherParams(); + WalletFile.CipherParams cipherParams2 = (WalletFile.CipherParams) getSame(cipherParams); + Assert.assertEquals(cipherParams, cipherParams1); + Assert.assertEquals(cipherParams, cipherParams2); + Assert.assertNotEquals(cipherParams, null); + Assert.assertNotEquals(cipherParams, new Object()); + Assert.assertEquals(0, cipherParams.hashCode()); + + WalletFile.Aes128CtrKdfParams aes128CtrKdfParams = new WalletFile.Aes128CtrKdfParams(); + WalletFile.Aes128CtrKdfParams aes128CtrKdfParams1 = new WalletFile.Aes128CtrKdfParams(); + WalletFile.Aes128CtrKdfParams aes128CtrKdfParams2 = (WalletFile.Aes128CtrKdfParams) + getSame(aes128CtrKdfParams); + Assert.assertEquals(aes128CtrKdfParams, aes128CtrKdfParams1); + Assert.assertEquals(aes128CtrKdfParams, aes128CtrKdfParams2); + Assert.assertNotEquals(aes128CtrKdfParams, null); + Assert.assertNotEquals(aes128CtrKdfParams, new Object()); + Assert.assertEquals(0, aes128CtrKdfParams.hashCode()); + + WalletFile.ScryptKdfParams scryptKdfParams = new WalletFile.ScryptKdfParams(); + WalletFile.ScryptKdfParams scryptKdfParams1 = new WalletFile.ScryptKdfParams(); + WalletFile.ScryptKdfParams scryptKdfParams2 = (WalletFile.ScryptKdfParams) + getSame(scryptKdfParams); + Assert.assertEquals(scryptKdfParams, scryptKdfParams1); + Assert.assertEquals(scryptKdfParams, scryptKdfParams2); + Assert.assertNotEquals(scryptKdfParams, null); + Assert.assertNotEquals(scryptKdfParams, new Object()); + Assert.assertEquals(0, scryptKdfParams.hashCode()); + + WalletFile.Crypto crypto = new WalletFile.Crypto(); + WalletFile.Crypto crypto1 = new WalletFile.Crypto(); + WalletFile.Crypto crypto2 = (WalletFile.Crypto) getSame(crypto); + Assert.assertEquals(crypto, crypto1); + Assert.assertEquals(crypto, crypto2); + Assert.assertNotEquals(crypto, null); + Assert.assertNotEquals(crypto, new Object()); + Assert.assertEquals(0, crypto.hashCode()); + + } + + private Object getSame(Object obj) { + return obj; } } \ No newline at end of file diff --git a/framework/src/test/java/org/tron/keystroe/CredentialsTest.java b/framework/src/test/java/org/tron/keystroe/CredentialsTest.java new file mode 100644 index 00000000000..ce992c3443f --- /dev/null +++ b/framework/src/test/java/org/tron/keystroe/CredentialsTest.java @@ -0,0 +1,34 @@ +package org.tron.keystroe; + +import lombok.var; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; +import org.tron.common.crypto.SignInterface; +import org.tron.keystore.Credentials; + +public class CredentialsTest { + + @Test + public void test_equality() { + var aObject = new Object(); + var si = Mockito.mock(SignInterface.class); + var si2 = Mockito.mock(SignInterface.class); + var si3 = Mockito.mock(SignInterface.class); + var address = "TQhZ7W1RudxFdzJMw6FvMnujPxrS6sFfmj".getBytes(); + var address2 = "TNCmcTdyrYKMtmE1KU2itzeCX76jGm5Not".getBytes(); + Mockito.when(si.getAddress()).thenReturn(address); + Mockito.when(si2.getAddress()).thenReturn(address); + Mockito.when(si3.getAddress()).thenReturn(address2); + var aCredential = Credentials.create(si); + Assert.assertFalse(aObject.equals(aCredential)); + Assert.assertFalse(aCredential.equals(aObject)); + Assert.assertFalse(aCredential.equals(null)); + var anotherCredential = Credentials.create(si); + Assert.assertTrue(aCredential.equals(anotherCredential)); + var aCredential2 = Credentials.create(si2); + Assert.assertTrue(aCredential.equals(anotherCredential)); + var aCredential3 = Credentials.create(si3); + Assert.assertFalse(aCredential.equals(aCredential3)); + } +} diff --git a/framework/src/test/java/org/tron/program/AccountVoteWitnessTest.java b/framework/src/test/java/org/tron/program/AccountVoteWitnessTest.java index 9f61d91a938..decdbff5e25 100755 --- a/framework/src/test/java/org/tron/program/AccountVoteWitnessTest.java +++ b/framework/src/test/java/org/tron/program/AccountVoteWitnessTest.java @@ -22,8 +22,7 @@ public class AccountVoteWitnessTest extends BaseTest { private MaintenanceManager maintenanceManager; static { - dbPath = "output_witness_test"; - Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); + Args.setParam(new String[]{"-d", dbPath()}, Constant.TEST_CONF); } private static Boolean deleteFolder(File index) { diff --git a/framework/src/test/java/org/tron/program/LiteFullNodeToolTest.java b/framework/src/test/java/org/tron/program/LiteFullNodeToolTest.java index e7e164e8e3b..d1da0bf00d8 100644 --- a/framework/src/test/java/org/tron/program/LiteFullNodeToolTest.java +++ b/framework/src/test/java/org/tron/program/LiteFullNodeToolTest.java @@ -5,7 +5,6 @@ import java.io.File; import java.nio.file.Paths; import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; import org.junit.After; import org.junit.Test; @@ -25,6 +24,7 @@ import org.tron.tool.litefullnode.LiteFullNodeTool; @Slf4j +@Deprecated public class LiteFullNodeToolTest { private TronApplicationContext context; @@ -43,8 +43,6 @@ public void startApp() { appTest = ApplicationFactory.create(context); appTest.addService(context.getBean(RpcApiService.class)); appTest.addService(context.getBean(RpcApiServiceOnSolidity.class)); - appTest.initServices(Args.getInstance()); - appTest.startServices(); appTest.startup(); String fullNode = String.format("%s:%d", "127.0.0.1", @@ -76,9 +74,7 @@ public void shutdown() throws InterruptedException { if (channelFull != null) { channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); } - appTest.shutdownServices(); - appTest.shutdown(); - context.destroy(); + context.close(); } public void init() { diff --git a/framework/src/test/java/org/tron/program/SolidityNodeTest.java b/framework/src/test/java/org/tron/program/SolidityNodeTest.java index 422ec5e6876..a77fa2fa8c6 100755 --- a/framework/src/test/java/org/tron/program/SolidityNodeTest.java +++ b/framework/src/test/java/org/tron/program/SolidityNodeTest.java @@ -1,33 +1,37 @@ package org.tron.program; import java.io.File; +import java.io.IOException; +import javax.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import org.tron.common.application.TronApplicationContext; +import org.tron.common.BaseTest; import org.tron.common.client.DatabaseGrpcClient; import org.tron.core.Constant; -import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; import org.tron.core.services.RpcApiService; +import org.tron.core.services.http.solidity.SolidityNodeHttpApiService; import org.tron.protos.Protocol.Block; import org.tron.protos.Protocol.DynamicProperties; @Slf4j -public class SolidityNodeTest { +public class SolidityNodeTest extends BaseTest { - private static TronApplicationContext context; - - private static RpcApiService rpcApiService; - private static String dbPath = "output_sn_test"; + @Resource + RpcApiService rpcApiService; + @Resource + SolidityNodeHttpApiService solidityNodeHttpApiService; static { - Args.setParam(new String[]{"-d", dbPath}, Constant.TEST_CONF); - context = new TronApplicationContext(DefaultConfig.class); + try { + Args.setParam(new String[]{"-d", temporaryFolder.newFolder().toString()}, Constant.TEST_CONF); + } catch (IOException e) { + Assert.fail("create temp directory failed."); + } Args.getInstance().setSolidityNode(true); - rpcApiService = context.getBean(RpcApiService.class); } /** @@ -35,7 +39,6 @@ public class SolidityNodeTest { */ @BeforeClass public static void init() { - rpcApiService.start(); } /** @@ -44,14 +47,6 @@ public static void init() { @AfterClass public static void removeDb() { Args.clearParam(); - rpcApiService.stop(); - context.destroy(); - File dbFolder = new File(dbPath); - if (deleteFolder(dbFolder)) { - logger.info("Release resources successful."); - } else { - logger.info("Release resources failure."); - } } private static Boolean deleteFolder(File index) { @@ -74,6 +69,8 @@ public void testSolidityArgs() { @Test public void testSolidityGrpcCall() { + rpcApiService.init(Args.getInstance()); + rpcApiService.start(); DatabaseGrpcClient databaseGrpcClient = null; String address = Args.getInstance().getTrustNodeAddr(); try { @@ -97,6 +94,14 @@ public void testSolidityGrpcCall() { logger.error("Failed to create database grpc client {}", address); } databaseGrpcClient.shutdown(); + rpcApiService.stop(); } + @Test + public void testSolidityNodeHttpApiService() { + solidityNodeHttpApiService.init(Args.getInstance()); + solidityNodeHttpApiService.start(); + solidityNodeHttpApiService.stop(); + Assert.assertTrue(true); + } } diff --git a/framework/src/test/java/org/tron/program/SupplementTest.java b/framework/src/test/java/org/tron/program/SupplementTest.java index 5655ee4a098..ffa6b14f46b 100644 --- a/framework/src/test/java/org/tron/program/SupplementTest.java +++ b/framework/src/test/java/org/tron/program/SupplementTest.java @@ -5,16 +5,14 @@ import static org.junit.Assert.assertTrue; import java.io.File; +import java.io.IOException; import java.math.BigInteger; import javax.annotation.Resource; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.tron.common.BaseTest; import org.tron.common.config.DbBackupConfig; import org.tron.common.entity.PeerInfo; import org.tron.common.utils.CompactEncoder; @@ -23,18 +21,14 @@ import org.tron.core.Constant; import org.tron.core.capsule.StorageRowCapsule; import org.tron.core.capsule.utils.RLP; -import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; import org.tron.core.services.http.HttpSelfFormatFieldName; import org.tron.core.store.StorageRowStore; import org.tron.keystore.WalletUtils; -@RunWith(SpringJUnit4ClassRunner.class) -@DirtiesContext -@ContextConfiguration(classes = {DefaultConfig.class}) -public class SupplementTest { +public class SupplementTest extends BaseTest { - private static final String dbPath = "output_coverage_test"; + private static String dbPath; @Resource private StorageRowStore storageRowStore; @@ -43,7 +37,8 @@ public class SupplementTest { public ExpectedException thrown = ExpectedException.none(); @BeforeClass - public static void init() { + public static void init() throws IOException { + dbPath = dbPath(); Args.setParam(new String[]{"--output-directory", dbPath, "--debug"}, Constant.TEST_CONF); } @@ -53,7 +48,8 @@ public void testGet() throws Exception { assertNotNull(storageRowCapsule); DbBackupConfig dbBackupConfig = new DbBackupConfig(); - dbBackupConfig.initArgs(true, "propPath", "bak1path/", "bak2path/", 1); + String p = dbPath + File.separator; + dbBackupConfig.initArgs(true, p + "propPath", p + "bak1path/", p + "bak2path/", 1); WalletUtils.generateFullNewWalletFile("123456", new File(dbPath)); WalletUtils.generateLightNewWalletFile("123456", new File(dbPath)); diff --git a/framework/src/test/resources/config-test.conf b/framework/src/test/resources/config-test.conf index 40c175f53a9..74a4bad09ea 100644 --- a/framework/src/test/resources/config-test.conf +++ b/framework/src/test/resources/config-test.conf @@ -66,6 +66,8 @@ storage { # the estimated number of block transactions (default 1000, min 100, max 10000). # so the total number of cached transactions is 65536 * txCache.estimatedTransactions txCache.estimatedTransactions = 50 + # if true, transaction cache initialization will be faster. default false + txCache.initOptimization = true stateRoot.switch = true stateGenesis.directory = "state-genesis" stateRoot.db = { @@ -357,6 +359,7 @@ committee = { rate.limiter.global.qps = 1000 rate.limiter.global.ip.qps = 1000 +rate.limiter.global.api.qps = 100 rate.limiter.http = [ { component = "GetNowBlockServlet", diff --git a/framework/src/test/resources/daily-build.xml b/framework/src/test/resources/daily-build.xml deleted file mode 100644 index 4120973c34a..00000000000 --- a/framework/src/test/resources/daily-build.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/framework/src/test/resources/solcDir/README.txt b/framework/src/test/resources/solcDir/README.txt deleted file mode 100644 index f390cc49698..00000000000 --- a/framework/src/test/resources/solcDir/README.txt +++ /dev/null @@ -1 +0,0 @@ -to storage solidity compiler \ No newline at end of file diff --git a/framework/src/test/resources/solidityFile.xml b/framework/src/test/resources/solidityFile.xml deleted file mode 100644 index 6082ba41ccd..00000000000 --- a/framework/src/test/resources/solidityFile.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/AssertException002.sol b/framework/src/test/resources/soliditycode/AssertException002.sol deleted file mode 100644 index 15cc07ff984..00000000000 --- a/framework/src/test/resources/soliditycode/AssertException002.sol +++ /dev/null @@ -1,17 +0,0 @@ - - -contract AssertException{ - function divideIHaveArgsReturn(int x,int y) public returns (int z) { - return x / y; - } - function testAssert() public { - require(2==1); - } -} -contract C { - constructor() public payable { - assert(1==2); - } - function fun() public { - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/AssignToExternal.sol b/framework/src/test/resources/soliditycode/AssignToExternal.sol deleted file mode 100644 index d4f09590a36..00000000000 --- a/framework/src/test/resources/soliditycode/AssignToExternal.sol +++ /dev/null @@ -1,30 +0,0 @@ -contract AssignToExternal { - // Not allow: - // function f(uint256[] calldata x, uint256[] calldata y) external pure { - // x = y; - // } - - // allow: - - function f(uint256 a) external returns (uint){ - a = a + 1; - return a; - } - - function StringSet(string calldata a) external returns (string memory){ - return a; - } - - function ByteSet(bytes32 a) external returns (bytes32){ - return a; - } - - function UintArraySet(uint256[2] calldata a) external returns (uint256[2] memory){ - return a; - } - - function AddSet(address a) external returns (address){ - return a; - } - -} diff --git a/framework/src/test/resources/soliditycode/BlockHash.sol b/framework/src/test/resources/soliditycode/BlockHash.sol deleted file mode 100644 index 6603da65e44..00000000000 --- a/framework/src/test/resources/soliditycode/BlockHash.sol +++ /dev/null @@ -1,38 +0,0 @@ -contract TestBlockHash { - - function testOR1(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = blockhash(block.number - 1) | bytes32(value); - return (b1, c, blockhash(block.number - 1)); - } - - function testOR2(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = bytes32(value) | blockhash(block.number - 1); - return (b1, c, blockhash(block.number - 1)); - } - - function testAND1(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = blockhash(block.number - 1) & bytes32(value); - return (b1, c, blockhash(block.number - 1)); - } - - function testAND2(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = bytes32(value) & blockhash(block.number - 1); - return (b1, c, blockhash(block.number - 1)); - } - - function testXOR1(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = blockhash(block.number - 1) ^ bytes32(value); - return (b1, c, blockhash(block.number - 1)); - } - - function testXOR2(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = bytes32(value) ^ blockhash(block.number - 1); - return (b1, c, blockhash(block.number - 1)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/ClearAbi001.sol b/framework/src/test/resources/soliditycode/ClearAbi001.sol deleted file mode 100644 index 39a8e8cf005..00000000000 --- a/framework/src/test/resources/soliditycode/ClearAbi001.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract testConstantContract{ -function testPayable() public view returns (int z) { -return 1; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/ClearAbi005.sol b/framework/src/test/resources/soliditycode/ClearAbi005.sol deleted file mode 100644 index a3115398386..00000000000 --- a/framework/src/test/resources/soliditycode/ClearAbi005.sol +++ /dev/null @@ -1,26 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract TestConstract { - uint public i=0; - constructor () public { - } - function plusOne() public returns(uint){ - i++; - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/ConstructorDefaults.sol b/framework/src/test/resources/soliditycode/ConstructorDefaults.sol deleted file mode 100644 index 4b6186ccb95..00000000000 --- a/framework/src/test/resources/soliditycode/ConstructorDefaults.sol +++ /dev/null @@ -1,9 +0,0 @@ -contract testIsContract{ - bool result; - constructor (bool a) public { - result = a; - } -function test( address a) public returns (bool) { -return result; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/Create2Test023.sol b/framework/src/test/resources/soliditycode/Create2Test023.sol deleted file mode 100644 index ef022a8e83d..00000000000 --- a/framework/src/test/resources/soliditycode/Create2Test023.sol +++ /dev/null @@ -1,31 +0,0 @@ -contract factory { - constructor() payable public { - } - - function deploy(bytes memory code, uint256 salt) public returns(address){ - Caller addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - return address(addr); - } - - function testCreate() payable public returns (address){ - Caller add = (new Caller){value:0}(); - return address(add); - } - - function kill( ) payable public{ - selfdestruct(payable(msg.sender)); - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/Create2Test024.sol b/framework/src/test/resources/soliditycode/Create2Test024.sol deleted file mode 100644 index 5d43c0f4ab2..00000000000 --- a/framework/src/test/resources/soliditycode/Create2Test024.sol +++ /dev/null @@ -1,56 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - TestConstract addr; - TestConstract addr1; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - - addr.testSuicideNonexistentTarget(payable(msg.sender)); - addr.set(); - emit Deployed(address(addr), salt, msg.sender); - return address(addr); - } - - function deploy2(bytes memory code, uint256 salt) public returns(address){ - TestConstract addr; - TestConstract addr1; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - - //addr.testSuicideNonexistentTarget(msg.sender); - //addr.set(); - - assembly { - addr1 := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr1)) { - revert(0, 0) - } - } - emit Deployed(address(addr), salt, msg.sender); - return address(addr); - } -} - - - -contract TestConstract { - uint public i=1; - constructor () public { - } - - function set() public{ - i=9; - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/Create2Test025.sol b/framework/src/test/resources/soliditycode/Create2Test025.sol deleted file mode 100644 index 895dc43e56f..00000000000 --- a/framework/src/test/resources/soliditycode/Create2Test025.sol +++ /dev/null @@ -1,34 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - constructor() public { - } - - function create2(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } - - function get(bytes1 prefix, bytes calldata code, uint256 salt) external view returns(address) { - //bytes32 hash = keccak256(abi.encodePacked(bytes1(0x41),address(this), salt, keccak256(code))); - bytes32 hash = keccak256(abi.encodePacked(prefix,address(this), salt, keccak256(code))); - address addr = address(uint160(uint256(hash))); - return addr; - } -} - -contract TestContract{ - uint256 public num; - constructor(uint256 j) public{ - num = j; - } - function getNum() public returns (uint256){ - return num; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/EthGrammer.sol b/framework/src/test/resources/soliditycode/EthGrammer.sol deleted file mode 100644 index 1be4d2d0881..00000000000 --- a/framework/src/test/resources/soliditycode/EthGrammer.sol +++ /dev/null @@ -1,191 +0,0 @@ -contract C { - constructor() public payable{} - - function baseFee() external view returns (uint ret) { - assembly { - ret := basefee() - } - assert(block.basefee == ret); - } - - function baseFeeOnly() external view returns (uint ret) { - assembly { - ret := basefee() - } - } - - function gasPrice() external view returns (uint ret) { - assembly { - ret := basefee() - } - assert(tx.gasprice == ret); - } - - function gasPriceOnly() external view returns (uint) { - return tx.gasprice; - } - - function testCall(address payable caller, address payable transferTo) public { - (bool success, bytes memory data) = caller.call(abi.encodeWithSignature("transfer(address)",transferTo)); - require(success); - } - - function testDelegateCall(address payable caller, address payable transferTo) public { - (bool success, bytes memory data) = caller.delegatecall(abi.encodeWithSignature("transfer(address)",transferTo)); - require(success); - } - - uint sum = 0; - function transfer(address payable transerTo) public { - for (uint i = 0; i < type(uint256).max; i++) - sum = 0; - for (uint j = 0; j < type(uint8).max; j++) - sum += j; - transerTo.transfer(1); - } - - function testCallFunctionInContract(address payable transferTo) public { - this.transfer(transferTo); - } - - - function getRipemd160(string memory input) public returns(bytes32 output) { - bytes memory tem = bytes(input); - assembly { - if iszero(staticcall(not(0), 0x020003, add(tem, 0x20), mload(tem), output, 0x20)) { - revert(0, 0) - } - output := mload(add(output,0x0c)) - } - } - - function getRipemd160Str(string memory input) public view returns(bytes32 output) { - assembly { - if iszero(staticcall(not(0), 0x020003, add(input, 0x20), mload(input), output, 0x20)) { - revert(0, 0) - } - output := mload(add(output,0x0c)) - } - - } - - function F(uint32 rounds, bytes32[2] memory h, bytes32[4] memory m, bytes8[2] memory t, bool f) public view returns (bytes32[2] memory) { - bytes32[2] memory output; - - bytes memory args = abi.encodePacked(rounds, h[0], h[1], m[0], m[1], m[2], m[3], t[0], t[1], f); - - assembly { - if iszero(staticcall(not(0), 0x020009, add(args, 32), 0xd5, output, 0x40)) { - revert(0, 0) - } - } - - return output; - } - - function callF() public view returns (bytes32[2] memory) { - uint32 rounds = 12; - - bytes32[2] memory h; - h[0] = hex"48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5"; - h[1] = hex"d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b"; - - bytes32[4] memory m; - m[0] = hex"6162630000000000000000000000000000000000000000000000000000000000"; - m[1] = hex"0000000000000000000000000000000000000000000000000000000000000000"; - m[2] = hex"0000000000000000000000000000000000000000000000000000000000000000"; - m[3] = hex"0000000000000000000000000000000000000000000000000000000000000000"; - - bytes8[2] memory t; - t[0] = hex"03000000"; - t[1] = hex"00000000"; - - bool f = true; - - // Expected output: - // ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d1 - // 7d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923 - return F(rounds, h, m, t, f); - } - - -} - -contract D { - constructor() public payable{} - - function deploy(uint256 salt) public returns(address){ - address addr; - bytes memory code = type(C).creationCode; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - } - return addr; - } - - uint sum = 0; - function transfer(address payable transerTo) public { - for (uint i = 0; i < type(uint256).max; i++) - sum = 0; - for (uint j = 0; j < type(uint8).max; j++) - sum += j; - transerTo.transfer(1); - } - - function callCreate2(uint256 salt) public returns(address){ - address addr; - bytes memory code = type(C).creationCode; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - } - return addr; - } - - function fixCreate2StackDepth(uint salt) public { - if (isEmptyAddress(callCreate2(salt + 1))) { - revert(); - } - this.fixCreate2StackDepth(salt + 1); - } - - function callCreate() public returns(address){ - address addr; - bytes memory code = type(C).creationCode; - assembly { - addr := create(0, add(code, 0x20), mload(code)) - } - return addr; - } - - function fixCreateStackDepth() public { - if (isEmptyAddress(callCreate())) { - revert(); - } - this.fixCreateStackDepth(); - } - - bool constant bool1 = true; - function isEmptyAddress(address add2) public returns(bool result){ - - assembly { - if iszero(extcodesize(add2)) { - result := bool1 - } - } - } - - function deployef(bytes memory code) public payable{ - address addr; - assembly { - addr := create(0, add(code, 0x20), mload(code)) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - } -} - - - - - diff --git a/framework/src/test/resources/soliditycode/EthGrammer02.sol b/framework/src/test/resources/soliditycode/EthGrammer02.sol deleted file mode 100644 index d032b531fa6..00000000000 --- a/framework/src/test/resources/soliditycode/EthGrammer02.sol +++ /dev/null @@ -1,45 +0,0 @@ -contract D { - constructor() public payable{} - - event createAddress(address addr); - function createDeployEf(bytes memory code) public returns(address addr){ - address addr; - assembly { - addr := create(0, add(code, 0x20), mload(code)) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - return addr; - } - - function create2DeployEf(bytes memory code,uint256 salt) public returns(address addr){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit createAddress(addr); - return addr; - } - - function setSlot(bytes memory slot,uint256 value) external { -// uint256 value = 123; - assembly { - sstore(slot, value) - } - } - - function getSlot(bytes memory slot) view external returns(uint res) { - assembly { - res := sload(slot) - } - } -} - - - - - diff --git a/framework/src/test/resources/soliditycode/ExtCodeHashTest010.sol b/framework/src/test/resources/soliditycode/ExtCodeHashTest010.sol deleted file mode 100644 index e54c302addb..00000000000 --- a/framework/src/test/resources/soliditycode/ExtCodeHashTest010.sol +++ /dev/null @@ -1,46 +0,0 @@ -contract Counter { - uint count = 0; - address payable owner; - event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); - constructor() public{ - owner = payable(msg.sender); - } - function getCodeHashSuicide(address addr) public returns (bytes32 _hashBefore){ - assembly{ - _hashBefore := extcodehash(addr) - } - selfdestruct(owner); - return _hashBefore; - } - - function getCodeHashRevert() public returns (bytes32 _hashBefore, bytes32 _hashAfter) { - address addr = address(this); - assembly { - _hashBefore := extcodehash(addr) - } - if (owner == msg.sender) { - selfdestruct(owner); - } - assembly { - _hashAfter := extcodehash(addr) - } - revert(); - emit LogResult(_hashBefore, _hashAfter); - } - - function getCodeHashCreate() public returns (bytes32 _hashBefore){ - TestContract A = (new TestContract){value:0}(); - address addr = address(A); - assembly{ - _hashBefore := extcodehash(addr) - } - revert(); - return _hashBefore; - } -} - -contract TestContract{ - uint256 count = 1; - constructor() public payable{ - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/ExternalSelector.sol b/framework/src/test/resources/soliditycode/ExternalSelector.sol deleted file mode 100644 index 01fddac9e2e..00000000000 --- a/framework/src/test/resources/soliditycode/ExternalSelector.sol +++ /dev/null @@ -1,92 +0,0 @@ -//pragma solidity ^0.6.0; - -contract selectorContract { - function testSelectorNoParam() external pure returns(uint) { - return 11; - } - - function testSelectorWithParam(uint x) external pure returns(uint) { - return 22; - } -} - -interface interfaceSelector { - function getSelector() external pure returns(uint); -} - -interface B is interfaceSelector { - // interface现在可以继承自其他interface - function testImplemention() external pure returns(uint); -} - -contract implementContract is B{ - function getSelector() external override pure returns(uint) { - return 66; - } - - function testImplemention() external override pure returns(uint) { - return 77; - } - - constructor() public payable {} -} - -contract basicContract{ - function testNewUse() external payable returns(uint) { - return 345; - } - - constructor() public payable {} -} - -contract TestGasValue{ - constructor() public payable {} - - function testNewUse() external payable returns(uint) { - return 123; - } - basicContract bc = new basicContract(); - // external方法在调用时可以采用c.f{gas: 10000, value: 4 trx}()的形式 - function callWithGasAndValue(uint x,uint y) external returns(uint) { - return bc.testNewUse{gas:x, value:y}(); - } - - function callThisNoGasAnd1Value() external returns(uint) { - return this.testNewUse{gas:0, value:1}(); - } - - // inline assembly中允许true和false字面量 - function testAssemblyTrue() public pure returns(uint x) { - assembly { - x := true - } - } - - // inline assembly中允许true和false字面量 - function testAssemblyFalse() public pure returns(uint x) { - assembly { - x := false - } - } - - // create2的high-level用法new C{salt: 0x1234, value: 1 ether}(arg1, arg2) - function testCreate2() public returns(address) { - basicContract c = new basicContract{salt: bytes32(bytes1(0x01)), value: 1 trx}(); - return address(c); - } - - - function getContractSelectorNoParam() public pure returns(bytes4) { - return selectorContract.testSelectorNoParam.selector; - } - - function getContractSelectorWithParam() public pure returns(bytes4) { - return selectorContract.testSelectorWithParam.selector; - } - - function getInterfaceSelectorNoParam() public pure returns(bytes4) { - return interfaceSelector.getSelector.selector; - } - -} - diff --git a/framework/src/test/resources/soliditycode/NewFeature068.sol b/framework/src/test/resources/soliditycode/NewFeature068.sol deleted file mode 100644 index 8bfe805450c..00000000000 --- a/framework/src/test/resources/soliditycode/NewFeature068.sol +++ /dev/null @@ -1,131 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -//pragma solidity ^0.6.8; - -abstract contract testModifier { - modifier isOwner() virtual; -} - -abstract contract testInterfaceId { - function getValue() external view virtual returns(uint); - function getOwner() external view virtual returns(uint); - -} - -interface a { - function getValue() external view returns(uint); - function getOwner() external view returns(uint); -} - -contract testMapKey is testModifier{ - - enum size{ - SMALL, - LARGE - } - - mapping(size => uint) public enums; - - mapping(testMapKey => uint) public contracts; - - function setEnumValue(uint value) public { - enums[size.SMALL] = value; - } - - function getEnumValue() public view returns(uint) { - return enums[size.SMALL]; - } - - function setContractValue() public { - contracts[this] = 2; - } - - function getContractValue() public view returns(uint) { - return contracts[this]; - } - - bytes4 constant functionSelector = this.getEnumValue.selector; - - function getfunctionSelector() public pure returns(bytes4) { - return functionSelector; - } - - uint immutable x; - address immutable owner = msg.sender; - - constructor() public { - x = 5; - } - - string b = "test"; - - function testStorage() public view returns(string memory) { - string storage aa; - aa = b; - return aa; - - } - - function getImmutableVal() public view returns(uint) { - return x; - } - - function getOwner() public view returns(address) { - return owner; - } - - function getInterfaceId() public pure returns(bytes4,bytes4) { - return (type(a).interfaceId, type(testInterfaceId).interfaceId); - } - - modifier isOwner() override { - require(msg.sender == owner); - _; - } - - function requireOwner() public view isOwner returns(uint) { - return 6; - } - - - function getUint256MinAndMax() public pure returns(uint, uint) { - return (type(uint).min, type(uint).max); - } - - - function getUint8MinAndMax() public pure returns(uint8, uint8) { - return (type(uint8).min, type(uint8).max); - } - - function calldataModifier(bytes calldata a) external returns(bytes calldata) { - bytes calldata b = a; - return b; - } - -} - - -abstract contract base { - function abstractfun() virtual public returns(uint); -} - -abstract contract callEmptyFunction is base { - function callfun() public returns(uint) { - return abstractfun(); - } -} - - - - - - - - - - - - - - - - diff --git a/framework/src/test/resources/soliditycode/NewFeature076.sol b/framework/src/test/resources/soliditycode/NewFeature076.sol deleted file mode 100644 index 3191acb8f1d..00000000000 --- a/framework/src/test/resources/soliditycode/NewFeature076.sol +++ /dev/null @@ -1,21 +0,0 @@ -function a() returns (uint) { - return 1; -} -abstract contract abvd { - -} -interface qwer { - function getValue() external view returns(uint); - function getOwner() external view returns(uint); -} -contract C { - function getOutsideMethod() external returns (uint) { - return a(); - } - function getAbstractName() public returns(string memory) { - return type(abvd).name; - } - function getInterfaceName() public returns(string memory) { - return type(qwer).name; - } -} diff --git a/framework/src/test/resources/soliditycode/NewFeature080.sol b/framework/src/test/resources/soliditycode/NewFeature080.sol deleted file mode 100644 index 7422e8d34b4..00000000000 --- a/framework/src/test/resources/soliditycode/NewFeature080.sol +++ /dev/null @@ -1,109 +0,0 @@ -contract C { - constructor() public payable{} - - function subNoUncheck() public pure returns (uint) { - uint8 x = 0; - return x--; - } - - function subWithUncheck() public pure returns (uint) { - uint8 x = 0; - unchecked { x--; } - return x; - } - - function addNoUncheck() public pure returns (uint) { - uint8 x = 255; - return x++; - } - - function divideZeroNoUncheck() public pure returns (uint) { - uint8 x = 0; - uint8 y = 1; - return y/x; - } - - function assertFailNoUncheck() public pure { - assert(1==2); - } - - int64[] b = [-1, 2, -3]; - function arrayOutofIndex() public view returns (int) { - return b[3]; - } - - function typeConvert() public pure returns(uint16) { - // return uint16(int8(-1)); //0.8.0报错 之前不报错 - return uint16(int16(int8(-1))); //0xffff - // return uint16(uint8(int8(-1))); // 0xff - } - - function powerMultiRightToLeft() public pure returns(uint) { - return 2**1**2**3; - } - - function powerMultiLeftToRight() public pure returns(uint) { - return ((2**1)**2)**3; - } - - function powerMultiWith2Params() public pure returns(uint) { - return 2**3; - } - //log 0,1,2,3 disallowed in solidity v0.8.0 -// function f2() public payable { -// uint256 x=1; -// uint256 y=2; -// uint256 z=3; -// bytes32 _id = bytes32(x); -// log3( -// bytes32(x), -// bytes32(y), -// bytes32(z), -// _id -// ); -// } - - - function getBlockChainId111111() view public returns(uint256) { - return block.chainid; - } - - - function getBlockChainId() view public returns(uint256) { - uint256 id; - assembly { - id := chainid() - } - assert(block.chainid == id); - return block.chainid; - } - function getAddressCodehash(address addr) view public returns(bytes32 newHash) { - bytes32 _hashBefore; - assembly{ - _hashBefore := extcodehash(addr) - } - bytes32 newHash = addr.codehash; - assert(_hashBefore == newHash); - return newHash; - } - - function transferToTxorigin(uint64 value) payable public { - payable(tx.origin).transfer(value); - } - -// msg.data was removed in receive() function -// event FallbackCalled(bytes data); -// receive() external payable { -// -// emit FallbackCalled(msg.data); -// } - - function transferToLiteralAddress(uint64 value) public{ - uint160 num = type(uint160).max-3; - address add = address(num); - payable(add).transfer(value); - } -} - - - diff --git a/framework/src/test/resources/soliditycode/NewFeature0811.sol b/framework/src/test/resources/soliditycode/NewFeature0811.sol deleted file mode 100644 index bb7cb1ab567..00000000000 --- a/framework/src/test/resources/soliditycode/NewFeature0811.sol +++ /dev/null @@ -1,101 +0,0 @@ - -type TestInt128 is int128; -pragma abicoder v2; -interface I { -function foo() external; -} - -contract C is I { -uint8 immutable i; -uint8 x; - -constructor() { -i = 33; -x = readI(); -} - -function readX() public view returns (uint8) { -return x; -} - -function readI() public view returns (uint8) { -return i; -} - - - - -function fExternal(uint256 p, string memory t) external {} - -function fSignatureFromLiteralCall() public view returns (bytes memory) { -return abi.encodeCall(this.fExternal, (1, "123")); -} - - - - - -enum FreshJuiceSize{ SMALL, MEDIUM, LARGE, FINAL } - - -TestInt128 a = TestInt128.wrap(45); -function getUserDefinedValue() public view returns(TestInt128) { -return a; -} - - - - -function foo() external { // Does not compile without override -} - -function getEnumMin() public view returns (FreshJuiceSize) { -return type(FreshJuiceSize).min; - -} - - -function getEnumMax() public view returns (FreshJuiceSize) { -return type(FreshJuiceSize).max; - -} - - -function testFunction() external {} - -function testYul1() public view returns (address adr) { -function() external fp = this.testFunction; - -assembly { -adr := fp.address -} -} -function testGetAddress() public view returns (address) { -return this.testFunction.address; -} -function testYul2() public view returns (uint32) { -function() external fp = this.testFunction; -uint selectorValue = 0; - -assembly { -selectorValue := fp.selector -} - -// Value is right-aligned, we shift it so it can be compared -return uint32(bytes4(bytes32(selectorValue << (256 - 32)))); -} -function testGetSelector() public view returns (uint32) { -return uint32(this.testFunction.selector); -} - - - -int8 immutable bugValue = -4; -function fixBugTest() public view returns (bytes32 r) { -int8 y = bugValue; -assembly { r := y } -} - - - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/NewFeature086.sol b/framework/src/test/resources/soliditycode/NewFeature086.sol deleted file mode 100644 index f898fadde3e..00000000000 --- a/framework/src/test/resources/soliditycode/NewFeature086.sol +++ /dev/null @@ -1,121 +0,0 @@ -contract C { - constructor() public payable{} - - function catchAssertFail() external view returns(uint) { - try this.assertFail() { - return 0; - } catch Panic(uint _code) { - if (_code == 0x01) { - return 0x01; - } - return 2; - } - return 3; - } - function assertFail() external pure { - assert(0 == 1); - } - function catchUnderFlow() external view returns(uint) { - try this.underflow() { - return 44; - } catch Panic(uint _code) { - if (_code == 0x11) { - return 0x11; - } - return 22; - } - return 33; - } - function underflow() public pure { - uint x = 0; - x--; - } - - function catchDivideZero() external view returns(uint) { - try this.divideZero() { - return 14; - } catch Panic(uint _code) { - if (_code == 0x12) { - return 0x12; - } - return 11; - } - return 13; - } - function divideZero() public pure { - uint8 x = 0; - uint8 y = 1; - uint8 z = y/x; - } - - function convertUint2Int() public pure { - uint16 a = 1; -// int32 b = int32(a); -// int32 b = a; - } - - function getAddressCodeLength() public returns(uint) { - return address(this).code.length; - } - - function keccak256Bug(string memory s) public returns (bool ret) { - assembly { - let a := keccak256(s, 32) - let b := keccak256(s, 8) - ret := eq(a, b) - } - } - - error InsufficientBalance(uint256 available, uint256 required); - mapping(address => uint) balance; - function transfer(address to, uint256 amount) public { - if (amount > balance[msg.sender]) - revert InsufficientBalance({available: balance[msg.sender], required: amount}); - balance[msg.sender] -= amount; - balance[to] += amount; - } - - error Unauthorized(); - function withdraw() public { - address payable owner; - if (msg.sender != owner) - revert Unauthorized(); - owner.transfer(address(this).balance); - } - - bytes s = "Storage"; - function bytesConcat(bytes calldata c, string memory m, bytes16 b) public view returns(uint256) { - bytes memory a = bytes.concat(s, c, c[:2], "Literal", bytes(m), b); - assert((s.length + c.length + 2 + 7 + bytes(m).length + 16) == a.length); - return a.length; - } - - bytes p = "hihello"; - function bytesConcatWithEmptyStr() public view { - bytes memory a = bytes.concat("hi", "", "hello"); - assert(p.length == a.length); - } - - event ssoo(uint256); - function testEmitEvent() public payable { - emit ssoo(6); - } - - function bytes2BytesN(bytes memory c) public returns (bytes8) { - // If c is longer than 8 bytes, truncation happens - return bytes3(c); - } - - function getContractAddress() public view returns (address a1, address a2) { - a1 = address(this); - this.getContractAddress.address; - [this.getContractAddress.address][0]; - a2 = [this.getContractAddress.address][0]; - } - -} - - - - - diff --git a/framework/src/test/resources/soliditycode/NoAbi001.sol b/framework/src/test/resources/soliditycode/NoAbi001.sol deleted file mode 100644 index 8f919cbb153..00000000000 --- a/framework/src/test/resources/soliditycode/NoAbi001.sol +++ /dev/null @@ -1,10 +0,0 @@ -contract testNoABiContract{ - uint public i = 2; - event trigger(uint256 i, address sender); - - function testTrigger() public returns (uint) { - i++; - emit trigger(i, msg.sender); - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/NoAbi002.sol b/framework/src/test/resources/soliditycode/NoAbi002.sol deleted file mode 100644 index 0bb30e78443..00000000000 --- a/framework/src/test/resources/soliditycode/NoAbi002.sol +++ /dev/null @@ -1,29 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract testNoABiContract { - uint public i=0; - event trigger(uint256 i, address sender); - - constructor () public {} - - function plusOne() public returns(uint){ - i++; - emit trigger(i, msg.sender); - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/ParentTypeBug.sol b/framework/src/test/resources/soliditycode/ParentTypeBug.sol deleted file mode 100644 index 897c843ae24..00000000000 --- a/framework/src/test/resources/soliditycode/ParentTypeBug.sol +++ /dev/null @@ -1,13 +0,0 @@ -contract Parent { - uint256 public m_aMember; - address public m_bMember; -} -contract Child is Parent { - function foo() public view returns (uint256) { return Parent.m_aMember; } - function bar() public view returns (address) { return Parent.m_bMember; } - - // complie failed - // function foo() public pure returns (uint256) { return Parent.m_aMember; } - // function bar() public pure returns (address) { return Parent.m_bMember; } - -} diff --git a/framework/src/test/resources/soliditycode/SafeMath.sol b/framework/src/test/resources/soliditycode/SafeMath.sol deleted file mode 100644 index 1a7f1be2b8e..00000000000 --- a/framework/src/test/resources/soliditycode/SafeMath.sol +++ /dev/null @@ -1,149 +0,0 @@ - - -/** - * @dev Wrappers over Solidity's arithmetic operations with added overflow - * checks. - * - * Arithmetic operations in Solidity wrap on overflow. This can easily result - * in bugs, because programmers usually assume that an overflow raises an - * error, which is the standard behavior in high level programming languages. - * `SafeMath` restores this intuition by reverting the transaction when an - * operation overflows. - * - * Using this library instead of the unchecked operations eliminates an entire - * class of bugs, so it's recommended to use it always. - */ -library SafeMath { - /** - * @dev Returns the addition of two unsigned integers, reverting on - * overflow. - * - * Counterpart to Solidity's `+` operator. - * - * Requirements: - * - Addition cannot overflow. - */ - function add(uint256 a, uint256 b) internal pure returns (uint256) { - uint256 c = a + b; - require(c >= a, "SafeMath: addition overflow"); - - return c; - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting on - * overflow (when the result is negative). - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - Subtraction cannot overflow. - */ - function sub(uint256 a, uint256 b) internal pure returns (uint256) { - return sub(a, b, "SafeMath: subtraction overflow"); - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting with custom message on - * overflow (when the result is negative). - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - Subtraction cannot overflow. - */ - function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b <= a, errorMessage); - uint256 c = a - b; - - return c; - } - - /** - * @dev Returns the multiplication of two unsigned integers, reverting on - * overflow. - * - * Counterpart to Solidity's `*` operator. - * - * Requirements: - * - Multiplication cannot overflow. - */ - function mul(uint256 a, uint256 b) internal pure returns (uint256) { - // Gas optimization: this is cheaper than requiring 'a' not being zero, but the - // benefit is lost if 'b' is also tested. - // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 - if (a == 0) { - return 0; - } - - uint256 c = a * b; - require(c / a == b, "SafeMath: multiplication overflow"); - - return c; - } - - /** - * @dev Returns the integer division of two unsigned integers. Reverts on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. Note: this function uses a - * `revert` opcode (which leaves remaining gas untouched) while Solidity - * uses an invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - return div(a, b, "SafeMath: division by zero"); - } - - /** - * @dev Returns the integer division of two unsigned integers. Reverts with custom message on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. Note: this function uses a - * `revert` opcode (which leaves remaining gas untouched) while Solidity - * uses an invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b > 0, errorMessage); - uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - - return c; - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * Reverts when dividing by zero. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function mod(uint256 a, uint256 b) internal pure returns (uint256) { - return mod(a, b, "SafeMath: modulo by zero"); - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * Reverts with custom message when dividing by zero. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b != 0, errorMessage); - return a % b; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/ShiftCommand001.sol b/framework/src/test/resources/soliditycode/ShiftCommand001.sol deleted file mode 100644 index 574ee2b571b..00000000000 --- a/framework/src/test/resources/soliditycode/ShiftCommand001.sol +++ /dev/null @@ -1,18 +0,0 @@ -contract TestBitwiseShift { - - function shlTest(uint256 num, uint256 input) public returns (bytes32 out) { - assembly { - out := shl(num, input) - } - } - function shrTest(uint256 num, uint256 input) public returns (bytes32 out) { - assembly { - out := shr(num, input) - } - } - function sarTest(uint256 num, uint256 input) public returns (bytes32 out) { - assembly { - out := sar(num, input) - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/SolidityMappingFix.sol b/framework/src/test/resources/soliditycode/SolidityMappingFix.sol deleted file mode 100644 index 98f9752e4b3..00000000000 --- a/framework/src/test/resources/soliditycode/SolidityMappingFix.sol +++ /dev/null @@ -1,9 +0,0 @@ -//pragma experimental ABIEncoderV2; -contract Tests { - mapping(address => uint) public balances; - function update(uint256 amount) public returns (address addr) - { - balances[msg.sender] = amount; - return msg.sender; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/TestMappings_array_pop.sol b/framework/src/test/resources/soliditycode/TestMappings_array_pop.sol deleted file mode 100644 index 0d5c4bb7013..00000000000 --- a/framework/src/test/resources/soliditycode/TestMappings_array_pop.sol +++ /dev/null @@ -1,19 +0,0 @@ -contract C { - mapping (uint256 => uint256)[] a; - - function n1(uint256 key, uint256 value) public { - a.push(); - a[a.length - 1][key] = value; - } - - - - function map(uint256 key) public view returns (uint) { - return a[a.length - 1][key]; - } - - function p() public { - a.pop(); - } -} - diff --git a/framework/src/test/resources/soliditycode/TransferFailed001.sol b/framework/src/test/resources/soliditycode/TransferFailed001.sol deleted file mode 100644 index 538a07fdf5c..00000000000 --- a/framework/src/test/resources/soliditycode/TransferFailed001.sol +++ /dev/null @@ -1,147 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - - function testTransferTokenCompiledLongMax() payable public{ - payable(address(0x1)).transferToken(1,9223372036855775827); - } - - function testTransferTokenCompiled() payable public{ - payable(address(0x1)).transferToken(1,1); - } - - function testTransferTokenCompiledLongMin() payable public{ - //address(0x1).transferToken(1,-9223372036855775828); - } - - function testTransferTokenCompiledLongMin1() payable public returns(uint256){ - return address(0x2).tokenBalance(trcToken(uint256(int256(-9223372036855775828)))); - } - - function testTransferTokenCompiled1() payable public returns(uint256){ - return address(0x1).tokenBalance(trcToken(1)); - } - - function testTransferTokenCompiledLongMax1() payable public returns(uint256){ - return address(0x2).tokenBalance(trcToken(9223372036855775827)); - } - - function testTransferTokenCompiledTokenId(uint256 tokenid) payable public returns(uint256){ - return address(0x1).tokenBalance(trcToken(tokenid)); - } - - function testTransferTokenTest(address addr ,uint256 tokenid) payable public returns(uint256){ - return addr.tokenBalance(trcToken(tokenid)); - } - - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - payable(msg.sender).transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - payable(msg.sender).send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - payable(msg.sender).transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address payable caller) public { - caller.call{value:i}(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller){value:i}(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - nonexistentTarget.send(i); - } - - function testSendTrxRevert(uint256 i,address payable nonexistentTarget) payable public { - nonexistentTarget.send(i); - revert(); - } - - function testTransferTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - nonexistentTarget.transfer(i); - } - - function testTransferTrxrevert(uint256 i,address payable nonexistentTarget) payable public{ - nonexistentTarget.transfer(i); - revert(); - } - - function testTransferTokenNonexistentTarget(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - nonexistentTarget.transferToken(i, tokenId); - } - - function testTransferTokenRevert(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - nonexistentTarget.transferToken(i, tokenId); - revert(); - } - - function testCallTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - nonexistentTarget.call{value:i}(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - function testSuicideRevert(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - revert(); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - address payable self = payable(address(uint160(address(this)))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - address payable self = payable(address(uint160(address(this)))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - address payable self = payable(address(uint160(address(this)))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } - function deploy2(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(300, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/TransferFailed005.sol b/framework/src/test/resources/soliditycode/TransferFailed005.sol deleted file mode 100644 index 66b946199c2..00000000000 --- a/framework/src/test/resources/soliditycode/TransferFailed005.sol +++ /dev/null @@ -1,90 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - payable(msg.sender).transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - payable(msg.sender).send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - payable(msg.sender).transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address payable caller) public returns (bool,bytes memory){ - return caller.call{value:i}(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller){value:i}(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.send(i); - } - - function testTransferTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.transfer(i); - } - - function testTransferTokenNonexistentTarget(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - require(address(this).balance >= i); - nonexistentTarget.transferToken(i, tokenId); - } - - function testCallTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.call{value:i}(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = payable(address(uint160(address(this)))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = payable(address(uint160(address(this)))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - require(address(this).balance >= i); - address payable self = payable(address(uint160(address(this)))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256 ){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/TransferFailed006.sol b/framework/src/test/resources/soliditycode/TransferFailed006.sol deleted file mode 100644 index 66b946199c2..00000000000 --- a/framework/src/test/resources/soliditycode/TransferFailed006.sol +++ /dev/null @@ -1,90 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - payable(msg.sender).transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - payable(msg.sender).send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - payable(msg.sender).transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address payable caller) public returns (bool,bytes memory){ - return caller.call{value:i}(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller){value:i}(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.send(i); - } - - function testTransferTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.transfer(i); - } - - function testTransferTokenNonexistentTarget(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - require(address(this).balance >= i); - nonexistentTarget.transferToken(i, tokenId); - } - - function testCallTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.call{value:i}(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = payable(address(uint160(address(this)))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = payable(address(uint160(address(this)))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - require(address(this).balance >= i); - address payable self = payable(address(uint160(address(this)))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256 ){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/TransferFailed007.sol b/framework/src/test/resources/soliditycode/TransferFailed007.sol deleted file mode 100644 index 66b946199c2..00000000000 --- a/framework/src/test/resources/soliditycode/TransferFailed007.sol +++ /dev/null @@ -1,90 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - payable(msg.sender).transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - payable(msg.sender).send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - payable(msg.sender).transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address payable caller) public returns (bool,bytes memory){ - return caller.call{value:i}(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller){value:i}(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.send(i); - } - - function testTransferTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.transfer(i); - } - - function testTransferTokenNonexistentTarget(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - require(address(this).balance >= i); - nonexistentTarget.transferToken(i, tokenId); - } - - function testCallTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.call{value:i}(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = payable(address(uint160(address(this)))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = payable(address(uint160(address(this)))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - require(address(this).balance >= i); - address payable self = payable(address(uint160(address(this)))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256 ){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/TriggerConstant001.sol b/framework/src/test/resources/soliditycode/TriggerConstant001.sol deleted file mode 100644 index b385850577d..00000000000 --- a/framework/src/test/resources/soliditycode/TriggerConstant001.sol +++ /dev/null @@ -1,28 +0,0 @@ - - -contract testConstantContract{ - uint256 public i; - function testPayable() public payable returns (uint256 z) { - i=1; - z=i; - return z; - } - function testNoPayable() public returns (uint256 z) { - i=1; - z=i; - return z; - } - function testView() public view returns (uint256 z) { - uint256 i=1; - return i; - } - function testPure() public pure returns (uint256 z) { - uint256 i=1; - return i; - } - function testView2() public view returns (uint256 z) { - uint256 i=1; - revert(); - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/TriggerConstant002.sol b/framework/src/test/resources/soliditycode/TriggerConstant002.sol deleted file mode 100644 index 7708d81792a..00000000000 --- a/framework/src/test/resources/soliditycode/TriggerConstant002.sol +++ /dev/null @@ -1,10 +0,0 @@ - - -contract testConstantContract{ - uint256 public i; - function testNoPayable() public returns (uint256 z) { - i=1; - z=i; - return z; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/TriggerConstant003.sol b/framework/src/test/resources/soliditycode/TriggerConstant003.sol deleted file mode 100644 index 947b3f610e6..00000000000 --- a/framework/src/test/resources/soliditycode/TriggerConstant003.sol +++ /dev/null @@ -1,18 +0,0 @@ - - -contract testConstantContract{ - function testView() public view returns (uint256 z) { - uint256 i=1; - return i; - } - - function testPure() public pure returns (uint256 z) { - uint256 i=1; - return i; - } - - function testPayable() public payable returns (uint256 z) { - uint256 i=1; - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/TriggerConstant004.sol b/framework/src/test/resources/soliditycode/TriggerConstant004.sol deleted file mode 100644 index 7fcb44950e7..00000000000 --- a/framework/src/test/resources/soliditycode/TriggerConstant004.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract testConstantContract{ -function testPure() public pure returns (uint256 z) { -uint256 i=1; -return i; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/TriggerConstant015.sol b/framework/src/test/resources/soliditycode/TriggerConstant015.sol deleted file mode 100644 index d926c43c824..00000000000 --- a/framework/src/test/resources/soliditycode/TriggerConstant015.sol +++ /dev/null @@ -1,24 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract TestConstract { - constructor () public { - } - function plusOne() public returns(uint){ - return 1; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/TriggerConstant024.sol b/framework/src/test/resources/soliditycode/TriggerConstant024.sol deleted file mode 100644 index 69ad3a2d5b5..00000000000 --- a/framework/src/test/resources/soliditycode/TriggerConstant024.sol +++ /dev/null @@ -1,9 +0,0 @@ - - -contract testConstantContract{ -function testView() public view returns (uint256 z) { -uint256 i=1; -revert(); -return i; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/TvmIsContract.sol b/framework/src/test/resources/soliditycode/TvmIsContract.sol deleted file mode 100644 index 4266b9e92ca..00000000000 --- a/framework/src/test/resources/soliditycode/TvmIsContract.sol +++ /dev/null @@ -1,15 +0,0 @@ -contract testIsContract{ -bool public isContrct; -constructor () public { - isContrct = address(this).isContract; -} -function testIsContractCommand(address a) public returns (bool) { -return (a.isContract); -} -function selfdestructContract(address payable a) public { - selfdestruct(a); -} -function testConstructor() public returns(bool){ - return isContrct; -} -} diff --git a/framework/src/test/resources/soliditycode/TvmIsContract001.sol b/framework/src/test/resources/soliditycode/TvmIsContract001.sol deleted file mode 100644 index 77aae930b59..00000000000 --- a/framework/src/test/resources/soliditycode/TvmIsContract001.sol +++ /dev/null @@ -1,24 +0,0 @@ -contract testIsContract{ -bool public isContrct; -constructor () public { - isContrct = address(this).isContract; -} -function testIsContractCommand(address a) public returns (bool) { -return (a.isContract); -} - -function testIsContractView(address a) view public returns (bool) { -return (a.isContract); -} - -function selfdestructContract(address payable a) public { - selfdestruct(a); -} -function testConstructor() public returns(bool){ - return isContrct; -} - -function testConstructorView() public view returns(bool){ - return isContrct; -} -} diff --git a/framework/src/test/resources/soliditycode/TvmIsContract002.sol b/framework/src/test/resources/soliditycode/TvmIsContract002.sol deleted file mode 100644 index 2fe474fd98c..00000000000 --- a/framework/src/test/resources/soliditycode/TvmIsContract002.sol +++ /dev/null @@ -1,5 +0,0 @@ -contract testIsContract{ -function testIsContractCommand(address a) public returns (bool) { -return (a.isContract); -} -} diff --git a/framework/src/test/resources/soliditycode/TvmNewCommand043.sol b/framework/src/test/resources/soliditycode/TvmNewCommand043.sol deleted file mode 100644 index 04d9f7dde28..00000000000 --- a/framework/src/test/resources/soliditycode/TvmNewCommand043.sol +++ /dev/null @@ -1,18 +0,0 @@ -contract TestBitwiseShift { - - function shlTest(int256 num, int256 input) public returns (bytes32 out) { - assembly { - out := shl(num, input) - } - } - function shrTest(int256 num, int256 input) public returns (bytes32 out) { - assembly { - out := shr(num, input) - } - } - function sarTest(int256 num, int256 input) public returns (bytes32 out) { - assembly { - out := sar(num, input) - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/TvmNewCommand103.sol b/framework/src/test/resources/soliditycode/TvmNewCommand103.sol deleted file mode 100644 index dbc7fd0f0f4..00000000000 --- a/framework/src/test/resources/soliditycode/TvmNewCommand103.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract testConstantContract{ -function testView() public constant returns (uint256 z) { -uint256 i=1; -return i; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/TvmNewCommand107.sol b/framework/src/test/resources/soliditycode/TvmNewCommand107.sol deleted file mode 100644 index 5b51cd1842c..00000000000 --- a/framework/src/test/resources/soliditycode/TvmNewCommand107.sol +++ /dev/null @@ -1,9 +0,0 @@ - - - contract testConstantContract{ - int256 public i; - function testPayable() public returns (int z) { - z=1+1; - return z; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/TvmNewCommand108.sol b/framework/src/test/resources/soliditycode/TvmNewCommand108.sol deleted file mode 100644 index 0088054faf9..00000000000 --- a/framework/src/test/resources/soliditycode/TvmNewCommand108.sol +++ /dev/null @@ -1,7 +0,0 @@ - - - contract testConstantContract{ - function test() pure public returns (int z) { - return 1; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/TvmNewCommand109.sol b/framework/src/test/resources/soliditycode/TvmNewCommand109.sol deleted file mode 100644 index dc8dd1e8399..00000000000 --- a/framework/src/test/resources/soliditycode/TvmNewCommand109.sol +++ /dev/null @@ -1,7 +0,0 @@ - - - contract testConstantContract{ - function test() view public returns (int z) { - return 1; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/TvmOldCommand001.sol b/framework/src/test/resources/soliditycode/TvmOldCommand001.sol deleted file mode 100644 index f2927bd8e45..00000000000 --- a/framework/src/test/resources/soliditycode/TvmOldCommand001.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract binaryRightContract{ - function binaryMoveR(uint i)public returns (uint z) { - return z = 5 >> i; - } - function binaryLiftR(uint i)public returns (uint z) { - return z = 5 << i; - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/VerifyBurnProof001.sol b/framework/src/test/resources/soliditycode/VerifyBurnProof001.sol deleted file mode 100644 index 4173e84de23..00000000000 --- a/framework/src/test/resources/soliditycode/VerifyBurnProof001.sol +++ /dev/null @@ -1,20 +0,0 @@ - -contract VerifyBurnProof001Test { - // verifyBurnProof(bytes32[10],bytes32[2],uint64,bytes32[2],bytes32) - // size = 512 - // - - function VerifyBurnProofSize001(bytes32[10] memory output, bytes32[2] memory spendAuthoritySignature, uint64 value, bytes32[2] memory bindingSignature,bytes32 signHash) public returns (bool){ - return verifyBurnProof(output, spendAuthoritySignature, value, bindingSignature, signHash); - } - - function VerifyBurnProofSize002(bytes memory data) public returns (bool, bytes memory){ - // bytes memory empty = ""; - return address(0x1000003).delegatecall(data); - } - - function VerifyBurnProofSize003() public returns (bool, bytes memory){ - bytes memory empty = ""; - return address(0x1000003).delegatecall(empty); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/VerifyMintProof001.sol b/framework/src/test/resources/soliditycode/VerifyMintProof001.sol deleted file mode 100644 index cb0812c2ef5..00000000000 --- a/framework/src/test/resources/soliditycode/VerifyMintProof001.sol +++ /dev/null @@ -1,33 +0,0 @@ - -contract VerifyMintProof001Test { - // verifyMintProof(bytes32[9],bytes32[2],uint64,bytes32,bytes32[33],uint256) - - function VerifyMintProofSize001(bytes32[9] memory output, bytes32[2] memory bindingSignature, uint64 value, bytes32 signHash, bytes32[33] memory frontier,uint256 leafCount) public returns (bytes32[] memory){ - return verifyMintProof(output, bindingSignature, value, signHash, frontier, leafCount); - } - - function VerifyMintProofSize002(bytes memory data) public returns (bool, bytes memory){ -// address verifyMint = address (0x1000001); -// -// assembly { -// let succeeded := delegatecall(sub(gas, 5000), verifyMint, add(data, 0x20), mload(data), 0, 0) -// let size := returndatasize -// let response := mload(0x40) -// mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f)))) -// mstore(response, size) -// returndatacopy(add(response, 0x20), 0, size) -// switch iszero(succeeded) -// case 1 { -// // throw if delegatecall failed -// revert(add(response, 0x20), size) -// } -// } - - return address(0x1000001).delegatecall(data); - } - - function VerifyMintProofSize003() public returns (bool, bytes memory){ - bytes memory empty = ""; - return address(0x1000001).call(empty); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/abiencode.sol b/framework/src/test/resources/soliditycode/abiencode.sol deleted file mode 100644 index 38fad3454d6..00000000000 --- a/framework/src/test/resources/soliditycode/abiencode.sol +++ /dev/null @@ -1,16 +0,0 @@ -pragma experimental ABIEncoderV2; - -// tests encoding from storage arrays - -contract AbiEncode { - int256[2][] tmp_h; - function h(int256[2][] calldata s) external returns (bytes memory) { - tmp_h = s; - return abi.encode(tmp_h); - } - int256[2][2] tmp_i; - function i(int256[2][2] calldata s) external returns (bytes memory) { - tmp_i = s; - return abi.encode(tmp_i); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/abstract001.sol b/framework/src/test/resources/soliditycode/abstract001.sol deleted file mode 100644 index 741f236925d..00000000000 --- a/framework/src/test/resources/soliditycode/abstract001.sol +++ /dev/null @@ -1,11 +0,0 @@ -//pragma solidity ^0.6.0; - -interface X { - function setValue(uint _x) external; - function setBalance(uint _x) external; -} - -abstract contract abstract001 is X { - uint x; - function setX(uint _x) public { x = _x; } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/abstract002.sol b/framework/src/test/resources/soliditycode/abstract002.sol deleted file mode 100644 index 7358fc8e163..00000000000 --- a/framework/src/test/resources/soliditycode/abstract002.sol +++ /dev/null @@ -1,13 +0,0 @@ -//pragma solidity ^0.6.0; - -interface X { - function setValue(uint _x) external; - function setBalance(uint _x) external; -} - -abstract contract abstract002 is X { - uint x; - function setX(uint _x) public { x = _x; } - function setValue(uint _x) external override{ x = _x; } - function setBalance(uint _x) external override{ x = _x; } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/abstractContractWithMapParamsConstructor.sol b/framework/src/test/resources/soliditycode/abstractContractWithMapParamsConstructor.sol deleted file mode 100644 index 380c57180b8..00000000000 --- a/framework/src/test/resources/soliditycode/abstractContractWithMapParamsConstructor.sol +++ /dev/null @@ -1,23 +0,0 @@ -abstract contract Feline { - - constructor (mapping (uint => uint) storage m) { - m[5] = 20; - } - - function utterance() public virtual returns (bytes32); - - function getContractName() public returns (string memory){ - return "Feline"; - } -} - - -contract Cat is Feline { - mapping (uint => uint) public m; - - constructor() Feline(m) { - } - function utterance() public override returns (bytes32) { return "miaow"; } - function getMapValue() public returns (uint) { return m[5]; } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/accountAssert.sol b/framework/src/test/resources/soliditycode/accountAssert.sol deleted file mode 100644 index ef10d5fedd8..00000000000 --- a/framework/src/test/resources/soliditycode/accountAssert.sol +++ /dev/null @@ -1,94 +0,0 @@ -//pragma solidity ^0.6.0; - -contract transferTokenTestA { - - // transfer trc10 to a new address or exist address in constructor - constructor(address payable toAddress, uint256 tokenValue, trcToken id) payable public{ - toAddress.transferToken(tokenValue, id); - require(toAddress.tokenBalance(id) > 0, "tokenBalance should not be 0"); - } - - fallback() payable external{} - - function transferTest(address payable toAddress, uint256 tokenValue) payable public { - toAddress.transfer(tokenValue); - } - - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - - // suicide to a new address - function selfdestructTest(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - - // transfer to a new contract - function createContractTest(uint256 tokenValue, trcToken id) payable public returns(address){ - Simple s = new Simple(); - require(address(s).tokenBalance(id)==0, "tokenBalance should be 0"); - payable(address(s)).transferToken(tokenValue, id); - require(address(s).tokenBalance(id)==tokenValue, "tokenBalance should not be 0"); - return address(s); - } - - // revert transfer to a new contract - function revertCreateContractTest(uint256 tokenValue, trcToken id) payable public { - Simple s = new Simple(); - payable(address(s)).transferToken(tokenValue, id); - revert(); - } -} - -contract transferTokenTestB { - - constructor() payable public{ - } - - fallback() payable external{} - - function transferTest(address payable toAddress, uint256 tokenValue) payable public { - toAddress.transfer(tokenValue); - } - - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - - // suicide to a new address - function selfdestructTest(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - - // transfer to a new contract - function createContractTest(uint256 tokenValue, trcToken id) payable public returns(address){ - Simple s = new Simple(); - require(address(s).tokenBalance(id)==0, "tokenBalance should be 0"); - payable(address(s)).transferToken(tokenValue, id); - require(address(s).tokenBalance(id)==tokenValue, "tokenBalance should not be 0"); - return address(s); - } - - // revert transfer to a new contract - function revertCreateContractTest(uint256 tokenValue, trcToken id) payable public { - Simple s = new Simple(); - payable(address(s)).transferToken(tokenValue, id); - revert(); - } -} - -contract transferTokenTestC { - Simple public s; - - // transfer to a new address in constructor - constructor(trcToken id) payable public{ - s = new Simple(); - require(address(s).tokenBalance(id)==0, "new contract tokenBalance should be 0"); - require(address(this).tokenBalance(id)==0, "this.tokenBalance should be 0"); - } -} - -contract Simple { - constructor() payable public{} - fallback() payable external{} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/addMsg001Nonpayable.sol b/framework/src/test/resources/soliditycode/addMsg001Nonpayable.sol deleted file mode 100644 index fcd40cdb521..00000000000 --- a/framework/src/test/resources/soliditycode/addMsg001Nonpayable.sol +++ /dev/null @@ -1,20 +0,0 @@ - - -contract IllegalDecorate { - -event log(uint256); -constructor() payable public{} - -fallback() payable external{} - -function transferTokenWithOutPayable(address payable toAddress, uint256 tokenValue)public { -// function transferTokenWithValue(address toAddress, uint256 tokenValue) payable public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); - -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/addMsg002View.sol b/framework/src/test/resources/soliditycode/addMsg002View.sol deleted file mode 100644 index 0c04b5c0b8a..00000000000 --- a/framework/src/test/resources/soliditycode/addMsg002View.sol +++ /dev/null @@ -1,20 +0,0 @@ - - -contract IllegalDecorate { - -constructor() payable public{} - -fallback() payable external{} - -event log(uint256); - -function transferTokenWithView(address payable toAddress, uint256 tokenValue) public view{ -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} - diff --git a/framework/src/test/resources/soliditycode/addMsg003Constant.sol b/framework/src/test/resources/soliditycode/addMsg003Constant.sol deleted file mode 100644 index 2065802bed1..00000000000 --- a/framework/src/test/resources/soliditycode/addMsg003Constant.sol +++ /dev/null @@ -1,19 +0,0 @@ - - -contract IllegalDecorate { - -constructor() payable public{} - -fallback() payable external{} - -event log(uint256); - -function transferTokenWithConstant(address payable toAddress, uint256 tokenValue) public constant{ -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/addMsg004Pure.sol b/framework/src/test/resources/soliditycode/addMsg004Pure.sol deleted file mode 100644 index 25f1a36d8b7..00000000000 --- a/framework/src/test/resources/soliditycode/addMsg004Pure.sol +++ /dev/null @@ -1,19 +0,0 @@ - - -contract IllegalDecorate { - -constructor() payable public{} - -fallback() payable external{} - -event log(uint256); - -function transferTokenWithPure(address payable toAddress, uint256 tokenValue) public pure{ -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/addTransferToken001Nonpayable.sol b/framework/src/test/resources/soliditycode/addTransferToken001Nonpayable.sol deleted file mode 100644 index 039b341b6ac..00000000000 --- a/framework/src/test/resources/soliditycode/addTransferToken001Nonpayable.sol +++ /dev/null @@ -1,13 +0,0 @@ - - - contract IllegalDecorate { - - constructor() payable public{} - - fallback() payable external{} - - function transferTokenWithOutPayable(address payable toAddress,trcToken id, uint256 tokenValue)public { - - toAddress.transferToken(tokenValue, id); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/addTransferToken001payable.sol b/framework/src/test/resources/soliditycode/addTransferToken001payable.sol deleted file mode 100644 index 17078e30189..00000000000 --- a/framework/src/test/resources/soliditycode/addTransferToken001payable.sol +++ /dev/null @@ -1,13 +0,0 @@ - - - contract IllegalDecorate { - - constructor() payable public{} - - fallback() payable external{} - - function transferTokenWithOutPayable(address payable toAddress,trcToken id, uint256 tokenValue) public payable{ - - toAddress.transferToken(tokenValue, id); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/addTransferToken002View.sol b/framework/src/test/resources/soliditycode/addTransferToken002View.sol deleted file mode 100644 index c50a16390f5..00000000000 --- a/framework/src/test/resources/soliditycode/addTransferToken002View.sol +++ /dev/null @@ -1,15 +0,0 @@ - - -contract IllegalDecorate { - - constructor() payable public{} - - fallback() payable external{} - - function transferTokenWithView(address payable toAddress,trcToken id, uint256 tokenValue) public view{ - - toAddress.transferToken(tokenValue, id); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/addTransferToken003Constant.sol b/framework/src/test/resources/soliditycode/addTransferToken003Constant.sol deleted file mode 100644 index 18721d9b94c..00000000000 --- a/framework/src/test/resources/soliditycode/addTransferToken003Constant.sol +++ /dev/null @@ -1,14 +0,0 @@ - -contract IllegalDecorate { - - constructor() payable public{} - - fallback() payable external{} - - function transferTokenWithConstant(address payable toAddress, uint256 tokenValue) public constant{ - - toAddress.transferToken(tokenValue, 0x6e6d62); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/addTransferToken004Pure.sol b/framework/src/test/resources/soliditycode/addTransferToken004Pure.sol deleted file mode 100644 index f7716ee3874..00000000000 --- a/framework/src/test/resources/soliditycode/addTransferToken004Pure.sol +++ /dev/null @@ -1,15 +0,0 @@ - - -contract IllegalDecorate { - - constructor() payable public{} - - fallback() payable external{} - - function transferTokenWithPure(address payable toAddress, uint256 tokenValue) public pure{ - - toAddress.transferToken(tokenValue, 0x6e6d62); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/addTrcToken001Assemble.sol b/framework/src/test/resources/soliditycode/addTrcToken001Assemble.sol deleted file mode 100644 index fe7a7f4cef8..00000000000 --- a/framework/src/test/resources/soliditycode/addTrcToken001Assemble.sol +++ /dev/null @@ -1,62 +0,0 @@ - - -contract InAssemble { - -mapping(trcToken => uint256) tokenCnt; -mapping(uint256 => mapping(trcToken => trcToken)) cntTokenToken; -constructor () payable public {} -function getBalance (address addr) view public returns(uint256 r) { -assembly{ -r := balance(addr) -} -} - -function getTokenBalanceConstant (address addr, trcToken tokenId) view public returns(uint256 r) { -assembly{ -r := tokenbalance(tokenId, addr) -} -} - -function getTokenBalance (address addr, trcToken tokenId) public returns(uint256 r) { -assembly{ -r := tokenbalance(tokenId, addr) -} -} - -function transferTokenInAssembly(address addr, trcToken tokenId, uint256 tokenValue) public payable { -bytes4 sig = bytes4(keccak256("()")); // function signature - -assembly { -let x := mload(0x40) // get empty storage location -mstore(x,sig) // 4 bytes - place signature in empty storage - -let ret := calltoken(gas, addr, tokenValue, tokenId, -x, // input -0x04, // input size = 4 bytes -x, // output stored at input location, save space -0x0 // output size = 0 bytes -) - -// let ret := calltoken(gas, addr, tokenValue, -// x, // input -// 0x04, // input size = 4 bytes -// x, // output stored at input location, save space -// 0x0 // output size = 0 bytes -// ) // ERROR - - -mstore(0x40, add(x,0x20)) // update free memory pointer -} - -} - -function trcTokenInMap(trcToken tokenId, uint256 tokenValue) public returns(uint256 r) { -tokenCnt[tokenId] += tokenValue; -r = tokenCnt[tokenId]; -} - -function cntTokenTokenInMap(trcToken tokenId1, trcToken tokenId2, uint256 tokenValue) public returns(trcToken r) { -cntTokenToken[tokenValue][tokenId1] = tokenId2; -r = cntTokenToken[tokenValue][tokenId1]; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/addTrcToken002Cat.sol b/framework/src/test/resources/soliditycode/addTrcToken002Cat.sol deleted file mode 100644 index 0cd407079ba..00000000000 --- a/framework/src/test/resources/soliditycode/addTrcToken002Cat.sol +++ /dev/null @@ -1,2051 +0,0 @@ - - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) public onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address payable public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address payable _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() public onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - emit Transfer(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(now), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - uint256 newKittenId = kitties.push(_kitty) - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - emit Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(address(0), _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -contract ERC721 { - // Required methods - function totalSupply() public view returns (uint256 total); - function balanceOf(address _owner) public view returns (uint256 balance); - function ownerOf(uint256 _tokenId) external view returns (address owner); - function approve(address _to, uint256 _tokenId) external; - function transfer(address _to, uint256 _tokenId) external; - function transferFrom(address _from, address _to, uint256 _tokenId) external; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) external view returns (bool); -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is ERC721, KittyBase { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public view returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - emit Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() public view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - external - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] memory _rawBytes, uint256 _stringLength) private view returns (string memory) { - string memory outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string calldata _preferredTransport) external view returns (string memory infoUrl) { - require( address(erc721Metadata) != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2 sun; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty memory _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty memory _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - emit Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.transfer(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, address(saleAuction)); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, address(siringAuction)); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid.value(msg.value - autoBirthFee)(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10 sun; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, address(saleAuction)); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(uint160(address(this))) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - constructor() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - emit ContractUpgrade(_v2Address); - } - - /// @notice No tipping! - /// @dev Reject all Ether from being sent here, unless it's from one of the - /// two auction contracts. (Hopefully, we can prevent user accidents.) - fallback() external payable { - require( - msg.sender == address(saleAuction) || - msg.sender == address(siringAuction) - ); - } - - /// @notice Returns all the relevant information about a specific kitty. - /// @param _id The ID of the kitty of interest. - function getKitty(uint256 _id) - external - view - returns ( - bool isGestating, - bool isReady, - uint256 cooldownIndex, - uint256 nextActionAt, - uint256 siringWithId, - uint256 birthTime, - uint256 matronId, - uint256 sireId, - uint256 generation, - uint256 genes - ) { - Kitty storage kit = kitties[_id]; - - // if this variable is 0 then it's not gestating - isGestating = (kit.siringWithId != 0); - isReady = (kit.cooldownEndBlock <= block.number); - cooldownIndex = uint256(kit.cooldownIndex); - nextActionAt = uint256(kit.cooldownEndBlock); - siringWithId = uint256(kit.siringWithId); - birthTime = uint256(kit.birthTime); - matronId = uint256(kit.matronId); - sireId = uint256(kit.sireId); - generation = uint256(kit.generation); - genes = kit.genes; - } - - /// @dev Override unpause so it requires all external contract addresses - /// to be set before contract can be unpaused. Also, we can't have - /// newContractAddress set either, because then the contract was upgraded. - /// @notice This is public rather than external so we can call super.unpause - /// without using an expensive CALL. - - function unpause(address payable toAddress, uint256 tokenValue, trcToken tokenId) public onlyCEO whenPaused returns (uint256 r) { - require(address(saleAuction) != address(0)); - require(address(siringAuction) != address(0)); - require(address(geneScience) != address(0)); - require(address(newContractAddress) == address(0)); - toAddress.transferToken(tokenValue, tokenId); - r = address(this).tokenBalance(tokenId); - // Actually unpause the contract. - super.unpause(); - } - - // @dev Allows the CFO to capture the balance available to the contract. - function withdrawBalance() external onlyCFO { - uint256 balance = address(this).balance; - // Subtract all the currently pregnant kittens we have, plus 1 of margin. - uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - - if (balance > subtractFees) { - cfoAddress.transfer(balance - subtractFees); - } - } -} - - - - - - - - - - - - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - - function isGeneScience() public pure returns (bool){ - return true; - } - - /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor - /// @param genes1 genes of mom - /// @param genes2 genes of sire - /// @return the genes that are supposed to be passed down the child - function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - - return (genes1+genes2+targetBlock)/2; - - -} -} - - - - - - - - - - - - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { - /// @dev Given a token Id, returns a byte array that is supposed to be converted into string. - function getMetadata(uint256 _tokenId, string memory) public view returns (bytes32[4] memory buffer, uint256 count) { - if (_tokenId == 1) { - buffer[0] = "Hello World! :D"; - count = 15; - } else if (_tokenId == 2) { - buffer[0] = "I would definitely choose a medi"; - buffer[1] = "um length string."; - count = 49; - } else if (_tokenId == 3) { - buffer[0] = "Lorem ipsum dolor sit amet, mi e"; - buffer[1] = "st accumsan dapibus augue lorem,"; - buffer[2] = " tristique vestibulum id, libero"; - buffer[3] = " suscipit varius sapien aliquam."; - count = 128; - } - } -} - - - - - - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - - // Represents an auction on an NFT - struct Auction { - // Current owner of NFT - address payable seller; - // Price (in wei) at beginning of auction - uint128 startingPrice; - // Price (in wei) at end of auction - uint128 endingPrice; - // Duration (in seconds) of auction - uint64 duration; - // Time when auction started - // NOTE: 0 if this auction has been concluded - uint64 startedAt; - } - - // Reference to contract tracking NFT ownership - ERC721 public nonFungibleContract; - - // Cut owner takes on each auction, measured in basis points (1/100 of a percent). - // Values 0-10,000 map to 0%-100% - uint256 public ownerCut; - - // Map from token ID to their corresponding auction. - mapping (uint256 => Auction) tokenIdToAuction; - - event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); - event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); - event AuctionCancelled(uint256 tokenId); - - /// @dev Returns true if the claimant owns the token. - /// @param _claimant - Address claiming to own the token. - /// @param _tokenId - ID of token whose ownership to verify. - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return (nonFungibleContract.ownerOf(_tokenId) == _claimant); - } - - /// @dev Escrows the NFT, assigning ownership to this contract. - /// Throws if the escrow fails. - /// @param _owner - Current owner address of token to escrow. - /// @param _tokenId - ID of token whose approval to verify. - function _escrow(address _owner, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transferFrom(_owner, address(this), _tokenId); - } - - /// @dev Transfers an NFT owned by this contract to another address. - /// Returns true if the transfer succeeds. - /// @param _receiver - Address to transfer NFT to. - /// @param _tokenId - ID of token to transfer. - function _transfer(address _receiver, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transfer(_receiver, _tokenId); - } - - /// @dev Adds an auction to the list of open auctions. Also fires the - /// AuctionCreated event. - /// @param _tokenId The ID of the token to be put on auction. - /// @param _auction Auction to add. - function _addAuction(uint256 _tokenId, Auction memory _auction) internal { - // Require that all auctions have a duration of - // at least one minute. (Keeps our math from getting hairy!) - require(_auction.duration >= 1 minutes); - - tokenIdToAuction[_tokenId] = _auction; - - emit AuctionCreated( - uint256(_tokenId), - uint256(_auction.startingPrice), - uint256(_auction.endingPrice), - uint256(_auction.duration) - ); - } - - /// @dev Cancels an auction unconditionally. - function _cancelAuction(uint256 _tokenId, address _seller) internal { - _removeAuction(_tokenId); - _transfer(_seller, _tokenId); - emit AuctionCancelled(_tokenId); - } - - /// @dev Computes the price and transfers winnings. - /// Does NOT transfer ownership of token. - function _bid(uint256 _tokenId, uint256 _bidAmount) - internal - returns (uint256) - { - // Get a reference to the auction struct - Auction storage auction = tokenIdToAuction[_tokenId]; - - // Explicitly check that this auction is currently live. - // (Because of how Ethereum mappings work, we can't just count - // on the lookup above failing. An invalid _tokenId will just - // return an auction object that is all zeros.) - require(_isOnAuction(auction)); - - // Check that the bid is greater than or equal to the current price - uint256 price = _currentPrice(auction); - require(_bidAmount >= price); - - // Grab a reference to the seller before the auction struct - // gets deleted. - address payable seller = auction.seller; - - // The bid is good! Remove the auction before sending the fees - // to the sender so we can't have a reentrancy attack. - _removeAuction(_tokenId); - - // Transfer proceeds to seller (if there are any!) - if (price > 0) { - // Calculate the auctioneer's cut. - // (NOTE: _computeCut() is guaranteed to return a - // value <= price, so this subtraction can't go negative.) - uint256 auctioneerCut = _computeCut(price); - uint256 sellerProceeds = price - auctioneerCut; - - // NOTE: Doing a transfer() in the middle of a complex - // method like this is generally discouraged because of - // reentrancy attacks and DoS attacks if the seller is - // a contract with an invalid fallback function. We explicitly - // guard against reentrancy attacks by removing the auction - // before calling transfer(), and the only thing the seller - // can DoS is the sale of their own asset! (And if it's an - // accident, they can call cancelAuction(). ) - seller.transfer(sellerProceeds); - } - - // Calculate any excess funds included with the bid. If the excess - // is anything worth worrying about, transfer it back to bidder. - // NOTE: We checked above that the bid amount is greater than or - // equal to the price so this cannot underflow. - uint256 bidExcess = _bidAmount - price; - - // Return the funds. Similar to the previous transfer, this is - // not susceptible to a re-entry attack because the auction is - // removed before any transfers occur. - msg.sender.transfer(bidExcess); - - // Tell the world! - emit AuctionSuccessful(_tokenId, price, msg.sender); - - return price; - } - - /// @dev Removes an auction from the list of open auctions. - /// @param _tokenId - ID of NFT on auction. - function _removeAuction(uint256 _tokenId) internal { - delete tokenIdToAuction[_tokenId]; - } - - /// @dev Returns true if the NFT is on auction. - /// @param _auction - Auction to check. - function _isOnAuction(Auction storage _auction) internal view returns (bool) { - return (_auction.startedAt > 0); - } - - /// @dev Returns current price of an NFT on auction. Broken into two - /// functions (this one, that computes the duration from the auction - /// structure, and the other that does the price computation) so we - /// can easily test that the price computation works correctly. - function _currentPrice(Auction storage _auction) - internal - view - returns (uint256) - { - uint256 secondsPassed = 0; - - // A bit of insurance against negative values (or wraparound). - // Probably not necessary (since Ethereum guarnatees that the - // now variable doesn't ever go backwards). - if (now > _auction.startedAt) { - secondsPassed = now - _auction.startedAt; - } - - return _computeCurrentPrice( - _auction.startingPrice, - _auction.endingPrice, - _auction.duration, - secondsPassed - ); - } - - /// @dev Computes the current price of an auction. Factored out - /// from _currentPrice so we can run extensive unit tests. - /// When testing, make this function public and turn on - /// `Current price computation` test suite. - function _computeCurrentPrice( - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - uint256 _secondsPassed - ) - internal - pure - returns (uint256) - { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our public functions carefully cap the maximum values for - // time (at 64-bits) and currency (at 128-bits). _duration is - // also known to be non-zero (see the require() statement in - // _addAuction()) - if (_secondsPassed >= _duration) { - // We've reached the end of the dynamic pricing portion - // of the auction, just return the end price. - return _endingPrice; - } else { - // Starting price can be higher than ending price (and often is!), so - // this delta can be negative. - int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - - // This multiplication can't overflow, _secondsPassed will easily fit within - // 64-bits, and totalPriceChange will easily fit within 128-bits, their product - // will always fit within 256-bits. - int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - - // currentPriceChange can be negative, but if so, will have a magnitude - // less that _startingPrice. Thus, this result will always end up positive. - int256 currentPrice = int256(_startingPrice) + currentPriceChange; - - return uint256(currentPrice); - } - } - - /// @dev Computes owner's cut of a sale. - /// @param _price - Sale price of NFT. - function _computeCut(uint256 _price) internal view returns (uint256) { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our entry functions carefully cap the maximum values for - // currency (at 128-bits), and ownerCut <= 10000 (see the require() - // statement in the ClockAuction constructor). The result of this - // function is always guaranteed to be <= _price. - return _price * ownerCut / 10000; - } - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { - event Pause(); - event Unpause(); - - bool public paused = false; - - - /** - * @dev modifier to allow actions only when the contract IS paused - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev modifier to allow actions only when the contract IS NOT paused - */ - modifier whenPaused { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyOwner whenNotPaused public returns (bool) { - paused = true; - emit Pause(); - return true; - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyOwner whenPaused public returns (bool) { - paused = false; - emit Unpause(); - return true; - } -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - - /// @dev The ERC-165 interface signature for ERC-721. - /// Ref: https://github.com/ethereum/EIPs/issues/165 - /// Ref: https://github.com/ethereum/EIPs/issues/721 - bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - - /// @dev Constructor creates a reference to the NFT ownership contract - /// and verifies the owner cut is in the valid range. - /// @param _nftAddress - address of a deployed contract implementing - /// the Nonfungible Interface. - /// @param _cut - percent cut the owner takes on each auction, must be - /// between 0-10,000. - constructor(address _nftAddress, uint256 _cut) public { - require(_cut <= 10000); - ownerCut = _cut; - - ERC721 candidateContract = ERC721(_nftAddress); - require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); - nonFungibleContract = candidateContract; - } - - /// @dev Remove all Ether from the contract, which is the owner's cuts - /// as well as any Ether sent directly to the contract address. - /// Always transfers to the NFT contract, but can be called either by - /// the owner or the NFT contract. - function withdrawBalance() external { - address payable nftAddress = address(uint160(address(nonFungibleContract))); - - require( - msg.sender == owner || - msg.sender == nftAddress - ); - // We are using this boolean method to make sure that even if one fails it will still work - bool res = nftAddress.send(address(this).balance); - } - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of time to move between starting - /// price and ending price (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - whenNotPaused - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(_owns(msg.sender, _tokenId)); - _escrow(msg.sender, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Bids on an open auction, completing the auction and transferring - /// ownership of the NFT if enough Ether is supplied. - /// @param _tokenId - ID of token to bid on. - function bid(uint256 _tokenId) - external - payable - whenNotPaused - { - // _bid will throw if the bid or funds transfer fails - _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - } - - /// @dev Cancels an auction that hasn't been won yet. - /// Returns the NFT to original owner. - /// @notice This is a state-modifying function that can - /// be called while the contract is paused. - /// @param _tokenId - ID of token on auction - function cancelAuction(uint256 _tokenId) - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - address seller = auction.seller; - require(msg.sender == seller); - _cancelAuction(_tokenId, seller); - } - - /// @dev Cancels an auction when the contract is paused. - /// Only the owner may do this, and NFTs are returned to - /// the seller. This should only be used in emergencies. - /// @param _tokenId - ID of the NFT on auction to cancel. - function cancelAuctionWhenPaused(uint256 _tokenId) - whenPaused - onlyOwner - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - _cancelAuction(_tokenId, auction.seller); - } - - /// @dev Returns auction info for an NFT on auction. - /// @param _tokenId - ID of NFT on auction. - function getAuction(uint256 _tokenId) - external - view - returns - ( - address seller, - uint256 startingPrice, - uint256 endingPrice, - uint256 duration, - uint256 startedAt - ) { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return ( - auction.seller, - auction.startingPrice, - auction.endingPrice, - auction.duration, - auction.startedAt - ); - } - - /// @dev Returns the current price of an auction. - /// @param _tokenId - ID of the token price we are checking. - function getCurrentPrice(uint256 _tokenId) - external - view - returns (uint256) - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return _currentPrice(auction); - } - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSiringAuctionAddress() call. - bool public isSiringClockAuction = true; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. Since this function is wrapped, - /// require sender to be KittyCore contract. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Places a bid for siring. Requires the sender - /// is the KittyCore contract because all bid methods - /// should be wrapped. Also returns the kitty to the - /// seller rather than the winner. - function bid(uint256 _tokenId) - external - payable - { - require(msg.sender == address(nonFungibleContract)); - address seller = tokenIdToAuction[_tokenId].seller; - // _bid checks that token ID is valid and will throw if bid fails - _bid(_tokenId, msg.value); - // We transfer the kitty back to the seller, the winner will get - // the offspring - _transfer(seller, _tokenId); - } - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSaleAuctionAddress() call. - bool public isSaleClockAuction = true; - - // Tracks last 5 sale price of gen0 kitty sales - uint256 public gen0SaleCount; - uint256[5] public lastGen0SalePrices; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Updates lastSalePrice if seller is the nft contract - /// Otherwise, works the same as default bid method. - function bid(uint256 _tokenId) - external - payable - { - // _bid verifies token ID size - address seller = tokenIdToAuction[_tokenId].seller; - uint256 price = _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - - // If not a gen0 auction, exit - if (seller == address(nonFungibleContract)) { - // Track gen0 sale prices - lastGen0SalePrices[gen0SaleCount % 5] = price; - gen0SaleCount++; - } - } - - function averageGen0SalePrice() external view returns (uint256) { - uint256 sum = 0; - for (uint256 i = 0; i < 5; i++) { - sum += lastGen0SalePrices[i]; - } - return sum / 5; - } - -} - - - - - - - diff --git a/framework/src/test/resources/soliditycode/addTrcToken002Cat_withFinny.sol b/framework/src/test/resources/soliditycode/addTrcToken002Cat_withFinny.sol deleted file mode 100644 index 24117bc5e6b..00000000000 --- a/framework/src/test/resources/soliditycode/addTrcToken002Cat_withFinny.sol +++ /dev/null @@ -1,2051 +0,0 @@ - - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) public onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address payable public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address payable _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() public onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - emit Transfer(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(now), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - uint256 newKittenId = kitties.push(_kitty) - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - emit Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(address(0), _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -contract ERC721 { - // Required methods - function totalSupply() public view returns (uint256 total); - function balanceOf(address _owner) public view returns (uint256 balance); - function ownerOf(uint256 _tokenId) external view returns (address owner); - function approve(address _to, uint256 _tokenId) external; - function transfer(address _to, uint256 _tokenId) external; - function transferFrom(address _from, address _to, uint256 _tokenId) external; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) external view returns (bool); -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is ERC721, KittyBase { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public view returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - emit Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() public view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - external - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] memory _rawBytes, uint256 _stringLength) private view returns (string memory) { - string memory outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string calldata _preferredTransport) external view returns (string memory infoUrl) { - require( address(erc721Metadata) != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2 finney; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty memory _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty memory _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - emit Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.transfer(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, address(saleAuction)); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, address(siringAuction)); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid.value(msg.value - autoBirthFee)(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10 finney; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, address(saleAuction)); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(uint160(address(this))) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - constructor() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - emit ContractUpgrade(_v2Address); - } - - /// @notice No tipping! - /// @dev Reject all Ether from being sent here, unless it's from one of the - /// two auction contracts. (Hopefully, we can prevent user accidents.) - fallback() external payable { - require( - msg.sender == address(saleAuction) || - msg.sender == address(siringAuction) - ); - } - - /// @notice Returns all the relevant information about a specific kitty. - /// @param _id The ID of the kitty of interest. - function getKitty(uint256 _id) - external - view - returns ( - bool isGestating, - bool isReady, - uint256 cooldownIndex, - uint256 nextActionAt, - uint256 siringWithId, - uint256 birthTime, - uint256 matronId, - uint256 sireId, - uint256 generation, - uint256 genes - ) { - Kitty storage kit = kitties[_id]; - - // if this variable is 0 then it's not gestating - isGestating = (kit.siringWithId != 0); - isReady = (kit.cooldownEndBlock <= block.number); - cooldownIndex = uint256(kit.cooldownIndex); - nextActionAt = uint256(kit.cooldownEndBlock); - siringWithId = uint256(kit.siringWithId); - birthTime = uint256(kit.birthTime); - matronId = uint256(kit.matronId); - sireId = uint256(kit.sireId); - generation = uint256(kit.generation); - genes = kit.genes; - } - - /// @dev Override unpause so it requires all external contract addresses - /// to be set before contract can be unpaused. Also, we can't have - /// newContractAddress set either, because then the contract was upgraded. - /// @notice This is public rather than external so we can call super.unpause - /// without using an expensive CALL. - - function unpause(address payable toAddress, uint256 tokenValue, trcToken tokenId) public onlyCEO whenPaused returns (uint256 r) { - require(address(saleAuction) != address(0)); - require(address(siringAuction) != address(0)); - require(address(geneScience) != address(0)); - require(address(newContractAddress) == address(0)); - toAddress.transferToken(tokenValue, tokenId); - r = address(this).tokenBalance(tokenId); - // Actually unpause the contract. - super.unpause(); - } - - // @dev Allows the CFO to capture the balance available to the contract. - function withdrawBalance() external onlyCFO { - uint256 balance = address(this).balance; - // Subtract all the currently pregnant kittens we have, plus 1 of margin. - uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - - if (balance > subtractFees) { - cfoAddress.transfer(balance - subtractFees); - } - } -} - - - - - - - - - - - - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - - function isGeneScience() public pure returns (bool){ - return true; - } - - /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor - /// @param genes1 genes of mom - /// @param genes2 genes of sire - /// @return the genes that are supposed to be passed down the child - function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - - return (genes1+genes2+targetBlock)/2; - - -} -} - - - - - - - - - - - - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { - /// @dev Given a token Id, returns a byte array that is supposed to be converted into string. - function getMetadata(uint256 _tokenId, string memory) public view returns (bytes32[4] memory buffer, uint256 count) { - if (_tokenId == 1) { - buffer[0] = "Hello World! :D"; - count = 15; - } else if (_tokenId == 2) { - buffer[0] = "I would definitely choose a medi"; - buffer[1] = "um length string."; - count = 49; - } else if (_tokenId == 3) { - buffer[0] = "Lorem ipsum dolor sit amet, mi e"; - buffer[1] = "st accumsan dapibus augue lorem,"; - buffer[2] = " tristique vestibulum id, libero"; - buffer[3] = " suscipit varius sapien aliquam."; - count = 128; - } - } -} - - - - - - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - - // Represents an auction on an NFT - struct Auction { - // Current owner of NFT - address payable seller; - // Price (in wei) at beginning of auction - uint128 startingPrice; - // Price (in wei) at end of auction - uint128 endingPrice; - // Duration (in seconds) of auction - uint64 duration; - // Time when auction started - // NOTE: 0 if this auction has been concluded - uint64 startedAt; - } - - // Reference to contract tracking NFT ownership - ERC721 public nonFungibleContract; - - // Cut owner takes on each auction, measured in basis points (1/100 of a percent). - // Values 0-10,000 map to 0%-100% - uint256 public ownerCut; - - // Map from token ID to their corresponding auction. - mapping (uint256 => Auction) tokenIdToAuction; - - event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); - event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); - event AuctionCancelled(uint256 tokenId); - - /// @dev Returns true if the claimant owns the token. - /// @param _claimant - Address claiming to own the token. - /// @param _tokenId - ID of token whose ownership to verify. - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return (nonFungibleContract.ownerOf(_tokenId) == _claimant); - } - - /// @dev Escrows the NFT, assigning ownership to this contract. - /// Throws if the escrow fails. - /// @param _owner - Current owner address of token to escrow. - /// @param _tokenId - ID of token whose approval to verify. - function _escrow(address _owner, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transferFrom(_owner, address(this), _tokenId); - } - - /// @dev Transfers an NFT owned by this contract to another address. - /// Returns true if the transfer succeeds. - /// @param _receiver - Address to transfer NFT to. - /// @param _tokenId - ID of token to transfer. - function _transfer(address _receiver, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transfer(_receiver, _tokenId); - } - - /// @dev Adds an auction to the list of open auctions. Also fires the - /// AuctionCreated event. - /// @param _tokenId The ID of the token to be put on auction. - /// @param _auction Auction to add. - function _addAuction(uint256 _tokenId, Auction memory _auction) internal { - // Require that all auctions have a duration of - // at least one minute. (Keeps our math from getting hairy!) - require(_auction.duration >= 1 minutes); - - tokenIdToAuction[_tokenId] = _auction; - - emit AuctionCreated( - uint256(_tokenId), - uint256(_auction.startingPrice), - uint256(_auction.endingPrice), - uint256(_auction.duration) - ); - } - - /// @dev Cancels an auction unconditionally. - function _cancelAuction(uint256 _tokenId, address _seller) internal { - _removeAuction(_tokenId); - _transfer(_seller, _tokenId); - emit AuctionCancelled(_tokenId); - } - - /// @dev Computes the price and transfers winnings. - /// Does NOT transfer ownership of token. - function _bid(uint256 _tokenId, uint256 _bidAmount) - internal - returns (uint256) - { - // Get a reference to the auction struct - Auction storage auction = tokenIdToAuction[_tokenId]; - - // Explicitly check that this auction is currently live. - // (Because of how Ethereum mappings work, we can't just count - // on the lookup above failing. An invalid _tokenId will just - // return an auction object that is all zeros.) - require(_isOnAuction(auction)); - - // Check that the bid is greater than or equal to the current price - uint256 price = _currentPrice(auction); - require(_bidAmount >= price); - - // Grab a reference to the seller before the auction struct - // gets deleted. - address payable seller = auction.seller; - - // The bid is good! Remove the auction before sending the fees - // to the sender so we can't have a reentrancy attack. - _removeAuction(_tokenId); - - // Transfer proceeds to seller (if there are any!) - if (price > 0) { - // Calculate the auctioneer's cut. - // (NOTE: _computeCut() is guaranteed to return a - // value <= price, so this subtraction can't go negative.) - uint256 auctioneerCut = _computeCut(price); - uint256 sellerProceeds = price - auctioneerCut; - - // NOTE: Doing a transfer() in the middle of a complex - // method like this is generally discouraged because of - // reentrancy attacks and DoS attacks if the seller is - // a contract with an invalid fallback function. We explicitly - // guard against reentrancy attacks by removing the auction - // before calling transfer(), and the only thing the seller - // can DoS is the sale of their own asset! (And if it's an - // accident, they can call cancelAuction(). ) - seller.transfer(sellerProceeds); - } - - // Calculate any excess funds included with the bid. If the excess - // is anything worth worrying about, transfer it back to bidder. - // NOTE: We checked above that the bid amount is greater than or - // equal to the price so this cannot underflow. - uint256 bidExcess = _bidAmount - price; - - // Return the funds. Similar to the previous transfer, this is - // not susceptible to a re-entry attack because the auction is - // removed before any transfers occur. - msg.sender.transfer(bidExcess); - - // Tell the world! - emit AuctionSuccessful(_tokenId, price, msg.sender); - - return price; - } - - /// @dev Removes an auction from the list of open auctions. - /// @param _tokenId - ID of NFT on auction. - function _removeAuction(uint256 _tokenId) internal { - delete tokenIdToAuction[_tokenId]; - } - - /// @dev Returns true if the NFT is on auction. - /// @param _auction - Auction to check. - function _isOnAuction(Auction storage _auction) internal view returns (bool) { - return (_auction.startedAt > 0); - } - - /// @dev Returns current price of an NFT on auction. Broken into two - /// functions (this one, that computes the duration from the auction - /// structure, and the other that does the price computation) so we - /// can easily test that the price computation works correctly. - function _currentPrice(Auction storage _auction) - internal - view - returns (uint256) - { - uint256 secondsPassed = 0; - - // A bit of insurance against negative values (or wraparound). - // Probably not necessary (since Ethereum guarnatees that the - // now variable doesn't ever go backwards). - if (now > _auction.startedAt) { - secondsPassed = now - _auction.startedAt; - } - - return _computeCurrentPrice( - _auction.startingPrice, - _auction.endingPrice, - _auction.duration, - secondsPassed - ); - } - - /// @dev Computes the current price of an auction. Factored out - /// from _currentPrice so we can run extensive unit tests. - /// When testing, make this function public and turn on - /// `Current price computation` test suite. - function _computeCurrentPrice( - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - uint256 _secondsPassed - ) - internal - pure - returns (uint256) - { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our public functions carefully cap the maximum values for - // time (at 64-bits) and currency (at 128-bits). _duration is - // also known to be non-zero (see the require() statement in - // _addAuction()) - if (_secondsPassed >= _duration) { - // We've reached the end of the dynamic pricing portion - // of the auction, just return the end price. - return _endingPrice; - } else { - // Starting price can be higher than ending price (and often is!), so - // this delta can be negative. - int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - - // This multiplication can't overflow, _secondsPassed will easily fit within - // 64-bits, and totalPriceChange will easily fit within 128-bits, their product - // will always fit within 256-bits. - int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - - // currentPriceChange can be negative, but if so, will have a magnitude - // less that _startingPrice. Thus, this result will always end up positive. - int256 currentPrice = int256(_startingPrice) + currentPriceChange; - - return uint256(currentPrice); - } - } - - /// @dev Computes owner's cut of a sale. - /// @param _price - Sale price of NFT. - function _computeCut(uint256 _price) internal view returns (uint256) { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our entry functions carefully cap the maximum values for - // currency (at 128-bits), and ownerCut <= 10000 (see the require() - // statement in the ClockAuction constructor). The result of this - // function is always guaranteed to be <= _price. - return _price * ownerCut / 10000; - } - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { - event Pause(); - event Unpause(); - - bool public paused = false; - - - /** - * @dev modifier to allow actions only when the contract IS paused - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev modifier to allow actions only when the contract IS NOT paused - */ - modifier whenPaused { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyOwner whenNotPaused public returns (bool) { - paused = true; - emit Pause(); - return true; - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyOwner whenPaused public returns (bool) { - paused = false; - emit Unpause(); - return true; - } -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - - /// @dev The ERC-165 interface signature for ERC-721. - /// Ref: https://github.com/ethereum/EIPs/issues/165 - /// Ref: https://github.com/ethereum/EIPs/issues/721 - bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - - /// @dev Constructor creates a reference to the NFT ownership contract - /// and verifies the owner cut is in the valid range. - /// @param _nftAddress - address of a deployed contract implementing - /// the Nonfungible Interface. - /// @param _cut - percent cut the owner takes on each auction, must be - /// between 0-10,000. - constructor(address _nftAddress, uint256 _cut) public { - require(_cut <= 10000); - ownerCut = _cut; - - ERC721 candidateContract = ERC721(_nftAddress); - require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); - nonFungibleContract = candidateContract; - } - - /// @dev Remove all Ether from the contract, which is the owner's cuts - /// as well as any Ether sent directly to the contract address. - /// Always transfers to the NFT contract, but can be called either by - /// the owner or the NFT contract. - function withdrawBalance() external { - address payable nftAddress = address(uint160(address(nonFungibleContract))); - - require( - msg.sender == owner || - msg.sender == nftAddress - ); - // We are using this boolean method to make sure that even if one fails it will still work - bool res = nftAddress.send(address(this).balance); - } - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of time to move between starting - /// price and ending price (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - whenNotPaused - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(_owns(msg.sender, _tokenId)); - _escrow(msg.sender, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Bids on an open auction, completing the auction and transferring - /// ownership of the NFT if enough Ether is supplied. - /// @param _tokenId - ID of token to bid on. - function bid(uint256 _tokenId) - external - payable - whenNotPaused - { - // _bid will throw if the bid or funds transfer fails - _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - } - - /// @dev Cancels an auction that hasn't been won yet. - /// Returns the NFT to original owner. - /// @notice This is a state-modifying function that can - /// be called while the contract is paused. - /// @param _tokenId - ID of token on auction - function cancelAuction(uint256 _tokenId) - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - address seller = auction.seller; - require(msg.sender == seller); - _cancelAuction(_tokenId, seller); - } - - /// @dev Cancels an auction when the contract is paused. - /// Only the owner may do this, and NFTs are returned to - /// the seller. This should only be used in emergencies. - /// @param _tokenId - ID of the NFT on auction to cancel. - function cancelAuctionWhenPaused(uint256 _tokenId) - whenPaused - onlyOwner - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - _cancelAuction(_tokenId, auction.seller); - } - - /// @dev Returns auction info for an NFT on auction. - /// @param _tokenId - ID of NFT on auction. - function getAuction(uint256 _tokenId) - external - view - returns - ( - address seller, - uint256 startingPrice, - uint256 endingPrice, - uint256 duration, - uint256 startedAt - ) { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return ( - auction.seller, - auction.startingPrice, - auction.endingPrice, - auction.duration, - auction.startedAt - ); - } - - /// @dev Returns the current price of an auction. - /// @param _tokenId - ID of the token price we are checking. - function getCurrentPrice(uint256 _tokenId) - external - view - returns (uint256) - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return _currentPrice(auction); - } - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSiringAuctionAddress() call. - bool public isSiringClockAuction = true; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. Since this function is wrapped, - /// require sender to be KittyCore contract. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Places a bid for siring. Requires the sender - /// is the KittyCore contract because all bid methods - /// should be wrapped. Also returns the kitty to the - /// seller rather than the winner. - function bid(uint256 _tokenId) - external - payable - { - require(msg.sender == address(nonFungibleContract)); - address seller = tokenIdToAuction[_tokenId].seller; - // _bid checks that token ID is valid and will throw if bid fails - _bid(_tokenId, msg.value); - // We transfer the kitty back to the seller, the winner will get - // the offspring - _transfer(seller, _tokenId); - } - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSaleAuctionAddress() call. - bool public isSaleClockAuction = true; - - // Tracks last 5 sale price of gen0 kitty sales - uint256 public gen0SaleCount; - uint256[5] public lastGen0SalePrices; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Updates lastSalePrice if seller is the nft contract - /// Otherwise, works the same as default bid method. - function bid(uint256 _tokenId) - external - payable - { - // _bid verifies token ID size - address seller = tokenIdToAuction[_tokenId].seller; - uint256 price = _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - - // If not a gen0 auction, exit - if (seller == address(nonFungibleContract)) { - // Track gen0 sale prices - lastGen0SalePrices[gen0SaleCount % 5] = price; - gen0SaleCount++; - } - } - - function averageGen0SalePrice() external view returns (uint256) { - uint256 sum = 0; - for (uint256 i = 0; i < 5; i++) { - sum += lastGen0SalePrices[i]; - } - return sum / 5; - } - -} - - - - - - - diff --git a/framework/src/test/resources/soliditycode/addressCheckNew.sol b/framework/src/test/resources/soliditycode/addressCheckNew.sol deleted file mode 100644 index 3c10b8c680d..00000000000 --- a/framework/src/test/resources/soliditycode/addressCheckNew.sol +++ /dev/null @@ -1,9 +0,0 @@ -pragma experimental ABIEncoderV2; -contract testIsContract{ - function checkAddress(address addr) public returns (address){ - return addr; - } - function checkAddress2(address addr) pure public returns(address){ - return addr; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/addressCheckOld.sol b/framework/src/test/resources/soliditycode/addressCheckOld.sol deleted file mode 100644 index 6c6b15d1736..00000000000 --- a/framework/src/test/resources/soliditycode/addressCheckOld.sol +++ /dev/null @@ -1,8 +0,0 @@ -contract testIsContract{ - function checkAddress(address addr) public returns (address){ - return addr; - } - function checkAddress2(address addr) pure public returns (address){ - return addr; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/altbn.sol b/framework/src/test/resources/soliditycode/altbn.sol deleted file mode 100644 index c3cfcdbe2b9..00000000000 --- a/framework/src/test/resources/soliditycode/altbn.sol +++ /dev/null @@ -1,61 +0,0 @@ -contract AltBn128 { - constructor() public payable {} - function callBn256Add(bytes32 ax, bytes32 ay, bytes32 bx, bytes32 by) public returns (bytes32[2] memory result) { - bytes32[4] memory input; - input[0] = ax; - input[1] = ay; - input[2] = bx; - input[3] = by; - assembly { - let success := call(gas(), 0x06, 0, input, 0x80, result, 0x40) - } - - } - - function callBn256AddNoValue(bytes32 ax, bytes32 ay, bytes32 bx, bytes32 by) public returns - (bytes32[2] memory result) { - bytes32[4] memory input; - input[0] = ax; - input[1] = ay; - input[2] = bx; - input[3] = by; - assembly { - let success := call(gas(), 0xac, 0, input, 0x80, result, 0x40) - } - } - - function callBn256ScalarMul(bytes32 x, bytes32 y, bytes32 scalar) public returns (bytes32[2] memory result) { - bytes32[3] memory input; - input[0] = x; - input[1] = y; - input[2] = scalar; - assembly { - let success := call(gas(), 0x07, 0, input, 0x60, result, 0x40) - switch success - case 0 { - revert(0,0) - } - } - } - - function callBn256Pairing(bytes memory input) public returns (bytes32 result) { - // input is a serialized bytes stream of (a1, b1, a2, b2, ..., ak, bk) from (G_1 x G_2)^k - uint256 len = input.length; - require(len % 192 == 0); - assembly { - let memPtr := mload(0x40) - let success := call(gas(), 0x08, 0, add(input, 0x20), len, memPtr, 0x20) - switch success - case 0 { - revert(0,0) - } default { - result := mload(memPtr) - } - } - } - - function convert(uint256 num) public view returns(bytes32) { - return bytes32(num); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/arrayLength001.sol b/framework/src/test/resources/soliditycode/arrayLength001.sol deleted file mode 100644 index 81a779f059d..00000000000 --- a/framework/src/test/resources/soliditycode/arrayLength001.sol +++ /dev/null @@ -1,64 +0,0 @@ - - -contract arrayLength { - bytes1[] a; - uint256[] IntergerArray; - bytes bs; - - // arrary length - function arrayPushValue() public returns (bytes1[] memory){ - a = new bytes1[](1); - a.push(0x01); - return a; - } - - function arrayPush() public returns(bytes1[] memory){ - a = new bytes1[](1); - a.push(); - return a; - } - - function arrayPop() public returns(bytes1[] memory){ - a = new bytes1[](1); - a.pop(); - return a; - } - - // arrary push/pop return Value - function arrayPushValueReturn() public { - a = new bytes1[](1); - return a.push(0x01); - } - - function arrayPushReturn() public returns (bytes1){ - a = new bytes1[](1); - return a.push(); - } - - function arrayPopReturn() public{ - a = new bytes1[](1); - return a.pop(); - } - - function uint256ArrayPushValue() public returns (bytes1[] memory){ - IntergerArray = [1,2,3]; - IntergerArray.push(); - return a; - } - - - // bytes - function bytesPushValue() public { - - return bs.push(0x01); - } - - function bytesPush() public returns (bytes1){ - return bs.push(); - } - - function bytesPop() public { - return bs.pop(); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/assemblyTest.sol b/framework/src/test/resources/soliditycode/assemblyTest.sol deleted file mode 100644 index 519a5a85fa3..00000000000 --- a/framework/src/test/resources/soliditycode/assemblyTest.sol +++ /dev/null @@ -1,61 +0,0 @@ - -contract assemblyTest { - - uint constant x = 1; - uint constant y = x; - function getZuint() public view returns (uint) { - uint z = y + 1; - assembly { - z := y - } - return z; - } - - function getZuint2() public returns (uint) { - uint z = y + 1; - assembly { - z := y - } - return z; - } - - bool constant bool1 = true; - bool constant bool2 = bool1; - function getZbool() public view returns (bool) { - bool z; - assembly { - z := bool2 - } - return z; - } - - function getZbool2() public returns (bool) { - bool z; - assembly { - z := bool2 - } - return z; - } - - -// string constant string1 = "abc"; -// string constant string2 = string1; -// function getZstring() public view returns (string memory) { -// string memory z; -// assembly { -// z := string2 -// } -// return z; -// } - - -// address origin1 = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF; -// address origin2 = origin1; -// function getZaddress() public view returns (address) { -// address z; -// assembly { -// z := origin2 -// } -// return z; -// } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/assertExceptiontest1DivideInt.sol b/framework/src/test/resources/soliditycode/assertExceptiontest1DivideInt.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode/assertExceptiontest1DivideInt.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/assertExceptiontest2FindArgsContractMinTest.sol b/framework/src/test/resources/soliditycode/assertExceptiontest2FindArgsContractMinTest.sol deleted file mode 100644 index 75436287805..00000000000 --- a/framework/src/test/resources/soliditycode/assertExceptiontest2FindArgsContractMinTest.sol +++ /dev/null @@ -1,10 +0,0 @@ - -contract findArgsIContract{ -function findArgsByIndex1(uint i) public returns (uint z) { -uint[] memory a = new uint[](3); -a[0]=1; -a[1]=2; -a[2]=3; -return a[i]; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/assertExceptiontest3ByteMinContract.sol b/framework/src/test/resources/soliditycode/assertExceptiontest3ByteMinContract.sol deleted file mode 100644 index c8a2e5e363b..00000000000 --- a/framework/src/test/resources/soliditycode/assertExceptiontest3ByteMinContract.sol +++ /dev/null @@ -1,11 +0,0 @@ - -contract byteContract{ -bytes b; -function testBytesGet(uint i) public returns (bytes1){ -b = new bytes(3); -b[0]=0x0b; -b[1]=0x0c; -b[2]=0x0d; -return b[i]; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/assertExceptiontest4Enum.sol b/framework/src/test/resources/soliditycode/assertExceptiontest4Enum.sol deleted file mode 100644 index 6bd2ade2eea..00000000000 --- a/framework/src/test/resources/soliditycode/assertExceptiontest4Enum.sol +++ /dev/null @@ -1,13 +0,0 @@ - - -contract enumContract { - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices _choice; - function setGoStraight(ActionChoices choice) public { - _choice = choice; - } - - function getChoice() public returns (ActionChoices) { - return _choice; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/assertExceptiontest5MoveRight.sol b/framework/src/test/resources/soliditycode/assertExceptiontest5MoveRight.sol deleted file mode 100644 index ad8f6f0f173..00000000000 --- a/framework/src/test/resources/soliditycode/assertExceptiontest5MoveRight.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract binaryRightContract{ - function binaryMoveR(uint i)public returns (uint z) { - return z = 5 >> i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/assertExceptiontest6UninitializedContract.sol b/framework/src/test/resources/soliditycode/assertExceptiontest6UninitializedContract.sol deleted file mode 100644 index c82e0f5806c..00000000000 --- a/framework/src/test/resources/soliditycode/assertExceptiontest6UninitializedContract.sol +++ /dev/null @@ -1,27 +0,0 @@ - -contract uni { -function b(int x, int y) internal returns (int) -{ - return x * y; -} - -function test1() external returns (int) -{ - // Variable containing a function pointer - function (int, int) internal returns (int) funcPtr; - - funcPtr = b; - - // This call to funcPtr will succeed - return funcPtr(4, 5); -} - -function test2() external returns (int) -{ - // Variable containing a function pointer - function (int, int) internal returns (int) funcPtr; - - // This call will fail because funcPtr is still a zero-initialized function pointer - return funcPtr(4, 5); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/assertExceptiontest7TestAssertContract.sol b/framework/src/test/resources/soliditycode/assertExceptiontest7TestAssertContract.sol deleted file mode 100644 index 05b592e0682..00000000000 --- a/framework/src/test/resources/soliditycode/assertExceptiontest7TestAssertContract.sol +++ /dev/null @@ -1,14 +0,0 @@ -contract TestThrowsContract{ - function testAssert() public{ - assert(1==2); - } - function testRequire() public{ - require(2==1); - } - function testRevert() public{ - revert(); - } - function testThrow() public{ - revert(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/batchvalidatesign.sol b/framework/src/test/resources/soliditycode/batchvalidatesign.sol deleted file mode 100644 index 9e1c1b289b5..00000000000 --- a/framework/src/test/resources/soliditycode/batchvalidatesign.sol +++ /dev/null @@ -1,14 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - - function testArray2(bytes memory data) public returns(bool, bytes memory){ - return address(0x9).delegatecall(data); - } - - function testArray4(bytes memory data) public { - //address(0x1).delegatecall(data); - } - //function testArray3(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public { - //address(0x9).delegatecall(hash,signatures,addresses); - //} -} diff --git a/framework/src/test/resources/soliditycode/batchvalidatesign001.sol b/framework/src/test/resources/soliditycode/batchvalidatesign001.sol deleted file mode 100644 index 57e051ce415..00000000000 --- a/framework/src/test/resources/soliditycode/batchvalidatesign001.sol +++ /dev/null @@ -1,10 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - function testPure(bytes32 hash, bytes[] memory signatures, address[] memory addresses) pure public returns(bytes32){ - return batchvalidatesign(hash, signatures, addresses); - } - - function testArray(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public returns(bytes32){ - return batchvalidatesign(hash, signatures, addresses); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/batchvalidatesign002.sol b/framework/src/test/resources/soliditycode/batchvalidatesign002.sol deleted file mode 100644 index 375cec3a2a2..00000000000 --- a/framework/src/test/resources/soliditycode/batchvalidatesign002.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - function testArray(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public returns(bytes32){ - - return batchvalidatesign(hash, signatures, addresses); - - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/batchvalidatesign003.sol b/framework/src/test/resources/soliditycode/batchvalidatesign003.sol deleted file mode 100644 index c43536af499..00000000000 --- a/framework/src/test/resources/soliditycode/batchvalidatesign003.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract Demo { -bytes32 public result; -constructor (bytes32 hash, bytes[] memory signatures, address[] memory addresses) public { - result = batchvalidatesign(hash, signatures, addresses); -} -function testConstructor() public returns(bytes32){ - return result; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/batchvalidatesign005.sol b/framework/src/test/resources/soliditycode/batchvalidatesign005.sol deleted file mode 100644 index 3a6ca362973..00000000000 --- a/framework/src/test/resources/soliditycode/batchvalidatesign005.sol +++ /dev/null @@ -1,14 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - - function testArray2(bytes memory data) public returns(bool, bytes memory){ - return address(0x9).delegatecall(data); - } - - function testArray4(bytes memory data) public { - //address(0x1).delegatecall(data); - } - function testArray3(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public { - //address(0x9).delegatecall(hash,signatures,addresses); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/batchvalidatesign007.sol b/framework/src/test/resources/soliditycode/batchvalidatesign007.sol deleted file mode 100644 index 974ffb34efe..00000000000 --- a/framework/src/test/resources/soliditycode/batchvalidatesign007.sol +++ /dev/null @@ -1,17 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract Demo { - bytes32 public result; - - constructor (bytes32 hash, bytes[] memory signatures, address[] memory addresses) public { - result = batchvalidatesign(hash, signatures, addresses); - } - - function testConstructor() public returns(bytes32){ - return result; - } - - function testConstructorPure() public view returns(bytes32){ - return result; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/batchvalidatesign02.sol b/framework/src/test/resources/soliditycode/batchvalidatesign02.sol deleted file mode 100644 index 375cec3a2a2..00000000000 --- a/framework/src/test/resources/soliditycode/batchvalidatesign02.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - function testArray(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public returns(bytes32){ - - return batchvalidatesign(hash, signatures, addresses); - - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/callValueGasPure.sol b/framework/src/test/resources/soliditycode/callValueGasPure.sol deleted file mode 100644 index 6aab49bab84..00000000000 --- a/framework/src/test/resources/soliditycode/callValueGasPure.sol +++ /dev/null @@ -1,8 +0,0 @@ - -contract C { -function check(address a) external pure returns (bool success) { - a.call{value:42,gas:42}; - a.call{gas:42}; - //a.call.value(1).gas(42)("fwefewf"); -} -} diff --git a/framework/src/test/resources/soliditycode/calldata.sol b/framework/src/test/resources/soliditycode/calldata.sol deleted file mode 100644 index 6e877ac1b2f..00000000000 --- a/framework/src/test/resources/soliditycode/calldata.sol +++ /dev/null @@ -1,33 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract C { - struct S { uint256 a; } - - function f(S calldata s) external returns (bytes memory) { - return abi.encode(s); - } - - function g(S calldata s) external returns (bytes memory) { - return this.f(s); - } - - function m(uint256[] calldata) external pure returns (bytes memory) { - return msg.data; - } - function h(uint8[] calldata s) external pure returns (bytes memory) { - return abi.encode(s); - } - function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) { - return this.h(s[which]); - } - function j(bytes calldata s) external pure returns (bytes memory) { - return abi.encode(s); - } - function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) { - return this.j(s[which]); - } - function l(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) { - assert(s.length == 3); - return (s[0](), s[1](), s[2]()); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/callvalue.sol b/framework/src/test/resources/soliditycode/callvalue.sol deleted file mode 100644 index f01dcf2b52f..00000000000 --- a/framework/src/test/resources/soliditycode/callvalue.sol +++ /dev/null @@ -1,9 +0,0 @@ -contract Callvalue { -function check() public payable returns(uint) { - uint256 wad; - assembly { - wad := callvalue() - } - return wad; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/chainid001.sol b/framework/src/test/resources/soliditycode/chainid001.sol deleted file mode 100644 index 9cf24077dfb..00000000000 --- a/framework/src/test/resources/soliditycode/chainid001.sol +++ /dev/null @@ -1,19 +0,0 @@ - -contract IstanbulTest { - constructor() public payable {} - function getId() public view returns(uint256){ - uint256 id; - assembly { - id := chainid() - } - return id; - } - - function getBalance(address src) public view returns(uint256){ - return address(src).balance; - } - - function getBalance() public view returns(uint256){ - return address(this).balance; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/codeSaftySupport.sol b/framework/src/test/resources/soliditycode/codeSaftySupport.sol deleted file mode 100644 index 1cee8e4646c..00000000000 --- a/framework/src/test/resources/soliditycode/codeSaftySupport.sol +++ /dev/null @@ -1,19 +0,0 @@ - - -contract IllegalDecorate { - -constructor() payable public{} - -fallback() payable external{} - -event log(uint256); - -function transferToken(address payable toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/codeSaftyUnsupport.sol b/framework/src/test/resources/soliditycode/codeSaftyUnsupport.sol deleted file mode 100644 index fa65a134001..00000000000 --- a/framework/src/test/resources/soliditycode/codeSaftyUnsupport.sol +++ /dev/null @@ -1,56 +0,0 @@ - - -contract SubC { - -event log(string); - -fallback() payable external{} - -function receiveToken() payable public{} - -function getBalance() view public returns (uint256 r) { -r = address(this).balance; -} -} - -contract UseDot { -constructor() payable public{} -fallback() payable external{} -mapping(address => mapping(trcToken => uint256)) sender_tokens; - -function trigger1(address payable addr, trcToken tokenInputId) payable public { - //address(SubC(addr)).call.value(1000).tokenId(tokenInputId)(abi.encodeWithSignature("receiveToken()")); // ERROR -} - -function trigger2(address payable addr) payable public { -// addr.transferToken.value(10)(10, 0x6e6d62); // ERROR -} - -function trigger3(address payable addr) payable public { - // address(SubC(addr)).receiveToken.tokenvalue(10)(); // ERROR -} - -function trigger4(address payable addr) payable public { - //SubC(addr).receiveToken.tokenId(0x6e6d62)(); // ERROR -} - -function trigger5(address payable addr) payable public { - SubC(addr).receiveToken{value:10}(); -} - -function trigger6(address payable addr, trcToken tokenId) payable public { -address(SubC(addr)).call{value:1000}(abi.encodeWithSignature("transferToken(uint256, trcToken)", 10, tokenId)); -} - -function trigger7(address addr) payable public { - //sender_tokens[msg.sender][msg.tokenid] += msg.tokenvalue; // compile success, no necessary to trigger -} - -function trigger8(address addr) public payable returns(bytes memory r){ -// r = msg.data; // compile success, no necessary to trigger -} - -function getBalance() public returns (uint256 r){ -r = address(this).balance; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/constantCallStorage001.sol b/framework/src/test/resources/soliditycode/constantCallStorage001.sol deleted file mode 100644 index 1f584923a55..00000000000 --- a/framework/src/test/resources/soliditycode/constantCallStorage001.sol +++ /dev/null @@ -1,159 +0,0 @@ -contract NotView { - uint256 public num = 123; - function setnum() public returns(uint256){ - num = num + 15; - return num; - } -} -contract NotViewInterface{ - function setnum() public returns(uint256); -} -contract UseNotView { - function setnumuseproxy(address contractAddress) public returns(uint256){ - NotViewInterface inter = NotViewInterface(contractAddress); - return inter.setnum(); - } -} -contract viewCall { - bool stopped = false; - int i = 32482989; - int i2 = -32482989; - uint ui = 23487823; - address origin = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF; - bytes32 b32 = bytes32(uint256(0xdCad3a6d3569DF655070DEd0)); - bytes bs = new bytes(3); - string s = "123qwe"; - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices choice = ActionChoices.GoRight; - int64[] b = [-1, 2, -3]; - int32[2][] tmp_h = [[1,2],[3,4],[5,6]]; - int256[2][2] tmp_i = [[11,22],[33,44]]; - mapping (address => uint256) public mapa; - constructor() payable public{ - mapa[address(0x00)] = 34; - } - event log(int); - event log(uint); - event log(bool); - event log(address); - event log(bytes32); - event log(bytes); - event log(string); - event log(ActionChoices); - event log(int64[]); - event log(int32[2][]); - event log(int256[2][2]); - function changeBool(bool param) public returns (bool){ - stopped = param; - emit log(stopped); - return stopped; - } - function getBool() public returns (bool){ - emit log(stopped); - return stopped; - } - function changeInt(int param) public returns (int){ - i = param; - emit log(i); - return i; - } - function getInt() public returns (int){ - emit log(i); - return i; - } - function changeNegativeInt(int param) public returns (int){ - i2 = param; - emit log(i2); - return i2; - } - function getNegativeInt() public returns (int){ - emit log(i2); - return i2; - } - function changeUint(uint param) public returns (uint){ - ui = param; - emit log(ui); - return ui; - } - function getUint() public returns (uint){ - emit log(ui); - return ui; - } - function changeAddress(address param) public returns (address){ - origin = param; - emit log(origin); - return origin; - } - function getAddress() public returns (address){ - emit log(origin); - return origin; - } - function changeBytes32(bytes32 param) public returns (bytes32){ - b32 = param; - emit log(b32); - return b32; - } - function getBytes32() public returns (bytes32){ - emit log(b32); - return b32; - } - function changeBytes(bytes memory param) public returns (bytes memory){ - bs = param; - emit log(bs); - return bs; - } - function getBytes() public returns (bytes memory){ - emit log(bs); - return bs; - } - function changeString(string memory param) public returns (string memory){ - s = param; - emit log(s); - return s; - } - function getString() public returns (string memory){ - emit log(s); - return s; - } - function changeActionChoices(ActionChoices param) public returns (ActionChoices){ - choice = param; - emit log(choice); - return choice; - } - function getActionChoices() public returns (ActionChoices){ - emit log(choice); - return choice; - } - function changeInt64NegativeArray(int64[] memory param) public returns (int64[] memory){ - b = param; - emit log(b); - return b; - } - function getInt64NegativeArray() public returns (int64[] memory){ - emit log(b); - return b; - } - function changeInt32Array(int32[2][] memory param) public returns (int32[2][] memory){ - tmp_h = param; - emit log(tmp_h); - return tmp_h; - } - function getInt32Array() public returns (int32[2][] memory){ - emit log(tmp_h); - return tmp_h; - } - function changeInt256Array(int256[2][2] memory param) public returns (int256[2][2] memory){ - tmp_i = param; - emit log(tmp_i); - return tmp_i; - } - function getInt256Array() public returns (int256[2][2] memory){ - emit log(tmp_i); - return tmp_i; - } - function setMapping(uint256 param) public returns (uint256){ - mapa[msg.sender] = param; - return mapa[msg.sender]; - - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/constantCallStorage002.sol b/framework/src/test/resources/soliditycode/constantCallStorage002.sol deleted file mode 100644 index 1ceba5e87d2..00000000000 --- a/framework/src/test/resources/soliditycode/constantCallStorage002.sol +++ /dev/null @@ -1,16 +0,0 @@ -contract NotView { - uint256 public num = 123; - function setnum() public returns(uint256){ - num = num + 15; - return num; - } -} -contract NotViewInterface{ - function setnum() public view returns(uint256); -} -contract UseNotView { - function setnumuseproxy(address contractAddress) public view returns(uint256){ - NotViewInterface inter = NotViewInterface(contractAddress); - return inter.setnum(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/constantCallStorage0425.sol b/framework/src/test/resources/soliditycode/constantCallStorage0425.sol deleted file mode 100644 index 8ecf771626d..00000000000 --- a/framework/src/test/resources/soliditycode/constantCallStorage0425.sol +++ /dev/null @@ -1,156 +0,0 @@ -contract constantCall { - bool stopped = false; - int i = 32482989; - int i2 = -32482989; - uint ui = 23487823; - address origin = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF; - bytes32 b32 = 0xb55a21aaee0ce8f1c8ffaa0dbd23105cb55a21aaee0ce8f1c8ffaa0dbd23105c; - bytes bs = new bytes(9); - string s = "123qwe"; - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices choice = ActionChoices.SitStill; - int64[] b = [91, 2, 333]; - int32[2][] tmp_h = [[1,2],[3,4],[5,6]]; - int256[2][2] tmp_i = [[11,22],[33,44]]; - mapping (address => uint256) public mapa; - - constructor() payable public{ - mapa[address(0x00)] = 88; - } - event log(int); - event log(uint); - event log(bool); - event log(address); - event log(bytes32); - event log(bytes); - event log(string); - event log(ActionChoices); - event log(int64[]); - event log(int32[2][]); - event log(int256[2][2]); - - function changeBool(bool param) public constant returns (bool){ - stopped = param; - log(stopped); - return stopped; - } - function getBool() public constant returns (bool){ - log(stopped); - return stopped; - } - - function changeInt(int param) public returns (int){ - i = param; - log(i); - return i; - } - function getInt() public returns (int){ - log(i); - return i; - } - - function changeNegativeInt(int param) public constant returns (int){ - i2 = param; - log(i2); - return i2; - } - function getNegativeInt() public constant returns (int){ - log(i2); - return i2; - } - - function changeUint(uint param) public returns (uint){ - ui = param; - log(ui); - return ui; - } - function getUint() public returns (uint){ - log(ui); - return ui; - } - - function changeAddress(address param) public constant returns (address){ - origin = param; - log(origin); - return origin; - } - function getAddress() public constant returns (address){ - log(origin); - return origin; - } - - function changeBytes32(bytes32 param) public constant returns (bytes32){ - b32 = param; - log(b32); - return b32; - } - function getBytes32() public returns (bytes32){ - log(b32); - return b32; - } - - function changeBytes(bytes param) public constant returns (bytes){ - bs = param; - log(bs); - return bs; - } - function getBytes() public constant returns (bytes){ - log(bs); - return bs; - } - - function changeString(string param) public constant returns (string){ - s = param; - log(s); - return s; - } - function getString() public returns (string){ - log(s); - return s; - } - - function changeActionChoices(ActionChoices param) public constant returns (ActionChoices){ - choice = param; - log(choice); - return choice; - } - function getActionChoices() public constant returns (ActionChoices){ - log(choice); - return choice; - } - - function changeInt64NegativeArray(int64[] param) public constant returns (int64[]){ - b = param; - log(b); - return b; - } - function getInt64NegativeArray() public constant returns (int64[]){ - log(b); - return b; - } - - function changeInt32Array(int32[2][] param) public returns (int32[2][]){ - tmp_h = param; - log(tmp_h); - return tmp_h; - } - function getInt32Array() public constant returns (int32[2][]){ - log(tmp_h); - return tmp_h; - } - - function changeInt256Array(int256[2][2] param) public returns (int256[2][2]){ - tmp_i = param; - log(tmp_i); - return tmp_i; - } - function getInt256Array() public constant returns (int256[2][2]){ - log(tmp_i); - return tmp_i; - } - function setMapping(uint256 param) public returns (uint256){ - mapa[msg.sender] = param; - return mapa[msg.sender]; - - } -} diff --git a/framework/src/test/resources/soliditycode/constantContract001.sol b/framework/src/test/resources/soliditycode/constantContract001.sol deleted file mode 100644 index 7d574c5a008..00000000000 --- a/framework/src/test/resources/soliditycode/constantContract001.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract testConstantContract{ -function testPure(uint256 x,uint256 y) public pure returns (uint256 z) { -uint256 i=1; -return i + x + y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGetterContract.sol b/framework/src/test/resources/soliditycode/contractGetterContract.sol deleted file mode 100644 index 365b53ebf1a..00000000000 --- a/framework/src/test/resources/soliditycode/contractGetterContract.sol +++ /dev/null @@ -1,17 +0,0 @@ - - - -contract getterContract { - -constructor() public payable{} -fallback() external payable{} - -uint public c = msg.value; - -function getDataUsingAccessor() public payable returns (uint){ - -return c; - -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar001test1Grammar001.sol b/framework/src/test/resources/soliditycode/contractGrammar001test1Grammar001.sol deleted file mode 100644 index 659e56c9150..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar001test1Grammar001.sol +++ /dev/null @@ -1,18 +0,0 @@ - -contract FunctionSelector { - function select(bool useB, uint x) public returns (uint z) { - //var f = a; - //if (useB) f = b; - //return f(x); - if (useB) - return b(x); - else - return a(x); - } -function a(uint x) public returns (uint z) { - return x * x; - } -function b(uint x) public returns (uint z) { - return 2 * x; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar001test2Grammar002.sol b/framework/src/test/resources/soliditycode/contractGrammar001test2Grammar002.sol deleted file mode 100644 index 744b17e9585..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar001test2Grammar002.sol +++ /dev/null @@ -1,44 +0,0 @@ - -library Set { - // We define a new struct datatype that will be used to - // hold its data in the calling contract. - struct Data { mapping(uint => bool) flags; } - - // Note that the first parameter is of type "storage - // reference" and thus only its storage address and not - // its contents is passed as part of the call. This is a - // special feature of library functions. It is idiomatic - // to call the first parameter 'self', if the function can - // be seen as a method of that object. - function insert(Data storage self, uint value) public returns (bool) { - if (self.flags[value]) - return false; // already there - self.flags[value] = true; - return true; - } - - function remove(Data storage self, uint value) public returns (bool) { - if (!self.flags[value]) - return false; // not there - self.flags[value] = false; - return true; - } - - function contains(Data storage self, uint value) public returns (bool) { - return self.flags[value]; - } -} - - -contract C { - Set.Data knownValues; - - function register (uint value) public{ - // The library functions can be called without a - // specific instance of the library, since the - // "instance" will be the current contract. - if (!Set.insert(knownValues, value)) - revert(); - } - // In this contract, we can also directly access knownValues.flags, if we want. -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar001test3Grammar003.sol b/framework/src/test/resources/soliditycode/contractGrammar001test3Grammar003.sol deleted file mode 100644 index 140ba2a8f56..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar001test3Grammar003.sol +++ /dev/null @@ -1,44 +0,0 @@ - - -library Set { - struct Data { mapping(uint => bool) flags; } - - function insert(Data storage self, uint value) public - returns (bool) - { - if (self.flags[value]) - return false; // already there - self.flags[value] = true; - return true; - } - - function remove(Data storage self, uint value) public - returns (bool) - { - if (!self.flags[value]) - return false; // not there - self.flags[value] = false; - return true; - } - - function contains(Data storage self, uint value) public - returns (bool) - { - return self.flags[value]; - } -} - - -contract C { - using Set for Set.Data; // this is the crucial change - Set.Data knownValues; - - function register(uint value) public{ - // Here, all variables of type Set.Data have - // corresponding member functions. - // The following function call is identical to - // Set.insert(knownValues, value) - if (!knownValues.insert(value)) - revert(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar001test4Grammar004.sol b/framework/src/test/resources/soliditycode/contractGrammar001test4Grammar004.sol deleted file mode 100644 index bd7ffbc8360..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar001test4Grammar004.sol +++ /dev/null @@ -1,31 +0,0 @@ - - -library Search { - function indexOf(uint[] storage self, uint value) public returns (uint) { - for (uint i = 0; i < self.length; i++) - if (self[i] == value) return i; - return uint(int256(-1)); - } -} - - -contract C { - using Search for uint[]; - uint[] public data; - - function append(uint value) public{ - data.push(value); - } - - function replace(uint _old, uint _new) public{ - // This performs the library function call - uint index = data.indexOf(_old); - if (index == uint(int256(-1))) - data.push(_new); - else - data[index] = _new; - } - function getData(uint256 index) public returns(uint256){ - return data[index]; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar001test5Grammar006.sol b/framework/src/test/resources/soliditycode/contractGrammar001test5Grammar006.sol deleted file mode 100644 index 275d42d1e71..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar001test5Grammar006.sol +++ /dev/null @@ -1,45 +0,0 @@ -contract InfoFeed { -function d1(uint x1) public{ - - assembly{ - function f(x) -> y { switch x case 0 { y := 1 } default { y := mul(x, f(sub(x, 1))) } } - } - } - function d2(uint x1) public{ - assembly { - let x:=1 - x := mul(1, add(2, 3))} - } - function f(uint x) public{ - assembly { x := sub(x, 1) } - - } - // 0.6.0 Variable declarations cannot shadow declarations outside the assembly block. - function d(uint x1) public returns(uint256){ - uint256 x; - assembly{ - x := add(2, 3) - let y := mload(0x40) - x := add(x, y) - } - return x; - } - function d4(uint x) public{ - // Error: The labels 'repeat' is disallowed. Please use "if", "switch", "for" or function calls instead - //assembly{let x := 10 repeat: x := sub(x, 1) jumpi(repeat, eq(x, 0)) - x = x; - //} - } - function d5(uint x1) public{ - assembly{ - function f(x) -> y { switch x case 0 { y := mul(x, 2) } default { y := 0 } } - - } - } - - function d6(uint x1) public{ - assembly{ - function f(x) -> y { for { let i := 0 } lt(i, x) { i := add(i, 1) } { y := mul(2, y) } } - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar002test1Grammar007_1.sol b/framework/src/test/resources/soliditycode/contractGrammar002test1Grammar007_1.sol deleted file mode 100644 index 020c2a38ca4..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar002test1Grammar007_1.sol +++ /dev/null @@ -1,60 +0,0 @@ -contract Doug{ - mapping (bytes32 => uint) public contracts; - constructor() public{ - contracts['hww'] = 1; - contracts['brian'] = 2; - contracts['zzy'] = 7; - } - - function getDougName(string memory _name) public view returns(string memory) { - return _name; - } - - function getDougAge(uint _age) public pure returns(uint) { - return 3 ** _age; - } -} - -// -abstract contract DogInterface { - function getDougAge(uint _age) public virtual returns (uint); - function contracts(bytes32 name) public virtual returns (uint); -} -contract main{ - - event FetchContract(address dogInterfaceAddress, address sender, bytes32 name); - - address public DOUG; - - address dogInterfaceAddress; - DogInterface dogContract ; - - function setDOUG(address _doug) public { - DOUG = _doug; - } - - constructor(address addr) public{ - dogInterfaceAddress = addr; - dogContract = DogInterface(dogInterfaceAddress); - } - - function dougOfage(uint _age) public returns(uint) { - - uint num = dogContract.getDougAge(_age); - return _age+num; - // return num; - } - - function uintOfName(bytes32 _name) public returns (uint) { - - dogContract.contracts(_name); - emit FetchContract(dogInterfaceAddress, msg.sender, _name); - - } - - // function getTest(string _name) public view returns(string) { - // string memory newName = _name ; - // DogInterface(DOUG).getDougName(newName); - // return newName; - // } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar002test1Grammar007_2.sol b/framework/src/test/resources/soliditycode/contractGrammar002test1Grammar007_2.sol deleted file mode 100644 index 8945b566543..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar002test1Grammar007_2.sol +++ /dev/null @@ -1,60 +0,0 @@ - -contract Doug{ - mapping (bytes32 => uint) public contracts; - constructor() public{ - contracts['hww'] = 1; - contracts['brian'] = 2; - contracts['zzy'] = 7; - } - - function getDougName(string memory _name) public view returns(string memory) { - return _name; - } - - function getDougAge(uint _age) public pure returns(uint) { - return 3 ** _age; - } -} - -abstract contract DogInterface { - function getDougAge(uint _age) public virtual returns (uint); - function contracts(bytes32 name) public virtual returns (uint); -} -contract main{ - - event FetchContract(address dogInterfaceAddress, address sender, bytes32 name); - - address public DOUG; - - address dogInterfaceAddress; - DogInterface dogContract ; - - function setDOUG(address _doug) public { - DOUG = _doug; - } - - constructor(address addr) public{ - dogInterfaceAddress = addr; - dogContract = DogInterface(dogInterfaceAddress); - } - - function dougOfage(uint _age) public returns(uint) { - - uint num = dogContract.getDougAge(_age); - return _age+num; - // return num; - } - - function uintOfName(bytes32 _name) public returns (uint) { - - dogContract.contracts(_name); - emit FetchContract(dogInterfaceAddress, msg.sender, _name); - - } - - // function getTest(string _name) public view returns(string) { - // string memory newName = _name ; - // DogInterface(DOUG).getDougName(newName); - // return newName; - // } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar002test2Grammar008.sol b/framework/src/test/resources/soliditycode/contractGrammar002test2Grammar008.sol deleted file mode 100644 index 956623c3103..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar002test2Grammar008.sol +++ /dev/null @@ -1,18 +0,0 @@ - - -// version 0.6.0 change -// add abstract and override -abstract contract Feline { - - function utterance() public virtual returns (bytes32); - - function getContractName() public returns (string memory){ - return "Feline"; - } -} - - -contract Cat is Feline { - function utterance() public override returns (bytes32) { return "miaow"; } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar002test3Grammar010.sol b/framework/src/test/resources/soliditycode/contractGrammar002test3Grammar010.sol deleted file mode 100644 index 617f96cb4e5..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar002test3Grammar010.sol +++ /dev/null @@ -1,10 +0,0 @@ - -contract InfoFeed { -function info() public payable returns (uint ret) { return 42; } -} -contract Consumer { -constructor() payable public{} -InfoFeed feed; -function setFeed(address addr) public { feed = InfoFeed(addr); } -function callFeed() public payable { feed.info{value:10,gas:800}(); } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar002test4Grammar011.sol b/framework/src/test/resources/soliditycode/contractGrammar002test4Grammar011.sol deleted file mode 100644 index fcd18f438ef..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar002test4Grammar011.sol +++ /dev/null @@ -1,11 +0,0 @@ - -contract C { -function f(uint key, uint value) public returns(uint) { -return key; -// do something -} -function g() public { -// named arguments -f({value: 2, key: 3}); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar002test4Grammar012.sol b/framework/src/test/resources/soliditycode/contractGrammar002test4Grammar012.sol deleted file mode 100644 index cb81d8810cd..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar002test4Grammar012.sol +++ /dev/null @@ -1,24 +0,0 @@ - -contract rTest { -function info() public payable returns (uint,address,bytes4,uint,uint,uint,address,uint) { -//function info() public payable returns (address ,uint,uint,uint,bytes32,uint,bytes,uint,address,bytes4,uint,uint,uint,address,uint) { -//var a = block.coinbase ; -//var b = block.difficulty; -//var c = block.gaslimit; -//var d = block.number; -//var e = block.blockhash(0); -//var e = d; -//var f = block.timestamp; -//bytes memory g = msg.data; -uint256 h = gasleft(); -address payable i = payable(msg.sender); -bytes4 j = msg.sig; -uint256 k = msg.value; -uint256 l = block.timestamp; -uint256 m = tx.gasprice; -address payable n = payable(tx.origin); -uint256 o = address(this).balance; -return (h,i,j,k,l,m,n,o); -//return (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar002test6Grammar013.sol b/framework/src/test/resources/soliditycode/contractGrammar002test6Grammar013.sol deleted file mode 100644 index be863303a3d..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar002test6Grammar013.sol +++ /dev/null @@ -1,24 +0,0 @@ - -contract Counter { -uint count = 0; -address payable owner; -//function Counter() public{ -constructor() public{ -owner = payable(msg.sender); -} -function increment() public { -uint step = 10; -if (owner == msg.sender) { -count = count + step; -} -} -function getCount() public returns (uint){ -return count; -} -function kill() public{ -if (owner == msg.sender) { -selfdestruct(owner); -//selfdestruct(address(owner)); -} -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar003test1Grammar014.sol b/framework/src/test/resources/soliditycode/contractGrammar003test1Grammar014.sol deleted file mode 100644 index b2d70b3741c..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar003test1Grammar014.sol +++ /dev/null @@ -1,67 +0,0 @@ -contract A { -uint256 public numberForB; -address public senderForB; -function callTest(address bAddress, uint256 _number) public{ - -//bAddress.call(bytes4(sha3("setValue(uint256)")), _number); // B's storage is set, A is not modified -bAddress.call(abi.encodeWithSignature("setValue(uint256)",_number)); // B's storage is set, A is not modified -} -function callcodeTest(address bAddress, uint256 _number) public{ -//bAddress.callcode(bytes4(sha3("setValue(uint256)")), _number); // A's storage is set, B is not modified -bAddress.delegatecall(abi.encodeWithSignature("setValue(uint256)", _number)); // A's storage is set, B is not modified -} -function delegatecallTest(address bAddress, uint256 _number) public{ -//bAddress.delegatecall(bytes4(sha3("setValue(uint256)")), _number); // A's storage is set, B is not modified -bAddress.delegatecall(abi.encodeWithSignature("setValue(uint256)", _number)); // A's storage is set, B is not modified -} - -function callAddTest(address bAddress) public{ -//bAddress.call(bytes4(sha3("add()"))); // B's storage is set, A is not modified -bAddress.call(abi.encodeWithSignature("add()")); // B's storage is set, A is not modified -//bAddress.call(bytes4(sha3("add()"))); // B's storage is set, A is not modified -bAddress.call(abi.encodeWithSignature("add()")); // B's storage is set, A is not modified -} -function getnumberForB() public returns(uint256){ - return numberForB; - } - function getsenderForB() public returns(address){ - return senderForB; - } -} -contract B { -uint256 public numberForB; -address public senderForB; -address public addr11; -mapping(uint256=>address) public addr1; -mapping(uint256=>address) public addr2; -event ssss(uint256); -function setValue(uint256 _number) public{ - -emit ssss(_number); -numberForB = _number; -senderForB = msg.sender; -// senderForB is A if invoked by A's callTest. B's storage will be updated -// senderForB is A if invoked by A's callcodeTest. None of B's storage is updated -// senderForB is OWNER if invoked by A's delegatecallTest. None of B's storage is updated -} - -function add() public{ -numberForB=numberForB+1; -C c1 = new C(); -addr1[numberForB]=c1.getAddress(); -addr11 = c1.getAddress(); -C c2 = new C(); -addr2[numberForB] = c2.getAddress(); -} -function getnumberForB() public returns(uint256){ - return numberForB; - } - function getsenderForB() public returns(address){ - return senderForB; - } -} -contract C { -function getAddress() public view returns(address){ -return address(this); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar003test2Grammar015.sol b/framework/src/test/resources/soliditycode/contractGrammar003test2Grammar015.sol deleted file mode 100644 index 0aa93e5e94f..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar003test2Grammar015.sol +++ /dev/null @@ -1,40 +0,0 @@ - - -contract ExecuteFallback{ - - //回退事件,会把调用的数据打印出来 - event FallbackCalled(bytes data); - //fallback函数,注意是没有名字的,没有参数,没有返回值的 - // 0.6.0 Split unnamed fallback functions into two cases defined using fallback() and receive() - fallback() external{ - emit FallbackCalled(msg.data); - } - - //调用已存在函数的事件,会把调用的原始数据,请求参数打印出来 - event ExistFuncCalled(bytes data, uint256 para); - //一个存在的函数 - function existFunc(uint256 para) public{ - emit ExistFuncCalled(msg.data, para); - } - - // 模拟从外部对一个存在的函数发起一个调用,将直接调用函数 - function callExistFunc() public{ - bytes4 funcIdentifier = bytes4(keccak256("existFunc(uint256)")); - //this.call(funcIdentifier, uint256(1)); - address(this).call(abi.encode(funcIdentifier, uint256(1))); - } - - //模拟从外部对一个不存在的函数发起一个调用,由于匹配不到函数,将调用回退函数 - function callNonExistFunc() public{ - bytes4 funcIdentifier = bytes4(keccak256("functionNotExist()")); - //this.call(funcIdentifier); - address(this).call(abi.encode(funcIdentifier)); - } - - function ExistFuncCalledTopic() view public returns(bytes32){ - return keccak256("ExistFuncCalled(bytes,uint256)"); - } - function FallbackCalledTopic() view public returns(bytes32){ - return keccak256("FallbackCalled(bytes)"); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar003test3Grammar016.sol b/framework/src/test/resources/soliditycode/contractGrammar003test3Grammar016.sol deleted file mode 100644 index 6a73d7a8d7e..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar003test3Grammar016.sol +++ /dev/null @@ -1,23 +0,0 @@ - -contract C { -uint private data; -function f(uint a) private returns(uint b) { return a + 1; } -function setData(uint a) public { data = a; } -function getData() public returns(uint) { return data; } -function compute(uint a, uint b) internal returns (uint) { return a+b; } -} -contract D { -function readData() public{ -C c = new C(); -//uint local = c.f(7); // error: member "f" is not visible -c.setData(3); -uint local = c.getData(); -// local = c.compute(3, 5); // error: member "compute" is not visible -} -} -contract E is C { -function g() public { -C c = new C(); -uint val = compute(3, 5); // access to internal member (from derived to parent contract) -} -} diff --git a/framework/src/test/resources/soliditycode/contractGrammar003test4Grammar017.sol b/framework/src/test/resources/soliditycode/contractGrammar003test4Grammar017.sol deleted file mode 100644 index 38746d90734..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar003test4Grammar017.sol +++ /dev/null @@ -1,51 +0,0 @@ -contract CrowdFunding{ - struct Funder{ - address addr; - uint amount; - } - - struct Campaign{ - address payable beneficiary; - uint goal; - uint amount; - uint funderNum; - mapping(uint => Funder) funders; - } - - uint compaingnID; - mapping (uint => Campaign) campaigns; - - function candidate(address payable beneficiary, uint goal) public payable returns (uint compaingnID){ - // initialize - Campaign storage c = campaigns[compaingnID++]; - c.beneficiary = beneficiary; - c.goal = goal; - } - - function vote(uint compaingnID) payable public { - Campaign storage c = campaigns[compaingnID]; - - //another way to initialize - c.funders[c.funderNum++] = Funder({addr: msg.sender, amount: msg.value}); - c.amount += msg.value; - } - - function check(uint comapingnId) public payable returns (bool){ - Campaign storage c = campaigns[comapingnId]; - - if(c.amount < c.goal){ - return false; - } - - uint amount = c.amount; - // incase send much more - c.amount = 0; - // address payable addr = address(uint160(c.beneficiary)); - //if(! addr.send(amount)){ - - if (! c.beneficiary.send(amount)){ - revert(); - } - return true; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar003test5Grammar018.sol b/framework/src/test/resources/soliditycode/contractGrammar003test5Grammar018.sol deleted file mode 100644 index ec241f3eae9..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar003test5Grammar018.sol +++ /dev/null @@ -1,37 +0,0 @@ - - - -contract Grammar18{ - function testAddmod() public returns (uint z) { - //计算(x + y)%k,其中以任意精度执行加法,并且不在2 ** 256处围绕 - z=addmod(2, 2, 3); - return z; - } - function testMulmod() public returns (uint z) { -//计算(x * y)%k,其中乘法以任意精度执行,并且不会在2 ** 256处循环。 - z=mulmod(2, 3, 4); - return z; - } - - function testKeccak256() public returns(bytes32){ - //计算的(紧凑)参数的Ethereum-SHA-3(Keccak-256)的散列 - return keccak256("11"); - } - - function testSha256() public returns(bytes32){ - //计算(紧密包装)参数的SHA-256散列 - return sha256("11"); - } - function testSha3() public returns(bytes32){ - //计算(紧密包装)参数的SHA-256散列 - //return sha3("11"); - return keccak256("11"); - } - - function testRipemd160() public returns(bytes32){ - //计算(紧密包装)参数的RIPEMD-160哈希值 - return ripemd160("11"); - } - - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar003test6Grammar019.sol b/framework/src/test/resources/soliditycode/contractGrammar003test6Grammar019.sol deleted file mode 100644 index 727ef7091e7..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar003test6Grammar019.sol +++ /dev/null @@ -1,12 +0,0 @@ - -contract timetest { - -constructor() public { -require( 1 == 1 seconds); -require(1 minutes == 60 seconds); -require(1 hours == 60 minutes); -require(1 days == 24 hours); -require(1 weeks == 7 days); -//require(1 years == 365 days); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractGrammar003test7Grammar020.sol b/framework/src/test/resources/soliditycode/contractGrammar003test7Grammar020.sol deleted file mode 100644 index 39a7fddcb7e..00000000000 --- a/framework/src/test/resources/soliditycode/contractGrammar003test7Grammar020.sol +++ /dev/null @@ -1,8 +0,0 @@ - -contract trxtest { - -function test() public { -require(1 trx == 1000000 sun); - -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractInnerContract.sol b/framework/src/test/resources/soliditycode/contractInnerContract.sol deleted file mode 100644 index 5e6addef105..00000000000 --- a/framework/src/test/resources/soliditycode/contractInnerContract.sol +++ /dev/null @@ -1,32 +0,0 @@ - - - - -contract InnerContract { - - constructor() public payable{} - fallback() external payable{} - - function messageI() payable public returns (uint ret) { - - - - } - -} - - - -contract OuterContract { - - - constructor() public payable{} - fallback() external payable{} - - function callInner(address payable addr) payable public returns (uint) { - - return InnerContract(addr).messageI{value:1}(); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction001.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction001.sol deleted file mode 100644 index 52dcfb16fc3..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction001.sol +++ /dev/null @@ -1,41 +0,0 @@ - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address payable cAddr) public payable{ - B b1 = (new B){value:10}();//1.1 - B b2 = new B();//1.2 - payable(address(b2)).transfer(5);//1.3 - b2.callCGetZero(cAddr, 1);//1.4 - b2.callCGetZero(cAddr,2);//1.6 - } - function test2(address payable cAddress,uint256 amount) public payable{ - cAddress.call{value:amount}(abi.encodeWithSignature("newBAndTransfer()"));//2.1 - cAddress.call{value:amount + 1}(abi.encodeWithSignature("newBAndTransfer()"));//2.6 - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero(address payable cAddress,uint256 amount) public{ - cAddress.call{value:amount}(abi.encodeWithSignature("getZero()"));//1.5,1.7 - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - B b1 = (new B){value:7}();//2.2,2.7 - b1.getOne();//2.3,2.8 - B b2 = (new B){value:3}();//2.4,2.9 - b2.getOne();//2.5,2.10 - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction002.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction002.sol deleted file mode 100644 index 502e42d0c7b..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction002.sol +++ /dev/null @@ -1,20 +0,0 @@ - -contract A{ - constructor() payable public{} - fallback() payable external{} - - function test2(address cAddress,uint256 amount) public payable{ - //cAddress.call.value(amount)();//2.1 - cAddress.call{value:amount}("");//2.1 - } -} - - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction003.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction003.sol deleted file mode 100644 index 9d3e38affbd..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction003.sol +++ /dev/null @@ -1,30 +0,0 @@ - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer() payable public{ - B b = (new B){value:10}();//1 - - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable public returns(bool) { - return true; - } - constructor() public payable {} - function payC(address payable c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - fallback() payable external{} - } - diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction004.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction004.sol deleted file mode 100644 index e8f32d7bfd9..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction004.sol +++ /dev/null @@ -1,24 +0,0 @@ - -contract A{ - constructor () payable public{} - function test(address payable toAddress) public payable{ - selfdestruct(toAddress); - } - fallback() payable external{} - function getBalance() public view returns(uint256){ - return address(this).balance; - } -} -contract B{ - fallback() external payable{} - function kill(address contractAddres, address toAddress) payable public { - contractAddres.call(abi.encodeWithSignature("test(address)",address(this))); - } - function kill2() public{ - A a = new A(); - a.test(payable(address(this))); - } - function getBalance() public view returns(uint256){ - return address(this).balance; - } -} diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction005.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction005.sol deleted file mode 100644 index f6bdf294a99..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction005.sol +++ /dev/null @@ -1,53 +0,0 @@ - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1() public payable{ - B b1 = (new B){value:10}();//1.1 - b1.callCGetZero(false); - b1.callCGetZero(true);//1.4 - } - function test2() public payable{ - C c1 = (new C){value:10}();//1.1 - c1.newBAndTransfer(false); - c1.newBAndTransfer(true);//1.4 - - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero(bool success) public payable{ - if(!success){ - assert(1==2); - } - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract C{ - uint256 public flag=0; - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer(bool success) payable public returns(uint256){ - flag = 1; - if(!success){ - require(2==1); - } - } - function getFlag() public returns(uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction006.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction006.sol deleted file mode 100644 index ec574998b29..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction001testInternalTransaction006.sol +++ /dev/null @@ -1,54 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1() public payable{ - B b1 = (new B){value:10}();//1.1 - b1.callCGetZero(true);//1.4 - b1.callCGetZero(false); - } - function test2() public payable{ - C c1 = (new C){value:10}();//1.1 - c1.newBAndTransfer(true);//1.4 - c1.newBAndTransfer(false); - - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero(bool success) public payable{ - if(!success){ - assert(1==2); - } - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract C{ - uint256 public flag=0; - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer(bool success) payable public returns(uint256){ - flag = 1; - if(!success){ - require(2==1); - } - } - function getFlag() public returns(uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction002test1InternalTransaction007.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction002test1InternalTransaction007.sol deleted file mode 100644 index d14c3d8aa16..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction002test1InternalTransaction007.sol +++ /dev/null @@ -1,38 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address cAddr) public payable{ - B b1 = (new B){value:10}();//1.1 - B b2 = new B();//1.2 - payable(address(b2)).transfer(5);//1.3 - b2.callCGetZero();//1.4 - } - function test2(address cAddress,uint256 amount) public payable{ - cAddress.call{value:amount}(abi.encodeWithSignature("newBAndTransfer()"));//2.1 - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero() public{ - assert(1==2); - - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction002test2InternalTransaction008.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction002test2InternalTransaction008.sol deleted file mode 100644 index 2e57a0e635c..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction002test2InternalTransaction008.sol +++ /dev/null @@ -1,60 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - - function testAssert(address bAddress,uint256 amount) public payable{ - bAddress.call{value:amount,gas:1000000}(abi.encodeWithSignature("callCGetZero(bool)",false));//2.1 - bAddress.call{value:amount,gas:1000000}(abi.encodeWithSignature("callCGetZero(bool)",true)); - } - function testRequire(address cAddress,uint256 amount) public payable{ - cAddress.call{value:amount,gas:1000000}(abi.encodeWithSignature("newBAndTransfer(bool)",false));//2.1 - cAddress.call{value:amount,gas:1000000}(abi.encodeWithSignature("newBAndTransfer(bool)",true)); - } - function testAssert1(address bAddress,uint256 amount) public payable{ - bAddress.call{value:amount,gas:1000000}(abi.encodeWithSignature("callCGetZero(bool)",true)); - bAddress.call{value:amount,gas:1000000}(abi.encodeWithSignature("callCGetZero(bool)",false));//2.1 - } - function testtRequire2(address cAddress,uint256 amount) public payable{ - cAddress.call{value:amount,gas:1000000}(abi.encodeWithSignature("newBAndTransfer(bool)",true)); - cAddress.call{value:amount,gas:1000000}(abi.encodeWithSignature("newBAndTransfer(bool)",false));//2.1 - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero(bool success) payable public{ - if(!success){ - assert(1==2); - } - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract C{ - uint256 public flag=0; - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer(bool success) payable public returns(uint256){ - flag = 1; - if(!success){ - require(2==1); - } - } - function getFlag() public returns(uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction002test3InternalTransaction009.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction002test3InternalTransaction009.sol deleted file mode 100644 index d750df65ea4..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction002test3InternalTransaction009.sol +++ /dev/null @@ -1,47 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address cAddr,address dcontract,address baddress) public payable{ - B b1 = (new B){value:10}();//1.1 - payable(address(b1)).transfer(5);//1.3 - b1.callCGetZero(cAddr, 1);//1.4 - b1.getOne(dcontract,baddress); - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne(address contractAddres, address toAddress) payable public{ - contractAddres.call(abi.encodeWithSignature("suicide1(address)",address(this))); - - } - function callCGetZero(address cAddress,uint256 amount) public{ - cAddress.call{value:amount}(abi.encodeWithSignature("getZero()"));//1.5,1.7 - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public{ - B b1 = (new B){value:7}();//2.2,2.7 - B b2 = (new B){value:3}();//2.4,2.9 - } -} - -contract D{ - constructor () payable public{} - function suicide1(address payable toAddress) public payable{ - selfdestruct(toAddress); - } - fallback() payable external{} - function getBalance() public view returns(uint256){ - return address(this).balance; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction002test4InternalTransaction010.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction002test4InternalTransaction010.sol deleted file mode 100644 index ff5817ea173..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction002test4InternalTransaction010.sol +++ /dev/null @@ -1,186 +0,0 @@ - - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer() payable public{ - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - - } - function transfer2() payable public{ - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - - } - function getBalance() public returns(uint256) { - return address(this).balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable public returns(bool) { - return true; - } - constructor() public payable {} - function payC(address payable c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - fallback() payable external{} - } - diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction002test4InternalTransaction010_1.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction002test4InternalTransaction010_1.sol deleted file mode 100644 index d0c80d14ffb..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction002test4InternalTransaction010_1.sol +++ /dev/null @@ -1,210 +0,0 @@ - - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - } - function transfer2() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - - } - function getBalance() returns(uint256){ - return this.balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable returns(bool) { - return true; - } - constructor() public payable {} - function payC(address c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() returns(uint256){ - return this.balance; - } - fallback() payable{} - } - - \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction002test5InternalTransaction012.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction002test5InternalTransaction012.sol deleted file mode 100644 index 59ffe9f0fe9..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction002test5InternalTransaction012.sol +++ /dev/null @@ -1,51 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address bAddr,address eAddr) public payable{ - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - } - -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function testNN(address eAddress) public payable{ - D d1=(new D){value:1000}(); - d1.getOne(eAddress); - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract D{ - constructor() payable public{} - fallback() payable external{} - function getOne(address eAddress) payable public returns(uint256){ - eAddress.call{value:1}(abi.encodeWithSignature("getZero()"));//2.1 - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction013.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction013.sol deleted file mode 100644 index 1dae0beb03c..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction013.sol +++ /dev/null @@ -1,56 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address dAddr) public payable{ - B b1 = (new B){value:10}();//1.1 - b1.testNN(dAddr,2);//1.6 - // C c1 = (new C).value(1000000000000)();//1.2 - // E e1 = (new E).value(1)();//1.2 - } - function test2(address cAddress,uint256 amount) public payable{ - cAddress.call{value:amount}(abi.encodeWithSignature("newBAndTransfer()"));//2.1 - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function testNN(address dAddress,uint256 amount) public payable{ - // D d1=(new D)(); - dAddress.call{value:amount}(abi.encodeWithSignature("getOne()"));//2.1 - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract D{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - E e = (new E){value:5}(); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction014.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction014.sol deleted file mode 100644 index 0346cec669b..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction014.sol +++ /dev/null @@ -1,38 +0,0 @@ -contract callerContract { - constructor() payable public{} - fallback() payable external{} - function sendToB(address called_address,address c) public payable{ - called_address.delegatecall(abi.encodeWithSignature("transferTo(address)",c)); - } - function sendToB2(address called_address,address c) public payable{ - called_address.call(abi.encodeWithSignature("transferTo(address)",c)); - } - function sendToB3(address called_address,address c) public payable{ - called_address.delegatecall(abi.encodeWithSignature("transferTo(address)",c)); - } -} - - contract calledContract { - fallback() payable external {} - constructor() payable public{} - function transferTo(address payable toAddress)public payable{ - toAddress.transfer(5); - } - - function setIinC(address c) public payable{ - c.call{value:5}(abi.encodeWithSignature("setI()")); - } - - } - - contract c{ - uint256 public i=0; - constructor() public payable{} - function getBalance() public view returns(uint256){ - return address(this).balance; - } - function setI() payable public{ - i=5; - } - fallback() payable external{} - } diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction015.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction015.sol deleted file mode 100644 index edeb9488454..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction015.sol +++ /dev/null @@ -1,60 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address dAddr,address eAddr) public payable{ - B b1 = (new B){value:10}();//1.1 - b1.testNN(dAddr,2,eAddr);//1.6 - // C c1 = (new C).value(1000000000000)();//1.2 - // E e1 = (new E).value(1)();//1.2 - } - function test2(address cAddress,uint256 amount) public payable{ - cAddress.call{value:amount}(abi.encodeWithSignature("newBAndTransfer()"));//2.1 - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function testNN(address dAddress,uint256 amount,address eAddress) public payable{ - // D d1=(new D)(); - dAddress.call{value:amount}(abi.encodeWithSignature("getOne(address)",address(this)));//2.1 - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } - function suicide(address payable toAddress) public payable{ - selfdestruct(toAddress); - } -} -contract D{ - constructor() payable public{} - fallback() payable external{} - function getOne(address payable eAddress) payable public{ - E e = (new E){value:5}(); - e.suicide(eAddress); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction016.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction016.sol deleted file mode 100644 index 9b01c9e0d31..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction016.sol +++ /dev/null @@ -1,174 +0,0 @@ - - - contract A{ - uint256 public num = 0; - constructor() public payable{} - fallback() payable external{} - function transfer() payable public{ - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - B b1=(new B){value:1}();//1 - address payable aaa=payable(address(this)); - b1.suicide1(aaa); - } - function transfer2() payable public{ - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - B b1=(new B){value:1}();//1 - address payable aaa=payable(address(this)); - b1.suicide1(aaa); - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable public returns(bool) { - return true; - } - constructor() public payable {} - function payC(address payable c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - fallback() payable external{} - function suicide1(address payable toAddress) public payable{ - selfdestruct(toAddress); - } - } - diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction017.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction017.sol deleted file mode 100644 index 32cf9f2a04d..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction017.sol +++ /dev/null @@ -1,199 +0,0 @@ - - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer(address payable Address) payable public{ - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - - B b=(new B){value:1}();//1 - selfdestruct(Address); - } - function transfer2() payable public{ - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable public returns(bool) { - return true; - } - constructor() public payable {} - function payC(address payable c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - fallback() payable external{} - } - diff --git a/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction018.sol b/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction018.sol deleted file mode 100644 index fadb5f84b51..00000000000 --- a/framework/src/test/resources/soliditycode/contractInternalTransaction003testInternalTransaction018.sol +++ /dev/null @@ -1,97 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address payable bAddr,address eAddr) public payable{ - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - - } - -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function testNN(address eAddress) public payable { - D d1=(new D){value:100}(); - d1.getOne(eAddress); - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract D{ - constructor() payable public{} - fallback() payable external{} - function getOne(address eAddress) payable public returns(uint256){ - eAddress.call{value:1}(abi.encodeWithSignature("getZero()"));//2.1 - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractLinkage001.sol b/framework/src/test/resources/soliditycode/contractLinkage001.sol deleted file mode 100644 index 8d441fba2da..00000000000 --- a/framework/src/test/resources/soliditycode/contractLinkage001.sol +++ /dev/null @@ -1,9 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -constructor() payable public{} -fallback() payable external{} -function divideIHaveArgsReturn(int x,int y) public payable returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractLinkage002.sol b/framework/src/test/resources/soliditycode/contractLinkage002.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode/contractLinkage002.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractLinkage003.sol b/framework/src/test/resources/soliditycode/contractLinkage003.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode/contractLinkage003.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractLinkage004.sol b/framework/src/test/resources/soliditycode/contractLinkage004.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode/contractLinkage004.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractLinkage005.sol b/framework/src/test/resources/soliditycode/contractLinkage005.sol deleted file mode 100644 index 7b943aee5c1..00000000000 --- a/framework/src/test/resources/soliditycode/contractLinkage005.sol +++ /dev/null @@ -1,51 +0,0 @@ -contract timeoutTest { - string public iarray1; - // cpu - function oneCpu() public { - require(1==1); - } - - function storage8Char() public { - iarray1 = "12345678"; - } - - function testUseCpu(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - } - return count; - } - - - uint256[] public iarray; - uint public calculatedFibNumber; - mapping(address=>mapping(address=>uint256)) public m; - - function testUseStorage(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - iarray.push(i); - } - return count; - } - - // stack - //uint n = 0; - uint yy = 0; - function test() public { - //n += 1; - yy += 1; - test(); - } - - function setFibonacci(uint n) public returns (uint256){ - calculatedFibNumber = fibonacci(n); - return calculatedFibNumber; - } - - function fibonacci(uint n) internal returns (uint) { - return fibonacci(n - 1) + fibonacci(n - 2); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractLinkage006.sol b/framework/src/test/resources/soliditycode/contractLinkage006.sol deleted file mode 100644 index 53449f61ce2..00000000000 --- a/framework/src/test/resources/soliditycode/contractLinkage006.sol +++ /dev/null @@ -1,18 +0,0 @@ - -contract AA{ - uint256 public count=0; - constructor () payable public{} - function init(address payable addr, uint256 max) payable public { - count =0; - this.hack(addr,max); - } - function hack(address payable addr, uint256 max) payable public { - while (count < max) { - count = count +1; - this.hack(addr,max); - } - if (count == max) { - addr.send(20); - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractOriginEnergyLimit001.sol b/framework/src/test/resources/soliditycode/contractOriginEnergyLimit001.sol deleted file mode 100644 index 6feb7fff3b8..00000000000 --- a/framework/src/test/resources/soliditycode/contractOriginEnergyLimit001.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract findArgsContractTest{ - function findArgsByIndexTest(uint i) public returns (uint z) { - uint[] memory a = new uint[](3); - a[0]=1; - a[1]=2; - a[2]=3; - return a[i]; - } -} diff --git a/framework/src/test/resources/soliditycode/contractOriginEnergyLimit004.sol b/framework/src/test/resources/soliditycode/contractOriginEnergyLimit004.sol deleted file mode 100644 index 6feb7fff3b8..00000000000 --- a/framework/src/test/resources/soliditycode/contractOriginEnergyLimit004.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract findArgsContractTest{ - function findArgsByIndexTest(uint i) public returns (uint z) { - uint[] memory a = new uint[](3); - a[0]=1; - a[1]=2; - a[2]=3; - return a[i]; - } -} diff --git a/framework/src/test/resources/soliditycode/contractOtherToTrcToken.sol b/framework/src/test/resources/soliditycode/contractOtherToTrcToken.sol deleted file mode 100644 index c0bb2d7d88e..00000000000 --- a/framework/src/test/resources/soliditycode/contractOtherToTrcToken.sol +++ /dev/null @@ -1,41 +0,0 @@ - - -contract ConvertType { - -constructor() payable public{} - -fallback() payable external{} - -//function stringToTrctoken(address payable toAddress, string memory tokenStr, uint256 tokenValue) public { -// trcToken t = trcToken(tokenStr); // ERROR -// toAddress.transferToken(tokenValue, tokenStr); // ERROR -//} - -function uint256ToTrctoken(address payable toAddress, uint256 tokenValue, uint256 tokenInt) public { - trcToken t = trcToken(tokenInt); // OK - toAddress.transferToken(tokenValue, t); // OK - toAddress.transferToken(tokenValue, tokenInt); // OK -} - -function addressToTrctoken(address payable toAddress, uint256 tokenValue, address adr) public { - trcToken t = trcToken(uint256(uint160(adr))); // OK - toAddress.transferToken(tokenValue, t); // OK -//toAddress.transferToken(tokenValue, adr); // ERROR -} - -//function bytesToTrctoken(address payable toAddress, bytes memory b, uint256 tokenValue) public { - // trcToken t = trcToken(b); // ERROR - // toAddress.transferToken(tokenValue, b); // ERROR -//} - -function bytes32ToTrctoken(address payable toAddress, uint256 tokenValue, bytes32 b32) public { - trcToken t = trcToken(b32); // OK - toAddress.transferToken(tokenValue, t); // OK -// toAddress.transferToken(tokenValue, b32); // ERROR -} - -//function arrayToTrctoken(address payable toAddress, uint256[] memory arr, uint256 tokenValue) public { -//trcToken t = trcToken(arr); // ERROR -// toAddress.transferToken(tokenValue, arr); // ERROR -//} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractScenario001.sol b/framework/src/test/resources/soliditycode/contractScenario001.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode/contractScenario001.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractScenario002.sol b/framework/src/test/resources/soliditycode/contractScenario002.sol deleted file mode 100644 index 5b990fe36e8..00000000000 --- a/framework/src/test/resources/soliditycode/contractScenario002.sol +++ /dev/null @@ -1,53 +0,0 @@ - -contract TronNative{ - - address public voteContractAddress= address(0x10001); - address public freezeBalanceAddress = address(0x10002); - address public unFreezeBalanceAddress = address(0x10003); - address public withdrawBalanceAddress = address(0x10004); - address public approveProposalAddress = address(0x10005); - address public createProposalAddress = address(0x10006); - address public deleteProposalAddress = address(0x10007); - constructor () payable public {} - - function voteForSingleWitness (address payable witnessAddr, uint256 voteValue) public{ - // method 1: - voteContractAddress.delegatecall(abi.encode(witnessAddr,voteValue)); - } - - function voteUsingAssembly (address witnessAddr, uint256 voteValue) public{ - // method 2: - assembly{ - mstore(0x80,witnessAddr) - mstore(0xa0,voteValue) - // gas, address, in, size, out, size - if iszero(delegatecall(0, 0x10001, 0x80, 0x40, 0x80, 0x0)) { - revert(0, 0) - } - } - } - - function freezeBalance(uint256 frozen_Balance,uint256 frozen_Duration) public { - freezeBalanceAddress.delegatecall(abi.encode(frozen_Balance,frozen_Duration)); - } - - function unFreezeBalance() public { - unFreezeBalanceAddress.delegatecall(""); - } - - function withdrawBalance() public { - withdrawBalanceAddress.delegatecall(""); - } - - function approveProposal(uint256 id, bool isApprove) public { - approveProposalAddress.delegatecall(abi.encode(id,isApprove)); - } - - function createProposal(bytes32 [] memory data) public { - createProposalAddress.delegatecall(abi.encode(data)); - } - - function deleteProposal(uint256 id) public{ - deleteProposalAddress.delegatecall(abi.encode(id)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractScenario003.sol b/framework/src/test/resources/soliditycode/contractScenario003.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode/contractScenario003.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractScenario004.sol b/framework/src/test/resources/soliditycode/contractScenario004.sol deleted file mode 100644 index f6919502914..00000000000 --- a/framework/src/test/resources/soliditycode/contractScenario004.sol +++ /dev/null @@ -1,88 +0,0 @@ - - -contract TronToken { - - string public name = "Tronix"; // token name - string public symbol = "TRX"; // token symbol - uint256 public decimals = 6; // token digit - - mapping (address => uint256) public balanceOf; - mapping (address => mapping (address => uint256)) public allowance; - - uint256 public totalSupply = 0; - bool public stopped = false; - - uint256 constant valueFounder = 100000000000000000; - address owner = address(0x0); - - modifier isOwner { - assert(owner == msg.sender); - _; - } - - modifier isRunning { - assert (!stopped); - _; - } - - modifier validAddress { - assert(address(0x0) != msg.sender); - _; - } - - constructor(address _addressFounder) public { - owner = msg.sender; - totalSupply = valueFounder; - balanceOf[_addressFounder] = valueFounder; - emit Transfer(address(0x0), _addressFounder, valueFounder); - } - - function transfer(address _to, uint256 _value) isRunning validAddress public returns (bool success) { - require(balanceOf[msg.sender] >= _value); - require(balanceOf[_to] + _value >= balanceOf[_to]); - balanceOf[msg.sender] -= _value; - balanceOf[_to] += _value; - emit Transfer(msg.sender, _to, _value); - return true; - } - - function transferFrom(address _from, address _to, uint256 _value) isRunning validAddress public returns (bool success) { - require(balanceOf[_from] >= _value); - require(balanceOf[_to] + _value >= balanceOf[_to]); - require(allowance[_from][msg.sender] >= _value); - balanceOf[_to] += _value; - balanceOf[_from] -= _value; - allowance[_from][msg.sender] -= _value; - emit Transfer(_from, _to, _value); - return true; - } - - function approve(address _spender, uint256 _value) isRunning validAddress public returns (bool success) { - require(_value == 0 || allowance[msg.sender][_spender] == 0); - allowance[msg.sender][_spender] = _value; - emit Approval(msg.sender, _spender, _value); - return true; - } - - function stop() isOwner public { - stopped = true; - } - - function start() isOwner public { - stopped = false; - } - - function setName(string memory _name) isOwner public { - name = _name; - } - - function burn(uint256 _value) public { - require(balanceOf[msg.sender] >= _value); - balanceOf[msg.sender] -= _value; - balanceOf[address(0x0)] += _value; - emit Transfer(msg.sender, address(0x0), _value); - } - - event Transfer(address indexed _from, address indexed _to, uint256 _value); - event Approval(address indexed _owner, address indexed _spender, uint256 _value); -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractScenario005.sol b/framework/src/test/resources/soliditycode/contractScenario005.sol deleted file mode 100644 index 5d20d98c0ba..00000000000 --- a/framework/src/test/resources/soliditycode/contractScenario005.sol +++ /dev/null @@ -1,103 +0,0 @@ - - -interface token { - function transfer(address receiver, uint amount) external; -} - -contract Crowdsale { - address payable public beneficiary = payable(address(uint160(0x1b228F5D9f934c7bb18Aaa86F90418932888E7b4))); // 募资成功后的收款方 - uint public fundingGoal = 10000000; // 募资额度 - uint public amountRaised = 1000000; // 参与数量 - uint public deadline; // 募资截止期 - - uint public price; // token 与以太坊的汇率 , token卖多少钱 - token public tokenReward; // 要卖的token - - mapping(address => uint256) public balanceOf; - - bool fundingGoalReached = false; // 众筹是否达到目标 - bool crowdsaleClosed = false; // 众筹是否结束 - - /** - * 事件可以用来跟踪信息 - **/ - event GoalReached(address recipient, uint totalAmountRaised); - event FundTransfer(address backer, uint amount, bool isContribution); - - /** - * 构造函数, 设置相关属性 - */ - constructor( - address payable ifSuccessfulSendTo, - uint fundingGoalInEthers, - uint durationInMinutes, - uint finneyCostOfEachToken, - address addressOfTokenUsedAsReward) public{ - beneficiary = ifSuccessfulSendTo; - fundingGoal = fundingGoalInEthers * 1 sun; - deadline = block.timestamp + durationInMinutes * 1 minutes; - price = finneyCostOfEachToken * 1 trx; - tokenReward = token(addressOfTokenUsedAsReward); // 传入已发布的 token 合约的地址来创建实例 - } - - /** - * 无函数名的Fallback函数, - * 在向合约转账时,这个函数会被调用 - */ - fallback() payable external{ - require(!crowdsaleClosed); - uint amount = msg.value; - balanceOf[msg.sender] += amount; - amountRaised += amount; - tokenReward.transfer(msg.sender, amount / price); - emit FundTransfer(msg.sender, amount, true); - } - - /** - * 定义函数修改器modifier(作用和Python的装饰器很相似) - * 用于在函数执行前检查某种前置条件(判断通过之后才会继续执行该方法) - * _ 表示继续执行之后的代码 - **/ - modifier afterDeadline() { if (block.timestamp >= deadline) _; } - - /** - * 判断众筹是否完成融资目标, 这个方法使用了afterDeadline函数修改器 - * - */ - function checkGoalReached() afterDeadline public{ - if (amountRaised >= fundingGoal) { - fundingGoalReached = true; - emit GoalReached(beneficiary, amountRaised); - } - crowdsaleClosed = true; - } - - - /** - * 完成融资目标时,融资款发送到收款方 - * 未完成融资目标时,执行退款 - * - */ - function safeWithdrawal() afterDeadline public{ - if (!fundingGoalReached) { - uint amount = balanceOf[msg.sender]; - balanceOf[msg.sender] = 0; - if (amount > 0) { - if (payable(msg.sender).send(amount)) { - emit FundTransfer(msg.sender, amount, false); - } else { - balanceOf[msg.sender] = amount; - } - } - } - - if (fundingGoalReached && beneficiary == msg.sender) { - if (payable(beneficiary).send(amountRaised)) { - emit FundTransfer(beneficiary, amountRaised, false); - } else { - //If we fail to send the funds to beneficiary, unlock funders balance - fundingGoalReached = false; - } - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractScenario006.sol b/framework/src/test/resources/soliditycode/contractScenario006.sol deleted file mode 100644 index 15dca03d162..00000000000 --- a/framework/src/test/resources/soliditycode/contractScenario006.sol +++ /dev/null @@ -1,1963 +0,0 @@ - - -interface PlayerBookInterface { - function getPlayerID(address _addr) external returns (uint256); - function getPlayerName(uint256 _pID) external view returns (bytes32); - function getPlayerLAff(uint256 _pID) external view returns (uint256); - function getPlayerAddr(uint256 _pID) external view returns (address); - function getNameFee() external view returns (uint256); - function registerNameXIDFromDapp(address _addr, bytes32 _name, uint256 _affCode, bool _all) external payable returns(bool, uint256); - function registerNameXaddrFromDapp(address _addr, bytes32 _name, address _affCode, bool _all) external payable returns(bool, uint256); - function registerNameXnameFromDapp(address _addr, bytes32 _name, bytes32 _affCode, bool _all) external payable returns(bool, uint256); - function isDev(address _who) external view returns(bool); -} - - -/** -* @title -Name Filter- v0.1.9 -* ┌┬┐┌─┐┌─┐┌┬┐ ╦╦ ╦╔═╗╔╦╗ ┌─┐┬─┐┌─┐┌─┐┌─┐┌┐┌┌┬┐┌─┐ -* │ ├┤ ├─┤│││ ║║ ║╚═╗ ║ ├─┘├┬┘├┤ └─┐├┤ │││ │ └─┐ -* ┴ └─┘┴ ┴┴ ┴ ╚╝╚═╝╚═╝ ╩ ┴ ┴└─└─┘└─┘└─┘┘└┘ ┴ └─┘ -* _____ _____ -* (, / /) /) /) (, / /) /) -* ┌─┐ / _ (/_ // // / _ // _ __ _(/ -* ├─┤ ___/___(/_/(__(_/_(/_(/_ ___/__/_)_(/_(_(_/ (_(_(_ -* ┴ ┴ / / .-/ _____ (__ / -* (__ / (_/ (, / /)™ -* / __ __ __ __ _ __ __ _ _/_ _ _(/ -* ┌─┐┬─┐┌─┐┌┬┐┬ ┬┌─┐┌┬┐ /__/ (_(__(_)/ (_/_)_(_)/ (_(_(_(__(/_(_(_ -* ├─┘├┬┘│ │ │││ ││ │ (__ / .-/ © Jekyll Island Inc. 2018 -* ┴ ┴└─└─┘─┴┘└─┘└─┘ ┴ (_/ -* _ __ _ ____ ____ _ _ _____ ____ ___ -*=============| |\ | / /\ | |\/| | |_ =====| |_ | | | | | | | |_ | |_)==============* -*=============|_| \| /_/--\ |_| | |_|__=====|_| |_| |_|__ |_| |_|__ |_| \==============* -* -* ╔═╗┌─┐┌┐┌┌┬┐┬─┐┌─┐┌─┐┌┬┐ ╔═╗┌─┐┌┬┐┌─┐ ┌──────────┐ -* ║ │ ││││ │ ├┬┘├─┤│ │ ║ │ │ ││├┤ │ Inventor │ -* ╚═╝└─┘┘└┘ ┴ ┴└─┴ ┴└─┘ ┴ ╚═╝└─┘─┴┘└─┘ └──────────┘ -*/ - -library NameFilter { - /** - * @dev filters name strings - * -converts uppercase to lower case. - * -makes sure it does not start/end with a space - * -makes sure it does not contain multiple spaces in a row - * -cannot be only numbers - * -cannot start with 0x - * -restricts characters to A-Z, a-z, 0-9, and space. - * @return reprocessed string in bytes32 format - */ - function nameFilter(string memory _input) - internal - pure - returns(bytes32) - { - bytes memory _temp = bytes(_input); - uint256 _length = _temp.length; - - //sorry limited to 32 characters - require (_length <= 32 && _length > 0, "string must be between 1 and 32 characters"); - // make sure it doesnt start with or end with space - require(_temp[0] != 0x20 && _temp[_length-1] != 0x20, "string cannot start or end with space"); - // make sure first two characters are not 0x - if (_temp[0] == 0x30) - { - require(_temp[1] != 0x78, "string cannot start with 0x"); - require(_temp[1] != 0x58, "string cannot start with 0X"); - } - - // create a bool to track if we have a non number character - bool _hasNonNumber; - - // convert & check - for (uint256 i = 0; i < _length; i++) - { - // if its uppercase A-Z - if (_temp[i] > 0x40 && _temp[i] < 0x5b) - { - // convert to lower case a-z - _temp[i] = bytes1(uint8(_temp[i]) + 32); - - // we have a non number - if (_hasNonNumber == false) - _hasNonNumber = true; - } else { - require - ( - // require character is a space - _temp[i] == 0x20 || - // OR lowercase a-z - (_temp[i] > 0x60 && _temp[i] < 0x7b) || - // or 0-9 - (_temp[i] > 0x2f && _temp[i] < 0x3a), - "string contains invalid characters" - ); - // make sure theres not 2x spaces in a row - if (_temp[i] == 0x20) - require( _temp[i+1] != 0x20, "string cannot contain consecutive spaces"); - - // see if we have a character other than a number - if (_hasNonNumber == false && (_temp[i] < 0x30 || _temp[i] > 0x39)) - _hasNonNumber = true; - } - } - - require(_hasNonNumber == true, "string cannot be only numbers"); - - bytes32 _ret; - assembly { - _ret := mload(add(_temp, 32)) - } - return (_ret); - } -} - - -library SafeMath { - - /** - * @dev Multiplies two numbers, throws on overflow. - */ - function mul(uint256 a, uint256 b) - internal - pure - returns (uint256 c) - { - if (a == 0) { - return 0; - } - c = a * b; - require(c / a == b, "SafeMath mul failed"); - return c; - } - - /** - * @dev Integer division of two numbers, truncating the quotient. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - // assert(b > 0); // Solidity automatically throws when dividing by 0 - uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - return c; - } - - /** - * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). - */ - function sub(uint256 a, uint256 b) - internal - pure - returns (uint256) - { - require(b <= a, "SafeMath sub failed"); - return a - b; - } - - /** - * @dev Adds two numbers, throws on overflow. - */ - function add(uint256 a, uint256 b) - internal - pure - returns (uint256 c) - { - c = a + b; - require(c >= a, "SafeMath add failed"); - return c; - } - - /** - * @dev gives square root of given x. - */ - function sqrt(uint256 x) - internal - pure - returns (uint256 y) - { - uint256 z = ((add(x,1)) / 2); - y = x; - while (z < y) - { - y = z; - z = ((add((x / z),z)) / 2); - } - } - - /** - * @dev gives square. multiplies x by x - */ - function sq(uint256 x) - internal - pure - returns (uint256) - { - return (mul(x,x)); - } - - /** - * @dev x to the power of y - */ - function pwr(uint256 x, uint256 y) - internal - pure - returns (uint256) - { - if (x==0) - return (0); - else if (y==0) - return (1); - else - { - uint256 z = x; - for (uint256 i=1; i < y; i++) - z = mul(z,x); - return (z); - } - } -} - -//============================================================================== -// | _ _ _ | _ . -// |<(/_\/ (_(_||(_ . -//=======/====================================================================== -library F3DKeysCalcLong { - using SafeMath for *; - /** - * @dev calculates number of keys received given X eth - * @param _curEth current amount of eth in contract - * @param _newEth eth being spent - * @return amount of ticket purchased - */ - function keysRec(uint256 _curEth, uint256 _newEth) - internal - pure - returns (uint256) - { - return(keys((_curEth).add(_newEth)).sub(keys(_curEth))); - } - - /** - * @dev calculates amount of eth received if you sold X keys - * @param _curKeys current amount of keys that exist - * @param _sellKeys amount of keys you wish to sell - * @return amount of eth received - */ - function ethRec(uint256 _curKeys, uint256 _sellKeys) - internal - pure - returns (uint256) - { - return((eth(_curKeys)).sub(eth(_curKeys.sub(_sellKeys)))); - } - - /** - * @dev calculates how many keys would exist with given an amount of eth - * @param _eth eth "in contract" - * @return number of keys that would exist - */ - function keys(uint256 _eth) - internal - pure - returns(uint256) - { - return ((((((_eth).mul(1000000000000000000)).mul(312500000000000000000000000)).add(5624988281256103515625000000000000000000000000000000000000000000)).sqrt()).sub(74999921875000000000000000000000)) / (156250000); - } - - /** - * @dev calculates how much eth would be in contract given a number of keys - * @param _keys number of keys "in contract" - * @return eth that would exists - */ - function eth(uint256 _keys) - internal - pure - returns(uint256) - { - return ((78125000).mul(_keys.sq()).add(((149999843750000).mul(_keys.mul(1000000000000000000))) / (2))) / ((1000000000000000000).sq()); - } -} - -library F3Ddatasets { - //compressedData key - // [76-33][32][31][30][29][28-18][17][16-6][5-3][2][1][0] - // 0 - new player (bool) - // 1 - joined round (bool) - // 2 - new leader (bool) - // 3-5 - air drop tracker (uint 0-999) - // 6-16 - round end time - // 17 - winnerTeam - // 18 - 28 timestamp - // 29 - team - // 30 - 0 = reinvest (round), 1 = buy (round), 2 = buy (ico), 3 = reinvest (ico) - // 31 - airdrop happened bool - // 32 - airdrop tier - // 33 - airdrop amount won - //compressedIDs key - // [77-52][51-26][25-0] - // 0-25 - pID - // 26-51 - winPID - // 52-77 - rID - struct EventReturns { - uint256 compressedData; - uint256 compressedIDs; - address winnerAddr; // winner address - bytes32 winnerName; // winner name - uint256 amountWon; // amount won - uint256 newPot; // amount in new pot - uint256 P3DAmount; // amount distributed to p3d - uint256 genAmount; // amount distributed to gen - uint256 potAmount; // amount added to pot - } - struct Player { - address payable addr; // player address - bytes32 name; // player name - uint256 win; // winnings vault - uint256 gen; // general vault - uint256 aff; // affiliate vault - uint256 lrnd; // last round played - uint256 laff; // last affiliate id used - } - struct PlayerRounds { - uint256 eth; // eth player has added to round (used for eth limiter) - uint256 keys; // keys - uint256 mask; // player mask - uint256 ico; // ICO phase investment - } - struct Round { - uint256 plyr; // pID of player in lead - uint256 team; // tID of team in lead - uint256 end; // time ends/ended - bool ended; // has round end function been ran - uint256 strt; // time round started - uint256 keys; // keys - uint256 eth; // total eth in - uint256 pot; // eth to pot (during round) / final amount paid to winner (after round ends) - uint256 mask; // global mask - uint256 ico; // total eth sent in during ICO phase - uint256 icoGen; // total eth for gen during ICO phase - uint256 icoAvg; // average key price for ICO phase - } - struct TeamFee { - uint256 gen; // % of buy in thats paid to key holders of current round - uint256 p3d; // % of buy in thats paid to p3d holders - } - struct PotSplit { - uint256 gen; // % of pot thats paid to key holders of current round - uint256 p3d; // % of pot thats paid to p3d holders - } -} - -contract F3Devents { - // fired whenever a player registers a name - event onNewName - ( - uint256 indexed playerID, - address indexed playerAddress, - bytes32 indexed playerName, - bool isNewPlayer, - uint256 affiliateID, - address affiliateAddress, - bytes32 affiliateName, - uint256 amountPaid, - uint256 timeStamp - ); - - // fired at end of buy or reload - event onEndTx - ( - uint256 compressedData, - uint256 compressedIDs, - bytes32 playerName, - address playerAddress, - uint256 ethIn, - uint256 keysBought, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount, - uint256 potAmount, - uint256 airDropPot - ); - - // fired whenever theres a withdraw - event onWithdraw - ( - uint256 indexed playerID, - address playerAddress, - bytes32 playerName, - uint256 ethOut, - uint256 timeStamp - ); - - // fired whenever a withdraw forces end round to be ran - event onWithdrawAndDistribute - ( - address playerAddress, - bytes32 playerName, - uint256 ethOut, - uint256 compressedData, - uint256 compressedIDs, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount - ); - - // (fomo3d long only) fired whenever a player tries a buy after round timer - // hit zero, and causes end round to be ran. - event onBuyAndDistribute - ( - address playerAddress, - bytes32 playerName, - uint256 ethIn, - uint256 compressedData, - uint256 compressedIDs, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount - ); - - // (fomo3d long only) fired whenever a player tries a reload after round timer - // hit zero, and causes end round to be ran. - event onReLoadAndDistribute - ( - address playerAddress, - bytes32 playerName, - uint256 compressedData, - uint256 compressedIDs, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount - ); - - // fired whenever an affiliate is paid - event onAffiliatePayout - ( - uint256 indexed affiliateID, - address affiliateAddress, - bytes32 affiliateName, - uint256 indexed roundID, - uint256 indexed buyerID, - uint256 amount, - uint256 timeStamp - ); - - // received pot swap deposit - event onPotSwapDeposit - ( - uint256 roundID, - uint256 amountAddedToPot - ); -} - - - -contract FoMo3Dlong is F3Devents { - using SafeMath for *; - using NameFilter for string; - using F3DKeysCalcLong for uint256; - - address public otherF3D_; - address public Divies; - address public Jekyll_Island_Inc; - PlayerBookInterface public playerBook;// =PlayerBookInterface(0x0dcd2f752394c41875e259e00bb44fd505297caf);//new PlayerBook();// - // TeamJustInterface constant private teamJust = TeamJustInterface(0x3a5f8140b9213a0f733a6a639857c9df43ee3f5a);// new TeamJust();// - - //============================================================================== - // _ _ _ |`. _ _ _ |_ | _ _ . - // (_(_)| |~|~|(_||_|| (_||_)|(/__\ . (game settings) - //=================_|=========================================================== - string constant public name = "FoMo3D Long Official"; - string constant public symbol = "F3D"; - uint256 private rndExtra_ = 30;//extSettings.getLongExtra(); // length of the very first ICO - uint256 private rndGap_ = 30; //extSettings.getLongGap(); // length of ICO phase, set to 1 year for EOS. - uint256 constant private rndInit_ = 1 hours; // round timer starts at this - uint256 constant private rndInc_ = 30 seconds; // every full key purchased adds this much to the timer - uint256 constant private rndMax_ = 24 hours; // max length a round timer can be - //============================================================================== - // _| _ _|_ _ _ _ _|_ _ . - // (_|(_| | (_| _\(/_ | |_||_) . (data used to store game info that changes) - //=============================|================================================ - uint256 public airDropPot_; // person who gets the airdrop wins part of this pot - uint256 public airDropTracker_ = 0; // incremented each time a "qualified" tx occurs. used to determine winning air drop - uint256 public rID_; // round id number / total rounds that have happened - //**************** - // PLAYER DATA - //**************** - mapping(address => uint256) public pIDxAddr_; // (addr => pID) returns player id by address - mapping(bytes32 => uint256) public pIDxName_; // (name => pID) returns player id by name - mapping(uint256 => F3Ddatasets.Player) public plyr_; // (pID => data) player data - mapping(uint256 => mapping(uint256 => F3Ddatasets.PlayerRounds)) public plyrRnds_; // (pID => rID => data) player round data by player id & round id - mapping(uint256 => mapping(bytes32 => bool)) public plyrNames_; // (pID => name => bool) list of names a player owns. (used so you can change your display name amongst any name you own) - //**************** - // ROUND DATA - //**************** - mapping(uint256 => F3Ddatasets.Round) public round_; // (rID => data) round data - mapping(uint256 => mapping(uint256 => uint256)) public rndTmEth_; // (rID => tID => data) eth in per team, by round id and team id - //**************** - // TEAM FEE DATA - //**************** - mapping(uint256 => F3Ddatasets.TeamFee) public fees_; // (team => fees) fee distribution by team - mapping(uint256 => F3Ddatasets.PotSplit) public potSplit_; // (team => fees) pot split distribution by team - - function setPlayerBook(address _playerBook) external { - require(msg.sender == owner, 'only dev!'); - require(address(playerBook) == address(0), 'already set!'); - playerBook = PlayerBookInterface(_playerBook); - } - - address public owner; - - //============================================================================== - // _ _ _ __|_ _ __|_ _ _ . - // (_(_)| |_\ | | |_|(_ | (_)| . (initial data setup upon contract deploy) - //============================================================================== - constructor() - public - { - owner = msg.sender; - // Team allocation structures - // 0 = whales - // 1 = bears - // 2 = sneks - // 3 = bulls - - // Team allocation percentages - // (F3D, P3D) + (Pot , Referrals, Community) - // Referrals / Community rewards are mathematically designed to come from the winner's share of the pot. - fees_[0] = F3Ddatasets.TeamFee(30, 6); - //50% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - fees_[1] = F3Ddatasets.TeamFee(43, 0); - //43% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - fees_[2] = F3Ddatasets.TeamFee(56, 10); - //20% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - fees_[3] = F3Ddatasets.TeamFee(43, 8); - //35% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - - // how to split up the final pot based on which team was picked - // (F3D, P3D) - potSplit_[0] = F3Ddatasets.PotSplit(15, 10); - //48% to winner, 25% to next round, 2% to com - potSplit_[1] = F3Ddatasets.PotSplit(25, 0); - //48% to winner, 25% to next round, 2% to com - potSplit_[2] = F3Ddatasets.PotSplit(20, 20); - //48% to winner, 10% to next round, 2% to com - potSplit_[3] = F3Ddatasets.PotSplit(30, 10); - //48% to winner, 10% to next round, 2% to com - } - //============================================================================== - // _ _ _ _|. |`. _ _ _ . - // | | |(_)(_||~|~|(/_| _\ . (these are safety checks) - //============================================================================== - /** - * @dev used to make sure no one can interact with contract until it has - * been activated. - */ - modifier isActivated() { - require(activated_ == true, "its not ready yet. check ?eta in discord"); - _; - } - - /** - * @dev prevents contracts from interacting with fomo3d - */ - modifier isHuman() { - address _addr = msg.sender; - uint256 _codeLength; - - assembly {_codeLength := extcodesize(_addr)} - require(_codeLength == 0, "sorry humans only"); - _; - } - - modifier onlyDevs() - { - require(playerBook.isDev(msg.sender) == true, "msg sender is not a dev"); - _; - } - - /** - * @dev sets boundaries for incoming tx - */ - modifier isWithinLimits(uint256 _eth) { - require(_eth >= 1000000000, "pocket lint: not a valid currency"); - require(_eth <= 100000000000000000000000, "no vitalik, no"); - _; - } - - //============================================================================== - // _ |_ |. _ |` _ __|_. _ _ _ . - // |_)|_||_)||(_ ~|~|_|| |(_ | |(_)| |_\ . (use these to interact with contract) - //====|========================================================================= - /** - * @dev emergency buy uses last stored affiliate ID and team snek - */ - fallback() - isActivated() - isHuman() - isWithinLimits(msg.value) - external - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_ ; - _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // buy core - buyCore(_pID, plyr_[_pID].laff, 2, _eventData_); - } - - /** - * @dev converts all incoming ethereum to keys. - * -functionhash- 0x8f38f309 (using ID for affiliate) - * -functionhash- 0x98a0871d (using address for affiliate) - * -functionhash- 0xa65b37a1 (using name for affiliate) - * @param _affCode the ID/address/name of the player who gets the affiliate fee - * @param _team what team is the player playing for? - */ - function buyXid(uint256 _affCode, uint256 _team) - isActivated() - isHuman() - isWithinLimits(msg.value) - public - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_; - _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == 0 || _affCode == _pID) - { - // use last stored affiliate code - _affCode = plyr_[_pID].laff; - - // if affiliate code was given & its not the same as previously stored - } else if (_affCode != plyr_[_pID].laff) { - // update last affiliate - plyr_[_pID].laff = _affCode; - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // buy core - buyCore(_pID, _affCode, _team, _eventData_); - } - - function buyXaddr(address _affCode, uint256 _team) - isActivated() - isHuman() - isWithinLimits(msg.value) - public - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_; - _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == address(0) || _affCode == msg.sender) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxAddr_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // buy core - buyCore(_pID, _affID, _team, _eventData_); - } - - function buyXname(bytes32 _affCode, uint256 _team) - isActivated() - isHuman() - isWithinLimits(msg.value) - public - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_ ; - _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == '' || _affCode == plyr_[_pID].name) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxName_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // buy core - buyCore(_pID, _affID, _team, _eventData_); - } - - /** - * @dev essentially the same as buy, but instead of you sending ether - * from your wallet, it uses your unwithdrawn earnings. - * -functionhash- 0x349cdcac (using ID for affiliate) - * -functionhash- 0x82bfc739 (using address for affiliate) - * -functionhash- 0x079ce327 (using name for affiliate) - * @param _affCode the ID/address/name of the player who gets the affiliate fee - * @param _team what team is the player playing for? - * @param _eth amount of earnings to use (remainder returned to gen vault) - */ - function reLoadXid(uint256 _affCode, uint256 _team, uint256 _eth) - isActivated() - isHuman() - isWithinLimits(_eth) - public - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == 0 || _affCode == _pID) - { - // use last stored affiliate code - _affCode = plyr_[_pID].laff; - - // if affiliate code was given & its not the same as previously stored - } else if (_affCode != plyr_[_pID].laff) { - // update last affiliate - plyr_[_pID].laff = _affCode; - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // reload core - reLoadCore(_pID, _affCode, _team, _eth, _eventData_); - } - - function reLoadXaddr(address _affCode, uint256 _team, uint256 _eth) - isActivated() - isHuman() - isWithinLimits(_eth) - public - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == address(0) || _affCode == msg.sender) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxAddr_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // reload core - reLoadCore(_pID, _affID, _team, _eth, _eventData_); - } - - function reLoadXname(bytes32 _affCode, uint256 _team, uint256 _eth) - isActivated() - isHuman() - isWithinLimits(_eth) - public - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == '' || _affCode == plyr_[_pID].name) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxName_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // reload core - reLoadCore(_pID, _affID, _team, _eth, _eventData_); - } - - /** - * @dev withdraws all of your earnings. - * -functionhash- 0x3ccfd60b - */ - function withdraw() - isActivated() - isHuman() - public - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = block.timestamp; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // setup temp var for player eth - uint256 _eth; - - // check to see if round has ended and no one has run round end yet - if (_now > round_[_rID].end && round_[_rID].ended == false && round_[_rID].plyr != 0) - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // end the round (distributes pot) - round_[_rID].ended = true; - _eventData_ = endRound(_eventData_); - - // get their earnings - _eth = withdrawEarnings(_pID); - - // gib moni - if (_eth > 0) - plyr_[_pID].addr.transfer(_eth); - - // build event data - _eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID; - - // fire withdraw and distribute event - emit F3Devents.onWithdrawAndDistribute - ( - msg.sender, - plyr_[_pID].name, - _eth, - _eventData_.compressedData, - _eventData_.compressedIDs, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount - ); - - // in any other situation - } else { - // get their earnings - _eth = withdrawEarnings(_pID); - - // gib moni - if (_eth > 0) - plyr_[_pID].addr.transfer(_eth); - - // fire withdraw event - emit F3Devents.onWithdraw(_pID, msg.sender, plyr_[_pID].name, _eth, _now); - } - } - - /** - * @dev use these to register names. they are just wrappers that will send the - * registration requests to the PlayerBook contract. So registering here is the - * same as registering there. UI will always display the last name you registered. - * but you will still own all previously registered names to use as affiliate - * links. - * - must pay a registration fee. - * - name must be unique - * - names will be converted to lowercase - * - name cannot start or end with a space - * - cannot have more than 1 space in a row - * - cannot be only numbers - * - cannot start with 0x - * - name must be at least 1 char - * - max length of 32 characters long - * - allowed characters: a-z, 0-9, and space - * -functionhash- 0x921dec21 (using ID for affiliate) - * -functionhash- 0x3ddd4698 (using address for affiliate) - * -functionhash- 0x685ffd83 (using name for affiliate) - * @param _nameString players desired name - * @param _affCode affiliate ID, address, or name of who referred you - * @param _all set to true if you want this to push your info to all games - * (this might cost a lot of gas) - */ - function registerNameXID(string memory _nameString, uint256 _affCode, bool _all) - isHuman() - public - payable - { - bytes32 _name = _nameString.nameFilter(); - address _addr = msg.sender; - uint256 _paid = msg.value; - (bool _isNewPlayer, uint256 _affID) = playerBook.registerNameXIDFromDapp{value:_paid}(_addr, _name, _affCode, _all); - - uint256 _pID = pIDxAddr_[_addr]; - - // fire event - emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, block.timestamp); - } - - function registerNameXaddr(string memory _nameString, address _affCode, bool _all) - isHuman() - public - payable - { - bytes32 _name = _nameString.nameFilter(); - address _addr = msg.sender; - uint256 _paid = msg.value; - (bool _isNewPlayer, uint256 _affID) = playerBook.registerNameXaddrFromDapp{value:msg.value}(msg.sender, _name, _affCode, _all); - - uint256 _pID = pIDxAddr_[_addr]; - - // fire event - emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, block.timestamp); - } - - function registerNameXname(string memory _nameString, bytes32 _affCode, bool _all) - isHuman() - public - payable - { - bytes32 _name = _nameString.nameFilter(); - address _addr = msg.sender; - uint256 _paid = msg.value; - (bool _isNewPlayer, uint256 _affID) = playerBook.registerNameXnameFromDapp{value:msg.value}(msg.sender, _name, _affCode, _all); - - uint256 _pID = pIDxAddr_[_addr]; - - // fire event - emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, block.timestamp); - } - //============================================================================== - // _ _ _|__|_ _ _ _ . - // (_|(/_ | | (/_| _\ . (for UI & viewing things on etherscan) - //=====_|======================================================================= - /** - * @dev return the price buyer will pay for next 1 individual key. - * -functionhash- 0x018a25e8 - * @return price for next key bought (in wei format) - */ - function getBuyPrice() - public - view - returns (uint256) - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = block.timestamp; - - // are we in a round? - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - return ((round_[_rID].keys.add(1000000000000000000)).ethRec(1000000000000000000)); - else // rounds over. need price for new round - return (75000000000000); - // init - } - - /** - * @dev returns time left. dont spam this, you'll ddos yourself from your node - * provider - * -functionhash- 0xc7e284b8 - * @return time left in seconds - */ - function getTimeLeft() - public - view - returns (uint256) - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = block.timestamp; - - if (_now < round_[_rID].end) - if (_now > round_[_rID].strt + rndGap_) - return ((round_[_rID].end).sub(_now)); - else - return ((round_[_rID].strt + rndGap_).sub(_now)); - else - return (0); - } - - /** - * @dev returns player earnings per vaults - * -functionhash- 0x63066434 - * @return winnings vault - * @return general vault - * @return affiliate vault - */ - function getPlayerVaults(uint256 _pID) - public - view - returns (uint256, uint256, uint256) - { - // setup local rID - uint256 _rID = rID_; - - // if round has ended. but round end has not been run (so contract has not distributed winnings) - if (block.timestamp > round_[_rID].end && round_[_rID].ended == false && round_[_rID].plyr != 0) - { - // if player is winner - if (round_[_rID].plyr == _pID) - { - return - ( - (plyr_[_pID].win).add(((round_[_rID].pot).mul(48)) / 100), - (plyr_[_pID].gen).add(getPlayerVaultsHelper(_pID, _rID).sub(plyrRnds_[_pID][_rID].mask)), - plyr_[_pID].aff - ); - // if player is not the winner - } else { - return - ( - plyr_[_pID].win, - (plyr_[_pID].gen).add(getPlayerVaultsHelper(_pID, _rID).sub(plyrRnds_[_pID][_rID].mask)), - plyr_[_pID].aff - ); - } - - // if round is still going on, or round has ended and round end has been ran - } else { - return - ( - plyr_[_pID].win, - (plyr_[_pID].gen).add(calcUnMaskedEarnings(_pID, plyr_[_pID].lrnd)), - plyr_[_pID].aff - ); - } - } - - /** - * solidity hates stack limits. this lets us avoid that hate - */ - function getPlayerVaultsHelper(uint256 _pID, uint256 _rID) - private - view - returns (uint256) - { - return (((((round_[_rID].mask).add(((((round_[_rID].pot).mul(potSplit_[round_[_rID].team].gen)) / 100).mul(1000000000000000000)) / (round_[_rID].keys))).mul(plyrRnds_[_pID][_rID].keys)) / 1000000000000000000)); - } - - /** - * @dev returns all current round info needed for front end - * -functionhash- 0x747dff42 - * @return eth invested during ICO phase - * @return round id - * @return total keys for round - * @return time round ends - * @return time round started - * @return current pot - * @return current team ID & player ID in lead - * @return current player in leads address - * @return current player in leads name - * @return whales eth in for round - * @return bears eth in for round - * @return sneks eth in for round - * @return bulls eth in for round - * @return airdrop tracker # & airdrop pot - */ - function getCurrentRoundInfo() - public - view - returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256, address, bytes32, uint256, uint256, uint256, uint256, uint256) - { - // setup local rID - uint256 _rID = rID_; - - return - ( - round_[_rID].ico, //0 - _rID, //1 - round_[_rID].keys, //2 - round_[_rID].end, //3 - round_[_rID].strt, //4 - round_[_rID].pot, //5 - (round_[_rID].team + (round_[_rID].plyr * 10)), //6 - plyr_[round_[_rID].plyr].addr, //7 - plyr_[round_[_rID].plyr].name, //8 - rndTmEth_[_rID][0], //9 - rndTmEth_[_rID][1], //10 - rndTmEth_[_rID][2], //11 - rndTmEth_[_rID][3], //12 - airDropTracker_ + (airDropPot_ * 1000) //13 - ); - } - - /** - * @dev returns player info based on address. if no address is given, it will - * use msg.sender - * -functionhash- 0xee0b5d8b - * @param _addr address of the player you want to lookup - * @return player ID - * @return player name - * @return keys owned (current round) - * @return winnings vault - * @return general vault - * @return affiliate vault - * @return player round eth - */ - function getPlayerInfoByAddress(address _addr) - public - view - returns (uint256, bytes32, uint256, uint256, uint256, uint256, uint256) - { - // setup local rID - uint256 _rID = rID_; - - if (_addr == address(0)) - { - _addr == msg.sender; - } - uint256 _pID = pIDxAddr_[_addr]; - - return - ( - _pID, //0 - plyr_[_pID].name, //1 - plyrRnds_[_pID][_rID].keys, //2 - plyr_[_pID].win, //3 - (plyr_[_pID].gen).add(calcUnMaskedEarnings(_pID, plyr_[_pID].lrnd)), //4 - plyr_[_pID].aff, //5 - plyrRnds_[_pID][_rID].eth //6 - ); - } - - //============================================================================== - // _ _ _ _ | _ _ . _ . - // (_(_)| (/_ |(_)(_||(_ . (this + tools + calcs + modules = our softwares engine) - //=====================_|======================================================= - /** - * @dev logic runs whenever a buy order is executed. determines how to handle - * incoming eth depending on if we are in an active round or not - */ - function buyCore(uint256 _pID, uint256 _affID, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) - private - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = block.timestamp; - - // if round is active - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - { - // call core - core(_rID, _pID, msg.value, _affID, _team, _eventData_); - - // if round is not active - } else { - // check to see if end round needs to be ran - if (_now > round_[_rID].end && round_[_rID].ended == false) - { - // end the round (distributes pot) & start new round - round_[_rID].ended = true; - _eventData_ = endRound(_eventData_); - - // build event data - _eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID; - - // fire buy and distribute event - emit F3Devents.onBuyAndDistribute - ( - msg.sender, - plyr_[_pID].name, - msg.value, - _eventData_.compressedData, - _eventData_.compressedIDs, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount - ); - } - - // put eth in players vault - plyr_[_pID].gen = plyr_[_pID].gen.add(msg.value); - } - } - - /** - * @dev logic runs whenever a reload order is executed. determines how to handle - * incoming eth depending on if we are in an active round or not - */ - function reLoadCore(uint256 _pID, uint256 _affID, uint256 _team, uint256 _eth, F3Ddatasets.EventReturns memory _eventData_) - private - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = block.timestamp; - - // if round is active - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - { - // get earnings from all vaults and return unused to gen vault - // because we use a custom safemath library. this will throw if player - // tried to spend more eth than they have. - plyr_[_pID].gen = withdrawEarnings(_pID).sub(_eth); - - // call core - core(_rID, _pID, _eth, _affID, _team, _eventData_); - - // if round is not active and end round needs to be ran - } else if (_now > round_[_rID].end && round_[_rID].ended == false) { - // end the round (distributes pot) & start new round - round_[_rID].ended = true; - _eventData_ = endRound(_eventData_); - - // build event data - _eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID; - - // fire buy and distribute event - emit F3Devents.onReLoadAndDistribute - ( - msg.sender, - plyr_[_pID].name, - _eventData_.compressedData, - _eventData_.compressedIDs, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount - ); - } - } - - /** - * @dev this is the core logic for any buy/reload that happens while a round - * is live. - */ - function core(uint256 _rID, uint256 _pID, uint256 _eth, uint256 _affID, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) - private - { - // if player is new to round - if (plyrRnds_[_pID][_rID].keys == 0) - _eventData_ = managePlayer(_pID, _eventData_); - - // early round eth limiter - if (round_[_rID].eth < 100000000000000000000 && plyrRnds_[_pID][_rID].eth.add(_eth) > 1000000000000000000) - { - uint256 _availableLimit = (1000000000000000000).sub(plyrRnds_[_pID][_rID].eth); - uint256 _refund = _eth.sub(_availableLimit); - plyr_[_pID].gen = plyr_[_pID].gen.add(_refund); - _eth = _availableLimit; - } - - // if eth left is greater than min eth allowed (sorry no pocket lint) - if (_eth > 1000000000) - { - - // mint the new keys - uint256 _keys = (round_[_rID].eth).keysRec(_eth); - - // if they bought at least 1 whole key - if (_keys >= 1000000000000000000) - { - updateTimer(_keys, _rID); - - // set new leaders - if (round_[_rID].plyr != _pID) - round_[_rID].plyr = _pID; - if (round_[_rID].team != _team) - round_[_rID].team = _team; - - // set the new leader bool to true - _eventData_.compressedData = _eventData_.compressedData + 100; - } - - // manage airdrops - if (_eth >= 100000000000000000) - { - airDropTracker_++; - if (airdrop() == true) - { - // gib muni - uint256 _prize; - if (_eth >= 10000000000000000000) - { - // calculate prize and give it to winner - _prize = ((airDropPot_).mul(75)) / 100; - plyr_[_pID].win = (plyr_[_pID].win).add(_prize); - - // adjust airDropPot - airDropPot_ = (airDropPot_).sub(_prize); - - // let event know a tier 3 prize was won - _eventData_.compressedData += 300000000000000000000000000000000; - } else if (_eth >= 1000000000000000000 && _eth < 10000000000000000000) { - // calculate prize and give it to winner - _prize = ((airDropPot_).mul(50)) / 100; - plyr_[_pID].win = (plyr_[_pID].win).add(_prize); - - // adjust airDropPot - airDropPot_ = (airDropPot_).sub(_prize); - - // let event know a tier 2 prize was won - _eventData_.compressedData += 200000000000000000000000000000000; - } else if (_eth >= 100000000000000000 && _eth < 1000000000000000000) { - // calculate prize and give it to winner - _prize = ((airDropPot_).mul(25)) / 100; - plyr_[_pID].win = (plyr_[_pID].win).add(_prize); - - // adjust airDropPot - airDropPot_ = (airDropPot_).sub(_prize); - - // let event know a tier 3 prize was won - _eventData_.compressedData += 300000000000000000000000000000000; - } - // set airdrop happened bool to true - _eventData_.compressedData += 10000000000000000000000000000000; - // let event know how much was won - _eventData_.compressedData += _prize * 1000000000000000000000000000000000; - - // reset air drop tracker - airDropTracker_ = 0; - } - } - - // store the air drop tracker number (number of buys since last airdrop) - _eventData_.compressedData = _eventData_.compressedData + (airDropTracker_ * 1000); - - // update player - plyrRnds_[_pID][_rID].keys = _keys.add(plyrRnds_[_pID][_rID].keys); - plyrRnds_[_pID][_rID].eth = _eth.add(plyrRnds_[_pID][_rID].eth); - - // update round - round_[_rID].keys = _keys.add(round_[_rID].keys); - round_[_rID].eth = _eth.add(round_[_rID].eth); - rndTmEth_[_rID][_team] = _eth.add(rndTmEth_[_rID][_team]); - - // distribute eth - _eventData_ = distributeExternal(_rID, _pID, _eth, _affID, _team, _eventData_); - _eventData_ = distributeInternal(_rID, _pID, _eth, _team, _keys, _eventData_); - - // call end tx function to fire end tx event. - endTx(_pID, _team, _eth, _keys, _eventData_); - } - } - //============================================================================== - // _ _ | _ | _ _|_ _ _ _ . - // (_(_||(_|_||(_| | (_)| _\ . - //============================================================================== - /** - * @dev calculates unmasked earnings (just calculates, does not update mask) - * @return earnings in wei format - */ - function calcUnMaskedEarnings(uint256 _pID, uint256 _rIDlast) - private - view - returns (uint256) - { - return ((((round_[_rIDlast].mask).mul(plyrRnds_[_pID][_rIDlast].keys)) / (1000000000000000000)).sub(plyrRnds_[_pID][_rIDlast].mask)); - } - - /** - * @dev returns the amount of keys you would get given an amount of eth. - * -functionhash- 0xce89c80c - * @param _rID round ID you want price for - * @param _eth amount of eth sent in - * @return keys received - */ - function calcKeysReceived(uint256 _rID, uint256 _eth) - public - view - returns (uint256) - { - // grab time - uint256 _now = block.timestamp; - - // are we in a round? - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - return ((round_[_rID].eth).keysRec(_eth)); - else // rounds over. need keys for new round - return ((_eth).keys()); - } - - /** - * @dev returns current eth price for X keys. - * -functionhash- 0xcf808000 - * @param _keys number of keys desired (in 18 decimal format) - * @return amount of eth needed to send - */ - function iWantXKeys(uint256 _keys) - public - view - returns (uint256) - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = block.timestamp; - - // are we in a round? - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - return ((round_[_rID].keys.add(_keys)).ethRec(_keys)); - else // rounds over. need price for new round - return ((_keys).eth()); - } - //============================================================================== - // _|_ _ _ | _ . - // | (_)(_)|_\ . - //============================================================================== - /** - * @dev receives name/player info from names contract - */ - function receivePlayerInfo(uint256 _pID, address payable _addr, bytes32 _name, uint256 _laff) - external - { - require(msg.sender == address(playerBook), "your not playerNames contract... hmmm.."); - if (pIDxAddr_[_addr] != _pID) - pIDxAddr_[_addr] = _pID; - if (pIDxName_[_name] != _pID) - pIDxName_[_name] = _pID; - if (plyr_[_pID].addr != _addr) - plyr_[_pID].addr = _addr; - if (plyr_[_pID].name != _name) - plyr_[_pID].name = _name; - if (plyr_[_pID].laff != _laff) - plyr_[_pID].laff = _laff; - if (plyrNames_[_pID][_name] == false) - plyrNames_[_pID][_name] = true; - } - - /** - * @dev receives entire player name list - */ - function receivePlayerNameList(uint256 _pID, bytes32 _name) - external - { - require(msg.sender == address(playerBook), "your not playerNames contract... hmmm.."); - if (plyrNames_[_pID][_name] == false) - plyrNames_[_pID][_name] = true; - } - - /** - * @dev gets existing or registers new pID. use this when a player may be new - * @return pID - */ - function determinePID(F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - uint256 _pID = pIDxAddr_[msg.sender]; - // if player is new to this version of fomo3d - if (_pID == 0) - { - // grab their player ID, name and last aff ID, from player names contract - _pID = playerBook.getPlayerID(msg.sender); - bytes32 _name = playerBook.getPlayerName(_pID); - uint256 _laff = playerBook.getPlayerLAff(_pID); - - // set up player account - pIDxAddr_[msg.sender] = _pID; - plyr_[_pID].addr = payable(msg.sender); - - if (_name != "") - { - pIDxName_[_name] = _pID; - plyr_[_pID].name = _name; - plyrNames_[_pID][_name] = true; - } - - if (_laff != 0 && _laff != _pID) - plyr_[_pID].laff = _laff; - - // set the new player bool to true - _eventData_.compressedData = _eventData_.compressedData + 1; - } - return (_eventData_); - } - - /** - * @dev checks to make sure user picked a valid team. if not sets team - * to default (sneks) - */ - function verifyTeam(uint256 _team) - private - pure - returns (uint256) - { - if (_team < 0 || _team > 3) - return (2); - else - return (_team); - } - - /** - * @dev decides if round end needs to be run & new round started. and if - * player unmasked earnings from previously played rounds need to be moved. - */ - function managePlayer(uint256 _pID, F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - // if player has played a previous round, move their unmasked earnings - // from that round to gen vault. - if (plyr_[_pID].lrnd != 0) - updateGenVault(_pID, plyr_[_pID].lrnd); - - // update player's last round played - plyr_[_pID].lrnd = rID_; - - // set the joined round bool to true - _eventData_.compressedData = _eventData_.compressedData + 10; - - return (_eventData_); - } - - /** - * @dev ends the round. manages paying out winner/splitting up pot - */ - function endRound(F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - // setup local rID - uint256 _rID = rID_; - - // grab our winning player and team id's - uint256 _winPID = round_[_rID].plyr; - uint256 _winTID = round_[_rID].team; - - // grab our pot amount - uint256 _pot = round_[_rID].pot; - - // calculate our winner share, community rewards, gen share, - // p3d share, and amount reserved for next pot - uint256 _win = (_pot.mul(48)) / 100; - uint256 _com = (_pot / 50); - uint256 _gen = (_pot.mul(potSplit_[_winTID].gen)) / 100; - uint256 _p3d = (_pot.mul(potSplit_[_winTID].p3d)) / 100; - uint256 _res = (((_pot.sub(_win)).sub(_com)).sub(_gen)).sub(_p3d); - - // calculate ppt for round mask - uint256 _ppt = (_gen.mul(1000000000000000000)) / (round_[_rID].keys); - uint256 _dust = _gen.sub((_ppt.mul(round_[_rID].keys)) / 1000000000000000000); - if (_dust > 0) - { - _gen = _gen.sub(_dust); - _res = _res.add(_dust); - } - - // pay our winner - plyr_[_winPID].win = _win.add(plyr_[_winPID].win); - - // community rewards - address payable add = payable(address(uint160(Jekyll_Island_Inc))); - if (!add.send(_com)) - { - // This ensures Team Just cannot influence the outcome of FoMo3D with - // bank migrations by breaking outgoing transactions. - // Something we would never do. But that's not the point. - // We spent 2000$ in eth re-deploying just to patch this, we hold the - // highest belief that everything we create should be trustless. - // Team JUST, The name you shouldn't have to trust. - _p3d = _p3d.add(_com); - _com = 0; - } - - // distribute gen portion to key holders - round_[_rID].mask = _ppt.add(round_[_rID].mask); - - // send share for p3d to divies - if (_p3d > 0){ - address payable addr = payable(address(uint160(Divies))); - addr.transfer(_p3d); - } - // prepare event data - _eventData_.compressedData = _eventData_.compressedData + (round_[_rID].end * 1000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + (_winPID * 100000000000000000000000000) + (_winTID * 100000000000000000); - _eventData_.winnerAddr = plyr_[_winPID].addr; - _eventData_.winnerName = plyr_[_winPID].name; - _eventData_.amountWon = _win; - _eventData_.genAmount = _gen; - _eventData_.P3DAmount = _p3d; - _eventData_.newPot = _res; - - // start next round - rID_++; - _rID++; - round_[_rID].strt = block.timestamp; - round_[_rID].end = block.timestamp.add(rndInit_).add(rndGap_); - round_[_rID].pot = _res; - - return (_eventData_); - } - - /** - * @dev moves any unmasked earnings to gen vault. updates earnings mask - */ - function updateGenVault(uint256 _pID, uint256 _rIDlast) - private - { - uint256 _earnings = calcUnMaskedEarnings(_pID, _rIDlast); - if (_earnings > 0) - { - // put in gen vault - plyr_[_pID].gen = _earnings.add(plyr_[_pID].gen); - // zero out their earnings by updating mask - plyrRnds_[_pID][_rIDlast].mask = _earnings.add(plyrRnds_[_pID][_rIDlast].mask); - } - } - - /** - * @dev updates round timer based on number of whole keys bought. - */ - function updateTimer(uint256 _keys, uint256 _rID) - private - { - // grab time - uint256 _now = block.timestamp; - - // calculate time based on number of keys bought - uint256 _newTime; - if (_now > round_[_rID].end && round_[_rID].plyr == 0) - _newTime = (((_keys) / (1000000000000000000)).mul(rndInc_)).add(_now); - else - _newTime = (((_keys) / (1000000000000000000)).mul(rndInc_)).add(round_[_rID].end); - - // compare to max and set new end time - if (_newTime < (rndMax_).add(_now)) - round_[_rID].end = _newTime; - else - round_[_rID].end = rndMax_.add(_now); - } - - /** - * @dev generates a random number between 0-99 and checks to see if thats - * resulted in an airdrop win - * @return do we have a winner? - */ - function airdrop() - private - view - returns (bool) - { - uint256 seed = uint256(keccak256(abi.encodePacked( - - (block.timestamp).add - (block.difficulty).add - ((uint256(keccak256(abi.encodePacked(block.coinbase)))) / (block.timestamp)).add - (block.gaslimit).add - ((uint256(keccak256(abi.encodePacked(msg.sender)))) / (block.timestamp)).add - (block.number) - - ))); - if ((seed - ((seed / 1000) * 1000)) < airDropTracker_) - return (true); - else - return (false); - } - - /** - * @dev distributes eth based on fees to com, aff, and p3d - */ - function distributeExternal(uint256 _rID, uint256 _pID, uint256 _eth, uint256 _affID, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - // pay 2% out to community rewards - uint256 _com = _eth / 50; - uint256 _p3d; - address payable addr = payable(address(uint160(Jekyll_Island_Inc))); - if (!addr.send(_com)) - { - // This ensures Team Just cannot influence the outcome of FoMo3D with - // bank migrations by breaking outgoing transactions. - // Something we would never do. But that's not the point. - // We spent 2000$ in eth re-deploying just to patch this, we hold the - // highest belief that everything we create should be trustless. - // Team JUST, The name you shouldn't have to trust. - _p3d = _com; - _com = 0; - } - - // pay 1% out to FoMo3D short - _com = _eth / 100; - address payable add = payable(address(uint160(otherF3D_))); - add.transfer(_com); - - // distribute share to affiliate - _com = _eth / 10; - - // decide what to do with affiliate share of fees - // affiliate must not be self, and must have a name registered - if (_affID != _pID && plyr_[_affID].name != '') { - plyr_[_affID].aff = _com.add(plyr_[_affID].aff); - emit F3Devents.onAffiliatePayout(_affID, plyr_[_affID].addr, plyr_[_affID].name, _rID, _pID, _com, block.timestamp); - } else { - _p3d = _com; - } - - // pay out p3d - _p3d = _p3d.add((_eth.mul(fees_[_team].p3d)) / (100)); - if (_p3d > 0) - { - // deposit to divies contract - address payable add = payable(address(uint160(Divies))); - add.transfer(_p3d); - - // set up event data - _eventData_.P3DAmount = _p3d.add(_eventData_.P3DAmount); - } - - return (_eventData_); - } - - function potSwap() - external - payable - { - // setup local rID - uint256 _rID = rID_ + 1; - - round_[_rID].pot = round_[_rID].pot.add(msg.value); - emit F3Devents.onPotSwapDeposit(_rID, msg.value); - } - - /** - * @dev distributes eth based on fees to gen and pot - */ - function distributeInternal(uint256 _rID, uint256 _pID, uint256 _eth, uint256 _team, uint256 _keys, F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - // calculate gen share - uint256 _gen = (_eth.mul(fees_[_team].gen)) / 100; - - // toss 1% into airdrop pot - uint256 _air = (_eth / 100); - airDropPot_ = airDropPot_.add(_air); - - // update eth balance (eth = eth - (com share + pot swap share + aff share + p3d share + airdrop pot share)) - _eth = _eth.sub(((_eth.mul(14)) / 100).add((_eth.mul(fees_[_team].p3d)) / 100)); - - // calculate pot - uint256 _pot = _eth.sub(_gen); - - // distribute gen share (thats what updateMasks() does) and adjust - // balances for dust. - uint256 _dust = updateMasks(_rID, _pID, _gen, _keys); - if (_dust > 0) - _gen = _gen.sub(_dust); - - // add eth to pot - round_[_rID].pot = _pot.add(_dust).add(round_[_rID].pot); - - // set up event data - _eventData_.genAmount = _gen.add(_eventData_.genAmount); - _eventData_.potAmount = _pot; - - return (_eventData_); - } - - /** - * @dev updates masks for round and player when keys are bought - * @return dust left over - */ - function updateMasks(uint256 _rID, uint256 _pID, uint256 _gen, uint256 _keys) - private - returns (uint256) - { - /* MASKING NOTES - earnings masks are a tricky thing for people to wrap their minds around. - the basic thing to understand here. is were going to have a global - tracker based on profit per share for each round, that increases in - relevant proportion to the increase in share supply. - - the player will have an additional mask that basically says "based - on the rounds mask, my shares, and how much i've already withdrawn, - how much is still owed to me?" - */ - - // calc profit per key & round mask based on this buy: (dust goes to pot) - uint256 _ppt = (_gen.mul(1000000000000000000)) / (round_[_rID].keys); - round_[_rID].mask = _ppt.add(round_[_rID].mask); - - // calculate player earning from their own buy (only based on the keys - // they just bought). & update player earnings mask - uint256 _pearn = (_ppt.mul(_keys)) / (1000000000000000000); - plyrRnds_[_pID][_rID].mask = (((round_[_rID].mask.mul(_keys)) / (1000000000000000000)).sub(_pearn)).add(plyrRnds_[_pID][_rID].mask); - - // calculate & return dust - return (_gen.sub((_ppt.mul(round_[_rID].keys)) / (1000000000000000000))); - } - - /** - * @dev adds up unmasked earnings, & vault earnings, sets them all to 0 - * @return earnings in wei format - */ - function withdrawEarnings(uint256 _pID) - private - returns (uint256) - { - // update gen vault - updateGenVault(_pID, plyr_[_pID].lrnd); - - // from vaults - uint256 _earnings = (plyr_[_pID].win).add(plyr_[_pID].gen).add(plyr_[_pID].aff); - if (_earnings > 0) - { - plyr_[_pID].win = 0; - plyr_[_pID].gen = 0; - plyr_[_pID].aff = 0; - } - - return (_earnings); - } - - /** - * @dev prepares compression data and fires event for buy or reload tx's - */ - function endTx(uint256 _pID, uint256 _team, uint256 _eth, uint256 _keys, F3Ddatasets.EventReturns memory _eventData_) - private - { - _eventData_.compressedData = _eventData_.compressedData + (block.timestamp * 1000000000000000000) + (_team * 100000000000000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID + (rID_ * 10000000000000000000000000000000000000000000000000000); - - emit F3Devents.onEndTx - ( - _eventData_.compressedData, - _eventData_.compressedIDs, - plyr_[_pID].name, - msg.sender, - _eth, - _keys, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount, - _eventData_.potAmount, - airDropPot_ - ); - } - //============================================================================== - // (~ _ _ _._|_ . - // _)(/_(_|_|| | | \/ . - //====================/========================================================= - /** upon contract deploy, it will be deactivated. this is a one time - * use function that will activate the contract. we do this so devs - * have time to set things up on the web end **/ - bool public activated_ = false; - - function activate() - public - onlyDevs - { - - // can only be ran once - require(activated_ == false, "fomo3d already activated"); - - // activate the contract - activated_ = true; - - otherF3D_ = msg.sender; - Divies = msg.sender; - Jekyll_Island_Inc = msg.sender; - - // lets start first round - rID_ = 1; - round_[1].strt = block.timestamp + rndExtra_ - rndGap_; - round_[1].end = block.timestamp + rndInit_ + rndExtra_; - } - - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractScenario007.sol b/framework/src/test/resources/soliditycode/contractScenario007.sol deleted file mode 100644 index a6fa095860f..00000000000 --- a/framework/src/test/resources/soliditycode/contractScenario007.sol +++ /dev/null @@ -1,1432 +0,0 @@ - -/** - * @title ERC165 - * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md - */ -interface ERC165 { - - /** - * @notice Query if a contract implements an interface - * @param _interfaceId The interface identifier, as specified in ERC-165 - * @dev Interface identification is specified in ERC-165. This function - * uses less than 30,000 gas. - */ - function supportsInterface(bytes4 _interfaceId) external view returns (bool); - -} - -contract ERC721Basic is ERC165 { - - event Transfer( - address indexed _from, - address indexed _to, - uint256 indexed _tokenId - ); - event Approval( - address indexed _owner, - address indexed _approved, - uint256 indexed _tokenId - ); - event ApprovalForAll( - address indexed _owner, - address indexed _operator, - bool _approved - ); - - function balanceOf(address _owner) public view returns (uint256 _balance); - function ownerOf(uint256 _tokenId) public view returns (address _owner); - function exists(uint256 _tokenId) public view returns (bool _exists); - - function approve(address _to, uint256 _tokenId) public; - function getApproved(uint256 _tokenId) - public view returns (address _operator); - - function setApprovalForAll(address _operator, bool _approved) public; - function isApprovedForAll(address _owner, address _operator) - public view returns (bool); - - function transferFrom(address _from, address _to, uint256 _tokenId) public; - function safeTransferFrom(address _from, address _to, uint256 _tokenId) - public; - - function safeTransferFrom( - address _from, - address _to, - uint256 _tokenId, - bytes memory _data - ) - public; -} - - -/** - * @title SupportsInterfaceWithLookup - * @author Matt Condon (@shrugs) - * @dev Implements ERC165 using a lookup table. - */ -contract SupportsInterfaceWithLookup is ERC165 { - bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7; - /** - * 0x01ffc9a7 === - * bytes4(keccak256('supportsInterface(bytes4)')) - */ - - /** - * @dev a mapping of interface id to whether or not it's supported - */ - mapping(bytes4 => bool) internal supportedInterfaces; - - /** - * @dev A contract implementing SupportsInterfaceWithLookup - * implement ERC165 itself - */ - constructor() public { - _registerInterface(InterfaceId_ERC165); - } - - /** - * @dev implement supportsInterface(bytes4) using a lookup table - */ - function supportsInterface(bytes4 _interfaceId) external view returns (bool) { - return supportedInterfaces[_interfaceId]; - } - - /** - * @dev private method for registering an interface - */ - function _registerInterface(bytes4 _interfaceId) internal { - require(_interfaceId != 0xffffffff); - supportedInterfaces[_interfaceId] = true; - } -} - -contract Governable { - - event Pause(); - event Unpause(); - - address public governor; - bool public paused = false; - - constructor() public { - governor = msg.sender; - } - - function setGovernor(address _gov) public onlyGovernor { - governor = _gov; - } - - modifier onlyGovernor { - require(msg.sender == governor); - _; - } - - /** - * @dev Modifier to make a function callable only when the contract is not paused. - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev Modifier to make a function callable only when the contract is paused. - */ - modifier whenPaused() { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyGovernor whenNotPaused public { - paused = true; - emit Pause(); - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyGovernor whenPaused public { - paused = false; - emit Unpause(); - } - -} - -contract CardBase is Governable { - - struct Card { - uint16 proto; - uint16 purity; - } - - function getCard(uint id) public view returns (uint16 proto, uint16 purity) { - Card memory card = cards[id]; - return (card.proto, card.purity); - } - - function getShine(uint16 purity) public pure returns (uint8) { - return uint8(purity / 1000); - } - - Card[] public cards; - -} - -contract CardProto is CardBase { - - event NewProtoCard( - uint16 id, uint8 season, uint8 god, - Rarity rarity, uint8 mana, uint8 attack, - uint8 health, uint8 cardType, uint8 tribe, bool packable - ); - - struct Limit { - uint64 limit; - bool exists; - } - - // limits for mythic cards - mapping(uint16 => Limit) public limits; - - // can only set limits once - function setLimit(uint16 id, uint64 limit) public onlyGovernor { - Limit memory l = limits[id]; - require(!l.exists); - limits[id] = Limit({ - limit: limit, - exists: true - }); - } - - function getLimit(uint16 id) public view returns (uint64 limit, bool set) { - Limit memory l = limits[id]; - return (l.limit, l.exists); - } - - // could make these arrays to save gas - // not really necessary - will be update a very limited no of times - mapping(uint8 => bool) public seasonTradable; - mapping(uint8 => bool) public seasonTradabilityLocked; - uint8 public currentSeason; - - function makeTradable(uint8 season) public onlyGovernor { - seasonTradable[season] = true; - } - - function makeUntradable(uint8 season) public onlyGovernor { - require(!seasonTradabilityLocked[season]); - seasonTradable[season] = false; - } - - function makePermanantlyTradable(uint8 season) public onlyGovernor { - require(seasonTradable[season]); - seasonTradabilityLocked[season] = true; - } - - function isTradable(uint16 proto) public view returns (bool) { - return seasonTradable[protos[proto].season]; - } - - function nextSeason() public onlyGovernor { - //Seasons shouldn't go to 0 if there is more than the uint8 should hold, the governor should know this ¯\_(ツ)_/¯ -M - require(currentSeason <= 255); - - currentSeason++; - mythic.length = 0; - legendary.length = 0; - epic.length = 0; - rare.length = 0; - common.length = 0; - } - - enum Rarity { - Common, - Rare, - Epic, - Legendary, - Mythic - } - - uint8 constant SPELL = 1; - uint8 constant MINION = 2; - uint8 constant WEAPON = 3; - uint8 constant HERO = 4; - - struct ProtoCard { - bool exists; - uint8 god; - uint8 season; - uint8 cardType; - Rarity rarity; - uint8 mana; - uint8 attack; - uint8 health; - uint8 tribe; - } - - // there is a particular design decision driving this: - // need to be able to iterate over mythics only for card generation - // don't store 5 different arrays: have to use 2 ids - // better to bear this cost (2 bytes per proto card) - // rather than 1 byte per instance - - uint16 public protoCount; - - mapping(uint16 => ProtoCard) protos; - - uint16[] public mythic; - uint16[] public legendary; - uint16[] public epic; - uint16[] public rare; - uint16[] public common; - - function addProtos( - uint16[] memory externalIDs, uint8[] memory gods, Rarity[] memory rarities, uint8[] memory manas, uint8[] memory attacks, - uint8[] memory healths, uint8[] memory cardTypes, uint8[] memory tribes, bool[] memory packable - ) public onlyGovernor returns(uint16) { - - for (uint i = 0; i < externalIDs.length; i++) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: gods[i], - season: currentSeason, - cardType: cardTypes[i], - rarity: rarities[i], - mana: manas[i], - attack: attacks[i], - health: healths[i], - tribe: tribes[i] - }); - - _addProto(externalIDs[i], card, packable[i]); - } - - } - - function addProto( - uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 cardType, uint8 tribe, bool packable - ) public onlyGovernor returns(uint16) { - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: cardType, - rarity: rarity, - mana: mana, - attack: attack, - health: health, - tribe: tribe - }); - - _addProto(externalID, card, packable); - } - - function addWeapon( - uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 durability, bool packable - ) public onlyGovernor returns(uint16) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: WEAPON, - rarity: rarity, - mana: mana, - attack: attack, - health: durability, - tribe: 0 - }); - - _addProto(externalID, card, packable); - } - - function addSpell(uint16 externalID, uint8 god, Rarity rarity, uint8 mana, bool packable) public onlyGovernor returns(uint16) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: SPELL, - rarity: rarity, - mana: mana, - attack: 0, - health: 0, - tribe: 0 - }); - - _addProto(externalID, card, packable); - } - - function addMinion( - uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 tribe, bool packable - ) public onlyGovernor returns(uint16) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: MINION, - rarity: rarity, - mana: mana, - attack: attack, - health: health, - tribe: tribe - }); - - _addProto(externalID, card, packable); - } - - function _addProto(uint16 externalID, ProtoCard memory card, bool packable) internal { - - require(!protos[externalID].exists); - - card.exists = true; - - protos[externalID] = card; - - protoCount++; - - emit NewProtoCard( - externalID, currentSeason, card.god, - card.rarity, card.mana, card.attack, - card.health, card.cardType, card.tribe, packable - ); - - if (packable) { - Rarity rarity = card.rarity; - if (rarity == Rarity.Common) { - common.push(externalID); - } else if (rarity == Rarity.Rare) { - rare.push(externalID); - } else if (rarity == Rarity.Epic) { - epic.push(externalID); - } else if (rarity == Rarity.Legendary) { - legendary.push(externalID); - } else if (rarity == Rarity.Mythic) { - mythic.push(externalID); - } else { - require(false); - } - } - } - - function getProto(uint16 id) public view returns( - bool exists, uint8 god, uint8 season, uint8 cardType, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 tribe - ) { - ProtoCard memory proto = protos[id]; - return ( - proto.exists, - proto.god, - proto.season, - proto.cardType, - proto.rarity, - proto.mana, - proto.attack, - proto.health, - proto.tribe - ); - } - - function getRandomCard(Rarity rarity, uint16 random) public view returns (uint16) { - // modulo bias is fine - creates rarity tiers etc - // will obviously revert is there are no cards of that type: this is expected - should never happen - if (rarity == Rarity.Common) { - return common[random % common.length]; - } else if (rarity == Rarity.Rare) { - return rare[random % rare.length]; - } else if (rarity == Rarity.Epic) { - return epic[random % epic.length]; - } else if (rarity == Rarity.Legendary) { - return legendary[random % legendary.length]; - } else if (rarity == Rarity.Mythic) { - // make sure a mythic is available - uint16 id; - uint64 limit; - bool set; - for (uint i = 0; i < mythic.length; i++) { - id = mythic[(random + i) % mythic.length]; - (limit, set) = getLimit(id); - if (set && limit > 0){ - return id; - } - } - // if not, they get a legendary :( - return legendary[random % legendary.length]; - } - require(false); - return 0; - } - - // can never adjust tradable cards - // each season gets a 'balancing beta' - // totally immutable: season, rarity - function replaceProto( - uint16 index, uint8 god, uint8 cardType, uint8 mana, uint8 attack, uint8 health, uint8 tribe - ) public onlyGovernor { - ProtoCard memory pc = protos[index]; - require(!seasonTradable[pc.season]); - protos[index] = ProtoCard({ - exists: true, - god: god, - season: pc.season, - cardType: cardType, - rarity: pc.rarity, - mana: mana, - attack: attack, - health: health, - tribe: tribe - }); - } - -} - -contract ERC721Receiver { - /** - * @dev Magic value to be returned upon successful reception of an NFT - * Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`, - * which can be also obtained as `ERC721Receiver(0).onERC721Received.selector` - */ - bytes4 internal constant ERC721_RECEIVED = 0x150b7a02; - - /** - * @notice Handle the receipt of an NFT - * @dev The ERC721 smart contract calls this function on the recipient - * after a `safetransfer`. This function MAY throw to revert and reject the - * transfer. Return of other than the magic value MUST result in the - * transaction being reverted. - * Note: the contract address is always the message sender. - * @param _operator The address which called `safeTransferFrom` function - * @param _from The address which previously owned the token - * @param _tokenId The NFT identifier which is being transfered - * @param _data Additional data with no specified format - * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` - */ - function onERC721Received( - address _operator, - address _from, - uint256 _tokenId, - bytes memory _data - ) - public - returns(bytes4); -} - -library AddressUtils { - - /** - * Returns whether the target address is a contract - * @dev This function will return false if invoked during the constructor of a contract, - * as the code is not actually created until after the constructor finishes. - * @param addr address to check - * @return whether the target address is a contract - */ - function isContract1(address addr) internal view returns (bool) { - uint256 size; - // XXX Currently there is no better way to check if there is a contract in an address - // than to check the size of the code at that address. - // See https://ethereum.stackexchange.com/a/14016/36603 - // for more details about how this works. - // TODO Check this again before the Serenity release, because all addresses will be - // contracts then. - // solium-disable-next-line security/no-inline-assembly - assembly { size := extcodesize(addr) } - return size > 0; - } - -} - -library SafeMath { - - /** - * @dev Multiplies two numbers, throws on overflow. - */ - function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { - // Gas optimization: this is cheaper than asserting 'a' not being zero, but the - // benefit is lost if 'b' is also tested. - // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 - if (a == 0) { - return 0; - } - - c = a * b; - assert(c / a == b); - return c; - } - - /** - * @dev Integer division of two numbers, truncating the quotient. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - // assert(b > 0); // Solidity automatically throws when dividing by 0 - // uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - return a / b; - } - - /** - * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). - */ - function sub(uint256 a, uint256 b) internal pure returns (uint256) { - assert(b <= a); - return a - b; - } - - /** - * @dev Adds two numbers, throws on overflow. - */ - function add(uint256 a, uint256 b) internal pure returns (uint256 c) { - c = a + b; - assert(c >= a); - return c; - } -} - -contract ERC721BasicToken is CardProto, SupportsInterfaceWithLookup, ERC721Basic { - - bytes4 private constant InterfaceId_ERC721 = 0x80ac58cd; - /* - * 0x80ac58cd === - * bytes4(keccak256('balanceOf(address)')) ^ - * bytes4(keccak256('ownerOf(uint256)')) ^ - * bytes4(keccak256('approve(address,uint256)')) ^ - * bytes4(keccak256('getApproved(uint256)')) ^ - * bytes4(keccak256('setApprovalForAll(address,bool)')) ^ - * bytes4(keccak256('isApprovedForAll(address,address)')) ^ - * bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^ - * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) - */ - - bytes4 private constant InterfaceId_ERC721Exists = 0x4f558e79; - /* - * 0x4f558e79 === - * bytes4(keccak256('exists(uint256)')) - */ - - using SafeMath for uint256; - using AddressUtils for address; - - // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` - // which can be also obtained as `ERC721Receiver(0).onERC721Received.selector` - bytes4 private constant ERC721_RECEIVED = 0x150b7a02; - - // Mapping from token ID to owner - mapping (uint256 => address) internal tokenOwner; - - // Mapping from token ID to approved address - mapping (uint256 => address) internal tokenApprovals; - - // Mapping from owner to number of owned token - // mapping (address => uint256) internal ownedTokensCount; - - // Mapping from owner to operator approvals - mapping (address => mapping (address => bool)) internal operatorApprovals; - - /** - * @dev Guarantees msg.sender is owner of the given token - * @param _tokenId uint256 ID of the token to validate its ownership belongs to msg.sender - */ - modifier onlyOwnerOf(uint256 _tokenId) { - require(ownerOf(_tokenId) == msg.sender); - _; - } - - /** - * @dev Checks msg.sender can transfer a token, by being owner, approved, or operator - * @param _tokenId uint256 ID of the token to validate - */ - modifier canTransfer(uint256 _tokenId) { - require(isApprovedOrOwner(msg.sender, _tokenId)); - _; - } - - constructor() - public - { - // register the supported interfaces to conform to ERC721 via ERC165 - _registerInterface(InterfaceId_ERC721); - _registerInterface(InterfaceId_ERC721Exists); - } - - /** - * @dev Gets the balance of the specified address - * @param _owner address to query the balance of - * @return uint256 representing the amount owned by the passed address - */ - function balanceOf(address _owner) public view returns (uint256); - - /** - * @dev Gets the owner of the specified token ID - * @param _tokenId uint256 ID of the token to query the owner of - * @return owner address currently marked as the owner of the given token ID - */ - function ownerOf(uint256 _tokenId) public view returns (address) { - address owner = tokenOwner[_tokenId]; - require(owner != address(0)); - return owner; - } - - /** - * @dev Returns whether the specified token exists - * @param _tokenId uint256 ID of the token to query the existence of - * @return whether the token exists - */ - function exists(uint256 _tokenId) public view returns (bool) { - address owner = tokenOwner[_tokenId]; - return owner != address(0); - } - - /** - * @dev Approves another address to transfer the given token ID - * The zero address indicates there is no approved address. - * There can only be one approved address per token at a given time. - * Can only be called by the token owner or an approved operator. - * @param _to address to be approved for the given token ID - * @param _tokenId uint256 ID of the token to be approved - */ - function approve(address _to, uint256 _tokenId) public { - address owner = ownerOf(_tokenId); - require(_to != owner); - require(msg.sender == owner || isApprovedForAll(owner, msg.sender)); - - tokenApprovals[_tokenId] = _to; - emit Approval(owner, _to, _tokenId); - } - - /** - * @dev Gets the approved address for a token ID, or zero if no address set - * @param _tokenId uint256 ID of the token to query the approval of - * @return address currently approved for the given token ID - */ - function getApproved(uint256 _tokenId) public view returns (address) { - return tokenApprovals[_tokenId]; - } - - /** - * @dev Sets or unsets the approval of a given operator - * An operator is allowed to transfer all tokens of the sender on their behalf - * @param _to operator address to set the approval - * @param _approved representing the status of the approval to be set - */ - function setApprovalForAll(address _to, bool _approved) public { - require(_to != msg.sender); - operatorApprovals[msg.sender][_to] = _approved; - emit ApprovalForAll(msg.sender, _to, _approved); - } - - /** - * @dev Tells whether an operator is approved by a given owner - * @param _owner owner address which you want to query the approval of - * @param _operator operator address which you want to query the approval of - * @return bool whether the given operator is approved by the given owner - */ - function isApprovedForAll( - address _owner, - address _operator - ) - public - view - returns (bool) - { - return operatorApprovals[_owner][_operator]; - } - - /** - * @dev Transfers the ownership of a given token ID to another address - * Usage of this method is discouraged, use `safeTransferFrom` whenever possible - * Requires the msg sender to be the owner, approved, or operator - * @param _from current owner of the token - * @param _to address to receive the ownership of the given token ID - * @param _tokenId uint256 ID of the token to be transferred - */ - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - public - canTransfer(_tokenId) - { - require(_from != address(0)); - require(_to != address(0)); - - clearApproval(_from, _tokenId); - removeTokenFrom(_from, _tokenId); - addTokenTo(_to, _tokenId); - - emit Transfer(_from, _to, _tokenId); - } - - /** - * @dev Safely transfers the ownership of a given token ID to another address - * If the target address is a contract, it must implement `onERC721Received`, - * which is called upon a safe transfer, and return the magic value - * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, - * the transfer is reverted. - * - * Requires the msg sender to be the owner, approved, or operator - * @param _from current owner of the token - * @param _to address to receive the ownership of the given token ID - * @param _tokenId uint256 ID of the token to be transferred - */ - function safeTransferFrom( - address _from, - address _to, - uint256 _tokenId - ) - public - canTransfer(_tokenId) - { - // solium-disable-next-line arg-overflow - safeTransferFrom(_from, _to, _tokenId, ""); - } - - /** - * @dev Safely transfers the ownership of a given token ID to another address - * If the target address is a contract, it must implement `onERC721Received`, - * which is called upon a safe transfer, and return the magic value - * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, - * the transfer is reverted. - * Requires the msg sender to be the owner, approved, or operator - * @param _from current owner of the token - * @param _to address to receive the ownership of the given token ID - * @param _tokenId uint256 ID of the token to be transferred - * @param _data bytes data to send along with a safe transfer check - */ - function safeTransferFrom( - address _from, - address _to, - uint256 _tokenId, - bytes memory _data - ) - public - canTransfer(_tokenId) - { - transferFrom(_from, _to, _tokenId); - // solium-disable-next-line arg-overflow - require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data)); - } - - /** - * @dev Returns whether the given spender can transfer a given token ID - * @param _spender address of the spender to query - * @param _tokenId uint256 ID of the token to be transferred - * @return bool whether the msg.sender is approved for the given token ID, - * is an operator of the owner, or is the owner of the token - */ - function isApprovedOrOwner( - address _spender, - uint256 _tokenId - ) - internal - view - returns (bool) - { - address owner = ownerOf(_tokenId); - // Disable solium check because of - // https://github.com/duaraghav8/Solium/issues/175 - // solium-disable-next-line operator-whitespace - return ( - _spender == owner || - getApproved(_tokenId) == _spender || - isApprovedForAll(owner, _spender) - ); - } - - /** - * @dev Internal function to clear current approval of a given token ID - * Reverts if the given address is not indeed the owner of the token - * @param _owner owner of the token - * @param _tokenId uint256 ID of the token to be transferred - */ - function clearApproval(address _owner, uint256 _tokenId) internal { - require(ownerOf(_tokenId) == _owner); - if (tokenApprovals[_tokenId] != address(0)) { - tokenApprovals[_tokenId] = address(0); - } - } - - /** - * @dev Internal function to mint a new token - * Reverts if the given token ID already exists - * @param _to The address that will own the minted token - * @param _tokenId uint256 ID of the token to be minted by the msg.sender - */ - function _mint(address _to, uint256 _tokenId) internal { - require(_to != address(0)); - addNewTokenTo(_to, _tokenId); - emit Transfer(address(0), _to, _tokenId); - } - - - /** - * @dev Internal function to burn a specific token - * Reverts if the token does not exist - * @param _tokenId uint256 ID of the token being burned by the msg.sender - */ - function _burn(address _owner, uint256 _tokenId) internal { - clearApproval(_owner, _tokenId); - removeTokenFrom(_owner, _tokenId); - emit Transfer(_owner, address(0), _tokenId); - } - - function addNewTokenTo(address _to, uint256 _tokenId) internal { - require(tokenOwner[_tokenId] == address(0)); - tokenOwner[_tokenId] = _to; - } - - /** - * @dev Internal function to add a token ID to the list of a given address - * @param _to address representing the new owner of the given token ID - * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address - */ - function addTokenTo(address _to, uint256 _tokenId) internal { - require(tokenOwner[_tokenId] == address(0)); - tokenOwner[_tokenId] = _to; - // ownedTokensCount[_to] = ownedTokensCount[_to].add(1); - } - - /** - * @dev Internal function to remove a token ID from the list of a given address - * @param _from address representing the previous owner of the given token ID - * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address - */ - function removeTokenFrom(address _from, uint256 _tokenId) internal { - require(ownerOf(_tokenId) == _from); - // ownedTokensCount[_from] = ownedTokensCount[_from].sub(1); - tokenOwner[_tokenId] = address(0); - } - - /** - * @dev Internal function to invoke `onERC721Received` on a target address - * The call is not executed if the target address is not a contract - * @param _from address representing the previous owner of the given token ID - * @param _to target address that will receive the tokens - * @param _tokenId uint256 ID of the token to be transferred - * @param _data bytes optional data to send along with the call - * @return whether the call correctly returned the expected magic value - */ - function checkAndCallSafeTransfer( - address _from, - address _to, - uint256 _tokenId, - bytes memory _data - ) - internal - returns (bool) - { - if (!_to.isContract1()) { - return true; - } - bytes4 retval = ERC721Receiver(_to).onERC721Received( - msg.sender, _from, _tokenId, _data); - return (retval == ERC721_RECEIVED); - } - -} - - - -contract ERC721Enumerable is ERC721Basic { - function totalSupply() public view returns (uint256); - function tokenOfOwnerByIndex( - address _owner, - uint256 _index - ) - public - view - returns (uint256 _tokenId); - - function tokenByIndex(uint256 _index) public view returns (uint256); -} - -contract ERC721Metadata is ERC721Basic { - function name() external view returns (string memory _name); - function symbol() external view returns (string memory _symbol); - function tokenURI(uint256 _tokenId) public view returns (string memory); -} - -contract ERC721 is ERC721Basic, ERC721Enumerable, ERC721Metadata { - -} - - - - -library Strings { - - // via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol - function strConcat(string memory _a, string memory _b, string memory _c, string memory _d, string memory _e) internal pure returns (string memory ) { - bytes memory _ba = bytes(_a); - bytes memory _bb = bytes(_b); - bytes memory _bc = bytes(_c); - bytes memory _bd = bytes(_d); - bytes memory _be = bytes(_e); - string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length); - bytes memory babcde = bytes(abcde); - uint k = 0; - for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i]; - for (uint i = 0; i < _bb.length; i++) babcde[k++] = _bb[i]; - for (uint i = 0; i < _bc.length; i++) babcde[k++] = _bc[i]; - for (uint i = 0; i < _bd.length; i++) babcde[k++] = _bd[i]; - for (uint i = 0; i < _be.length; i++) babcde[k++] = _be[i]; - return string(babcde); - } - - function strConcat(string memory _a, string memory _b, string memory _c, string memory _d) internal pure returns (string memory ) { - return strConcat(_a, _b, _c, _d, ""); - } - - function strConcat(string memory _a, string memory _b, string memory _c) internal pure returns (string memory ) { - return strConcat(_a, _b, _c, "", ""); - } - - function strConcat(string memory _a, string memory _b) internal pure returns (string memory ) { - return strConcat(_a, _b, "", "", ""); - } - - function uint2str(uint i) internal pure returns (string memory ) { - if (i == 0) return "0"; - uint j = i; - uint len; - while (j != 0){ - len++; - j /= 10; - } - bytes memory bstr = new bytes(len); - uint k = len - 1; - while (i != 0){ - bstr[k--] = byte(uint8(48 + i % 10)); - i /= 10; - } - return string(bstr); - } -} - -contract ERC721Token is SupportsInterfaceWithLookup, ERC721BasicToken, ERC721 { - - using Strings for string; - - bytes4 private constant InterfaceId_ERC721Enumerable = 0x780e9d63; - /** - * 0x780e9d63 === - * bytes4(keccak256('totalSupply()')) ^ - * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^ - * bytes4(keccak256('tokenByIndex(uint256)')) - */ - - bytes4 private constant InterfaceId_ERC721Metadata = 0x5b5e139f; - /** - * 0x5b5e139f === - * bytes4(keccak256('name()')) ^ - * bytes4(keccak256('symbol()')) ^ - * bytes4(keccak256('tokenURI(uint256)')) - */ - - /*** Constants ***/ - // Configure these for your own deployment - string public constant NAME = "Gods Unchained"; - string public constant SYMBOL = "GODS"; - string public tokenMetadataBaseURI = "https://api.godsunchained.com/card/"; - - // Mapping from owner to list of owned token IDs - // EDITED: limit to 2^40 (around 1T) - mapping(address => uint40[]) internal ownedTokens; - - uint32[] ownedTokensIndex; - - /** - * @dev Constructor function - */ - constructor() public { - - // register the supported interfaces to conform to ERC721 via ERC165 - _registerInterface(InterfaceId_ERC721Enumerable); - _registerInterface(InterfaceId_ERC721Metadata); - } - - /** - * @dev Gets the token name - * @return string representing the token name - */ - function name() external view returns (string memory) { - return NAME; - } - - /** - * @dev Gets the token symbol - * @return string representing the token symbol - */ - function symbol() external view returns (string memory) { - return SYMBOL; - } - - /** - * @dev Returns an URI for a given token ID - * Throws if the token ID does not exist. May return an empty string. - * @param _tokenId uint256 ID of the token to query - */ - function tokenURI(uint256 _tokenId) public view returns (string memory) { - return Strings.strConcat( - tokenMetadataBaseURI, - Strings.uint2str(_tokenId) - ); - } - - /** - * @dev Gets the token ID at a given index of the tokens list of the requested owner - * @param _owner address owning the tokens list to be accessed - * @param _index uint256 representing the index to be accessed of the requested tokens list - * @return uint256 token ID at the given index of the tokens list owned by the requested address - */ - function tokenOfOwnerByIndex( - address _owner, - uint256 _index - ) - public - view - returns (uint256) - { - require(_index < balanceOf(_owner)); - return ownedTokens[_owner][_index]; - } - - /** - * @dev Gets the total amount of tokens stored by the contract - * @return uint256 representing the total amount of tokens - */ - function totalSupply() public view returns (uint256) { - return cards.length; - } - - /** - * @dev Gets the token ID at a given index of all the tokens in this contract - * Reverts if the index is greater or equal to the total number of tokens - * @param _index uint256 representing the index to be accessed of the tokens list - * @return uint256 token ID at the given index of the tokens list - */ - function tokenByIndex(uint256 _index) public view returns (uint256) { - require(_index < totalSupply()); - return _index; - } - - /** - * @dev Internal function to add a token ID to the list of a given address - * @param _to address representing the new owner of the given token ID - * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address - */ - function addTokenTo(address _to, uint256 _tokenId) internal { - super.addTokenTo(_to, _tokenId); - uint256 length = ownedTokens[_to].length; - // EDITED: prevent overflow - require(length == uint32(length)); - ownedTokens[_to].push(uint40(_tokenId)); - - ownedTokensIndex[_tokenId] = uint32(length); - } - - // EDITED - // have to have in order to use array rather than mapping - function addNewTokenTo(address _to, uint256 _tokenId) internal { - super.addNewTokenTo(_to, _tokenId); - uint256 length = ownedTokens[_to].length; - // EDITED: prevent overflow - require(length == uint32(length)); - ownedTokens[_to].push(uint40(_tokenId)); - ownedTokensIndex.push(uint32(length)); - } - - /** - * @dev Internal function to remove a token ID from the list of a given address - * @param _from address representing the previous owner of the given token ID - * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address - */ - function removeTokenFrom(address _from, uint256 _tokenId) internal { - super.removeTokenFrom(_from, _tokenId); - - uint32 tokenIndex = ownedTokensIndex[_tokenId]; - uint256 lastTokenIndex = ownedTokens[_from].length.sub(1); - uint40 lastToken = ownedTokens[_from][lastTokenIndex]; - - ownedTokens[_from][tokenIndex] = lastToken; - ownedTokens[_from][lastTokenIndex] = 0; - // Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to - // be zero. Then we can make sure that we will remove _tokenId from the ownedTokens list since we are first swapping - // the lastToken to the first position, and then dropping the element placed in the last position of the list - - ownedTokens[_from].length--; - ownedTokensIndex[_tokenId] = 0; - ownedTokensIndex[lastToken] = tokenIndex; - } - - /** - * @dev Gets the balance of the specified address - overrriden from previous to save gas - * @param _owner address to query the balance of - * @return uint256 representing the amount owned by the passed address - */ - function balanceOf(address _owner) public view returns (uint256) { - return ownedTokens[_owner].length; - } - -} - -contract CardOwnershipTwo is ERC721Token { - - uint public burnCount; - - function getActiveCards() public view returns (uint) { - return totalSupply() - burnCount; - } - - /** - * @param to : the address to which the card will be transferred - * @param id : the id of the card to be transferred - */ - function transfer(address to, uint id) public payable onlyOwnerOf(id) { - require(isTradable(cards[id].proto)); - require(to != address(0)); - - _transfer(msg.sender, to, id); - } - - function _transfer(address from, address to, uint id) internal { - - clearApproval(from, id); - - removeTokenFrom(from, id); - - addTokenTo(to, id); - - emit Transfer(from, to, id); - } - - /** - * @param to : the address to which the cards will be transferred - * @param ids : the ids of the cards to be transferred - */ - function transferAll(address to, uint[] memory ids) public payable { - for (uint i = 0; i < ids.length; i++) { - transfer(to, ids[i]); - } - } - - /** - * @param proposed : the claimed owner of the cards - * @param ids : the ids of the cards to check - * @return whether proposed owns all of the cards - */ - function ownsAll(address proposed, uint[] memory ids) public view returns (bool) { - require(ids.length > 0); - for (uint i = 0; i < ids.length; i++) { - if (!owns(proposed, ids[i])) { - return false; - } - } - return true; - } - - /** - * @param proposed : the claimed owner of the card - * @param id : the id of the card to check - * @return whether proposed owns the card - */ - function owns(address proposed, uint id) public view returns (bool) { - return ownerOf(id) == proposed; - } - - function burn(uint id) public onlyOwnerOf(id) { - burnCount++; - _burn(msg.sender, id); - } - - /** - * @param ids : the indices of the tokens to burn - */ - function burnAll(uint[] memory ids) public { - for (uint i = 0; i < ids.length; i++){ - burn(ids[i]); - } - } - - /** - * @param to : the address to approve for transfer - * @param id : the index of the card to be approved - */ - function approve(address to, uint id) public { - require(isTradable(cards[id].proto)); - super.approve(to, id); - } - - /** - * @param to : the address to approve for transfer - * @param ids : the indices of the cards to be approved - */ - function approveAll(address to, uint[] memory ids) public { - for (uint i = 0; i < ids.length; i++) { - approve(to, ids[i]); - } - } - - /** - * @param to : the address to which the token should be transferred - * @param id : the index of the token to transfer - */ - function transferFrom(address from, address to, uint id) public { - require(isTradable(cards[id].proto)); - super.transferFrom(from, to, id); - } - - /** - * @param to : the address to which the tokens should be transferred - * @param ids : the indices of the tokens to transfer - */ - function transferAllFrom(address from, address to, uint[] memory ids) public { - for (uint i = 0; i < ids.length; i++) { - transferFrom(from, to, ids[i]); - } - } - - /** - * @return the number of cards which have been burned - */ - function getBurnCount() public view returns (uint) { - return burnCount; - } - -} - -contract CardIntegrationTwo is CardOwnershipTwo { - - address[] public packs; - - event CardCreated(uint indexed id, uint16 proto, uint16 purity, address owner); - - function addPack(address approved) public onlyGovernor { - packs.push(approved); - } - - modifier onlyApprovedPacks { - require(_isApprovedPack()); - _; - } - - function _isApprovedPack() private view returns (bool) { - for (uint i = 0; i < packs.length; i++) { - if (msg.sender == address(packs[i])) { - return true; - } - } - return false; - } - - function createCard(address owner, uint16 proto, uint16 purity) public whenNotPaused onlyApprovedPacks returns (uint) { - ProtoCard memory card = protos[proto]; - require(card.season == currentSeason); - if (card.rarity == Rarity.Mythic) { - uint64 limit; - bool exists; - (limit, exists) = getLimit(proto); - require(!exists || limit > 0); - limits[proto].limit--; - } - return _createCard(owner, proto, purity); - } - - function _createCard(address owner, uint16 proto, uint16 purity) internal returns (uint) { - Card memory card = Card({ - proto: proto, - purity: purity - }); - - uint id = cards.push(card) - 1; - - _mint(owner, id); - - emit CardCreated(id, proto, purity, owner); - - return id; - } - - /*function combineCards(uint[] ids) public whenNotPaused { - require(ids.length == 5); - require(ownsAll(msg.sender, ids)); - Card memory first = cards[ids[0]]; - uint16 proto = first.proto; - uint8 shine = _getShine(first.purity); - require(shine < shineLimit); - uint16 puritySum = first.purity - (shine * 1000); - burn(ids[0]); - for (uint i = 1; i < ids.length; i++) { - Card memory next = cards[ids[i]]; - require(next.proto == proto); - require(_getShine(next.purity) == shine); - puritySum += (next.purity - (shine * 1000)); - burn(ids[i]); - } - uint16 newPurity = uint16(((shine + 1) * 1000) + (puritySum / ids.length)); - _createCard(msg.sender, proto, newPurity); - }*/ - - - // PURITY NOTES - // currently, we only - // however, to protect rarity, you'll never be abl - // this is enforced by the restriction in the create-card function - // no cards above this point can be found in packs - - - -} - -contract PreviousInterface { - - function ownerOf(uint id) public view returns (address); - - function getCard(uint id) public view returns (uint16, uint16); - - function totalSupply() public view returns (uint); - - function burnCount() public view returns (uint); - -} - -contract CardMigration is CardIntegrationTwo { - - constructor(PreviousInterface previous) public { - old = previous; - } - - // use interface to lower deployment cost - PreviousInterface old; - - mapping(uint => bool) public migrated; - - function migrate(uint id) public { - - require(!migrated[id]); - - migrated[id] = true; - - address owner = old.ownerOf(id); - - uint16 proto; - uint16 purity; - - (proto, purity) = old.getCard(id); - - _createCard(owner, proto, purity); - } - - function migrateAll(uint[] memory ids) public { - - for (uint i = 0; i < ids.length; i++){ - migrate(ids[i]); - } - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractScenario008.sol b/framework/src/test/resources/soliditycode/contractScenario008.sol deleted file mode 100644 index 0dbed350e4c..00000000000 --- a/framework/src/test/resources/soliditycode/contractScenario008.sol +++ /dev/null @@ -1,2061 +0,0 @@ - - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) public onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address payable public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address payable _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() virtual public onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer1(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - emit Transfer1(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(block.timestamp), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - kitties.push(_kitty); - uint256 newKittenId = kitties.length - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - emit Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(address(0), _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -abstract contract ERC721 { - // Required methods - function totalSupply() virtual public view returns (uint256 total); - function balanceOf(address _owner) virtual public view returns (uint256 balance); - function ownerOf(uint256 _tokenId) virtual external view returns (address owner); - function approve(address _to, uint256 _tokenId) virtual external; - function transfer(address _to, uint256 _tokenId) virtual external; - function transferFrom(address _from, address _to, uint256 _tokenId) virtual external; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) virtual external view returns (bool); -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is ERC721, KittyBase { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external override view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public override view returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - override - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - override - external - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - emit Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - override - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() override public view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - override - external - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] memory _rawBytes, uint256 _stringLength) private view returns (string memory) { - string memory outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string calldata _preferredTransport) external view returns (string memory infoUrl) { - require( address(erc721Metadata) != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty memory _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty memory _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - emit Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - payable(msg.sender).transfer(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, address(saleAuction)); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - payable(msg.sender) - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, address(siringAuction)); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - payable(msg.sender) - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid{value:(msg.value - autoBirthFee)}(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, address(saleAuction)); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - payable(address(uint160(address(this)))) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - constructor() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(int256(-1)), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - emit ContractUpgrade(_v2Address); - } - -/// @notice No tipping! -/// @dev Reject all Ether from being sent here, unless it's from one of the -/// two auction contracts. (Hopefully, we can prevent user accidents.) -fallback() external payable { -require( -msg.sender == address(saleAuction) || -msg.sender == address(siringAuction) -); -} - -/// @notice Returns all the relevant information about a specific kitty. -/// @param _id The ID of the kitty of interest. -function getKitty(uint256 _id) -external -view -returns ( -bool isGestating, -bool isReady, -uint256 cooldownIndex, -uint256 nextActionAt, -uint256 siringWithId, -uint256 birthTime, -uint256 matronId, -uint256 sireId, -uint256 generation, -uint256 genes -) { -Kitty storage kit = kitties[_id]; - -// if this variable is 0 then it's not gestating -isGestating = (kit.siringWithId != 0); -isReady = (kit.cooldownEndBlock <= block.number); -cooldownIndex = uint256(kit.cooldownIndex); -nextActionAt = uint256(kit.cooldownEndBlock); -siringWithId = uint256(kit.siringWithId); -birthTime = uint256(kit.birthTime); -matronId = uint256(kit.matronId); -sireId = uint256(kit.sireId); -generation = uint256(kit.generation); -genes = kit.genes; -} - -/// @dev Override unpause so it requires all external contract addresses -/// to be set before contract can be unpaused. Also, we can't have -/// newContractAddress set either, because then the contract was upgraded. -/// @notice This is public rather than external so we can call super.unpause -/// without using an expensive CALL. - -function unpause() override public onlyCEO whenPaused { -require(address(saleAuction) != address(0)); -require(address(siringAuction) != address(0)); -require(address(geneScience) != address(0)); -require(newContractAddress == address(0)); - -// Actually unpause the contract. -super.unpause(); -} - -// @dev Allows the CFO to capture the balance available to the contract. -function withdrawBalance() external onlyCFO { -uint256 balance = address(this).balance; -// Subtract all the currently pregnant kittens we have, plus 1 of margin. -uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - -if (balance > subtractFees) { -cfoAddress.transfer(balance - subtractFees); -} -} -} - - - - - - - - - - - - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - -function isGeneScience() public pure returns (bool){ -return true; -} - -/// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor -/// @param genes1 genes of mom -/// @param genes2 genes of sire -/// @return the genes that are supposed to be passed down the child -function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - -return (genes1+genes2+targetBlock)/2; - - -} -} - - - - - - - - - - - - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { -/// @dev Given a token Id, returns a byte array that is supposed to be converted into string. -function getMetadata(uint256 _tokenId, string memory) public view returns (bytes32[4] memory buffer, uint256 count) { -if (_tokenId == 1) { -buffer[0] = "Hello World! :D"; -count = 15; -} else if (_tokenId == 2) { -buffer[0] = "I would definitely choose a medi"; -buffer[1] = "um length string."; -count = 49; -} else if (_tokenId == 3) { -buffer[0] = "Lorem ipsum dolor sit amet, mi e"; -buffer[1] = "st accumsan dapibus augue lorem,"; -buffer[2] = " tristique vestibulum id, libero"; -buffer[3] = " suscipit varius sapien aliquam."; -count = 128; -} -} -} - - - - - - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - -// Represents an auction on an NFT -struct Auction { -// Current owner of NFT -address payable seller; -// Price (in wei) at beginning of auction -uint128 startingPrice; -// Price (in wei) at end of auction -uint128 endingPrice; -// Duration (in seconds) of auction -uint64 duration; -// Time when auction started -// NOTE: 0 if this auction has been concluded -uint64 startedAt; -} - -// Reference to contract tracking NFT ownership -ERC721 public nonFungibleContract; - -// Cut owner takes on each auction, measured in basis points (1/100 of a percent). -// Values 0-10,000 map to 0%-100% -uint256 public ownerCut; - -// Map from token ID to their corresponding auction. -mapping (uint256 => Auction) tokenIdToAuction; - -event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); -event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); -event AuctionCancelled(uint256 tokenId); - -/// @dev Returns true if the claimant owns the token. -/// @param _claimant - Address claiming to own the token. -/// @param _tokenId - ID of token whose ownership to verify. -function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { -return (nonFungibleContract.ownerOf(_tokenId) == _claimant); -} - -/// @dev Escrows the NFT, assigning ownership to this contract. -/// Throws if the escrow fails. -/// @param _owner - Current owner address of token to escrow. -/// @param _tokenId - ID of token whose approval to verify. -function _escrow(address _owner, uint256 _tokenId) internal { -// it will throw if transfer fails -nonFungibleContract.transferFrom(_owner, address(this), _tokenId); -} - -/// @dev Transfers an NFT owned by this contract to another address. -/// Returns true if the transfer succeeds. -/// @param _receiver - Address to transfer NFT to. -/// @param _tokenId - ID of token to transfer. -function _transfer(address _receiver, uint256 _tokenId) internal { -// it will throw if transfer fails -nonFungibleContract.transfer(_receiver, _tokenId); -} - -/// @dev Adds an auction to the list of open auctions. Also fires the -/// AuctionCreated event. -/// @param _tokenId The ID of the token to be put on auction. -/// @param _auction Auction to add. -function _addAuction(uint256 _tokenId, Auction memory _auction) internal { -// Require that all auctions have a duration of -// at least one minute. (Keeps our math from getting hairy!) -require(_auction.duration >= 1 minutes); - -tokenIdToAuction[_tokenId] = _auction; - -emit AuctionCreated( -uint256(_tokenId), -uint256(_auction.startingPrice), -uint256(_auction.endingPrice), -uint256(_auction.duration) -); -} - -/// @dev Cancels an auction unconditionally. -function _cancelAuction(uint256 _tokenId, address _seller) internal { -_removeAuction(_tokenId); -_transfer(_seller, _tokenId); -emit AuctionCancelled(_tokenId); -} - -/// @dev Computes the price and transfers winnings. -/// Does NOT transfer ownership of token. -function _bid(uint256 _tokenId, uint256 _bidAmount) -internal -returns (uint256) -{ -// Get a reference to the auction struct -Auction storage auction = tokenIdToAuction[_tokenId]; - -// Explicitly check that this auction is currently live. -// (Because of how Ethereum mappings work, we can't just count -// on the lookup above failing. An invalid _tokenId will just -// return an auction object that is all zeros.) -require(_isOnAuction(auction)); - -// Check that the bid is greater than or equal to the current price -uint256 price = _currentPrice(auction); -require(_bidAmount >= price); - -// Grab a reference to the seller before the auction struct -// gets deleted. -address payable seller = auction.seller; - -// The bid is good! Remove the auction before sending the fees -// to the sender so we can't have a reentrancy attack. -_removeAuction(_tokenId); - -// Transfer proceeds to seller (if there are any!) -if (price > 0) { -// Calculate the auctioneer's cut. -// (NOTE: _computeCut() is guaranteed to return a -// value <= price, so this subtraction can't go negative.) -uint256 auctioneerCut = _computeCut(price); -uint256 sellerProceeds = price - auctioneerCut; - -// NOTE: Doing a transfer() in the middle of a complex -// method like this is generally discouraged because of -// reentrancy attacks and DoS attacks if the seller is -// a contract with an invalid fallback function. We explicitly -// guard against reentrancy attacks by removing the auction -// before calling transfer(), and the only thing the seller -// can DoS is the sale of their own asset! (And if it's an -// accident, they can call cancelAuction(). ) -seller.transfer(sellerProceeds); -} - -// Calculate any excess funds included with the bid. If the excess -// is anything worth worrying about, transfer it back to bidder. -// NOTE: We checked above that the bid amount is greater than or -// equal to the price so this cannot underflow. -uint256 bidExcess = _bidAmount - price; - -// Return the funds. Similar to the previous transfer, this is -// not susceptible to a re-entry attack because the auction is -// removed before any transfers occur. - payable(msg.sender).transfer(bidExcess); - -// Tell the world! -emit AuctionSuccessful(_tokenId, price, msg.sender); - -return price; -} - -/// @dev Removes an auction from the list of open auctions. -/// @param _tokenId - ID of NFT on auction. -function _removeAuction(uint256 _tokenId) internal { -delete tokenIdToAuction[_tokenId]; -} - -/// @dev Returns true if the NFT is on auction. -/// @param _auction - Auction to check. -function _isOnAuction(Auction storage _auction) internal view returns (bool) { -return (_auction.startedAt > 0); -} - -/// @dev Returns current price of an NFT on auction. Broken into two -/// functions (this one, that computes the duration from the auction -/// structure, and the other that does the price computation) so we -/// can easily test that the price computation works correctly. -function _currentPrice(Auction storage _auction) -internal -view -returns (uint256) -{ -uint256 secondsPassed = 0; - -// A bit of insurance against negative values (or wraparound). -// Probably not necessary (since Ethereum guarnatees that the -// now variable doesn't ever go backwards). -if (block.timestamp > _auction.startedAt) { -secondsPassed = block.timestamp - _auction.startedAt; -} - -return _computeCurrentPrice( -_auction.startingPrice, -_auction.endingPrice, -_auction.duration, -secondsPassed -); -} - -/// @dev Computes the current price of an auction. Factored out -/// from _currentPrice so we can run extensive unit tests. -/// When testing, make this function public and turn on -/// `Current price computation` test suite. -function _computeCurrentPrice( -uint256 _startingPrice, -uint256 _endingPrice, -uint256 _duration, -uint256 _secondsPassed -) -internal -pure -returns (uint256) -{ -// NOTE: We don't use SafeMath (or similar) in this function because -// all of our public functions carefully cap the maximum values for -// time (at 64-bits) and currency (at 128-bits). _duration is -// also known to be non-zero (see the require() statement in -// _addAuction()) -if (_secondsPassed >= _duration) { -// We've reached the end of the dynamic pricing portion -// of the auction, just return the end price. -return _endingPrice; -} else { -// Starting price can be higher than ending price (and often is!), so -// this delta can be negative. -int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - -// This multiplication can't overflow, _secondsPassed will easily fit within -// 64-bits, and totalPriceChange will easily fit within 128-bits, their product -// will always fit within 256-bits. -int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - -// currentPriceChange can be negative, but if so, will have a magnitude -// less that _startingPrice. Thus, this result will always end up positive. -int256 currentPrice = int256(_startingPrice) + currentPriceChange; - -return uint256(currentPrice); -} -} - -/// @dev Computes owner's cut of a sale. -/// @param _price - Sale price of NFT. -function _computeCut(uint256 _price) internal view returns (uint256) { -// NOTE: We don't use SafeMath (or similar) in this function because -// all of our entry functions carefully cap the maximum values for -// currency (at 128-bits), and ownerCut <= 10000 (see the require() -// statement in the ClockAuction constructor). The result of this -// function is always guaranteed to be <= _price. -return _price * ownerCut / 10000; -} - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { -event Pause(); -event Unpause(); - -bool public paused = false; - - -/** - * @dev modifier to allow actions only when the contract IS paused - */ -modifier whenNotPaused() { -require(!paused); -_; -} - -/** - * @dev modifier to allow actions only when the contract IS NOT paused - */ -modifier whenPaused { -require(paused); -_; -} - -/** - * @dev called by the owner to pause, triggers stopped state - */ -function pause() onlyOwner whenNotPaused public returns (bool) { -paused = true; -emit Pause(); -return true; -} - -/** - * @dev called by the owner to unpause, returns to normal state - */ -function unpause() onlyOwner whenPaused public returns (bool) { -paused = false; -emit Unpause(); -return true; -} -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - -/// @dev The ERC-165 interface signature for ERC-721. -/// Ref: https://github.com/ethereum/EIPs/issues/165 -/// Ref: https://github.com/ethereum/EIPs/issues/721 -bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - -/// @dev Constructor creates a reference to the NFT ownership contract -/// and verifies the owner cut is in the valid range. -/// @param _nftAddress - address of a deployed contract implementing -/// the Nonfungible Interface. -/// @param _cut - percent cut the owner takes on each auction, must be -/// between 0-10,000. -constructor(address _nftAddress, uint256 _cut) public { -require(_cut <= 10000); -ownerCut = _cut; - -ERC721 candidateContract = ERC721(_nftAddress); -require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); -nonFungibleContract = candidateContract; -} - -/// @dev Remove all Ether from the contract, which is the owner's cuts -/// as well as any Ether sent directly to the contract address. -/// Always transfers to the NFT contract, but can be called either by -/// the owner or the NFT contract. -function withdrawBalance() external { -address payable nftAddress = payable(address(uint160(address(nonFungibleContract)))); - -require( -msg.sender == owner || -msg.sender == nftAddress -); -// We are using this boolean method to make sure that even if one fails it will still work -bool res = nftAddress.send(address(this).balance); -} - -/// @dev Creates and begins a new auction. -/// @param _tokenId - ID of token to auction, sender must be owner. -/// @param _startingPrice - Price of item (in wei) at beginning of auction. -/// @param _endingPrice - Price of item (in wei) at end of auction. -/// @param _duration - Length of time to move between starting -/// price and ending price (in seconds). -/// @param _seller - Seller, if not the message sender -function createAuction( -uint256 _tokenId, -uint256 _startingPrice, -uint256 _endingPrice, -uint256 _duration, -address payable _seller -) -virtual -external -whenNotPaused -{ -// Sanity check that no inputs overflow how many bits we've allocated -// to store them in the auction struct. -require(_startingPrice == uint256(uint128(_startingPrice))); -require(_endingPrice == uint256(uint128(_endingPrice))); -require(_duration == uint256(uint64(_duration))); - -require(_owns(msg.sender, _tokenId)); -_escrow(msg.sender, _tokenId); -Auction memory auction = Auction( -_seller, -uint128(_startingPrice), -uint128(_endingPrice), -uint64(_duration), -uint64(block.timestamp) -); -_addAuction(_tokenId, auction); -} - -/// @dev Bids on an open auction, completing the auction and transferring -/// ownership of the NFT if enough Ether is supplied. -/// @param _tokenId - ID of token to bid on. -function bid(uint256 _tokenId) -external -payable -whenNotPaused -virtual -{ -// _bid will throw if the bid or funds transfer fails -_bid(_tokenId, msg.value); -_transfer(msg.sender, _tokenId); -} - -/// @dev Cancels an auction that hasn't been won yet. -/// Returns the NFT to original owner. -/// @notice This is a state-modifying function that can -/// be called while the contract is paused. -/// @param _tokenId - ID of token on auction -function cancelAuction(uint256 _tokenId) -external -{ -Auction storage auction = tokenIdToAuction[_tokenId]; -require(_isOnAuction(auction)); -address seller = auction.seller; -require(msg.sender == seller); -_cancelAuction(_tokenId, seller); -} - -/// @dev Cancels an auction when the contract is paused. -/// Only the owner may do this, and NFTs are returned to -/// the seller. This should only be used in emergencies. -/// @param _tokenId - ID of the NFT on auction to cancel. -function cancelAuctionWhenPaused(uint256 _tokenId) -whenPaused -onlyOwner -external -{ -Auction storage auction = tokenIdToAuction[_tokenId]; -require(_isOnAuction(auction)); -_cancelAuction(_tokenId, auction.seller); -} - -/// @dev Returns auction info for an NFT on auction. -/// @param _tokenId - ID of NFT on auction. -function getAuction(uint256 _tokenId) -external -view -returns -( -address seller, -uint256 startingPrice, -uint256 endingPrice, -uint256 duration, -uint256 startedAt -) { -Auction storage auction = tokenIdToAuction[_tokenId]; -require(_isOnAuction(auction)); -return ( -auction.seller, -auction.startingPrice, -auction.endingPrice, -auction.duration, -auction.startedAt -); -} - -/// @dev Returns the current price of an auction. -/// @param _tokenId - ID of the token price we are checking. -function getCurrentPrice(uint256 _tokenId) -external -view -returns (uint256) -{ -Auction storage auction = tokenIdToAuction[_tokenId]; -require(_isOnAuction(auction)); -return _currentPrice(auction); -} - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - -// @dev Sanity check that allows us to ensure that we are pointing to the -// right auction in our setSiringAuctionAddress() call. -bool public isSiringClockAuction = true; - -// Delegate constructor -constructor(address _nftAddr, uint256 _cut) public -ClockAuction(_nftAddr, _cut) {} - -/// @dev Creates and begins a new auction. Since this function is wrapped, -/// require sender to be KittyCore contract. -/// @param _tokenId - ID of token to auction, sender must be owner. -/// @param _startingPrice - Price of item (in wei) at beginning of auction. -/// @param _endingPrice - Price of item (in wei) at end of auction. -/// @param _duration - Length of auction (in seconds). -/// @param _seller - Seller, if not the message sender -function createAuction( -uint256 _tokenId, -uint256 _startingPrice, -uint256 _endingPrice, -uint256 _duration, -address payable _seller -) -override -external -{ -// Sanity check that no inputs overflow how many bits we've allocated -// to store them in the auction struct. -require(_startingPrice == uint256(uint128(_startingPrice))); -require(_endingPrice == uint256(uint128(_endingPrice))); -require(_duration == uint256(uint64(_duration))); - -require(msg.sender == address(nonFungibleContract)); -_escrow(_seller, _tokenId); -Auction memory auction = Auction( -_seller, -uint128(_startingPrice), -uint128(_endingPrice), -uint64(_duration), -uint64(block.timestamp) -); -_addAuction(_tokenId, auction); -} - -/// @dev Places a bid for siring. Requires the sender -/// is the KittyCore contract because all bid methods -/// should be wrapped. Also returns the kitty to the -/// seller rather than the winner. -function bid(uint256 _tokenId) -external -payable -override -{ -require(msg.sender == address(nonFungibleContract)); -address seller = tokenIdToAuction[_tokenId].seller; -// _bid checks that token ID is valid and will throw if bid fails -_bid(_tokenId, msg.value); -// We transfer the kitty back to the seller, the winner will get -// the offspring -_transfer(seller, _tokenId); -} - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - -// @dev Sanity check that allows us to ensure that we are pointing to the -// right auction in our setSaleAuctionAddress() call. -bool public isSaleClockAuction = true; - -// Tracks last 5 sale price of gen0 kitty sales -uint256 public gen0SaleCount; -uint256[5] public lastGen0SalePrices; - -// Delegate constructor -constructor(address _nftAddr, uint256 _cut) public -ClockAuction(_nftAddr, _cut) {} - -/// @dev Creates and begins a new auction. -/// @param _tokenId - ID of token to auction, sender must be owner. -/// @param _startingPrice - Price of item (in wei) at beginning of auction. -/// @param _endingPrice - Price of item (in wei) at end of auction. -/// @param _duration - Length of auction (in seconds). -/// @param _seller - Seller, if not the message sender -function createAuction( -uint256 _tokenId, -uint256 _startingPrice, -uint256 _endingPrice, -uint256 _duration, -address payable _seller -) -override -external -{ -// Sanity check that no inputs overflow how many bits we've allocated -// to store them in the auction struct. -require(_startingPrice == uint256(uint128(_startingPrice))); -require(_endingPrice == uint256(uint128(_endingPrice))); -require(_duration == uint256(uint64(_duration))); - -require(msg.sender == address(nonFungibleContract)); -_escrow(_seller, _tokenId); -Auction memory auction = Auction( -_seller, -uint128(_startingPrice), -uint128(_endingPrice), -uint64(_duration), -uint64(block.timestamp) -); -_addAuction(_tokenId, auction); -} - -/// @dev Updates lastSalePrice if seller is the nft contract -/// Otherwise, works the same as default bid method. -function bid(uint256 _tokenId) -external -override -payable -{ -// _bid verifies token ID size -address seller = tokenIdToAuction[_tokenId].seller; -uint256 price = _bid(_tokenId, msg.value); -_transfer(msg.sender, _tokenId); - -// If not a gen0 auction, exit -if (seller == address(nonFungibleContract)) { -// Track gen0 sale prices -lastGen0SalePrices[gen0SaleCount % 5] = price; -gen0SaleCount++; -} -} - -function averageGen0SalePrice() external view returns (uint256) { -uint256 sum = 0; -for (uint256 i = 0; i < 5; i++) { -sum += lastGen0SalePrices[i]; -} -return sum / 5; -} - -} - - - - - - - diff --git a/framework/src/test/resources/soliditycode/contractScenario009.sol b/framework/src/test/resources/soliditycode/contractScenario009.sol deleted file mode 100644 index 52fa63e90ac..00000000000 --- a/framework/src/test/resources/soliditycode/contractScenario009.sol +++ /dev/null @@ -1,51 +0,0 @@ - - -library Set { - // We define a new struct datatype that will be used to - // hold its data in the calling contract. - struct Data { mapping(uint => bool) flags; } - - // Note that the first parameter is of type "storage - // reference" and thus only its storage address and not - // its contents is passed as part of the call. This is a - // special feature of library functions. It is idiomatic - // to call the first parameter 'self', if the function can - // be seen as a method of that object. - function insert (Data storage self, uint value) public - returns (bool) - { - if (self.flags[value]) - return false; // already there - self.flags[value] = true; - return true; - } - - function remove(Data storage self, uint value) public - returns (bool) - { - if (!self.flags[value]) - return false; // not there - self.flags[value] = false; - return true; - } - - function contains(Data storage self, uint value) public - returns (bool) - { - return self.flags[value]; - } -} - - -contract C { - Set.Data knownValues; - - function register(uint value) public { - // The library functions can be called without a - // specific instance of the library, since the - // "instance" will be the current contract. - if (!Set.insert(knownValues, value)) - revert(); - } - // In this contract, we can also directly access knownValues.flags, if we want. -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractScenario010.sol b/framework/src/test/resources/soliditycode/contractScenario010.sol deleted file mode 100644 index 4e299efecad..00000000000 --- a/framework/src/test/resources/soliditycode/contractScenario010.sol +++ /dev/null @@ -1,107 +0,0 @@ - - -contract TRON_ERC721 { - //name - function name() view public returns (string memory name){ - return "Tron ERC721 Token"; - } - //symbol - function symbol() view public returns (string memory symbol){ - return "T721T"; - } - - //totalSupply - - function totalSupply() view public returns (uint256 supply){ - uint256 totalSupply = 1000000000000; - return totalSupply; - } - - mapping(address => uint) private balances; - function balanceOf(address _owner) view public returns (uint balance) - { - return balances[_owner]; - } - - - mapping(uint256 => address) private tokenOwners; - mapping(uint256 => bool) private tokenExists; - function ownerOf(uint256 _tokenId) view public returns (address owner) { - require(tokenExists[_tokenId]); - return tokenOwners[_tokenId]; - } - - - mapping(address => mapping (address => uint256)) allowed; - function approve(address _to, uint256 _tokenId) public{ - require(msg.sender == ownerOf(_tokenId)); - require(msg.sender != _to); - allowed[msg.sender][_to] = _tokenId; - emit Approval(msg.sender, _to, _tokenId); - } - - - function takeOwnership(uint256 _tokenId) public { - require(tokenExists[_tokenId]); - address oldOwner = ownerOf(_tokenId); - address newOwner = msg.sender; - require(newOwner != oldOwner); - require(allowed[oldOwner][newOwner] == _tokenId); - balances[oldOwner] -= 1; - tokenOwners[_tokenId] = newOwner; - balances[newOwner] += 1; - emit Transfer(oldOwner, newOwner, _tokenId); - } - - - mapping(address => mapping(uint256 => uint256)) private ownerTokens; - function removeFromTokenList(address owner, uint256 _tokenId) private { - for(uint256 i = 0;ownerTokens[owner][i] != _tokenId;i++){ - ownerTokens[owner][i] = 0; - } - } - - function transfer(address _to, uint256 _tokenId) public{ - address currentOwner = msg.sender; - address newOwner = _to; - require(tokenExists[_tokenId]); - require(currentOwner == ownerOf(_tokenId)); - require(currentOwner != newOwner); - require(newOwner != address(0)); - address oldOwner =currentOwner; - removeFromTokenList(oldOwner,_tokenId); - balances[oldOwner] -= 1; - tokenOwners[_tokenId] = newOwner; - balances[newOwner] += 1; - emit Transfer(oldOwner, newOwner, _tokenId); - } - - function transferFrom(address _from,address _to, uint256 _tokenId) public{ - address currentOwner = _from; - address newOwner = _to; - require(tokenExists[_tokenId]); - require(currentOwner == ownerOf(_tokenId)); - require(currentOwner != newOwner); - require(newOwner != address(0)); - address oldOwner =currentOwner; - removeFromTokenList(oldOwner,_tokenId); - balances[oldOwner] -= 1; - tokenOwners[_tokenId] = newOwner; - balances[newOwner] += 1; - emit Transfer(oldOwner, newOwner, _tokenId); - } - - - function tokenOfOwnerByIndex(address _owner, uint256 _index) view public returns (uint tokenId){ - return ownerTokens[_owner][_index]; - } - - - mapping(uint256 => string) tokenLinks; - function tokenMetadata(uint256 _tokenId) view public returns (string memory infoUrl) { - return tokenLinks[_tokenId]; - } - // Events - event Transfer(address indexed _from, address indexed _to, uint256 _tokenId); - event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId); -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractScenario011.sol b/framework/src/test/resources/soliditycode/contractScenario011.sol deleted file mode 100644 index c0d30e8ebab..00000000000 --- a/framework/src/test/resources/soliditycode/contractScenario011.sol +++ /dev/null @@ -1,2060 +0,0 @@ - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) public onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address payable public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address payable _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() public virtual onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer1(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - emit Transfer1(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(block.timestamp), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - kitties.push(_kitty); - uint256 newKittenId = kitties.length - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - emit Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(address(0), _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -abstract contract ERC721 { - // Required methods - function totalSupply() public virtual view returns (uint256 total); - function balanceOf(address _owner) public virtual view returns (uint256 balance); - function ownerOf(uint256 _tokenId) external virtual view returns (address owner); - function approve(address _to, uint256 _tokenId) external virtual; - function transfer(address _to, uint256 _tokenId) external virtual; - function transferFrom(address _from, address _to, uint256 _tokenId) external virtual; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) external virtual view returns (bool); -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is ERC721, KittyBase { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external override view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public view override returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - override - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - external - override - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - emit Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - external - override - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() public override view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - external - override - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] memory _rawBytes, uint256 _stringLength) private view returns (string memory) { - string memory outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string calldata _preferredTransport) external view returns (string memory infoUrl) { - require( address(erc721Metadata) != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2 ; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty memory _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty memory _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - emit Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - payable(msg.sender).transfer(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, address(saleAuction)); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - payable(msg.sender) - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, address(siringAuction)); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - payable(msg.sender) - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid{value : (msg.value - autoBirthFee)}(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10 ; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, address(saleAuction)); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - payable(address(uint160(address(this)))) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - constructor() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(int256(-1)), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - emit ContractUpgrade(_v2Address); - } - - /// @notice No tipping! - /// @dev Reject all Ether from being sent here, unless it's from one of the - /// two auction contracts. (Hopefully, we can prevent user accidents.) - fallback() external payable { - require( - msg.sender == address(saleAuction) || - msg.sender == address(siringAuction) - ); - } - - /// @notice Returns all the relevant information about a specific kitty. - /// @param _id The ID of the kitty of interest. - function getKitty(uint256 _id) - external - view - returns ( - bool isGestating, - bool isReady, - uint256 cooldownIndex, - uint256 nextActionAt, - uint256 siringWithId, - uint256 birthTime, - uint256 matronId, - uint256 sireId, - uint256 generation, - uint256 genes - ) { - Kitty storage kit = kitties[_id]; - - // if this variable is 0 then it's not gestating - isGestating = (kit.siringWithId != 0); - isReady = (kit.cooldownEndBlock <= block.number); - cooldownIndex = uint256(kit.cooldownIndex); - nextActionAt = uint256(kit.cooldownEndBlock); - siringWithId = uint256(kit.siringWithId); - birthTime = uint256(kit.birthTime); - matronId = uint256(kit.matronId); - sireId = uint256(kit.sireId); - generation = uint256(kit.generation); - genes = kit.genes; - } - - /// @dev Override unpause so it requires all external contract addresses - /// to be set before contract can be unpaused. Also, we can't have - /// newContractAddress set either, because then the contract was upgraded. - /// @notice This is public rather than external so we can call super.unpause - /// without using an expensive CALL. - - function unpause() public override onlyCEO whenPaused { - require(address(saleAuction) != address(0)); - require(address(siringAuction) != address(0)); - require(address(geneScience) != address(0)); - require(newContractAddress == address(0)); - - // Actually unpause the contract. - super.unpause(); - } - - // @dev Allows the CFO to capture the balance available to the contract. - function withdrawBalance() external onlyCFO { - uint256 balance = address(this).balance; - // Subtract all the currently pregnant kittens we have, plus 1 of margin. - uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - - if (balance > subtractFees) { - cfoAddress.transfer(balance - subtractFees); - } - } -} - - - - - - - - - - - - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - - function isGeneScience() public pure returns (bool){ - return true; - } - - /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor - /// @param genes1 genes of mom - /// @param genes2 genes of sire - /// @return the genes that are supposed to be passed down the child - function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - - return (genes1+genes2+targetBlock)/2; - - - } -} - - - - - - - - - - - - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { - /// @dev Given a token Id, returns a byte array that is supposed to be converted into string. - function getMetadata(uint256 _tokenId, string memory) public view returns (bytes32[4] memory buffer, uint256 count) { - if (_tokenId == 1) { - buffer[0] = "Hello World! :D"; - count = 15; - } else if (_tokenId == 2) { - buffer[0] = "I would definitely choose a medi"; - buffer[1] = "um length string."; - count = 49; - } else if (_tokenId == 3) { - buffer[0] = "Lorem ipsum dolor sit amet, mi e"; - buffer[1] = "st accumsan dapibus augue lorem,"; - buffer[2] = " tristique vestibulum id, libero"; - buffer[3] = " suscipit varius sapien aliquam."; - count = 128; - } - } -} - - - - - - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - - // Represents an auction on an NFT - struct Auction { - // Current owner of NFT - address payable seller; - // Price (in wei) at beginning of auction - uint128 startingPrice; - // Price (in wei) at end of auction - uint128 endingPrice; - // Duration (in seconds) of auction - uint64 duration; - // Time when auction started - // NOTE: 0 if this auction has been concluded - uint64 startedAt; - } - - // Reference to contract tracking NFT ownership - ERC721 public nonFungibleContract; - - // Cut owner takes on each auction, measured in basis points (1/100 of a percent). - // Values 0-10,000 map to 0%-100% - uint256 public ownerCut; - - // Map from token ID to their corresponding auction. - mapping (uint256 => Auction) tokenIdToAuction; - - event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); - event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); - event AuctionCancelled(uint256 tokenId); - - /// @dev Returns true if the claimant owns the token. - /// @param _claimant - Address claiming to own the token. - /// @param _tokenId - ID of token whose ownership to verify. - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return (nonFungibleContract.ownerOf(_tokenId) == _claimant); - } - - /// @dev Escrows the NFT, assigning ownership to this contract. - /// Throws if the escrow fails. - /// @param _owner - Current owner address of token to escrow. - /// @param _tokenId - ID of token whose approval to verify. - function _escrow(address _owner, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transferFrom(_owner, address(this), _tokenId); - } - - /// @dev Transfers an NFT owned by this contract to another address. - /// Returns true if the transfer succeeds. - /// @param _receiver - Address to transfer NFT to. - /// @param _tokenId - ID of token to transfer. - function _transfer(address _receiver, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transfer(_receiver, _tokenId); - } - - /// @dev Adds an auction to the list of open auctions. Also fires the - /// AuctionCreated event. - /// @param _tokenId The ID of the token to be put on auction. - /// @param _auction Auction to add. - function _addAuction(uint256 _tokenId, Auction memory _auction) internal { - // Require that all auctions have a duration of - // at least one minute. (Keeps our math from getting hairy!) - require(_auction.duration >= 1 minutes); - - tokenIdToAuction[_tokenId] = _auction; - - emit AuctionCreated( - uint256(_tokenId), - uint256(_auction.startingPrice), - uint256(_auction.endingPrice), - uint256(_auction.duration) - ); - } - - /// @dev Cancels an auction unconditionally. - function _cancelAuction(uint256 _tokenId, address _seller) internal { - _removeAuction(_tokenId); - _transfer(_seller, _tokenId); - emit AuctionCancelled(_tokenId); - } - - /// @dev Computes the price and transfers winnings. - /// Does NOT transfer ownership of token. - function _bid(uint256 _tokenId, uint256 _bidAmount) - internal - returns (uint256) - { - // Get a reference to the auction struct - Auction storage auction = tokenIdToAuction[_tokenId]; - - // Explicitly check that this auction is currently live. - // (Because of how Ethereum mappings work, we can't just count - // on the lookup above failing. An invalid _tokenId will just - // return an auction object that is all zeros.) - require(_isOnAuction(auction)); - - // Check that the bid is greater than or equal to the current price - uint256 price = _currentPrice(auction); - require(_bidAmount >= price); - - // Grab a reference to the seller before the auction struct - // gets deleted. - address payable seller = auction.seller; - - // The bid is good! Remove the auction before sending the fees - // to the sender so we can't have a reentrancy attack. - _removeAuction(_tokenId); - - // Transfer proceeds to seller (if there are any!) - if (price > 0) { - // Calculate the auctioneer's cut. - // (NOTE: _computeCut() is guaranteed to return a - // value <= price, so this subtraction can't go negative.) - uint256 auctioneerCut = _computeCut(price); - uint256 sellerProceeds = price - auctioneerCut; - - // NOTE: Doing a transfer() in the middle of a complex - // method like this is generally discouraged because of - // reentrancy attacks and DoS attacks if the seller is - // a contract with an invalid fallback function. We explicitly - // guard against reentrancy attacks by removing the auction - // before calling transfer(), and the only thing the seller - // can DoS is the sale of their own asset! (And if it's an - // accident, they can call cancelAuction(). ) - seller.transfer(sellerProceeds); - } - - // Calculate any excess funds included with the bid. If the excess - // is anything worth worrying about, transfer it back to bidder. - // NOTE: We checked above that the bid amount is greater than or - // equal to the price so this cannot underflow. - uint256 bidExcess = _bidAmount - price; - - // Return the funds. Similar to the previous transfer, this is - // not susceptible to a re-entry attack because the auction is - // removed before any transfers occur. - payable(msg.sender).transfer(bidExcess); - - // Tell the world! - emit AuctionSuccessful(_tokenId, price, msg.sender); - - return price; - } - - /// @dev Removes an auction from the list of open auctions. - /// @param _tokenId - ID of NFT on auction. - function _removeAuction(uint256 _tokenId) internal { - delete tokenIdToAuction[_tokenId]; - } - - /// @dev Returns true if the NFT is on auction. - /// @param _auction - Auction to check. - function _isOnAuction(Auction storage _auction) internal view returns (bool) { - return (_auction.startedAt > 0); - } - - /// @dev Returns current price of an NFT on auction. Broken into two - /// functions (this one, that computes the duration from the auction - /// structure, and the other that does the price computation) so we - /// can easily test that the price computation works correctly. - function _currentPrice(Auction storage _auction) - internal - view - returns (uint256) - { - uint256 secondsPassed = 0; - - // A bit of insurance against negative values (or wraparound). - // Probably not necessary (since Ethereum guarnatees that the - // now variable doesn't ever go backwards). - if (block.timestamp > _auction.startedAt) { - secondsPassed = block.timestamp - _auction.startedAt; - } - - return _computeCurrentPrice( - _auction.startingPrice, - _auction.endingPrice, - _auction.duration, - secondsPassed - ); - } - - /// @dev Computes the current price of an auction. Factored out - /// from _currentPrice so we can run extensive unit tests. - /// When testing, make this function public and turn on - /// `Current price computation` test suite. - function _computeCurrentPrice( - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - uint256 _secondsPassed - ) - internal - pure - returns (uint256) - { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our public functions carefully cap the maximum values for - // time (at 64-bits) and currency (at 128-bits). _duration is - // also known to be non-zero (see the require() statement in - // _addAuction()) - if (_secondsPassed >= _duration) { - // We've reached the end of the dynamic pricing portion - // of the auction, just return the end price. - return _endingPrice; - } else { - // Starting price can be higher than ending price (and often is!), so - // this delta can be negative. - int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - - // This multiplication can't overflow, _secondsPassed will easily fit within - // 64-bits, and totalPriceChange will easily fit within 128-bits, their product - // will always fit within 256-bits. - int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - - // currentPriceChange can be negative, but if so, will have a magnitude - // less that _startingPrice. Thus, this result will always end up positive. - int256 currentPrice = int256(_startingPrice) + currentPriceChange; - - return uint256(currentPrice); - } - } - - /// @dev Computes owner's cut of a sale. - /// @param _price - Sale price of NFT. - function _computeCut(uint256 _price) internal view returns (uint256) { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our entry functions carefully cap the maximum values for - // currency (at 128-bits), and ownerCut <= 10000 (see the require() - // statement in the ClockAuction constructor). The result of this - // function is always guaranteed to be <= _price. - return _price * ownerCut / 10000; - } - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { - event Pause(); - event Unpause(); - - bool public paused = false; - - - /** - * @dev modifier to allow actions only when the contract IS paused - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev modifier to allow actions only when the contract IS NOT paused - */ - modifier whenPaused { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyOwner whenNotPaused public returns (bool) { - paused = true; - emit Pause(); - return true; - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyOwner whenPaused public returns (bool) { - paused = false; - emit Unpause(); - return true; - } -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - - /// @dev The ERC-165 interface signature for ERC-721. - /// Ref: https://github.com/ethereum/EIPs/issues/165 - /// Ref: https://github.com/ethereum/EIPs/issues/721 - bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - - /// @dev Constructor creates a reference to the NFT ownership contract - /// and verifies the owner cut is in the valid range. - /// @param _nftAddress - address of a deployed contract implementing - /// the Nonfungible Interface. - /// @param _cut - percent cut the owner takes on each auction, must be - /// between 0-10,000. - constructor(address _nftAddress, uint256 _cut) public { - require(_cut <= 10000); - ownerCut = _cut; - - ERC721 candidateContract = ERC721(_nftAddress); - require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); - nonFungibleContract = candidateContract; - } - - /// @dev Remove all Ether from the contract, which is the owner's cuts - /// as well as any Ether sent directly to the contract address. - /// Always transfers to the NFT contract, but can be called either by - /// the owner or the NFT contract. - function withdrawBalance() external { - address payable nftAddress = payable(address(uint160(address(nonFungibleContract)))); - - require( - msg.sender == owner || - msg.sender == nftAddress - ); - // We are using this boolean method to make sure that even if one fails it will still work - bool res = nftAddress.send(address(this).balance); - } - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of time to move between starting - /// price and ending price (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - virtual - whenNotPaused - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(_owns(msg.sender, _tokenId)); - _escrow(msg.sender, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(block.timestamp) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Bids on an open auction, completing the auction and transferring - /// ownership of the NFT if enough Ether is supplied. - /// @param _tokenId - ID of token to bid on. - function bid(uint256 _tokenId) - external - payable - virtual - whenNotPaused - { - // _bid will throw if the bid or funds transfer fails - _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - } - - /// @dev Cancels an auction that hasn't been won yet. - /// Returns the NFT to original owner. - /// @notice This is a state-modifying function that can - /// be called while the contract is paused. - /// @param _tokenId - ID of token on auction - function cancelAuction(uint256 _tokenId) - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - address seller = auction.seller; - require(msg.sender == seller); - _cancelAuction(_tokenId, seller); - } - - /// @dev Cancels an auction when the contract is paused. - /// Only the owner may do this, and NFTs are returned to - /// the seller. This should only be used in emergencies. - /// @param _tokenId - ID of the NFT on auction to cancel. - function cancelAuctionWhenPaused(uint256 _tokenId) - whenPaused - onlyOwner - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - _cancelAuction(_tokenId, auction.seller); - } - - /// @dev Returns auction info for an NFT on auction. - /// @param _tokenId - ID of NFT on auction. - function getAuction(uint256 _tokenId) - external - view - returns - ( - address seller, - uint256 startingPrice, - uint256 endingPrice, - uint256 duration, - uint256 startedAt - ) { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return ( - auction.seller, - auction.startingPrice, - auction.endingPrice, - auction.duration, - auction.startedAt - ); - } - - /// @dev Returns the current price of an auction. - /// @param _tokenId - ID of the token price we are checking. - function getCurrentPrice(uint256 _tokenId) - external - view - returns (uint256) - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return _currentPrice(auction); - } - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSiringAuctionAddress() call. - bool public isSiringClockAuction = true; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. Since this function is wrapped, - /// require sender to be KittyCore contract. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - override - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(block.timestamp) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Places a bid for siring. Requires the sender - /// is the KittyCore contract because all bid methods - /// should be wrapped. Also returns the kitty to the - /// seller rather than the winner. - function bid(uint256 _tokenId) - external - payable - override - { - require(msg.sender == address(nonFungibleContract)); - address seller = tokenIdToAuction[_tokenId].seller; - // _bid checks that token ID is valid and will throw if bid fails - _bid(_tokenId, msg.value); - // We transfer the kitty back to the seller, the winner will get - // the offspring - _transfer(seller, _tokenId); - } - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSaleAuctionAddress() call. - bool public isSaleClockAuction = true; - - // Tracks last 5 sale price of gen0 kitty sales - uint256 public gen0SaleCount; - uint256[5] public lastGen0SalePrices; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - override - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(block.timestamp) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Updates lastSalePrice if seller is the nft contract - /// Otherwise, works the same as default bid method. - function bid(uint256 _tokenId) - external - payable - override - { - // _bid verifies token ID size - address seller = tokenIdToAuction[_tokenId].seller; - uint256 price = _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - - // If not a gen0 auction, exit - if (seller == address(nonFungibleContract)) { - // Track gen0 sale prices - lastGen0SalePrices[gen0SaleCount % 5] = price; - gen0SaleCount++; - } - } - - function averageGen0SalePrice() external view returns (uint256) { - uint256 sum = 0; - for (uint256 i = 0; i < 5; i++) { - sum += lastGen0SalePrices[i]; - } - return sum / 5; - } - -} - - - - - - - diff --git a/framework/src/test/resources/soliditycode/contractScenario012.sol b/framework/src/test/resources/soliditycode/contractScenario012.sol deleted file mode 100644 index ae6882685a8..00000000000 --- a/framework/src/test/resources/soliditycode/contractScenario012.sol +++ /dev/null @@ -1,57 +0,0 @@ - -contract PayTest { - -uint256 public n; -constructor() payable public{ -n = 0; -} - -function nPlusOne() public{ -n = n+1; -} - -//get current contract balance -function getBalance() payable public returns (uint) { -return address(this).balance; -} - -function getSenderBalance() public view returns(address, uint) { -return (msg.sender, msg.sender.balance); -} - -address public user; - -//deposit 1 coin to msg.sender -function depositOneCoin() payable public returns(bool success){ -return payable(msg.sender).send(1); -} - -// function transferOneCoin() payable public returns(){ -// address(msg.sender).transfer(1); -// } - -// function depositOneCoin() payable public returns(address addr, uint amount, bool success){ -// return (msg.sender, msg.value, msg.sender.send(1)); -// } - -//deposit coin to msg.sender -function deposit(uint256 money) payable public returns(bool success){ -return payable(msg.sender).send(money); -} -// function deposit(uint money) payable public returns(address addr, uint amount, bool success){ -// return (msg.sender, msg.value, msg.sender.send(money)); -// } - -// fallback() payable { -// msg.sender.send(1); -// } - -function sendToAddress(address payable _receiver) payable public{ -_receiver.transfer(msg.value); -} - -function sendToAddress2(address payable _receiver) payable public{ -_receiver.transfer(5); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractScenario013.sol b/framework/src/test/resources/soliditycode/contractScenario013.sol deleted file mode 100644 index 93b7905679b..00000000000 --- a/framework/src/test/resources/soliditycode/contractScenario013.sol +++ /dev/null @@ -1,8 +0,0 @@ - -contract timetest { - -function time() public{ -require(1 trx == 1000000 sun); - -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractScenario014.sol b/framework/src/test/resources/soliditycode/contractScenario014.sol deleted file mode 100644 index 9f423d1b1ab..00000000000 --- a/framework/src/test/resources/soliditycode/contractScenario014.sol +++ /dev/null @@ -1,34 +0,0 @@ - -contract Contract1 { - constructor() public payable{} - function send5SunToReceiver(address payable _receiver) payable public{ - _receiver.transfer(5); - } -} -contract contract2 { - address public payContract; - - constructor(address _add) payable public{ - payContract = _add; - } - - function triggerContract1(address _receiver) payable public{ - payContract.call(abi.encodeWithSignature("send5SunToReceiver(address)",_receiver)); - } - - function triggerContract1ButRevert(address _receiver) payable public{ - payContract.call(abi.encodeWithSignature("send5SunToReceiver(address)",_receiver)); - require(1 == 2); - } - -} -contract contract3 { - address public payContract; - constructor(address _add) payable public{ - payContract = _add; - } - - function triggerContract2(address _receiver) payable public{ - payContract.call(abi.encodeWithSignature("triggerContract1(address)",_receiver)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTest.sol b/framework/src/test/resources/soliditycode/contractTest.sol deleted file mode 100644 index 9a72b4a53b4..00000000000 --- a/framework/src/test/resources/soliditycode/contractTest.sol +++ /dev/null @@ -1,19 +0,0 @@ - - -contract Test{ - -function a() public returns (uint){ - -uint256 count = 0; - -for (uint256 i = 1; i > 0; i++) { - -count++; - -} - -return count; - -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractToMathedFeed.sol b/framework/src/test/resources/soliditycode/contractToMathedFeed.sol deleted file mode 100644 index d9df9d9c10d..00000000000 --- a/framework/src/test/resources/soliditycode/contractToMathedFeed.sol +++ /dev/null @@ -1,21 +0,0 @@ - - -contract ToMathedFeed { - uint public i=1; - function ToMathed (uint value) public { - i=value; - } -} - -contract ToMathedUseINContract { - function ToMathedIUseNR(address a,uint256 n) public returns(bool){ - address payContract=a; - (bool success, bytes memory data) = payContract.call(abi.encodeWithSignature("ToMathedNot(uint256)",n)); - return success; - } - function ToMathedIUseNRE(address a,uint256 value) public returns(bool){ - address payContract=a; - (bool success, bytes memory data) = payContract.call(abi.encodeWithSignature("ToMathed(uint256)",value)); - return success; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTransferToken001.sol b/framework/src/test/resources/soliditycode/contractTransferToken001.sol deleted file mode 100644 index 0edbbfbb44a..00000000000 --- a/framework/src/test/resources/soliditycode/contractTransferToken001.sol +++ /dev/null @@ -1,22 +0,0 @@ -contract A { - address public a; - constructor() public payable{} - function kill(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - function newB() public payable returns(address){ - B bAddress=new B(); - a= address(bAddress); - return a; - - } - - } - -contract B{ - constructor() public payable {} - fallback() external payable {} - function kill(address payable toAddress) payable public{ - selfdestruct(toAddress); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrc1155.sol b/framework/src/test/resources/soliditycode/contractTrc1155.sol deleted file mode 100644 index c33d07b3dfc..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrc1155.sol +++ /dev/null @@ -1,612 +0,0 @@ -pragma solidity ^0.8.0; - -interface IERC165 { - - function supportsInterface(bytes4 interfaceId) external view returns (bool); -} - - - -abstract contract ERC165 is IERC165 { - - function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - return interfaceId == type(IERC165).interfaceId; - } -} - -interface IERC1155 is IERC165 { - - event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); - - - event TransferBatch( - address indexed operator, - address indexed from, - address indexed to, - uint256[] ids, - uint256[] values - ); - - - event ApprovalForAll(address indexed account, address indexed operator, bool approved); - - - event URI(string value, uint256 indexed id); - - - function balanceOf(address account, uint256 id) external view returns (uint256); - - - function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) - external - view - returns (uint256[] memory); - - - function setApprovalForAll(address operator, bool approved) external; - - - function isApprovedForAll(address account, address operator) external view returns (bool); - - - function safeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes calldata data - ) external; - - function safeBatchTransferFrom( - address from, - address to, - uint256[] calldata ids, - uint256[] calldata amounts, - bytes calldata data - ) external; -} - - -abstract contract Context { - function _msgSender() internal view virtual returns (address) { - return msg.sender; - } - - function _msgData() internal view virtual returns (bytes calldata) { - return msg.data; - } -} - - -library Address { - - - function isAContract(address account) internal view returns (bool) { - // This method relies on extcodesize, which returns 0 for contracts in - // construction, since the code is only stored at the end of the - // constructor execution. - - uint256 size; - assembly { - size := extcodesize(account) - } - return size > 0; - } - - - function sendValue(address payable recipient, uint256 amount) internal { - require(address(this).balance >= amount, "Address: insufficient balance"); - - (bool success, ) = recipient.call{value: amount}(""); - require(success, "Address: unable to send value, recipient may have reverted"); - } - - - function functionCall(address target, bytes memory data) internal returns (bytes memory) { - return functionCall(target, data, "Address: low-level call failed"); - } - - - function functionCall( - address target, - bytes memory data, - string memory errorMessage - ) internal returns (bytes memory) { - return functionCallWithValue(target, data, 0, errorMessage); - } - - - function functionCallWithValue( - address target, - bytes memory data, - uint256 value - ) internal returns (bytes memory) { - return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); - } - - function functionCallWithValue( - address target, - bytes memory data, - uint256 value, - string memory errorMessage - ) internal returns (bytes memory) { - require(address(this).balance >= value, "Address: insufficient balance for call"); - require(isAContract(target), "Address: call to non-contract"); - - (bool success, bytes memory returndata) = target.call{value: value}(data); - return verifyCallResult(success, returndata, errorMessage); - } - - - function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { - return functionStaticCall(target, data, "Address: low-level static call failed"); - } - - - function functionStaticCall( - address target, - bytes memory data, - string memory errorMessage - ) internal view returns (bytes memory) { - require(isAContract(target), "Address: static call to non-contract"); - - (bool success, bytes memory returndata) = target.staticcall(data); - return verifyCallResult(success, returndata, errorMessage); - } - - - function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { - return functionDelegateCall(target, data, "Address: low-level delegate call failed"); - } - - - function functionDelegateCall( - address target, - bytes memory data, - string memory errorMessage - ) internal returns (bytes memory) { - require(isAContract(target), "Address: delegate call to non-contract"); - - (bool success, bytes memory returndata) = target.delegatecall(data); - return verifyCallResult(success, returndata, errorMessage); - } - - function verifyCallResult( - bool success, - bytes memory returndata, - string memory errorMessage - ) internal pure returns (bytes memory) { - if (success) { - return returndata; - } else { - // Look for revert reason and bubble it up if present - if (returndata.length > 0) { - // The easiest way to bubble the revert reason is using memory via assembly - - assembly { - let returndata_size := mload(returndata) - revert(add(32, returndata), returndata_size) - } - } else { - revert(errorMessage); - } - } - } -} - - -interface IERC1155MetadataURI is IERC1155 { - - function uri(uint256 id) external view returns (string memory); -} - - - - -interface IERC1155Receiver is IERC165 { - - function onERC1155Received( - address operator, - address from, - uint256 id, - uint256 value, - bytes calldata data - ) external returns (bytes4); - - - function onERC1155BatchReceived( - address operator, - address from, - uint256[] calldata ids, - uint256[] calldata values, - bytes calldata data - ) external returns (bytes4); -} - - -contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI { - using Address for address; - - // Mapping from token ID to account balances - mapping(uint256 => mapping(address => uint256)) private _balances; - - // Mapping from account to operator approvals - mapping(address => mapping(address => bool)) private _operatorApprovals; - - // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json - string private _uri; - - /** - * @dev See {_setURI}. - */ - constructor(string memory uri_) { - _setURI(uri_); - } - - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { - return - interfaceId == type(IERC1155).interfaceId || - interfaceId == type(IERC1155MetadataURI).interfaceId || - super.supportsInterface(interfaceId); - } - - - function uri(uint256 id) public view virtual override returns (string memory) { - return _uri; - } - - function balanceOf(address account, uint256 id) public view virtual override returns (uint256) { - require(account != address(0), "ERC1155: balance query for the zero address"); - return _balances[id][account]; - } - - - function balanceOfBatch(address[] memory accounts, uint256[] memory ids) - public - view - virtual - override - returns (uint256[] memory) - { - require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch"); - - uint256[] memory batchBalances = new uint256[](accounts.length); - - for (uint256 i = 0; i < accounts.length; ++i) { - batchBalances[i] = balanceOf(accounts[i], ids[i]); - } - - return batchBalances; - } - - - function setApprovalForAll(address operator, bool approved) public virtual override { - _setApprovalForAll(_msgSender(), operator, approved); - } - - - function isApprovedForAll(address account, address operator) public view virtual override returns (bool) { - return _operatorApprovals[account][operator]; - } - - - function safeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) public virtual override { - require( - from == _msgSender() || isApprovedForAll(from, _msgSender()), - "ERC1155: caller is not owner nor approved" - ); - _safeTransferFrom(from, to, id, amount, data); - } - - - function safeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) public virtual override { - require( - from == _msgSender() || isApprovedForAll(from, _msgSender()), - "ERC1155: transfer caller is not owner nor approved" - ); - _safeBatchTransferFrom(from, to, ids, amounts, data); - } - - - function _safeTransferFrom( - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) internal virtual { - require(to != address(0), "ERC1155: transfer to the zero address"); - - address operator = _msgSender(); - - _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data); - - uint256 fromBalance = _balances[id][from]; - require(fromBalance >= amount, "ERC1155: insufficient balance for transfer"); - unchecked { - _balances[id][from] = fromBalance - amount; - } - _balances[id][to] += amount; - - emit TransferSingle(operator, from, to, id, amount); - - _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); - } - - - function _safeBatchTransferFrom( - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual { - require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); - require(to != address(0), "ERC1155: transfer to the zero address"); - - address operator = _msgSender(); - - _beforeTokenTransfer(operator, from, to, ids, amounts, data); - - for (uint256 i = 0; i < ids.length; ++i) { - uint256 id = ids[i]; - uint256 amount = amounts[i]; - - uint256 fromBalance = _balances[id][from]; - require(fromBalance >= amount, "ERC1155: insufficient balance for transfer"); - unchecked { - _balances[id][from] = fromBalance - amount; - } - _balances[id][to] += amount; - } - - emit TransferBatch(operator, from, to, ids, amounts); - - _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data); - } - - - function _setURI(string memory newuri) internal virtual { - _uri = newuri; - } - - - function _mint( - address to, - uint256 id, - uint256 amount, - bytes memory data - ) internal virtual { - require(to != address(0), "ERC1155: mint to the zero address"); - - address operator = _msgSender(); - - _beforeTokenTransfer(operator, address(0), to, _asSingletonArray(id), _asSingletonArray(amount), data); - - _balances[id][to] += amount; - emit TransferSingle(operator, address(0), to, id, amount); - - _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data); - } - - - function _mintBatch( - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual { - require(to != address(0), "ERC1155: mint to the zero address"); - require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); - - address operator = _msgSender(); - - _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); - - for (uint256 i = 0; i < ids.length; i++) { - _balances[ids[i]][to] += amounts[i]; - } - - emit TransferBatch(operator, address(0), to, ids, amounts); - - _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data); - } - - - function _burn( - address from, - uint256 id, - uint256 amount - ) internal virtual { - require(from != address(0), "ERC1155: burn from the zero address"); - - address operator = _msgSender(); - - _beforeTokenTransfer(operator, from, address(0), _asSingletonArray(id), _asSingletonArray(amount), ""); - - uint256 fromBalance = _balances[id][from]; - require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); - unchecked { - _balances[id][from] = fromBalance - amount; - } - - emit TransferSingle(operator, from, address(0), id, amount); - } - - - function _burnBatch( - address from, - uint256[] memory ids, - uint256[] memory amounts - ) internal virtual { - require(from != address(0), "ERC1155: burn from the zero address"); - require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); - - address operator = _msgSender(); - - _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); - - for (uint256 i = 0; i < ids.length; i++) { - uint256 id = ids[i]; - uint256 amount = amounts[i]; - - uint256 fromBalance = _balances[id][from]; - require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); - unchecked { - _balances[id][from] = fromBalance - amount; - } - } - - emit TransferBatch(operator, from, address(0), ids, amounts); - } - - - function _setApprovalForAll( - address owner, - address operator, - bool approved - ) internal virtual { - require(owner != operator, "ERC1155: setting approval status for self"); - _operatorApprovals[owner][operator] = approved; - emit ApprovalForAll(owner, operator, approved); - } - - - function _beforeTokenTransfer( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) internal virtual {} - - function _doSafeTransferAcceptanceCheck( - address operator, - address from, - address to, - uint256 id, - uint256 amount, - bytes memory data - ) private { - if (to.isAContract()) { - try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) { - if (response != IERC1155Receiver.onERC1155Received.selector) { - revert("ERC1155: ERC1155Receiver rejected tokens"); - } - } catch Error(string memory reason) { - revert(reason); - } catch { - revert("ERC1155: transfer to non ERC1155Receiver implementer"); - } - } - } - - function _doSafeBatchTransferAcceptanceCheck( - address operator, - address from, - address to, - uint256[] memory ids, - uint256[] memory amounts, - bytes memory data - ) private { - if (to.isAContract()) { - try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns ( - bytes4 response - ) { - if (response != IERC1155Receiver.onERC1155BatchReceived.selector) { - revert("ERC1155: ERC1155Receiver rejected tokens"); - } - } catch Error(string memory reason) { - revert(reason); - } catch { - revert("ERC1155: transfer to non ERC1155Receiver implementer"); - } - } - } - - function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) { - uint256[] memory array = new uint256[](1); - array[0] = element; - - return array; - } - - -} - - -contract TronCoins is ERC1155 { - uint256 public constant TRX = 0; - uint256 public constant BTT = 1; - uint256 public constant WIN = 2; - uint256 public constant SUN = 3; - uint256 public constant APENFT = 4; - uint256 public constant APENFT1 = 5; - - constructor() public ERC1155("https://game.example/api/item/{id}.json") { - _mint(msg.sender, TRX, 10**3, ""); - _mint(msg.sender, BTT, 10**2, ""); - _mint(msg.sender, WIN, 10**5, ""); - _mint(msg.sender, SUN, 10**4, ""); - _mint(msg.sender, APENFT, 1, ""); - _mint(msg.sender, APENFT1, 1, ""); - } -} - - -abstract contract ERC1155Receiver is ERC165, IERC1155Receiver { - /** - * @dev See {IERC165-supportsInterface} - */ - function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { - return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); - } -} - - -contract ERC1155Holder is ERC1155Receiver { - function onERC1155Received( - address, - address, - uint256, - uint256, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC1155Received.selector; - } - - function onERC1155BatchReceived( - address, - address, - uint256[] memory, - uint256[] memory, - bytes memory - ) public virtual override returns (bytes4) { - return this.onERC1155BatchReceived.selector; - } -} - - -contract MyContractCanReceiver is ERC1155Holder { -} - - - -contract MyContractCanNotReceiver { -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken001.sol b/framework/src/test/resources/soliditycode/contractTrcToken001.sol deleted file mode 100644 index 4bd83e30229..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken001.sol +++ /dev/null @@ -1,41 +0,0 @@ - - - contract tokenTest{ - - uint pos0; - mapping(address => uint) pos1; - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - Storage(); - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - - - function Storage() public { - pos0 = 1234; - pos1[msg.sender] = 5678; - } - - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken002.sol b/framework/src/test/resources/soliditycode/contractTrcToken002.sol deleted file mode 100644 index ea28f4a62b6..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken002.sol +++ /dev/null @@ -1,30 +0,0 @@ - - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken003.sol b/framework/src/test/resources/soliditycode/contractTrcToken003.sol deleted file mode 100644 index 863429fc4f8..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken003.sol +++ /dev/null @@ -1,16 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken005.sol b/framework/src/test/resources/soliditycode/contractTrcToken005.sol deleted file mode 100644 index 863429fc4f8..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken005.sol +++ /dev/null @@ -1,16 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken011.sol b/framework/src/test/resources/soliditycode/contractTrcToken011.sol deleted file mode 100644 index 43e4010ec3f..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken011.sol +++ /dev/null @@ -1,35 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken012.sol b/framework/src/test/resources/soliditycode/contractTrcToken012.sol deleted file mode 100644 index ab0c19767e7..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken012.sol +++ /dev/null @@ -1,26 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken014.sol b/framework/src/test/resources/soliditycode/contractTrcToken014.sol deleted file mode 100644 index 589406c47c6..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken014.sol +++ /dev/null @@ -1,34 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken018.sol b/framework/src/test/resources/soliditycode/contractTrcToken018.sol deleted file mode 100644 index ab0c19767e7..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken018.sol +++ /dev/null @@ -1,26 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken023.sol b/framework/src/test/resources/soliditycode/contractTrcToken023.sol deleted file mode 100644 index 070acb201ff..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken023.sol +++ /dev/null @@ -1,26 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - toAddress.transferToken(amount,id); - } - } - -contract B{ - uint256 public flag = 0; - constructor() public payable {} - fallback() external { - flag = 1; -} - -} - -contract C{ - uint256 public flag = 0; - constructor() public payable {} - fallback() external payable { - //flag = 1; -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken026.sol b/framework/src/test/resources/soliditycode/contractTrcToken026.sol deleted file mode 100644 index 5464265d81f..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken026.sol +++ /dev/null @@ -1,31 +0,0 @@ - - -contract token{ - constructor() payable public{} - fallback() payable external{} - function testInCall(address callBAddress,address callCAddress, address toAddress ,uint256 amount,trcToken id) payable public{ - //callBAddress.call(bytes4(keccak256("transC(address,address,uint256,trcToken)")),callCAddress,toAddress,amount,id); - callBAddress.call(abi.encodeWithSignature("transC(address,address,uint256,trcToken)",callCAddress,toAddress,amount,id)); - } - function testIndelegateCall(address callBddress,address callAddressC, address toAddress,uint256 amount, trcToken id) payable public{ - callBddress.delegatecall(abi.encodeWithSignature("transC(address,address,uint256,trcToken)",callAddressC,toAddress,amount,id)); - } - } - - - -contract B{ - constructor() public payable{} - fallback() external payable{} - function transC(address payable callCAddress,address payable toAddress,uint256 amount, trcToken id) payable public{ - callCAddress.call(abi.encodeWithSignature("trans(address,uint256,trcToken)",toAddress,amount,id)); - } -} -contract C{ - constructor() payable public{} - fallback() payable external{} - function trans(address payable toAddress,uint256 amount, trcToken id) payable public{ - toAddress.transferToken(amount,id); - } - -} diff --git a/framework/src/test/resources/soliditycode/contractTrcToken027.sol b/framework/src/test/resources/soliditycode/contractTrcToken027.sol deleted file mode 100644 index e7d6ee768f3..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken027.sol +++ /dev/null @@ -1,30 +0,0 @@ - - -contract token{ - constructor() payable public{} - fallback() payable external{} - function testInCall(address callBAddress,address callCAddress, address toAddress ,uint256 amount,trcToken id) payable public{ - callBAddress.call(abi.encodeWithSignature("transC(address,address,uint256,trcToken)",callCAddress,toAddress,amount,id)); - } - function testIndelegateCall(address callBddress,address callAddressC, address toAddress,uint256 amount, trcToken id) payable public{ - callBddress.delegatecall(abi.encodeWithSignature("transC(address,address,uint256,trcToken)",callAddressC,toAddress,amount,id)); - } - } - - - -contract B{ - constructor() public payable{} - fallback() external payable{} - function transC(address callCAddress,address toAddress,uint256 amount, trcToken id) payable public{ - callCAddress.call(abi.encodeWithSignature("trans(address,uint256,trcToken)",toAddress,amount,id)); - } -} -contract C{ - constructor() payable public{} - fallback() payable external{} - function trans(address payable toAddress,uint256 amount, trcToken id) payable public{ - toAddress.transferToken(amount,id); - } - -} diff --git a/framework/src/test/resources/soliditycode/contractTrcToken028.sol b/framework/src/test/resources/soliditycode/contractTrcToken028.sol deleted file mode 100644 index 0f27d89c819..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken028.sol +++ /dev/null @@ -1,25 +0,0 @@ - - -contract token{ - uint256 public a=1; - constructor() public payable{} - function tokenBalanceWithSameName(trcToken id) public payable{ - B b= new B(); - a= b.tokenBalance(id); - } - function getA() public returns(uint256){ - return a; - } -} - - -contract B{ - uint256 public flag =0; - constructor() public payable{} - fallback() external payable{} - function tokenBalance(trcToken id) payable public returns(uint256){ - flag =9; - return flag; - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken029.sol b/framework/src/test/resources/soliditycode/contractTrcToken029.sol deleted file mode 100644 index 8480cf6f19d..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken029.sol +++ /dev/null @@ -1,24 +0,0 @@ - - -contract token{ - address public a; - constructor() public payable{} - function transferTokenWithSameName(trcToken id,uint256 amount) public payable{ - B b= new B(); - b.transferToken(amount,id); - a= address(b); - } -} - - -contract B{ - uint256 public flag =0; - constructor() public payable{} - fallback() external payable{} - function transferToken(uint256 amount, trcToken id) payable public returns(bool){ - flag =9; - } - function getFlag() public view returns (uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken030.sol b/framework/src/test/resources/soliditycode/contractTrcToken030.sol deleted file mode 100644 index 06b8201979c..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken030.sol +++ /dev/null @@ -1,17 +0,0 @@ - - contract token{ - constructor() public payable{} - - // 4)suicide也会转移token - // 所有token,trx均被转移到toAddress, - // 若toAddress为合约地址本身,则所有token,trx均被烧掉进黑洞 - function kill(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - - } - -contract B{ - constructor() public payable {} - fallback() external payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken031.sol b/framework/src/test/resources/soliditycode/contractTrcToken031.sol deleted file mode 100644 index 65ec394e8da..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken031.sol +++ /dev/null @@ -1,18 +0,0 @@ - - - contract token{ - constructor() public payable{} - - // 4)suicide也会转移token - // 所有token,trx均被转移到toAddress, - // 若toAddress为合约地址本身,则所有token,trx均被烧掉进黑洞 - function kill(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - - } - -contract B{ - constructor() public payable {} - fallback() external payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken034.sol b/framework/src/test/resources/soliditycode/contractTrcToken034.sol deleted file mode 100644 index 32c55f8c84b..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken034.sol +++ /dev/null @@ -1,25 +0,0 @@ - - - contract token{ - - constructor() public payable {} - - // 2. 异常测试 - // 1)revert, 金额回退 - function failTransferTokenRevert(address payable toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - require(1==2); - } - - // 2)Error, 金额回退, fee limit 扣光 - function failTransferTokenError(address payable toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - assert(1==2); - } - - } - contract B{ - uint256 public flag = 0; - constructor() public payable {} - fallback() external payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken035.sol b/framework/src/test/resources/soliditycode/contractTrcToken035.sol deleted file mode 100644 index ca45dde790d..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken035.sol +++ /dev/null @@ -1,24 +0,0 @@ - - - contract token{ - constructor() public payable {} - - // 2. 异常测试 - // 1)revert, 金额回退 - function failTransferTokenRevert(address payable toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - require(1==2); - } - - // 2)Error, 金额回退, fee limit 扣光 - function failTransferTokenError(address payable toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - assert(1==2); - } - - } - contract B{ - uint256 public flag = 0; - constructor() public payable {} - fallback() external payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken036.sol b/framework/src/test/resources/soliditycode/contractTrcToken036.sol deleted file mode 100644 index c1da2f7555e..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken036.sol +++ /dev/null @@ -1,52 +0,0 @@ - -contract IllegalDecorate { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithPure(address payable toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate1 { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithConstant(address payable toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate2 { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithView(address payable toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate3 { -event log(uint256); -constructor() payable public{} -fallback() payable external{} -function transferTokenWithOutPayable(address payable toAddress, uint256 tokenValue) public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken036_1.sol b/framework/src/test/resources/soliditycode/contractTrcToken036_1.sol deleted file mode 100644 index 327ab5a756e..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken036_1.sol +++ /dev/null @@ -1,13 +0,0 @@ - -contract IllegalDecorate { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithPure(address payable toAddress, uint256 tokenValue) public pure { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} diff --git a/framework/src/test/resources/soliditycode/contractTrcToken036_2.sol b/framework/src/test/resources/soliditycode/contractTrcToken036_2.sol deleted file mode 100644 index 817a96e3c80..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken036_2.sol +++ /dev/null @@ -1,13 +0,0 @@ - -contract IllegalDecorate { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithConstant(address toAddress, uint256 tokenValue) public constant { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken036_3.sol b/framework/src/test/resources/soliditycode/contractTrcToken036_3.sol deleted file mode 100644 index 67400c2e8ad..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken036_3.sol +++ /dev/null @@ -1,13 +0,0 @@ - -contract IllegalDecorate { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithView(address payable toAddress, uint256 tokenValue) public view { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken036_4.sol b/framework/src/test/resources/soliditycode/contractTrcToken036_4.sol deleted file mode 100644 index cbaca0d4b38..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken036_4.sol +++ /dev/null @@ -1,13 +0,0 @@ - -contract IllegalDecorate { -event log(uint256); -constructor() payable public{} -fallback() payable external{} -function transferTokenWithOutPayable(address payable toAddress, uint256 tokenValue) public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken036_old.sol b/framework/src/test/resources/soliditycode/contractTrcToken036_old.sol deleted file mode 100644 index 1f03afb7636..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken036_old.sol +++ /dev/null @@ -1,41 +0,0 @@ - - - -contract IllegalDecorate1 { -constructor() payable public{} -fallback() payable public{} -event log(uint256); -function transferTokenWithConstant(address toAddress, uint256 tokenValue) public constant { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate2 { -constructor() payable public{} -fallback() payable public{} -event log(uint256); -function transferTokenWithView(address toAddress, uint256 tokenValue) public view { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate3 { -event log(uint256); -constructor() payable public{} -fallback() payable public{} -function transferTokenWithOutPayable(address toAddress, uint256 tokenValue) public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken037.sol b/framework/src/test/resources/soliditycode/contractTrcToken037.sol deleted file mode 100644 index 7cdd91702e8..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken037.sol +++ /dev/null @@ -1,24 +0,0 @@ - - -contract transferTrc10 { - function receive(address payable rec) public payable { - uint256 aamount=address(this).tokenBalance(msg.tokenid); - uint256 bamount=rec.tokenBalance(msg.tokenid); - require(msg.tokenvalue==aamount); - require(aamount==msg.tokenvalue); - rec.transferToken(aamount,msg.tokenid); - require(0==address(this).tokenBalance(msg.tokenid)); - require(bamount+aamount==rec.tokenBalance(msg.tokenid)); - (bool success, bytes memory data) =rec.call(abi.encodeWithSignature("checkTrc10(uint256,trcToken,uint256)",bamount+aamount,msg.tokenid,0)); - require(success); - - } -} - -contract receiveTrc10 { - fallback() external payable {} - function checkTrc10(uint256 amount,trcToken tid,uint256 meamount) public{ - require(amount==address(this).tokenBalance(tid)); - require(meamount==msg.sender.tokenBalance(tid)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken038.sol b/framework/src/test/resources/soliditycode/contractTrcToken038.sol deleted file mode 100644 index eeb5ae744cf..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken038.sol +++ /dev/null @@ -1,24 +0,0 @@ - - -contract transferTrc10 { - function receive(address payable rec) public payable { - uint256 aamount=address(this).tokenBalance(msg.tokenid); - uint256 bamount=rec.tokenBalance(msg.tokenid); - require(msg.tokenvalue==aamount); - require(aamount==msg.tokenvalue); - rec.transferToken(aamount,msg.tokenid); - //require(rec.call(abi.encode(bytes4(keccak256("AssertError()"))))); - (bool suc, bytes memory data) = rec.call(abi.encodeWithSignature("AssertError()")); - require(suc); - require(aamount==address(this).tokenBalance(msg.tokenid)); - require(bamount==rec.tokenBalance(msg.tokenid)); - } -} - -contract receiveTrc10 { - fallback() external payable { - } - function AssertError() public{ - assert(1==2); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken039.sol b/framework/src/test/resources/soliditycode/contractTrcToken039.sol deleted file mode 100644 index ebf6fb932ed..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken039.sol +++ /dev/null @@ -1,44 +0,0 @@ - -/* - * 1. caller账户issue一个token - * 2. caller部署proxy, 传入1000 token,1000 trx - * 3. caller部署A - * 4. caller部署B - * 5. caller调用proxy中upgradetTo函数,传入A的地址 - * 6. caller调用proxy中不存在的trans(uint256,address,trcToken)函数,注意这时trcToken是无意义的,但也带上tokenid。address是任意另外某账户的地址 - * 7. 可以看到目标地址trx增长5,caller账户trx减少5 - * 8. caller调用proxy中upgradeTo函数,传入B的地址 - * 9. caller调用proxy中不存在的trans(uint256,address,trcToken)函数。 - * 10. 可以看到目标地址token增长5,caller账户token减少5 -*/ -contract Proxy { - constructor() payable public{} - address public implementation; - function upgradeTo(address _address) public { - implementation = _address; - } - fallback() payable external{ - address addr = implementation; - require(addr != address(0)); - assembly { - let freememstart := mload(0x40) - calldatacopy(freememstart, 0, calldatasize()) - let success := delegatecall(not(0), addr, freememstart, calldatasize(), freememstart, 0) - returndatacopy(freememstart, 0, returndatasize()) - switch success - case 0 { revert(freememstart, returndatasize()) } - default { return(freememstart, returndatasize()) } - } - } -} - -contract A { - function trans(uint256 amount, address payable toAddress, trcToken id) payable public { - toAddress.transfer(amount); - } -} -contract B{ - function trans(uint256 amount, address payable toAddress, trcToken id) payable public { - toAddress.transferToken(amount,id); - } -} diff --git a/framework/src/test/resources/soliditycode/contractTrcToken041.sol b/framework/src/test/resources/soliditycode/contractTrcToken041.sol deleted file mode 100644 index 6284253d1d5..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken041.sol +++ /dev/null @@ -1,20 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } - -contract B{ - uint256 public flag = 0; - constructor() public payable {} - fallback() external payable {} - - function setFlag() public payable{ - flag = 1; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken043.sol b/framework/src/test/resources/soliditycode/contractTrcToken043.sol deleted file mode 100644 index 43e4010ec3f..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken043.sol +++ /dev/null @@ -1,35 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken048.sol b/framework/src/test/resources/soliditycode/contractTrcToken048.sol deleted file mode 100644 index e705f696c1d..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken048.sol +++ /dev/null @@ -1,14 +0,0 @@ - - - contract Test { - event log(uint256); - function testMsgTokenValue() payable public returns(uint256 value) { - emit log(msg.tokenvalue); - return msg.tokenvalue; - } - - function testMsgValue() payable public returns(uint256 value) { - emit log(msg.value); - return msg.value; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken049.sol b/framework/src/test/resources/soliditycode/contractTrcToken049.sol deleted file mode 100644 index d40480720df..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken049.sol +++ /dev/null @@ -1,9 +0,0 @@ - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken050.sol b/framework/src/test/resources/soliditycode/contractTrcToken050.sol deleted file mode 100644 index 6bc6d956898..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken050.sol +++ /dev/null @@ -1,10 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken051.sol b/framework/src/test/resources/soliditycode/contractTrcToken051.sol deleted file mode 100644 index 493016b777f..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken051.sol +++ /dev/null @@ -1,11 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - fallback() external payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken052.sol b/framework/src/test/resources/soliditycode/contractTrcToken052.sol deleted file mode 100644 index 6bc6d956898..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken052.sol +++ /dev/null @@ -1,10 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken054.sol b/framework/src/test/resources/soliditycode/contractTrcToken054.sol deleted file mode 100644 index 863429fc4f8..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken054.sol +++ /dev/null @@ -1,16 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken055.sol b/framework/src/test/resources/soliditycode/contractTrcToken055.sol deleted file mode 100644 index 863429fc4f8..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken055.sol +++ /dev/null @@ -1,16 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken060.sol b/framework/src/test/resources/soliditycode/contractTrcToken060.sol deleted file mode 100644 index ea28f4a62b6..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken060.sol +++ /dev/null @@ -1,30 +0,0 @@ - - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken061.sol b/framework/src/test/resources/soliditycode/contractTrcToken061.sol deleted file mode 100644 index ea28f4a62b6..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken061.sol +++ /dev/null @@ -1,30 +0,0 @@ - - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken064.sol b/framework/src/test/resources/soliditycode/contractTrcToken064.sol deleted file mode 100644 index 43e0da8a510..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken064.sol +++ /dev/null @@ -1,49 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } - function transferTokenTestValueMaxBigInteger(address payable toAddress) payable public { - toAddress.transferToken(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0); - } - function transferTokenTestValueOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(9223372036854775808, 1000001); - } - function transferTokenTestValueMaxLong(address payable toAddress) payable public { - toAddress.transferToken(9223372036854775807, 1000001); - } - function transferTokenTestValue0IdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(0, 9223372036854775809); - } -} - - - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken066.sol b/framework/src/test/resources/soliditycode/contractTrcToken066.sol deleted file mode 100644 index 43e4010ec3f..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken066.sol +++ /dev/null @@ -1,35 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken067.sol b/framework/src/test/resources/soliditycode/contractTrcToken067.sol deleted file mode 100644 index 43e4010ec3f..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken067.sol +++ /dev/null @@ -1,35 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken073.sol b/framework/src/test/resources/soliditycode/contractTrcToken073.sol deleted file mode 100644 index a9ee8ea412b..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken073.sol +++ /dev/null @@ -1,16 +0,0 @@ - -contract Dest { - event logFallback(uint256 indexed, uint256 indexed, uint256 indexed); - event logGetToken(uint256 indexed, uint256 indexed, uint256 indexed, uint256); - - - constructor() payable public {} - - function getToken(trcToken tokenId) payable public{ - emit logGetToken(msg.sender.tokenBalance(tokenId), msg.tokenid, msg.tokenvalue, msg.value); - } - - fallback() payable external{ - emit logFallback(msg.tokenid, msg.tokenvalue, msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken075.sol b/framework/src/test/resources/soliditycode/contractTrcToken075.sol deleted file mode 100644 index c90f8dcbee3..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken075.sol +++ /dev/null @@ -1,26 +0,0 @@ - - -contract Dest { - event logFallback(uint256 indexed, uint256 indexed, uint256 indexed); - event logGetToken(uint256 indexed, uint256 indexed, uint256 indexed, uint256); - - constructor() payable public {} - - function getToken(trcToken tokenId) payable public{ - emit logGetToken(msg.sender.tokenBalance(tokenId), msg.tokenid, msg.tokenvalue, msg.value); - } - - function getTokenLongMin() payable public{ - // long.min - 1000020 - emit logGetToken(msg.sender.tokenBalance(trcToken(uint256(int256(-9223372036855775828)))), msg.tokenid, msg.tokenvalue, msg.value); - } - - function getTokenLongMax() payable public{ - // long.max + 1000020 - emit logGetToken(msg.sender.tokenBalance(trcToken(9223372036855775827)), msg.tokenid, msg.tokenvalue, msg.value); - } - - fallback() payable external{ - emit logFallback(msg.tokenid, msg.tokenvalue, msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken076.sol b/framework/src/test/resources/soliditycode/contractTrcToken076.sol deleted file mode 100644 index a9decbee320..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken076.sol +++ /dev/null @@ -1,19 +0,0 @@ - -contract Test { - address public origin; - address public sender; - bool public result1; - bool public result2; - function test() external { - origin = tx.origin; - sender = msg.sender; - result1 = msg.sender == tx.origin; // true - result2 = origin == sender; // true - } -function getResult1() public returns(bool){ - return result1; -} -function getResult2() public returns(bool){ - return result2; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken077.sol b/framework/src/test/resources/soliditycode/contractTrcToken077.sol deleted file mode 100644 index aeecf9cb9a5..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken077.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract trcToken077 { -function addressTest() public returns(bytes32 addressValue) { - assembly{ - let x := mload(0x40) //Find empty storage location using "free memory pointer" - mstore(x,address) //Place current contract address - addressValue := mload(x) - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken078.sol b/framework/src/test/resources/soliditycode/contractTrcToken078.sol deleted file mode 100644 index 8d10d25312d..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken078.sol +++ /dev/null @@ -1,35 +0,0 @@ - -contract callerContract { - constructor() public payable{} - fallback() external payable{} - function sendToB(address called_address, address c) public payable{ - called_address.delegatecall(abi.encodeWithSignature("transferTo(address)",c)); - } - function sendToB2(address called_address,address c) public payable{ - called_address.call(abi.encodeWithSignature("transferTo(address)",c)); - } - function sendToB3(address called_address,address c) public payable{ - called_address.delegatecall(abi.encodeWithSignature("transferTo(address)",c)); - } -} - contract calledContract { - fallback() external payable{} - constructor() public payable {} - function transferTo(address payable toAddress)public payable{ - toAddress.transfer(5); - } - - function setIinC(address c) public payable{ - c.call{value:5}(abi.encode(bytes4(keccak256("setI()")))); - } - - } - contract c{ - address public origin; - address public sender; - constructor() public payable{} - event log(address,address); - fallback() payable external{ - emit log(tx.origin,msg.sender); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken079.sol b/framework/src/test/resources/soliditycode/contractTrcToken079.sol deleted file mode 100644 index 863429fc4f8..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken079.sol +++ /dev/null @@ -1,16 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken080.sol b/framework/src/test/resources/soliditycode/contractTrcToken080.sol deleted file mode 100644 index 2d2688b74a4..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken080.sol +++ /dev/null @@ -1,30 +0,0 @@ - - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - fallback() external payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcToken081.sol b/framework/src/test/resources/soliditycode/contractTrcToken081.sol deleted file mode 100644 index b69ecde68b2..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcToken081.sol +++ /dev/null @@ -1,51 +0,0 @@ -contract TokenSender { - constructor() payable public{} - function sendTRC10(address target) public payable { - trcToken tokenId = msg.tokenid; - bytes memory callData = abi.encodeWithSignature("receiveTRC10(address,uint256,trcToken)", msg.sender, 1, tokenId); - assembly { - let ret := calltoken( - gas(), - target, - 1, - tokenId, - add(callData, 0x20), - mload(callData), - 0, - 0) - if iszero(ret) { - revert(0, 0) - } - } - } - - function sendTRC10NoMethod(address target) public payable { - trcToken tokenId = msg.tokenid; - bytes4 sig = bytes4(keccak256("()")); // function signature - assembly { - let x := mload(0x40) // get empty storage location - mstore(x,sig) - let ret := calltoken( - gas(), - target, - 1, //token value - tokenId, //token id - x, // input - 0x04, // input size = 4 bytes - x, // output stored at input location, save space - 0x04) - if iszero(ret) { - revert(0, 0) - } - } - } -} - -contract TokenReceiver { - constructor() payable public{} - event Received(address, address, uint256, trcToken); - - function receiveTRC10(address origin, uint256 value, trcToken id) external payable { - emit Received(msg.sender, origin, value, id); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractTrcTokenToOther.sol b/framework/src/test/resources/soliditycode/contractTrcTokenToOther.sol deleted file mode 100644 index 6a18fac311a..00000000000 --- a/framework/src/test/resources/soliditycode/contractTrcTokenToOther.sol +++ /dev/null @@ -1,44 +0,0 @@ - - -contract ConvertType { - -constructor() payable public{} - -fallback() payable external{} - -//function trcTokenOnStorage(trcToken storage token) internal { // ERROR: Data location can only be specified for array, struct or mapping types, but "storage" was given. -//} - -function trcTokenToString(trcToken token) public pure returns(string memory s){ -// s = token; // ERROR -// s = string(token); // ERROR -} - -function trcTokenToUint256(trcToken token) public pure returns(uint256 r){ -uint256 u = token; // OK -uint256 u2 = uint256(token); // OK -r = u2; -} - -function trcTokenToAddress(trcToken token) public pure returns(address r){ -//r = token; // ERROR -token = 1000001; -address a2 = address(uint160(token)); // OK -r = a2; -} - -function trcTokenToBytes(trcToken token) public pure returns(bytes memory r){ -//r = token; // ERROR -// r = bytes(token); // ERROR -} - -function trcTokenToBytes32(trcToken token) public pure returns(bytes32 r){ -// r = token; // ERROR -bytes32 b2 = bytes32(token); // OK -r = b2; -} - -function trcTokenToArray(trcToken token) public pure returns(uint[] memory r){ -//r = token; // ERROR -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/contractUnknownException.sol b/framework/src/test/resources/soliditycode/contractUnknownException.sol deleted file mode 100644 index d2d37364a0e..00000000000 --- a/framework/src/test/resources/soliditycode/contractUnknownException.sol +++ /dev/null @@ -1,64 +0,0 @@ - -contract testA { - constructor() public payable { - A a = (new A){value:10}(); - a.fun(); - } -} - -contract testB { - constructor() public payable { - B b = (new B){value:10}(); - b.fun(); - } -} - - -contract testC { - constructor() public payable{ - C c = (new C){value:10}(); - c.fun(); - } -} - -contract testD { - constructor() public payable{ - D d = (new D){value:10}(); - d.fun(); - } -} - - -contract A { - constructor() public payable{ - selfdestruct(payable(msg.sender)); - } - function fun() public { - } - -} - -contract B { - constructor() public payable { - revert(); - } - function fun() public { - } -} - - -contract C { - constructor() public payable { - assert(1==2); - } - function fun() public { - } -} - -contract D { - constructor() public payable { - require(1==2); - } - function fun() public { - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/create2CallContract.sol b/framework/src/test/resources/soliditycode/create2CallContract.sol deleted file mode 100644 index 046706ebd9e..00000000000 --- a/framework/src/test/resources/soliditycode/create2CallContract.sol +++ /dev/null @@ -1,37 +0,0 @@ -contract callerContract { - constructor() payable public{} - fallback() payable external{} - function delegateCallCreate2(address called_address, bytes memory code, uint256 salt) public { - called_address.delegatecall(abi.encodeWithSignature("deploy(bytes,uint256)",code,salt)); - } - function callCreate2(address called_address,bytes memory code, uint256 salt) public returns(bool,bytes memory){ - return called_address.call(abi.encodeWithSignature("deploy(bytes,uint256)",code,salt)); - } -} - - -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - -contract TestConstract { - uint public i; - constructor () public { - } - function plusOne() public returns(uint){ - i++; - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/create2Istanbul.sol b/framework/src/test/resources/soliditycode/create2Istanbul.sol deleted file mode 100644 index c2ef8f3236b..00000000000 --- a/framework/src/test/resources/soliditycode/create2Istanbul.sol +++ /dev/null @@ -1,28 +0,0 @@ - - -contract create2Istanbul { - function deploy(bytes memory code, uint256 salt) public returns(address) { - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - - } - return addr; - } - - // prefix in main net is 0x41, testnet config is 0xa0 - function get(bytes1 prefix, bytes calldata code, uint256 salt) external view returns(address) { - //bytes32 hash = keccak256(abi.encodePacked(bytes1(0x41),address(this), salt, keccak256(code))); - bytes32 hash = keccak256(abi.encodePacked(prefix,address(this), salt, keccak256(code))); - address addr = address(uint160(uint256(hash))); - return addr; - } - -} - -contract B { - constructor() public payable{} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/create2contract.sol b/framework/src/test/resources/soliditycode/create2contract.sol deleted file mode 100644 index 0171f4d5486..00000000000 --- a/framework/src/test/resources/soliditycode/create2contract.sol +++ /dev/null @@ -1,52 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } - - event Deployed(address addr, bytes32 salt, address sender); - function deploy(bytes memory code, bytes32 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - -contract FactoryBytes { - event Deployed(address addr, bytes32 salt, address sender); - function deploy(bytes memory code, bytes32 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - -contract TestConstract { - uint public i; - constructor () public { - } - function plusOne() public returns(uint){ - i++; - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/create2contract22.sol b/framework/src/test/resources/soliditycode/create2contract22.sol deleted file mode 100644 index cfad7c815fb..00000000000 --- a/framework/src/test/resources/soliditycode/create2contract22.sol +++ /dev/null @@ -1,109 +0,0 @@ -contract Factory { - event Deployed(address addr, trcToken salt, address sender); - event Deployed1(address addr, uint256 salt, address sender); - event Deployed2(address addr, address salt, address sender); - event Deployed3(address addr, string salt, address sender); - - - function deploy(bytes memory code, trcToken salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } - - function deploy1(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed1(addr, salt, msg.sender); - return addr; - } - - function deploy2(bytes memory code, address salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed2(addr, salt, msg.sender); - return addr; - } - - function deploy3(bytes memory code, string memory salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed3(addr, salt, msg.sender); - return addr; - } - -} - - -contract TestConstract { - uint public i=1; - function testTransfer(uint256 i) payable public{ - payable(msg.sender).transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - payable(msg.sender).transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} - -contract TestConstract1 { - uint public i=2; - function testTransfer(uint256 i) payable public{ - payable(msg.sender).transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - payable(msg.sender).transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} - -contract TestConstract2 { - uint public i=3; - function testTransfer(uint256 i) payable public{ - payable(msg.sender).transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - payable(msg.sender).transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} - -contract TestConstract3 { - uint public i=4; - function testTransfer(uint256 i) payable public{ - payable(msg.sender).transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - payable(msg.sender).transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/create2contractn.sol b/framework/src/test/resources/soliditycode/create2contractn.sol deleted file mode 100644 index 4ecf7bc16b4..00000000000 --- a/framework/src/test/resources/soliditycode/create2contractn.sol +++ /dev/null @@ -1,29 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract TestConstract { - uint public i=1; - function testTransfer(uint256 i) payable public{ - payable(msg.sender).transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - payable(msg.sender).transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/create2contractn2.sol b/framework/src/test/resources/soliditycode/create2contractn2.sol deleted file mode 100644 index 626988c4e04..00000000000 --- a/framework/src/test/resources/soliditycode/create2contractn2.sol +++ /dev/null @@ -1,26 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract TestConstract { - uint public i=1; - function set() payable public { - i=5; - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/demo.sol b/framework/src/test/resources/soliditycode/demo.sol deleted file mode 100644 index 06bf15387fc..00000000000 --- a/framework/src/test/resources/soliditycode/demo.sol +++ /dev/null @@ -1,73 +0,0 @@ - - - contract tokenTest{ - uint256 codesize; - constructor() payable public{ - uint256 m; - address addr = address(this); - assembly { - m := extcodesize(addr) - } - codesize = m; - } - - // positive case - function pulsone() public payable{ - uint256 j = 0; - uint i = 100; - for (; i < i; i++) { - j++; - } - } - - - function getCodeSize() public returns (uint256){ - return codesize; - } - - } - - contract confirmTest{ - - uint256 codesize; - constructor() payable public{ - uint256 m; - address addr = address(this); - assembly { - m := extcodesize(addr) - - } - codesize = m; - } - - function getCodeSize() public returns (uint256){ - return codesize; - } - - function confirm(address addr) public returns (uint256){ - uint256 j; - assembly { - j := extcodesize(addr) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - return j; - } - - function at(address _addr) public returns (bytes memory o_code) { - assembly { - // retrieve the size of the code, this needs assembly - let size := extcodesize(_addr) - // allocate output byte array - this could also be done without assembly - // by using o_code = new bytes(size) - o_code := mload(0x40) - // new "memory end" including padding - mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) - // store length in memory - mstore(o_code, size) - // actually retrieve the code, this needs assembly - extcodecopy(_addr, add(o_code, 0x20), 0, size) - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/enumAndStruct.sol b/framework/src/test/resources/soliditycode/enumAndStruct.sol deleted file mode 100644 index 836a4ac850e..00000000000 --- a/framework/src/test/resources/soliditycode/enumAndStruct.sol +++ /dev/null @@ -1,43 +0,0 @@ - - -struct S_out { -uint x; -} - -enum ErrorType { -Revert_Error, //0 -RevertWithMsg_Error, //1 -Require_Error, //2 -RequirewithMsg_Error, //3 -Assert_Error, //4 -Tansfer_Error, //5 -Send_Error, //6 -Math_Error, //7 -ArrayOverFlow_Error //8 -} - -contract enumAndStructTest { - -struct S_inner { -int x; -} - -enum ErrorType_inner { -Revert_Error, //0 -RevertWithMsg_Error, //1 -Require_Error, //2 -RequirewithMsg_Error, //3 -Assert_Error, //4 -Tansfer_Error, //5 -Send_Error, //6 -Math_Error, //7 -ArrayOverFlow_Error //8 -} - -function getvalue() public returns(uint) { - require(ErrorType.Require_Error == ErrorType(2)); - S_out memory s = S_out(1); - return s.x; -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/event001.sol b/framework/src/test/resources/soliditycode/event001.sol deleted file mode 100644 index 7662df3a5c6..00000000000 --- a/framework/src/test/resources/soliditycode/event001.sol +++ /dev/null @@ -1,10 +0,0 @@ -contract Event { - event xixi(uint256 id) ; - event log2(uint256,uint256,uint256); - constructor() public payable{} - function messageI() payable public returns (uint ret) { - //emit log2(1,2,3); - emit xixi(1); - return 1; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/event002.sol b/framework/src/test/resources/soliditycode/event002.sol deleted file mode 100644 index a61f834e1b5..00000000000 --- a/framework/src/test/resources/soliditycode/event002.sol +++ /dev/null @@ -1,52 +0,0 @@ - - -contract Event { - - event _0(); - event a_0() anonymous; - event a_4i(uint256 indexed x1, uint256 indexed x2 , uint256 indexed x3, uint256 indexed x4, uint256 x5)anonymous ; - event _3i(uint256 x1, uint256 indexed x2 , uint256 indexed x3, uint256 x4, uint256 x5) ; - event _1i(uint256 indexed x1, uint256, uint256 indexed, uint256 x4) ; - event a_1i(uint256) anonymous; - event _ai(uint8[2], uint8) ; - event a_ai(uint8[2], uint8) anonymous; - event _a1i(uint8[2] indexed, uint8) ; - event a_a1i(uint8[2] indexed, uint8) anonymous; - - constructor () public { - // emit a_0(); - // emit a_1i(123); - // emit a_4i(1,2,3,5,16); - // emit _0(); - emit _3i(1,2,3,5,16); - // emit _1i(1,2,3,5); - // emit _ai([1,2], 3); - // emit a_ai([3,4], 5); - // emit _a1i([1,2], 3); - // emit a_a1i([3,4], 5); - } - - function e() public { - emit _1i(1,2,3,4); - } - - function l() public { - emit a_1i(1); - } - - function k() public{ - emit a_4i(2,3,4,5,17); - emit _3i(2,3,4,5,16); - emit _1i(2,3,4,5); - emit a_1i(128); - emit _0(); - emit a_0(); - //selfdestruct(msg.sender); - //emit a_4i(1,2,3,5,16); - //emit _3i(1,2,3,5,16); - //emit _1i(1,2,3,5); - //emit a_1i(123); - //emit _0(); - //emit a_0(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/eventLog2.sol b/framework/src/test/resources/soliditycode/eventLog2.sol deleted file mode 100644 index 0ad82f6dd1f..00000000000 --- a/framework/src/test/resources/soliditycode/eventLog2.sol +++ /dev/null @@ -1,8 +0,0 @@ -contract Event { - event log2(uint256,uint256,uint256); - constructor() public payable{} - function messageI() payable public returns (uint ret) { - emit log2(1,1,1); - return 1; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/extCodeHash.sol b/framework/src/test/resources/soliditycode/extCodeHash.sol deleted file mode 100644 index d6209770682..00000000000 --- a/framework/src/test/resources/soliditycode/extCodeHash.sol +++ /dev/null @@ -1,13 +0,0 @@ -contract TestExtCodeHash { - - function getCodeHashByAddr(address _addr) public returns (bytes32 _hash) { - assembly { - _hash := extcodehash(_addr) - } - } - function getCodeHashByUint(uint256 _addr) public returns (bytes32 _hash) { - assembly { - _hash := extcodehash(_addr) - } - } -} diff --git a/framework/src/test/resources/soliditycode/extCodeHash11.sol b/framework/src/test/resources/soliditycode/extCodeHash11.sol deleted file mode 100644 index 961941c7d20..00000000000 --- a/framework/src/test/resources/soliditycode/extCodeHash11.sol +++ /dev/null @@ -1,103 +0,0 @@ -contract Counter { -uint count = 0; -address payable owner; -event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); -constructor() public{ -owner = payable(msg.sender); -} -function getCodeHashByAddr() public returns (bytes32 _hashBefore, bytes32 _hashAfter) { -address addr = address(this); -assembly { -_hashBefore := extcodehash(addr) -} -if (owner == msg.sender) { -selfdestruct(owner); -} -assembly { -_hashAfter := extcodehash(addr) -} -revert(); -emit LogResult(_hashBefore, _hashAfter); -} -} - -contract Counter1 { -uint count = 0; -address payable owner; -event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); -constructor() public{ -owner = payable(msg.sender); -} -function getCodeHashByAddr() public returns (bytes32 _hashBefore, bytes32 _hashAfter) { -address addr = address(this); -assembly { -_hashBefore := extcodehash(addr) -} -if (owner == msg.sender) { -selfdestruct(owner); -} -assembly { -_hashAfter := extcodehash(addr) -} - -emit LogResult(_hashBefore, _hashAfter); -} -} - - -contract Counter2 { -uint count = 0; -address payable owner; -event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); -constructor() public{ -owner = payable(msg.sender); -} -function getCodeHashByAddr(address c) public returns (bytes32 _hashBefore, bytes32 _hashAfter) { - TestConstract t=new TestConstract(); -address addr = address(t); -assembly { -_hashBefore := extcodehash(addr) -} - addr.call(abi.encodeWithSignature("testSuicideNonexistentTarget(address)",c)); - - -assembly { -_hashAfter := extcodehash(addr) -} - -emit LogResult(_hashBefore, _hashAfter); -} -} - - -contract Counter3 { -uint count = 0; -address payable owner; -event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); -constructor() public{ -owner = payable(msg.sender); -} -function getCodeHashByAddr(address c) public returns (bytes32 _hashBefore, bytes32 _hashAfter) { - TestConstract t=new TestConstract(); -address addr = address(t); -assembly { -_hashBefore := extcodehash(addr) -} -if (owner == msg.sender) { -selfdestruct(owner); -} - -assembly { -_hashAfter := extcodehash(addr) -} - -emit LogResult(_hashBefore, _hashAfter); -} -} - -contract TestConstract { - uint public i=1; - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/extCodeHashConstruct.sol b/framework/src/test/resources/soliditycode/extCodeHashConstruct.sol deleted file mode 100644 index 6d640ad7a23..00000000000 --- a/framework/src/test/resources/soliditycode/extCodeHashConstruct.sol +++ /dev/null @@ -1,14 +0,0 @@ -contract CounterConstruct { - uint count = 0; - address payable owner; - event LogResult(bytes32 _hashBefore); - constructor() public{ - owner = payable(msg.sender); - address addr = address(this); - bytes32 _hashBefore; - assembly { - _hashBefore := extcodehash(addr) - } - emit LogResult(_hashBefore); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/extCodeHashStress.sol b/framework/src/test/resources/soliditycode/extCodeHashStress.sol deleted file mode 100644 index cf41f3c8106..00000000000 --- a/framework/src/test/resources/soliditycode/extCodeHashStress.sol +++ /dev/null @@ -1,45 +0,0 @@ -contract Trigger { - function test(address addr) public returns(uint i) { - bytes32 hash; - while (gasleft() > 1000) { - assembly { - hash := extcodehash(addr) - } - i++; - } - } - - function test(address[] memory addrs) public returns(uint i) { - bytes32 hash; - uint i = 0; - for (; i < addrs.length; i++) { - address addr = addrs[i]; - assembly { - hash := extcodehash(addr) - } - } - return i; - } - } - - - - contract TriggerNormal { - function test(address addr) public returns(uint i) { - i = 0; - while (gasleft() > 100000) { - i++; - } - } - } - - contract TriggerNormal1 { - function test(address[] memory addrs) public returns(uint i) { - bytes32 hash; - uint i = 0; - for (; i < addrs.length; i++) { - address addr = addrs[i]; - addr.balance; - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/extCodeHashTestNoPayable.sol b/framework/src/test/resources/soliditycode/extCodeHashTestNoPayable.sol deleted file mode 100644 index c3a2ad8c6ae..00000000000 --- a/framework/src/test/resources/soliditycode/extCodeHashTestNoPayable.sol +++ /dev/null @@ -1,8 +0,0 @@ -contract testConstantContract{ -uint256 public i; -function testNoPayable() public returns (uint256 z) { -i=1; -z=i; -return z; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/fallbackUpgrade.sol b/framework/src/test/resources/soliditycode/fallbackUpgrade.sol deleted file mode 100644 index 6751858c65e..00000000000 --- a/framework/src/test/resources/soliditycode/fallbackUpgrade.sol +++ /dev/null @@ -1,83 +0,0 @@ -contract Test0{ - event FuncCalled(bytes data,uint a); -} - -contract Test1 { - - event FuncCalled(string a); - fallback() external { - x = "fallback"; - emit FuncCalled(x); - } - string x; -} -//含有payable的fallback,无receice -contract Test2 { - - event FuncCalled(string data); - fallback() external payable{ - x = "fallback"; - emit FuncCalled(x); - } - string x; -} - -contract TestPayable { - event FuncCalled(string a); - - fallback() external payable { - x = "fallback"; - emit FuncCalled(x); - } - - receive() external payable { - x = "receive"; - emit FuncCalled(x); - } - string x; -} - -contract Caller { - function callTest0(Test0 test) public{ - (bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()")); - require(success); - } - function callTest1(address test) public returns (bool) { - (bool success,) = test.call(abi.encodeWithSignature("nonExistingFunction()")); - require(success); - (success,) = address(test).call(""); - require(success); - return true; - } - function callTest2(address test) public payable returns (bool) { - (bool success,) = test.call{value:1000}(abi.encodeWithSignature("nonExistingFunction()")); - require(success); - return true; - } - function callTestPayable1(TestPayable test) public payable returns (bool) { - (bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()")); - require(success); - (success,) = address(test).call(""); - require(success); - return true; - } -} - - -//contract Test0 { -// event FallbackCall(string data,bytes msg); -// //event FuncCalled(string a,bytes data); -// function() external payable{ -// x = "fallback"; -// emit FallbackCall(x,msg.data); -// } -// string x; -//} -//contract Caller{ -// function call(Test0 test) public payable returns(bool){ -// (bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()")); -// require(success); -// return true; -// } -//} - diff --git a/framework/src/test/resources/soliditycode/freezeContract001.sol b/framework/src/test/resources/soliditycode/freezeContract001.sol deleted file mode 100644 index f8522c4166e..00000000000 --- a/framework/src/test/resources/soliditycode/freezeContract001.sol +++ /dev/null @@ -1,63 +0,0 @@ - -contract TestFreeze { - constructor() public payable {} - - function freeze(address payable receiver, uint amount, uint res) external payable{ - receiver.freeze(amount, res); - } - - function unfreeze(address payable receiver, uint res) external { - receiver.unfreeze(res); - } - - function destroy(address payable inheritor) external { - selfdestruct(inheritor); - } - - function send(address payable A) external { - A.transfer(10); - } - - function send(address payable A, uint256 value) external { - A.transfer(value); - } - - function getExpireTime(address payable target, uint res) external view returns(uint) { - return target.freezeExpireTime(res); - } - - function deploy(uint256 salt) public returns(address){ - address addr; - bytes memory code = type(C).creationCode; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } - - function freezeAndSend(address payable receiver, uint amount, uint res) external { - receiver.transfer(amount); - receiver.freeze(amount, res); - } - - -} - - -contract C { - constructor() public payable {} - - function destroy(address payable inheritor) external { - selfdestruct(inheritor); - } -} - -contract D { - constructor() public payable { - payable(msg.sender).freeze(msg.value, 1); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/function_type_array_to_storage.sol b/framework/src/test/resources/soliditycode/function_type_array_to_storage.sol deleted file mode 100644 index a2093023d6a..00000000000 --- a/framework/src/test/resources/soliditycode/function_type_array_to_storage.sol +++ /dev/null @@ -1,45 +0,0 @@ -contract C { - constructor() public payable{} - function () external returns(uint)[1] externalDefaultArray; - function () external view returns(uint)[1] externalViewArray; - function () external pure returns(uint)[1] externalPureArray; - - function () internal returns(uint)[1] internalDefaultArray; - function () internal view returns(uint)[1] internalViewArray; - function () internal pure returns(uint)[1] internalPureArray; - - function externalDefault() external returns(uint) { return 11; } - function externalView() external view returns(uint) { return 12; } - function externalPure() external pure returns(uint) { return 13; } - - function internalDefault() internal returns(uint) { return 21; } - function internalView() internal view returns(uint) { return 22; } - function internalPure() internal pure returns(uint) { return 23; } - - function testViewToDefault() public returns (uint, uint) { - externalDefaultArray = [this.externalView]; - internalDefaultArray = [internalView]; - - return (externalDefaultArray[0](), internalDefaultArray[0]()); - } - - function testPureToDefault() public returns (uint, uint) { - externalDefaultArray = [this.externalPure]; - internalDefaultArray = [internalPure]; - - return (externalDefaultArray[0](), internalDefaultArray[0]()); - } - - function testPureToView() public returns (uint, uint) { - externalViewArray = [this.externalPure]; - internalViewArray = [internalPure]; - - return (externalViewArray[0](), internalViewArray[0]()); - } -} -// ==== -// compileViaYul: also -// ---- -// testViewToDefault() -> 12, 22 -// testPureToDefault() -> 13, 23 -// testPureToView() -> 13, 23 diff --git a/framework/src/test/resources/soliditycode/getAddressChange.sol b/framework/src/test/resources/soliditycode/getAddressChange.sol deleted file mode 100644 index 2796da68770..00000000000 --- a/framework/src/test/resources/soliditycode/getAddressChange.sol +++ /dev/null @@ -1,12 +0,0 @@ -contract getAddressChange { - constructor() public payable {} - // testaddress1函数新增了一个address属性。0.6.0之前 external函数可以通过address(x)来转化为地址,6.0将其禁止,可以通过函数address属性直接获取 - function testaddress1() public view returns(address) { - //return address(this.getamount); //0.6.0之前可以使用 - return this.getamount.address; //0.6.0 - - } - function getamount(address) external view returns(uint256) { - return address(this).balance; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/isSRCandidate.sol b/framework/src/test/resources/soliditycode/isSRCandidate.sol deleted file mode 100644 index e8e9b692dec..00000000000 --- a/framework/src/test/resources/soliditycode/isSRCandidate.sol +++ /dev/null @@ -1,35 +0,0 @@ - - - -contract ContractB{ - address others; -} - -contract TestIsSRCandidate{ - - ContractB contractB = new ContractB(); - - function isSRCandidateTest(address addr) public view returns (bool) { - return address(addr).isSRCandidate; - } - - function zeroAddressTest() public view returns (bool) { - return address(0x0).isSRCandidate; - } - - function localContractAddrTest() public view returns (bool) { - return address(this).isSRCandidate; - } - - function otherContractAddrTest() public view returns (bool) { - return address(contractB).isSRCandidate; - } - - function nonpayableAddrTest(address addr) public view returns (bool) { - return addr.isSRCandidate; - } - - function payableAddrTest(address payable addr) public returns (bool) { - return addr.isSRCandidate; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/mappingGetter.sol b/framework/src/test/resources/soliditycode/mappingGetter.sol deleted file mode 100644 index dbd473717cb..00000000000 --- a/framework/src/test/resources/soliditycode/mappingGetter.sol +++ /dev/null @@ -1,4 +0,0 @@ -contract mappingGetter { - mapping(bytes => uint256) public balances1; - mapping(string => uint256) public balances2; -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/multiValiSignPerformance01.sol b/framework/src/test/resources/soliditycode/multiValiSignPerformance01.sol deleted file mode 100644 index 74baa963366..00000000000 --- a/framework/src/test/resources/soliditycode/multiValiSignPerformance01.sol +++ /dev/null @@ -1,37 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract ecrecoverValidateSign { - - using ECVerify for bytes32; - - function validateSign(bytes32 hash,bytes[] memory sig,address[] memory signer) public returns (bool) { - for(uint256 i=0;i=0.5.0 <0.7.0; - -contract A { - uint public x; - function setValue(uint _x) public { - x = _x; - } -} -contract B is A {} -contract C is A {} -// No explicit override required -contract D is B, C {} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/override003.sol b/framework/src/test/resources/soliditycode/override003.sol deleted file mode 100644 index 0ca6a2663d1..00000000000 --- a/framework/src/test/resources/soliditycode/override003.sol +++ /dev/null @@ -1,20 +0,0 @@ -//pragma solidity ^0.6.0; -contract A { - uint public x; - function setValue(uint _x) public virtual { - x = _x; - } -} - -contract B { - uint public y; - function setValue(uint _y) public virtual { - y = _y; - } -} - -contract C is A, B { - function setValue(uint _x) public override(B,A) { - A.setValue(_x); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/override004.sol b/framework/src/test/resources/soliditycode/override004.sol deleted file mode 100644 index d0cf20525d5..00000000000 --- a/framework/src/test/resources/soliditycode/override004.sol +++ /dev/null @@ -1,25 +0,0 @@ -//pragma solidity >=0.5.0 <0.7.0; - -contract A { - uint public x = 4; - function setValue(uint _x) public notZero { - x = _x; - } - modifier notZero() virtual { - require(x >= 5,"x must >= 5"); - _; - } -} - -contract B is A { - function setValue2(uint _x) public { - x = _x; - } -} - -contract C is A,B { - modifier notZero override { - require(x >= 6,"x must >= 6"); - _; - } -} diff --git a/framework/src/test/resources/soliditycode/override005.sol b/framework/src/test/resources/soliditycode/override005.sol deleted file mode 100644 index 0ea485ae0a2..00000000000 --- a/framework/src/test/resources/soliditycode/override005.sol +++ /dev/null @@ -1,39 +0,0 @@ -pragma solidity >= 0.6.0; - -contract Base { - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices public choice2 = ActionChoices.GoRight; - - function stopped() virtual external view returns (bool) { - return true; - } - function i() virtual external view returns (int) { - return 32482980; - } - function i2() virtual external view returns (int) { - return -32482980; - } - function ui() virtual external view returns (uint) { - return 23487820; - } - function origin() virtual external view returns (address) { - return 0x3b0E4a6EdEE231CE0c3433F00F1bbc5FeD409c0B; - } - function b32() virtual external view returns (bytes32) { - return 0xb55a21aaee0ce8f1c8ffaa0dbd23105cb55a21aaee0ce8f1c8ffaa0dbd231050; - } - function choice() virtual external returns (ActionChoices) { - return choice2; - } -} - -contract Test is Base { - - bool override public stopped = false; - int override public i = 32482989; - int override public i2 = -32482989; - uint override public ui = 23487823; - address override public origin = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF; - bytes32 override public b32 = 0xb55a21aaee0ce8f1c8ffaa0dbd23105cb55a21aaee0ce8f1c8ffaa0dbd23105c; - ActionChoices override public choice = ActionChoices.SitStill; -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/overridePrivateFunction.sol b/framework/src/test/resources/soliditycode/overridePrivateFunction.sol deleted file mode 100644 index b0b4d679620..00000000000 --- a/framework/src/test/resources/soliditycode/overridePrivateFunction.sol +++ /dev/null @@ -1,22 +0,0 @@ -pragma solidity ^0.5.17; - -contract A { - - function test() private pure returns(uint) { - return 1; - } - -} - -contract B is A { - - function basic() private pure returns(uint) { - return 2; - } - function testOverridePrivate() external payable returns(uint) { - return basic(); - } - - constructor() public payable {} -} - diff --git a/framework/src/test/resources/soliditycode/payable001.sol b/framework/src/test/resources/soliditycode/payable001.sol deleted file mode 100644 index 4fe7b20921f..00000000000 --- a/framework/src/test/resources/soliditycode/payable001.sol +++ /dev/null @@ -1,31 +0,0 @@ - - - -contract A { - constructor() public payable{ - } - - fallback() external payable { - } -} - -contract PayableTest { - -address payable a1; -function receiveMoneyTransfer(address a, uint256 _x) public { -a1 = payable(a); -a1.transfer(_x); -} - -function receiveMoneySend(address a, uint256 x) public { -address payable a2 = payable(a); -a2.send(x); -} - -function receiveMoneyTransferWithContract(A PayableTest, uint256 x) public { -payable(address(PayableTest)).transfer(x); -} - -constructor() public payable{ -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/pedersenHash001.sol b/framework/src/test/resources/soliditycode/pedersenHash001.sol deleted file mode 100644 index 6cad7cb9855..00000000000 --- a/framework/src/test/resources/soliditycode/pedersenHash001.sol +++ /dev/null @@ -1,18 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract pedersenHashTest { - - function test1() public returns (bool, bytes memory){ - bytes memory empty = ""; - return address(0x1000004).delegatecall(empty); - } - - function test2(bytes memory data) public returns (bool, bytes memory){ - return address(0x1000004).delegatecall(data); - } - - function test3(uint32 hash, bytes32 left, bytes32 right) public returns (bytes32){ - return pedersenHash(hash, left, right); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/pedersenHash002.sol b/framework/src/test/resources/soliditycode/pedersenHash002.sol deleted file mode 100644 index b0a78973ef2..00000000000 --- a/framework/src/test/resources/soliditycode/pedersenHash002.sol +++ /dev/null @@ -1,320 +0,0 @@ -pragma experimental ABIEncoderV2; - -import "./SafeMath.sol"; - -abstract contract TokenTRC20 { - function transfer(address _to, uint256 _value) public virtual returns (bool success); - - function transferFrom(address _from, address _to, uint256 _value) public virtual returns (bool success); -} - -contract ShieldedTRC20 { - using SafeMath for uint256; - - uint256 public scalingFactor; // used when decimals of TRC20 token is too large. - uint256 public leafCount; - uint256 constant INT64_MAX = 2 ** 63 - 1; - bytes32 public latestRoot; - mapping(bytes32 => bytes32) public nullifiers; // store nullifiers of spent commitments - mapping(bytes32 => bytes32) public roots; // store history root - mapping(uint256 => bytes32) public tree; - mapping(bytes32 => bytes32) public noteCommitment; - bytes32[33] frontier; - bytes32[32] zeroes = [bytes32(0x0100000000000000000000000000000000000000000000000000000000000000), bytes32(0x817de36ab2d57feb077634bca77819c8e0bd298c04f6fed0e6a83cc1356ca155), bytes32(0xffe9fc03f18b176c998806439ff0bb8ad193afdb27b2ccbc88856916dd804e34), bytes32(0xd8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c), bytes32(0xe110de65c907b9dea4ae0bd83a4b0a51bea175646a64c12b4c9f931b2cb31b49), bytes32(0x912d82b2c2bca231f71efcf61737fbf0a08befa0416215aeef53e8bb6d23390a), bytes32(0x8ac9cf9c391e3fd42891d27238a81a8a5c1d3a72b1bcbea8cf44a58ce7389613), bytes32(0xd6c639ac24b46bd19341c91b13fdcab31581ddaf7f1411336a271f3d0aa52813), bytes32(0x7b99abdc3730991cc9274727d7d82d28cb794edbc7034b4f0053ff7c4b680444), bytes32(0x43ff5457f13b926b61df552d4e402ee6dc1463f99a535f9a713439264d5b616b), bytes32(0xba49b659fbd0b7334211ea6a9d9df185c757e70aa81da562fb912b84f49bce72), bytes32(0x4777c8776a3b1e69b73a62fa701fa4f7a6282d9aee2c7a6b82e7937d7081c23c), bytes32(0xec677114c27206f5debc1c1ed66f95e2b1885da5b7be3d736b1de98579473048), bytes32(0x1b77dac4d24fb7258c3c528704c59430b630718bec486421837021cf75dab651), bytes32(0xbd74b25aacb92378a871bf27d225cfc26baca344a1ea35fdd94510f3d157082c), bytes32(0xd6acdedf95f608e09fa53fb43dcd0990475726c5131210c9e5caeab97f0e642f), bytes32(0x1ea6675f9551eeb9dfaaa9247bc9858270d3d3a4c5afa7177a984d5ed1be2451), bytes32(0x6edb16d01907b759977d7650dad7e3ec049af1a3d875380b697c862c9ec5d51c), bytes32(0xcd1c8dbf6e3acc7a80439bc4962cf25b9dce7c896f3a5bd70803fc5a0e33cf00), bytes32(0x6aca8448d8263e547d5ff2950e2ed3839e998d31cbc6ac9fd57bc6002b159216), bytes32(0x8d5fa43e5a10d11605ac7430ba1f5d81fb1b68d29a640405767749e841527673), bytes32(0x08eeab0c13abd6069e6310197bf80f9c1ea6de78fd19cbae24d4a520e6cf3023), bytes32(0x0769557bc682b1bf308646fd0b22e648e8b9e98f57e29f5af40f6edb833e2c49), bytes32(0x4c6937d78f42685f84b43ad3b7b00f81285662f85c6a68ef11d62ad1a3ee0850), bytes32(0xfee0e52802cb0c46b1eb4d376c62697f4759f6c8917fa352571202fd778fd712), bytes32(0x16d6252968971a83da8521d65382e61f0176646d771c91528e3276ee45383e4a), bytes32(0xd2e1642c9a462229289e5b0e3b7f9008e0301cbb93385ee0e21da2545073cb58), bytes32(0xa5122c08ff9c161d9ca6fc462073396c7d7d38e8ee48cdb3bea7e2230134ed6a), bytes32(0x28e7b841dcbc47cceb69d7cb8d94245fb7cb2ba3a7a6bc18f13f945f7dbd6e2a), bytes32(0xe1f34b034d4a3cd28557e2907ebf990c918f64ecb50a94f01d6fda5ca5c7ef72), bytes32(0x12935f14b676509b81eb49ef25f39269ed72309238b4c145803544b646dca62d), bytes32(0xb2eed031d4d6a4f02a097f80b54cc1541d4163c6b6f5971f88b6e41d35c53814)]; - address owner; - TokenTRC20 trc20Token; - - event MintNewLeaf(uint256 position, bytes32 cm, bytes32 cv, bytes32 epk, bytes32[21] c); - event TransferNewLeaf(uint256 position, bytes32 cm, bytes32 cv, bytes32 epk, bytes32[21] c); - event BurnNewLeaf(uint256 position, bytes32 cm, bytes32 cv, bytes32 epk, bytes32[21] c); - event TokenMint(address from, uint256 value); - event TokenBurn(address to, uint256 value, bytes32[3] ciphertext); - event NoteSpent(bytes32 nf); - - constructor (address trc20ContractAddress, uint256 scalingFactorExponent) public { - require(scalingFactorExponent < 77, "The scalingFactorExponent is out of range!"); - scalingFactor = 10 ** scalingFactorExponent; - owner = msg.sender; - trc20Token = TokenTRC20(trc20ContractAddress); - } - // output: cm, cv, epk, proof - function mint(uint256 rawValue, bytes32[9] calldata output, bytes32[2] calldata bindingSignature, bytes32[21] calldata c) external { - address sender = msg.sender; - // transfer the trc20Token from the sender to this contract - bool transferResult = trc20Token.transferFrom(sender, address(this), rawValue); - require(transferResult, "TransferFrom failed!"); - - require(noteCommitment[output[0]] == 0, "Duplicate noteCommitments!"); - uint64 value = rawValueToValue(rawValue); - bytes32 signHash = sha256(abi.encodePacked(address(this), value, output, c)); - (bytes32[] memory ret) = verifyMintProof(output, bindingSignature, value, signHash, frontier, leafCount); - uint256 result = uint256(ret[0]); - require(result == 1, "The proof and signature have not been verified by the contract!"); - - uint256 slot = uint256(ret[1]); - uint256 nodeIndex = leafCount + 2 ** 32 - 1; - tree[nodeIndex] = output[0]; - if (slot == 0) { - frontier[0] = output[0]; - } - for (uint256 i = 1; i < slot + 1; i++) { - nodeIndex = (nodeIndex - 1) / 2; - tree[nodeIndex] = ret[i + 1]; - if (i == slot) { - frontier[slot] = tree[nodeIndex]; - } - } - latestRoot = ret[slot + 2]; - roots[latestRoot] = latestRoot; - noteCommitment[output[0]] = output[0]; - leafCount ++; - - emit MintNewLeaf(leafCount - 1, output[0], output[1], output[2], c); - emit TokenMint(sender, rawValue); - } - //input: nf, anchor, cv, rk, proof - //output: cm, cv, epk, proof - function transfer(bytes32[10][] calldata input, bytes32[2][] calldata spendAuthoritySignature, bytes32[9][] calldata output, bytes32[2] calldata bindingSignature, bytes32[21][] calldata c) external { - require(input.length >= 1 && input.length <= 2, "Input number must be 1 or 2!"); - require(input.length == spendAuthoritySignature.length, "Input number must be equal to spendAuthoritySignature number!"); - require(output.length >= 1 && output.length <= 2, "Output number must be 1 or 2!"); - require(output.length == c.length, "Output number must be equal to c number!"); - - for (uint256 i = 0; i < input.length; i++) { - require(nullifiers[input[i][0]] == 0, "The note has already been spent!"); - require(roots[input[i][1]] != 0, "The anchor must exist!"); - } - for (uint256 i = 0; i < output.length; i++) { - require(noteCommitment[output[i][0]] == 0, "Duplicate noteCommitment!"); - } - - bytes32 signHash = sha256(abi.encodePacked(address(this), input, output, c)); - (bytes32[] memory ret) = verifyTransferProof(input, spendAuthoritySignature, output, bindingSignature, signHash, 0, frontier, leafCount); - uint256 result = uint256(ret[0]); - require(result == 1, "The proof and signature have not been verified by the contract!"); - - uint256 offset = 1; - //ret offset - for (uint256 i = 0; i < output.length; i++) { - uint256 slot = uint256(ret[offset++]); - uint256 nodeIndex = leafCount + 2 ** 32 - 1; - tree[nodeIndex] = output[i][0]; - if (slot == 0) { - frontier[0] = output[i][0]; - } - for (uint256 k = 1; k < slot + 1; k++) { - nodeIndex = (nodeIndex - 1) / 2; - tree[nodeIndex] = ret[offset++]; - if (k == slot) { - frontier[slot] = tree[nodeIndex]; - } - } - leafCount++; - } - latestRoot = ret[offset]; - roots[latestRoot] = latestRoot; - for (uint256 i = 0; i < input.length; i++) { - bytes32 nf = input[i][0]; - nullifiers[nf] = nf; - emit NoteSpent(nf); - } - for (uint256 i = 0; i < output.length; i++) { - noteCommitment[output[i][0]] = output[i][0]; - emit TransferNewLeaf(leafCount - (output.length - i), output[i][0], output[i][1], output[i][2], c[i]); - } - } - //input: nf, anchor, cv, rk, proof - //output: cm, cv, epk, proof - function burn(bytes32[10] calldata input, bytes32[2] calldata spendAuthoritySignature, uint256 rawValue, bytes32[2] calldata bindingSignature, address payTo, bytes32[3] calldata burnCipher, bytes32[9][] calldata output, bytes32[21][] calldata c) external { - uint64 value = rawValueToValue(rawValue); - bytes32 signHash = sha256(abi.encodePacked(address(this), input, output, c, payTo, value)); - - bytes32 nf = input[0]; - bytes32 anchor = input[1]; - require(nullifiers[nf] == 0, "The note has already been spent!"); - require(roots[anchor] != 0, "The anchor must exist!"); - - require(output.length <= 1, "Output number cannot exceed 1!"); - require(output.length == c.length, "Output number must be equal to length of c!"); - - // bytes32 signHash = sha256(abi.encodePacked(address(this), input, payTo, value, output, c)); - if (output.length == 0) { - (bool result) = verifyBurnProof(input, spendAuthoritySignature, value, bindingSignature, signHash); - require(result, "The proof and signature have not been verified by the contract!"); - } else { - transferInBurn(input, spendAuthoritySignature, value, bindingSignature, signHash, output, c); - } - - nullifiers[nf] = nf; - emit NoteSpent(nf); - //Finally, transfer trc20Token from this contract to the nominated address - bool transferResult = trc20Token.transfer(payTo, rawValue); - require(transferResult, "Transfer failed!"); - - emit TokenBurn(payTo, rawValue, burnCipher); - } - - function transferInBurn(bytes32[10] memory input, bytes32[2] memory spendAuthoritySignature, uint64 value, bytes32[2] memory bindingSignature, bytes32 signHash, bytes32[9][] memory output, bytes32[21][] memory c) private { - bytes32 cm = output[0][0]; - require(noteCommitment[cm] == 0, "Duplicate noteCommitment!"); - bytes32[10][] memory inputs = new bytes32[10][](1); - inputs[0] = input; - bytes32[2][] memory spendAuthoritySignatures = new bytes32[2][](1); - spendAuthoritySignatures[0] = spendAuthoritySignature; - (bytes32[] memory ret) = verifyTransferProof(inputs, spendAuthoritySignatures, output, bindingSignature, signHash, value, frontier, leafCount); - uint256 result = uint256(ret[0]); - require(result == 1, "The proof and signature have not been verified by the contract!"); - - uint256 slot = uint256(ret[1]); - uint256 nodeIndex = leafCount + 2 ** 32 - 1; - tree[nodeIndex] = cm; - if (slot == 0) { - frontier[0] = cm; - } - for (uint256 i = 1; i < slot + 1; i++) { - nodeIndex = (nodeIndex - 1) / 2; - tree[nodeIndex] = ret[i + 1]; - if (i == slot) { - frontier[slot] = tree[nodeIndex]; - } - } - latestRoot = ret[slot + 2]; - roots[latestRoot] = latestRoot; - noteCommitment[cm] = cm; - leafCount ++; - - emit BurnNewLeaf(leafCount - 1, cm, output[0][1], output[0][2], c[0]); - } - - //position: index of leafnode, start from 0 - function getPath(uint256 position) public view returns (bytes32, bytes32[32] memory) { - require(position >= 0, "Position should be non-negative!"); - require(position < leafCount, "Position should be smaller than leafCount!"); - uint256 index = position + 2 ** 32 - 1; - bytes32[32] memory path; - uint32 level = ancestorLevel(position); - bytes32 targetNodeValue = getTargetNodeValue(position, level); - for (uint32 i = 0; i < 32; i++) { - if (i == level) { - path[31 - i] = targetNodeValue; - } else { - if (index % 2 == 0) { - path[31 - i] = tree[index - 1]; - } else { - path[31 - i] = tree[index + 1] == 0 ? zeroes[i] : tree[index + 1]; - } - } - index = (index - 1) / 2; - } - return (latestRoot, path); - } - - //position: index of leafnode, start from 0 - function getPathByValueIsZero(uint256 position) public view returns (bytes32, bytes32[32] memory) { - require(position >= 0, "Position should be non-negative!"); - require(position < leafCount, "Position should be smaller than leafCount!"); - uint256 index = position + 2 ** 32 - 1; - bytes32[32] memory path; - uint32 level = ancestorLevel(position); - bytes32 targetNodeValue = getTargetNodeValueByValueIsZero(position, level); - for (uint32 i = 0; i < 32; i++) { - if (i == level) { - path[31 - i] = targetNodeValue; - } else { - if (index % 2 == 0) { - path[31 - i] = tree[index - 1]; - } else { - path[31 - i] = tree[index + 1] == 0 ? zeroes[i] : tree[index + 1]; - } - } - index = (index - 1) / 2; - } - return (latestRoot, path); - } - - function ancestorLevel(uint256 leafIndex) private view returns (uint32) { - uint256 nodeIndex1 = leafIndex + 2 ** 32 - 1; - uint256 nodeIndex2 = leafCount + 2 ** 32 - 2; - uint32 level = 0; - while (((nodeIndex1 - 1) / 2) != ((nodeIndex2 - 1) / 2)) { - nodeIndex1 = (nodeIndex1 - 1) / 2; - nodeIndex2 = (nodeIndex2 - 1) / 2; - level = level + 1; - } - return level; - } - - function getTargetNodeValue(uint256 leafIndex, uint32 level) private view returns (bytes32) { - bytes32 left; - bytes32 right; - uint256 index = leafIndex + 2 ** 32 - 1; - uint256 nodeIndex = leafCount + 2 ** 32 - 2; - bytes32 nodeValue = tree[nodeIndex]; - if (level == 0) { - if (index < nodeIndex) { - return nodeValue; - } - if (index == nodeIndex) { - if (index % 2 == 0) { - return tree[index - 1]; - } else { - return zeroes[0]; - } - } - } - for (uint32 i = 0; i < level; i++) { - if (nodeIndex % 2 == 0) { - left = tree[nodeIndex - 1]; - right = nodeValue; - } else { - left = nodeValue; - right = zeroes[i]; - } - nodeValue = pedersenHash(i, left, right); - nodeIndex = (nodeIndex - 1) / 2; - } - return nodeValue; - } - - function getTargetNodeValueByValueIsZero(uint256 leafIndex, uint32 level) private view returns (bytes32) { - bytes32 left; - bytes32 right; - uint256 index = leafIndex + 2 ** 32 - 1; - uint256 nodeIndex = leafCount + 2 ** 32 - 2; - bytes32 nodeValue = tree[nodeIndex]; - if (level == 0) { - if (index < nodeIndex) { - return nodeValue; - } - if (index == nodeIndex) { - if (index % 2 == 0) { - return tree[index - 1]; - } else { - return zeroes[0]; - } - } - } - for (uint32 i = 0; i < level; i++) { - if (nodeIndex % 2 == 0) { - left = tree[nodeIndex - 1]; - right = nodeValue; - } else { - left = nodeValue; - right = zeroes[i]; - } - left = bytes32(0x0); - right = bytes32(0x0); - nodeValue = pedersenHash(i, left, right); - nodeIndex = (nodeIndex - 1) / 2; - } - return nodeValue; - } - - function rawValueToValue(uint256 rawValue) private view returns (uint64) { - require(rawValue > 0, "Value must be positive!"); - require(rawValue.mod(scalingFactor) == 0, "Value must be integer multiples of scalingFactor!"); - uint256 value = rawValue.div(scalingFactor); - require(value < INT64_MAX); - return uint64(value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/requireExceptiontest1TestRequireContract.sol b/framework/src/test/resources/soliditycode/requireExceptiontest1TestRequireContract.sol deleted file mode 100644 index 16d01911d35..00000000000 --- a/framework/src/test/resources/soliditycode/requireExceptiontest1TestRequireContract.sol +++ /dev/null @@ -1,15 +0,0 @@ - -contract TestThrowsContract{ - function testAssert() public { - assert(1==2); - } - function testRequire() public { - require(2==1); - } - function testRevert() public { - revert(); - } - //function testThrow(){ - // throw; - //} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/requireExceptiontest2TestThrowsContract.sol b/framework/src/test/resources/soliditycode/requireExceptiontest2TestThrowsContract.sol deleted file mode 100644 index 1ff73ad6460..00000000000 --- a/framework/src/test/resources/soliditycode/requireExceptiontest2TestThrowsContract.sol +++ /dev/null @@ -1,15 +0,0 @@ - -contract TestThrowsContract{ - function testAssert() public { - assert(1==2); - } - function testRequire() public { - require(2==1); - } - function testRevert() public { - revert(); - } - // function testThrow() public { - // throw; - //} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/requireExceptiontest3TestRevertContract.sol b/framework/src/test/resources/soliditycode/requireExceptiontest3TestRevertContract.sol deleted file mode 100644 index b42a8c3fb23..00000000000 --- a/framework/src/test/resources/soliditycode/requireExceptiontest3TestRevertContract.sol +++ /dev/null @@ -1,15 +0,0 @@ - -contract TestThrowsContract{ - function testAssert() public { - assert(1==2); - } - function testRequire() public { - require(2==1); - } - function testRevert() public { - revert(); - } - // function testThrow(){ - // throw; - // } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/requireExceptiontest4noPayableContract.sol b/framework/src/test/resources/soliditycode/requireExceptiontest4noPayableContract.sol deleted file mode 100644 index 35f89631e7d..00000000000 --- a/framework/src/test/resources/soliditycode/requireExceptiontest4noPayableContract.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract noPayableContract { - -function noPayable() public payable returns (uint){ -return msg.value; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/requireExceptiontest4noPayableContract_1.sol b/framework/src/test/resources/soliditycode/requireExceptiontest4noPayableContract_1.sol deleted file mode 100644 index 35f89631e7d..00000000000 --- a/framework/src/test/resources/soliditycode/requireExceptiontest4noPayableContract_1.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract noPayableContract { - -function noPayable() public payable returns (uint){ -return msg.value; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/requireExceptiontest5noPayableConstructor.sol b/framework/src/test/resources/soliditycode/requireExceptiontest5noPayableConstructor.sol deleted file mode 100644 index 097594ab7c9..00000000000 --- a/framework/src/test/resources/soliditycode/requireExceptiontest5noPayableConstructor.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract MyContract { - uint money; - - //function MyContract(uint _money) { - constructor(uint _money) public payable{ - require(msg.value >= _money); - money = _money; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/requireExceptiontest5noPayableConstructor_1.sol b/framework/src/test/resources/soliditycode/requireExceptiontest5noPayableConstructor_1.sol deleted file mode 100644 index 5008ec5c9bf..00000000000 --- a/framework/src/test/resources/soliditycode/requireExceptiontest5noPayableConstructor_1.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract MyContract { - uint money; - - //function MyContract(uint _money) { - constructor(uint _money) public { - require(msg.value >= _money); - money = _money; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/requireExceptiontest6transferTestContract.sol b/framework/src/test/resources/soliditycode/requireExceptiontest6transferTestContract.sol deleted file mode 100644 index 4f171aebb9a..00000000000 --- a/framework/src/test/resources/soliditycode/requireExceptiontest6transferTestContract.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract transferTestContract { - function tranferTest(address payable addr) public payable{ - addr.transfer(10); - - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/requireExceptiontest7payableFallbakContract.sol b/framework/src/test/resources/soliditycode/requireExceptiontest7payableFallbakContract.sol deleted file mode 100644 index 534726cb1b4..00000000000 --- a/framework/src/test/resources/soliditycode/requireExceptiontest7payableFallbakContract.sol +++ /dev/null @@ -1,14 +0,0 @@ - - -contract Test { - fallback() external { x = 1; } - uint x; -} - - -contract Caller { - function callTest(Test test) public { - //test.call(0xabcdef01); // hash does not exist - address(test).call(abi.encode(0xabcdef01)); // hash does not exist - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/requireExceptiontest8newContractGasNoenough.sol b/framework/src/test/resources/soliditycode/requireExceptiontest8newContractGasNoenough.sol deleted file mode 100644 index b8743e8231a..00000000000 --- a/framework/src/test/resources/soliditycode/requireExceptiontest8newContractGasNoenough.sol +++ /dev/null @@ -1,19 +0,0 @@ - - -contract Account{ - uint256 public accId; - - // function Account(uint accountId) payable{ - constructor(uint accountId) payable public { - accId = accountId; - } -} - -contract Initialize{ - // Account public account = new Account(10); - - function newAccount() public { - Account account = new Account(1); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/requireExceptiontest9MessageUsedErrorFeed.sol b/framework/src/test/resources/soliditycode/requireExceptiontest9MessageUsedErrorFeed.sol deleted file mode 100644 index 18142d20ee8..00000000000 --- a/framework/src/test/resources/soliditycode/requireExceptiontest9MessageUsedErrorFeed.sol +++ /dev/null @@ -1,18 +0,0 @@ - - -contract MathedFeed { - - function divideMathed() public returns (uint ret) { - uint x=1; - uint y=0; - return x/y; - } -} - - -contract MathedUseContract { - - function MathedUse(address addr) public returns (uint) { - return MathedFeed(addr).divideMathed(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/requireExceptiontestFunctionUsedErrorFeed.sol b/framework/src/test/resources/soliditycode/requireExceptiontestFunctionUsedErrorFeed.sol deleted file mode 100644 index 64243dffd7c..00000000000 --- a/framework/src/test/resources/soliditycode/requireExceptiontestFunctionUsedErrorFeed.sol +++ /dev/null @@ -1,17 +0,0 @@ - - -contract MessageFeed { - - function mValue() payable public returns (uint ret) { - return msg.value; - } -} - -contract MessageUseContract { - function inputValue() payable public returns (uint){ - return msg.value; - } - function messageUse(address addr) payable public returns (uint) { - return MessageFeed(addr).mValue{value:1}(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/selector.sol b/framework/src/test/resources/soliditycode/selector.sol deleted file mode 100644 index 5805a6e8d22..00000000000 --- a/framework/src/test/resources/soliditycode/selector.sol +++ /dev/null @@ -1,21 +0,0 @@ - - -library A { - function getBalance(address) public view returns (uint256) { - return address(this).balance; - } - - function getamount(address) external view returns (uint256) { - return address(this).balance; - } -} - -contract testSelector { - using A for address; - - - function getselector2() public view returns (bytes4, bytes4) { - return (A.getBalance.selector, A.getamount.selector); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/slotAndOffsetNewGrammer.sol b/framework/src/test/resources/soliditycode/slotAndOffsetNewGrammer.sol deleted file mode 100644 index b4c2b0ed516..00000000000 --- a/framework/src/test/resources/soliditycode/slotAndOffsetNewGrammer.sol +++ /dev/null @@ -1,32 +0,0 @@ -contract A { - uint b; - uint a; - uint c; - uint d; - uint e; - - function getA() external returns(uint,uint) { - uint slot; - uint offset; - assembly { -// old grammer -// slot := a_slot -// offset := a_offset - slot := a.slot - offset := a.offset - } - return (slot, offset); - } - - function getE() external returns(uint,uint) { - uint slot; - uint offset; - assembly { -// slot := e_slot -// offset := e_offset - slot := e.slot - offset := e.offset - } - return (slot, offset); - } -} diff --git a/framework/src/test/resources/soliditycode/stackContract001.sol b/framework/src/test/resources/soliditycode/stackContract001.sol deleted file mode 100644 index c2e8f2f7611..00000000000 --- a/framework/src/test/resources/soliditycode/stackContract001.sol +++ /dev/null @@ -1,61 +0,0 @@ - - -contract A{ - event log(uint256); - constructor() payable public{ - emit log(withdrawreward()); - emit log(address(this).rewardbalance); - } - function withdrawRewardTest() public returns (uint256){ - return withdrawreward(); - } - - function test() public{ - emit log(123); - } -} - -contract B{ - event log(uint256); - constructor() payable public{ - emit log(withdrawreward()); - emit log(address(this).rewardbalance); - } - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } - function rewardBalance(address addr) public view returns (uint256){ - return addr.rewardbalance; - } - - function nullAddressTest() public view returns (uint256) { - return address(0x0).rewardbalance; - } - - function localContractAddrTest() public view returns (uint256) { - address payable localContract = address(uint160(address(this))); - return localContract.rewardbalance; - } - - function withdrawRewardTest() public returns (uint256){ - return withdrawreward(); - } - - function contractBWithdrawRewardTest(address contractB) public returns (uint) { - return B(contractB).withdrawRewardTest(); - } - - function createA() public returns (address){ - return address(new A()); - } - - function callA(address Addr) public{ - A(Addr).test(); - } -} diff --git a/framework/src/test/resources/soliditycode/stackSuicide001.sol b/framework/src/test/resources/soliditycode/stackSuicide001.sol deleted file mode 100644 index d1fc520ddb2..00000000000 --- a/framework/src/test/resources/soliditycode/stackSuicide001.sol +++ /dev/null @@ -1,84 +0,0 @@ - -contract testStakeSuicide{ - B b; - constructor() payable public{} - function deployB() payable public returns (B addrB){ - b = (new B).value(1000000000)(); - return b; - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } - function SelfdestructTest2(address sr, uint256 amount, address payable target) public{ - stake(sr, amount); - selfdestruct(target); - } - function Stake(address sr, uint256 amount) public payable returns (bool result){ - return stake(sr, amount); - } - function Stake2(address sr, uint256 amount) public returns (bool result){ - stake(sr, amount); - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function UnStake2() public returns (bool result){ - unstake(); - return unstake(); - } - function WithdrawReward() public { - withdrawreward(); - } - function RewardBalance(address addr) view public returns (uint256 balance) { - return addr.rewardbalance; - } - function revertTest1(address sr, uint256 amount, address payable transferAddr) public{ - transferAddr.transfer(1000000); - stake(sr, amount); - transferAddr.transfer(2000000); - stake(sr, 1000000000000000);//stake more than balance to fail - transferAddr.transfer(4000000); - } - function revertTest2(address payable transferAddr) public{ - transferAddr.transfer(1000000); - unstake(); - transferAddr.transfer(2000000); - unstake();//unstake twice to fail - transferAddr.transfer(4000000); - } - - function BStake(address sr, uint256 amount) public returns (bool result){ - return b.Stake(sr, amount); - } - function BUnStake() public returns (bool result){ - return b.UnStake(); - } - function transfer(address payable add,uint256 num) public { - return add.transfer(num); - } -} - -contract B{ - constructor() payable public{} - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } - - function deploy(bytes memory code, uint256 salt) public returns(address) { - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - return addr; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/stateVariableShadowing.sol b/framework/src/test/resources/soliditycode/stateVariableShadowing.sol deleted file mode 100644 index a9109ee296c..00000000000 --- a/framework/src/test/resources/soliditycode/stateVariableShadowing.sol +++ /dev/null @@ -1,21 +0,0 @@ -contract test { -// uint public x; -// function setValue1(uint _x) public returns (uint){ -// x = _x; -// return x; -// } - uint public y; - function setValue3(uint _x) public returns (uint){ - y = _x; - return y; - } -} - -contract stateVariableShadowing is test { - uint public x; - function setValue2(uint _x) public returns (uint){ - x = _x; - return x; - } -} - diff --git a/framework/src/test/resources/soliditycode/stringSplit.sol b/framework/src/test/resources/soliditycode/stringSplit.sol deleted file mode 100644 index 84231f2d1fe..00000000000 --- a/framework/src/test/resources/soliditycode/stringSplit.sol +++ /dev/null @@ -1,45 +0,0 @@ - - -contract testStringSplit { -string s1 = "s""1""2"",./"; -string s2 = "s123?\\'."; -string s3 = hex"41"hex"42"; -string s4 = hex"4142"; - -function getS1() public view returns (string memory) { -return s1; -} - -function getS1N1() public pure returns (string memory) { -string memory n1 = "s""1""2"",./"; -return n1; -} - -function getS2() public view returns (string memory) { -return s2; -} - -function getS2N2() public pure returns (string memory) { -string memory n2 = "s123?\'."; -return n2; -} - -function getS3() public view returns (string memory) { -return s3; -} - -function getS3N3() public pure returns (string memory) { -string memory n3 = hex"41"hex"42"; -return n3; -} - -function getS4() public view returns (string memory) { -return s4; -} - -function getS4N4() public pure returns (string memory) { -string memory n4 = hex"4142"; -return n4; -} - -} diff --git a/framework/src/test/resources/soliditycode/suicide001.sol b/framework/src/test/resources/soliditycode/suicide001.sol deleted file mode 100644 index cb4690e1043..00000000000 --- a/framework/src/test/resources/soliditycode/suicide001.sol +++ /dev/null @@ -1,32 +0,0 @@ -contract factory { - constructor() payable public { - } - - function create1() payable public returns (address){ - Caller add = (new Caller){value:0}(); - return address(add); - } - - function kill() payable public{ - selfdestruct(payable(msg.sender)); - } - - function create2(bytes memory code, uint256 salt) public returns(address){ - Caller addr; - Caller addr1; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - return address(addr); - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/suicide002.sol b/framework/src/test/resources/soliditycode/suicide002.sol deleted file mode 100644 index bb845f8e0d6..00000000000 --- a/framework/src/test/resources/soliditycode/suicide002.sol +++ /dev/null @@ -1,43 +0,0 @@ -contract Factory { - uint256 public num; - event Deployed(address addr, uint256 salt, address sender); - constructor() public { - } - function deploy(bytes memory code, uint256 salt) public returns(address){ - TestConstract addr; - TestConstract addr1; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - - addr.testSuicideNonexistentTarget(payable(msg.sender)); - addr.set(); - - assembly { - addr1 := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(address(addr), salt, msg.sender); - return address(addr); - } -} - - - -contract TestConstract { - uint public i=1; - constructor () public { - } - - function set() public{ - i=9; - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/super_skip_unimplemented_in_abstract_contract.sol b/framework/src/test/resources/soliditycode/super_skip_unimplemented_in_abstract_contract.sol deleted file mode 100644 index 82dc5d513f7..00000000000 --- a/framework/src/test/resources/soliditycode/super_skip_unimplemented_in_abstract_contract.sol +++ /dev/null @@ -1,22 +0,0 @@ -contract A { - function f() public virtual returns (uint) { - return 42; - } -} - -abstract contract I { - function f() external virtual returns (uint); -} - -contract B is A, I { - function f() override(A, I) public returns (uint) { - // I.f() is before A.f() in the C3 linearized order - // but it has no implementation. - return super.f(); - } -} -// ==== -// compileToEwasm: also -// compileViaYul: also -// ---- -// f() -> 42 diff --git a/framework/src/test/resources/soliditycode/testGetFilterChange.sol b/framework/src/test/resources/soliditycode/testGetFilterChange.sol deleted file mode 100644 index 8a922031c2f..00000000000 --- a/framework/src/test/resources/soliditycode/testGetFilterChange.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma solidity ^0.8.0; -contract SolidityTest { - event Deployed(address sender, uint256 a, uint256 num); - function getResult(uint256 num) public payable returns(uint256) { - uint256 a=0; - for(a=0;a1); - } else if (ErrorType(errorType) == ErrorType.RequirewithMsg_Error) { - require(0>1,"Require Msg."); - } else if (ErrorType(errorType) == ErrorType.Assert_Error) { - assert(1<0); - } else if (ErrorType(errorType) == ErrorType.Tansfer_Error) { - payable(msg.sender).transfer(1); - } else if (ErrorType(errorType) == ErrorType.Send_Error) { - payable(msg.sender).send(1); - } else if (ErrorType(errorType) == ErrorType.Math_Error) { - uint256 a = 1; - uint256 b = 0; - uint256 n = a / b; - } else if (ErrorType(errorType) == ErrorType.ArrayOverFlow_Error) { - arraryUint.pop(); - } - return "success"; - - } - - function callFun(string memory functionStr, string memory argsStr) public{ - address(this).call(abi.encodeWithSignature(functionStr, argsStr)); - } - -} - -contract NewContract { - uint256[] arraryUint ; - - constructor(uint256 errorType) public payable{ - if (ErrorType(errorType) == ErrorType.Revert_Error){ - revert(); - } else if (ErrorType(errorType) == ErrorType.RevertWithMsg_Error){ - revert("Revert Msg."); - } else if (ErrorType(errorType) == ErrorType.Require_Error) { - require(0>1); - } else if (ErrorType(errorType) == ErrorType.RequirewithMsg_Error) { - require(0>1,"Require Msg."); - } else if (ErrorType(errorType) == ErrorType.Assert_Error) { - assert(1<0); - } else if (ErrorType(errorType) == ErrorType.Tansfer_Error) { - payable(msg.sender).transfer(1); - } else if (ErrorType(errorType) == ErrorType.Send_Error) { - payable(msg.sender).send(1); - } else if (ErrorType(errorType) == ErrorType.Math_Error) { - uint256 a = 1; - uint256 b = 0; - uint256 n = a / b; - } else if (ErrorType(errorType) == ErrorType.ArrayOverFlow_Error) { - arraryUint.pop(); - } - } -} - -contract tryTest { - function getData(errorContract inter, string memory functionStr, string memory argsStr) public payable returns(string memory) { - try inter.callFun(functionStr,argsStr) { - return "123"; - } catch Error(string memory errorMsg/* 出错原因 */) { - return errorMsg; - } catch (bytes memory) { - return "3"; - } - } - - function getErrorSwitch(errorContract add, uint256 errorType ) public payable returns(string memory) { - try add.errorSwitch(errorType) returns (string memory Msg) { - return Msg; - } catch Error(string memory errorMsg/* 出错原因 */) { - return errorMsg; - } catch (bytes memory) { - return "NoErrorMsg"; - } - } - - function catchNewErrorSwitch(uint256 errorType) public returns (address nc){ - try new NewContract(errorType) returns (NewContract nc){ - return address(nc); - }catch { - return address(0x00); - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/tvmAssetIssue001.sol b/framework/src/test/resources/soliditycode/tvmAssetIssue001.sol deleted file mode 100644 index 5388ed68473..00000000000 --- a/framework/src/test/resources/soliditycode/tvmAssetIssue001.sol +++ /dev/null @@ -1,25 +0,0 @@ - -contract tvmAssetIssue001 { - constructor() payable public{} - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - return assetissue(name, abbr, totalSupply, precision); - } - - function updateAsset(trcToken tokenId, string memory url, string memory desc) public returns (bool) { - return updateasset(tokenId, bytes(url), bytes(desc)); - } - - function updateOtherAccountAsset(string memory url, string memory desc) public returns (bool) { - trcToken tokenId = trcToken(1000004); - return updateasset(tokenId, bytes(url), bytes(desc)); - } - - function updateAssetOnBytes(trcToken tokenId, bytes memory url, bytes memory desc) public returns (bool) { - return updateasset(tokenId, url, desc); - } - - function transferToken(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/tvmAssetIssue002.sol b/framework/src/test/resources/soliditycode/tvmAssetIssue002.sol deleted file mode 100644 index 87c1206b778..00000000000 --- a/framework/src/test/resources/soliditycode/tvmAssetIssue002.sol +++ /dev/null @@ -1,15 +0,0 @@ - - -contract tvmAssetIssue002 { - constructor() payable public{} - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - assetissue(name, abbr, totalSupply, precision); - return assetissue(name, abbr, totalSupply, precision); - } - - function updateAsset(trcToken tokenId, string memory url1, string memory desc1, string memory url2, string memory desc2) public returns (bool) { - updateasset(tokenId, bytes(url1), bytes(desc1)); - return updateasset(tokenId, bytes(url2), bytes(desc2)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/tvmAssetIssue003.sol b/framework/src/test/resources/soliditycode/tvmAssetIssue003.sol deleted file mode 100644 index f5ce5e0dc3e..00000000000 --- a/framework/src/test/resources/soliditycode/tvmAssetIssue003.sol +++ /dev/null @@ -1,23 +0,0 @@ - - -contract tvmAssetIssue003 { - constructor() payable public{} - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - return assetissue(name, abbr, totalSupply, precision); - } - - function tokenIssueAndTransfer(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision, address addr) public { - address payable newaddress = address(uint160(addr)); - newaddress.transfer(100000000); - assetissue(name, abbr, totalSupply, precision); - newaddress.transfer(100000000); - } - - function updateAssetAndTransfer(trcToken tokenId, string memory url, string memory desc, address addr) public { - address payable newaddress = address(uint160(addr)); - newaddress.transfer(100000000); - updateasset(tokenId, bytes(url), bytes(desc)); - newaddress.transfer(100000000); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/tvmAssetIssue004.sol b/framework/src/test/resources/soliditycode/tvmAssetIssue004.sol deleted file mode 100644 index c8332de8f45..00000000000 --- a/framework/src/test/resources/soliditycode/tvmAssetIssue004.sol +++ /dev/null @@ -1,39 +0,0 @@ - - -contract A { - - constructor() payable public{} - fallback() payable external {} - - function tokenIssueA(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint){ - return assetissue(name, abbr, totalSupply, precision); - } - - function updateAssetA(trcToken tokenId, string memory url, string memory desc) public returns (bool) { - return updateasset(tokenId, bytes(url), bytes(desc)); - } - - function transferToken(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } -} - -contract tvmAssetIssue004 { - - A a; - - constructor() payable public{} - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - return a.tokenIssueA(name, abbr, totalSupply, precision); - } - - function updateAsset(trcToken tokenId, string memory url, string memory desc) public returns (bool) { - return a.updateAssetA(tokenId, url, desc); - } - - function getContractAddress() public payable returns (address) { - a = (new A).value(1024000000)(); - return address(a); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/tvmAssetIssue005.sol b/framework/src/test/resources/soliditycode/tvmAssetIssue005.sol deleted file mode 100644 index 8c36d050ff8..00000000000 --- a/framework/src/test/resources/soliditycode/tvmAssetIssue005.sol +++ /dev/null @@ -1,45 +0,0 @@ - - -contract tvmAssetIssue005 { - constructor() payable public{} - - fallback() external payable { - } - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - return assetissue(name, abbr, totalSupply, precision); - } - - function updateAsset(trcToken tokenId, string memory url, string memory desc) public returns (bool) { - return updateasset(tokenId, bytes(url), bytes(desc)); - } - - function updateAssetOnBytes(trcToken tokenId, bytes memory url, bytes memory desc) public returns (bool) { - return updateasset(tokenId, url, desc); - } - - function transferToken(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - - function SelfdestructTest(address payable target) public { - selfdestruct(target); - } -} - -contract B { - event Deployed(address addr, uint256 salt); - - function deploy(uint256 salt) public returns (address) { - address addr; - bytes memory code = type(tvmAssetIssue005).creationCode; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt); - return addr; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/tvmVote.sol b/framework/src/test/resources/soliditycode/tvmVote.sol deleted file mode 100644 index 214c7c6b10c..00000000000 --- a/framework/src/test/resources/soliditycode/tvmVote.sol +++ /dev/null @@ -1,89 +0,0 @@ -contract TestVote { - - /** - * @dev Contract can accept value while creating. - */ - constructor() public payable {} - - /** - * @dev Freeze `amount` balance of contract to get resource for `receiver` - * which type is `res` (0 for bandwidth, 1 for energy). - */ - function freeze(address payable receiver, uint amount, uint res) external { - receiver.freeze(amount, res); - } - - /** - * @dev Unfreeze specific balance to get corresponding balance.You can use - * `receiver' and 'res' (0 for bandwidth, 1 for energy) parameters to - * unfreeze specific balance. - */ - function unfreeze(address payable receiver, uint res) external { - receiver.unfreeze(res); - } - - /** - * @dev Vote witness in `srList` array and every witness will get correspond - * tron power in `tpList` array. - */ - function voteWitness(address[] calldata srList, uint[] calldata tpList) external { - vote(srList, tpList); - } - - /** - * @dev Withdraw all allowance and reward to contract balance. Return actually withdraw amount. - */ - function withdrawReward() external returns(uint) { - return withdrawreward(); - } - - /** - * @dev query all allowance and reward of contract account. Return contract's all allowance. - */ - function queryRewardBalance() external view returns(uint) { - return rewardBalance(); - } - - /** - * @dev Judge whether the address is a candidate address.If the address is a candidate address, - * return `true`, or return `false`. - */ - function isWitness(address sr) external view returns(bool) { - return isSrCandidate(sr); - } - - /** - * @dev Query vote count of `from` votes for `to`. Return corresponding vote count. - */ - function queryVoteCount(address from, address to) external view returns(uint) { - return voteCount(from, to); - } - - /** - * @dev Query total vote count of `owner`. Return owner's total vote count. - */ - function queryTotalVoteCount(address owner) external view returns(uint) { - return totalVoteCount(owner); - } - - /** - * @dev Query `owner` recevied vote count. Return owner's received vote count. - */ - function queryReceivedVoteCount(address owner) external view returns(uint) { - return receivedVoteCount(owner); - } - - /** - * @dev Query `owner` used vote count. Return owner's used vote count. - */ - function queryUsedVoteCount(address owner) external view returns(uint) { - return usedVoteCount(owner); - } - - /** - * @dev Execute self destruct and transfer all balance and asset of contract to target address. - */ - function killme(address payable target) external { - selfdestruct(target); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/typeName.sol b/framework/src/test/resources/soliditycode/typeName.sol deleted file mode 100644 index 5b44abd1bbb..00000000000 --- a/framework/src/test/resources/soliditycode/typeName.sol +++ /dev/null @@ -1,5 +0,0 @@ -contract TypeName { - function testTypeName() public returns (string memory){ - return type(TypeName).name; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/unStake001.sol b/framework/src/test/resources/soliditycode/unStake001.sol deleted file mode 100644 index 03734fecfa5..00000000000 --- a/framework/src/test/resources/soliditycode/unStake001.sol +++ /dev/null @@ -1,90 +0,0 @@ - - -contract unStakeTest { - B b; - constructor() payable public{} - function deployB() payable public returns (B addrB){ - b = (new B).value(1000000000)(); - return b; - } - - function selfdestructTest(address payable target) public { - selfdestruct(target); - } - - function selfdestructTest2(address sr, uint256 amount, address payable target) public { - stake(sr, amount); - selfdestruct(target); - } - - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - - function stake2(address sr, uint256 amount) public returns (bool result){ - stake(sr, amount); - return stake(sr, amount); - } - - function unStake() public returns (bool result){ - return unstake(); - } - - function unStake2() public returns (bool result){ - unstake(); - return unstake(); - } - - function withdrawReward() public returns (uint256 amount) { - return withdrawreward(); - } - - function rewardBalance(address addr) view public returns (uint256 balance) { - return addr.rewardbalance; - } - - function revertTest1(address sr, uint256 amount, address payable transferAddr) public { - transferAddr.transfer(1000000); - stake(sr, amount); - transferAddr.transfer(2000000); - stake(sr, 1000000000000000); - //stake more than balance to fail - transferAddr.transfer(4000000); - } - - function revertTest2(address payable transferAddr) public { - transferAddr.transfer(1000000); - unstake(); - transferAddr.transfer(2000000); - unstake(); - //unstake twice to fail - transferAddr.transfer(4000000); - } - - function BStake(address sr, uint256 amount) public returns (bool result){ - return b.Stake(sr, amount); - } - - function BUnStake() public returns (bool result){ - return b.UnStake(); - } - - function BSelfdestructTest(address payable target) public { - b.SelfdestructTest(target); - } -} - -contract B { - constructor() payable public{} - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - - function UnStake() public returns (bool result){ - return unstake(); - } - - function SelfdestructTest(address payable target) public { - selfdestruct(target); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/validatemultisign001.sol b/framework/src/test/resources/soliditycode/validatemultisign001.sol deleted file mode 100644 index cc0a742d0c5..00000000000 --- a/framework/src/test/resources/soliditycode/validatemultisign001.sol +++ /dev/null @@ -1,15 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract validatemultisignTest { - function testmulti(address a, uint256 perid, bytes32 hash, bytes[] memory signatures) public returns (bool){ - return validatemultisign(a, perid, hash, signatures); - } - - function testbatch(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public returns (bytes32){ - return batchvalidatesign(hash, signatures, addresses); - } - - function testMultiPrecompileContract(bytes memory data) public returns(bool, bytes memory){ - return address(0xa).delegatecall(data); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/verifyTransferProof001.sol b/framework/src/test/resources/soliditycode/verifyTransferProof001.sol deleted file mode 100644 index 587b4defd10..00000000000 --- a/framework/src/test/resources/soliditycode/verifyTransferProof001.sol +++ /dev/null @@ -1,15 +0,0 @@ -contract verifyTransferProofTest { - - function test1() public returns (bool, bytes memory){ - bytes memory empty = ""; - return address(0x1000002).delegatecall(empty); - } - - function test2(bytes memory data) public returns (bool, bytes memory){ - return address(0x1000002).delegatecall(data); - } - - function test3(bytes32[10][] memory input, bytes32[2][] memory spendAuthoritySignature, bytes32[9][] memory output, bytes32[2] memory bindingSignature, bytes32 signHash, uint64 valueBalance, bytes32[33] memory frontier, uint256 leafCount) public returns (bytes32[] memory){ - return verifyTransferProof(input, spendAuthoritySignature, output, bindingSignature, signHash, valueBalance, frontier, leafCount); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode/virtual001.sol b/framework/src/test/resources/soliditycode/virtual001.sol deleted file mode 100644 index f7967626764..00000000000 --- a/framework/src/test/resources/soliditycode/virtual001.sol +++ /dev/null @@ -1,19 +0,0 @@ -//pragma solidity ^0.6.0; -interface X { - function setValue(uint _x) external; -} -abstract contract Y { - function setBool(bool _y) external virtual ; -} -contract Y2 { - string public z; - function setString(string calldata _z) external virtual { z = "123"; } -} - -contract Z is X,Y,Y2 { - uint public x; - bool public y; - function setValue(uint _x) external override { x = _x; } - function setBool(bool _y) external override { y = _y; } - function setString(string calldata _z) external override { z = _z; } -} diff --git a/framework/src/test/resources/soliditycode/walletTestMutiSign004.sol b/framework/src/test/resources/soliditycode/walletTestMutiSign004.sol deleted file mode 100644 index 7b943aee5c1..00000000000 --- a/framework/src/test/resources/soliditycode/walletTestMutiSign004.sol +++ /dev/null @@ -1,51 +0,0 @@ -contract timeoutTest { - string public iarray1; - // cpu - function oneCpu() public { - require(1==1); - } - - function storage8Char() public { - iarray1 = "12345678"; - } - - function testUseCpu(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - } - return count; - } - - - uint256[] public iarray; - uint public calculatedFibNumber; - mapping(address=>mapping(address=>uint256)) public m; - - function testUseStorage(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - iarray.push(i); - } - return count; - } - - // stack - //uint n = 0; - uint yy = 0; - function test() public { - //n += 1; - yy += 1; - test(); - } - - function setFibonacci(uint n) public returns (uint256){ - calculatedFibNumber = fibonacci(n); - return calculatedFibNumber; - } - - function fibonacci(uint n) internal returns (uint) { - return fibonacci(n - 1) + fibonacci(n - 2); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/AssertException002.sol b/framework/src/test/resources/soliditycode_0.5.15/AssertException002.sol deleted file mode 100644 index 2bff1dcec3e..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/AssertException002.sol +++ /dev/null @@ -1,17 +0,0 @@ -//pragma solidity ^0.4.0; - -contract AssertException{ - function divideIHaveArgsReturn(int x,int y) public returns (int z) { - return x / y; - } - function testAssert() public { - require(2==1); - } -} -contract C { - constructor() public payable { - assert(1==2); - } - function fun() public { - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/AssignToExternal.sol b/framework/src/test/resources/soliditycode_0.5.15/AssignToExternal.sol deleted file mode 100644 index d4f09590a36..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/AssignToExternal.sol +++ /dev/null @@ -1,30 +0,0 @@ -contract AssignToExternal { - // Not allow: - // function f(uint256[] calldata x, uint256[] calldata y) external pure { - // x = y; - // } - - // allow: - - function f(uint256 a) external returns (uint){ - a = a + 1; - return a; - } - - function StringSet(string calldata a) external returns (string memory){ - return a; - } - - function ByteSet(bytes32 a) external returns (bytes32){ - return a; - } - - function UintArraySet(uint256[2] calldata a) external returns (uint256[2] memory){ - return a; - } - - function AddSet(address a) external returns (address){ - return a; - } - -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/BlockHash.sol b/framework/src/test/resources/soliditycode_0.5.15/BlockHash.sol deleted file mode 100644 index 6603da65e44..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/BlockHash.sol +++ /dev/null @@ -1,38 +0,0 @@ -contract TestBlockHash { - - function testOR1(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = blockhash(block.number - 1) | bytes32(value); - return (b1, c, blockhash(block.number - 1)); - } - - function testOR2(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = bytes32(value) | blockhash(block.number - 1); - return (b1, c, blockhash(block.number - 1)); - } - - function testAND1(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = blockhash(block.number - 1) & bytes32(value); - return (b1, c, blockhash(block.number - 1)); - } - - function testAND2(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = bytes32(value) & blockhash(block.number - 1); - return (b1, c, blockhash(block.number - 1)); - } - - function testXOR1(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = blockhash(block.number - 1) ^ bytes32(value); - return (b1, c, blockhash(block.number - 1)); - } - - function testXOR2(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = bytes32(value) ^ blockhash(block.number - 1); - return (b1, c, blockhash(block.number - 1)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/ClearAbi001.sol b/framework/src/test/resources/soliditycode_0.5.15/ClearAbi001.sol deleted file mode 100644 index fccc59e14be..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/ClearAbi001.sol +++ /dev/null @@ -1,7 +0,0 @@ -//pragma solidity ^0.4.0; - -contract testConstantContract{ -function testPayable() public view returns (int z) { -return 1; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/ClearAbi005.sol b/framework/src/test/resources/soliditycode_0.5.15/ClearAbi005.sol deleted file mode 100644 index a3115398386..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/ClearAbi005.sol +++ /dev/null @@ -1,26 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract TestConstract { - uint public i=0; - constructor () public { - } - function plusOne() public returns(uint){ - i++; - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/ConstructorDefaults.sol b/framework/src/test/resources/soliditycode_0.5.15/ConstructorDefaults.sol deleted file mode 100644 index 4b6186ccb95..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/ConstructorDefaults.sol +++ /dev/null @@ -1,9 +0,0 @@ -contract testIsContract{ - bool result; - constructor (bool a) public { - result = a; - } -function test( address a) public returns (bool) { -return result; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/Create2Test023.sol b/framework/src/test/resources/soliditycode_0.5.15/Create2Test023.sol deleted file mode 100644 index 4c3f8af9f2b..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/Create2Test023.sol +++ /dev/null @@ -1,31 +0,0 @@ -contract factory { - constructor() payable public { - } - - function deploy(bytes memory code, uint256 salt) public returns(address){ - Caller addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - return address(addr); - } - - function testCreate() payable public returns (address){ - Caller add = (new Caller).value(0)(); - return address(add); - } - - function kill( ) payable public{ - selfdestruct(msg.sender); - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/Create2Test024.sol b/framework/src/test/resources/soliditycode_0.5.15/Create2Test024.sol deleted file mode 100644 index f5a9d032cff..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/Create2Test024.sol +++ /dev/null @@ -1,56 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - TestConstract addr; - TestConstract addr1; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - - addr.testSuicideNonexistentTarget(msg.sender); - addr.set(); - emit Deployed(address(addr), salt, msg.sender); - return address(addr); - } - - function deploy2(bytes memory code, uint256 salt) public returns(address){ - TestConstract addr; - TestConstract addr1; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - - //addr.testSuicideNonexistentTarget(msg.sender); - //addr.set(); - - assembly { - addr1 := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(address(addr), salt, msg.sender); - return address(addr); - } -} - - - -contract TestConstract { - uint public i=1; - constructor () public { - } - - function set() public{ - i=9; - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/Create2Test025.sol b/framework/src/test/resources/soliditycode_0.5.15/Create2Test025.sol deleted file mode 100644 index 895dc43e56f..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/Create2Test025.sol +++ /dev/null @@ -1,34 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - constructor() public { - } - - function create2(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } - - function get(bytes1 prefix, bytes calldata code, uint256 salt) external view returns(address) { - //bytes32 hash = keccak256(abi.encodePacked(bytes1(0x41),address(this), salt, keccak256(code))); - bytes32 hash = keccak256(abi.encodePacked(prefix,address(this), salt, keccak256(code))); - address addr = address(uint160(uint256(hash))); - return addr; - } -} - -contract TestContract{ - uint256 public num; - constructor(uint256 j) public{ - num = j; - } - function getNum() public returns (uint256){ - return num; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/ExtCodeHashTest010.sol b/framework/src/test/resources/soliditycode_0.5.15/ExtCodeHashTest010.sol deleted file mode 100644 index bfa8a7fa0d8..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/ExtCodeHashTest010.sol +++ /dev/null @@ -1,46 +0,0 @@ -contract Counter { - uint count = 0; - address payable owner; - event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); - constructor() public{ - owner = msg.sender; - } - function getCodeHashSuicide(address addr) public returns (bytes32 _hashBefore){ - assembly{ - _hashBefore := extcodehash(addr) - } - selfdestruct(owner); - return _hashBefore; - } - - function getCodeHashRevert() public returns (bytes32 _hashBefore, bytes32 _hashAfter) { - address addr = address(this); - assembly { - _hashBefore := extcodehash(addr) - } - if (owner == msg.sender) { - selfdestruct(owner); - } - assembly { - _hashAfter := extcodehash(addr) - } - revert(); - emit LogResult(_hashBefore, _hashAfter); - } - - function getCodeHashCreate() public returns (bytes32 _hashBefore){ - TestContract A = (new TestContract).value(0)(); - address addr = address(A); - assembly{ - _hashBefore := extcodehash(addr) - } - revert(); - return _hashBefore; - } -} - -contract TestContract{ - uint256 count = 1; - constructor() public payable{ - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/ParentTypeBug.sol b/framework/src/test/resources/soliditycode_0.5.15/ParentTypeBug.sol deleted file mode 100644 index 897c843ae24..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/ParentTypeBug.sol +++ /dev/null @@ -1,13 +0,0 @@ -contract Parent { - uint256 public m_aMember; - address public m_bMember; -} -contract Child is Parent { - function foo() public view returns (uint256) { return Parent.m_aMember; } - function bar() public view returns (address) { return Parent.m_bMember; } - - // complie failed - // function foo() public pure returns (uint256) { return Parent.m_aMember; } - // function bar() public pure returns (address) { return Parent.m_bMember; } - -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/SafeMath.sol b/framework/src/test/resources/soliditycode_0.5.15/SafeMath.sol deleted file mode 100644 index b154b8b81b5..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/SafeMath.sol +++ /dev/null @@ -1,149 +0,0 @@ -pragma solidity ^0.5.8; - -/** - * @dev Wrappers over Solidity's arithmetic operations with added overflow - * checks. - * - * Arithmetic operations in Solidity wrap on overflow. This can easily result - * in bugs, because programmers usually assume that an overflow raises an - * error, which is the standard behavior in high level programming languages. - * `SafeMath` restores this intuition by reverting the transaction when an - * operation overflows. - * - * Using this library instead of the unchecked operations eliminates an entire - * class of bugs, so it's recommended to use it always. - */ -library SafeMath { - /** - * @dev Returns the addition of two unsigned integers, reverting on - * overflow. - * - * Counterpart to Solidity's `+` operator. - * - * Requirements: - * - Addition cannot overflow. - */ - function add(uint256 a, uint256 b) internal pure returns (uint256) { - uint256 c = a + b; - require(c >= a, "SafeMath: addition overflow"); - - return c; - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting on - * overflow (when the result is negative). - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - Subtraction cannot overflow. - */ - function sub(uint256 a, uint256 b) internal pure returns (uint256) { - return sub(a, b, "SafeMath: subtraction overflow"); - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting with custom message on - * overflow (when the result is negative). - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - Subtraction cannot overflow. - */ - function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b <= a, errorMessage); - uint256 c = a - b; - - return c; - } - - /** - * @dev Returns the multiplication of two unsigned integers, reverting on - * overflow. - * - * Counterpart to Solidity's `*` operator. - * - * Requirements: - * - Multiplication cannot overflow. - */ - function mul(uint256 a, uint256 b) internal pure returns (uint256) { - // Gas optimization: this is cheaper than requiring 'a' not being zero, but the - // benefit is lost if 'b' is also tested. - // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 - if (a == 0) { - return 0; - } - - uint256 c = a * b; - require(c / a == b, "SafeMath: multiplication overflow"); - - return c; - } - - /** - * @dev Returns the integer division of two unsigned integers. Reverts on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. Note: this function uses a - * `revert` opcode (which leaves remaining gas untouched) while Solidity - * uses an invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - return div(a, b, "SafeMath: division by zero"); - } - - /** - * @dev Returns the integer division of two unsigned integers. Reverts with custom message on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. Note: this function uses a - * `revert` opcode (which leaves remaining gas untouched) while Solidity - * uses an invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b > 0, errorMessage); - uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - - return c; - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * Reverts when dividing by zero. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function mod(uint256 a, uint256 b) internal pure returns (uint256) { - return mod(a, b, "SafeMath: modulo by zero"); - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * Reverts with custom message when dividing by zero. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b != 0, errorMessage); - return a % b; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/ShiftCommand001.sol b/framework/src/test/resources/soliditycode_0.5.15/ShiftCommand001.sol deleted file mode 100644 index 574ee2b571b..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/ShiftCommand001.sol +++ /dev/null @@ -1,18 +0,0 @@ -contract TestBitwiseShift { - - function shlTest(uint256 num, uint256 input) public returns (bytes32 out) { - assembly { - out := shl(num, input) - } - } - function shrTest(uint256 num, uint256 input) public returns (bytes32 out) { - assembly { - out := shr(num, input) - } - } - function sarTest(uint256 num, uint256 input) public returns (bytes32 out) { - assembly { - out := sar(num, input) - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/SolidityMappingFix.sol b/framework/src/test/resources/soliditycode_0.5.15/SolidityMappingFix.sol deleted file mode 100644 index 67692d3b4ae..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/SolidityMappingFix.sol +++ /dev/null @@ -1,9 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Tests { - mapping(address => uint) public balances; - function update(uint256 amount) public returns (address addr) - { - balances[msg.sender] = amount; - return msg.sender; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/TestMappings_array_pop.sol b/framework/src/test/resources/soliditycode_0.5.15/TestMappings_array_pop.sol deleted file mode 100644 index 3ceac916049..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TestMappings_array_pop.sol +++ /dev/null @@ -1,19 +0,0 @@ -contract C { - mapping (uint256 => uint256)[] a; - - function n1(uint256 key, uint256 value) public { - a.length++; - a[a.length - 1][key] = value; - } - - - - function map(uint256 key) public view returns (uint) { - return a[a.length - 1][key]; - } - - function p() public { - a.pop(); - } -} - diff --git a/framework/src/test/resources/soliditycode_0.5.15/TransferFailed001.sol b/framework/src/test/resources/soliditycode_0.5.15/TransferFailed001.sol deleted file mode 100644 index dba043edcb3..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TransferFailed001.sol +++ /dev/null @@ -1,147 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - - function testTransferTokenCompiledLongMax() payable public{ - address(0x1).transferToken(1,9223372036855775827); - } - - function testTransferTokenCompiled() payable public{ - address(0x1).transferToken(1,1); - } - - function testTransferTokenCompiledLongMin() payable public{ - //address(0x1).transferToken(1,-9223372036855775828); - } - - function testTransferTokenCompiledLongMin1() payable public returns(uint256){ - return address(0x2).tokenBalance(trcToken(-9223372036855775828)); - } - - function testTransferTokenCompiled1() payable public returns(uint256){ - return address(0x1).tokenBalance(trcToken(1)); - } - - function testTransferTokenCompiledLongMax1() payable public returns(uint256){ - return address(0x2).tokenBalance(trcToken(9223372036855775827)); - } - - function testTransferTokenCompiledTokenId(uint256 tokenid) payable public returns(uint256){ - return address(0x1).tokenBalance(trcToken(tokenid)); - } - - function testTransferTokenTest(address addr ,uint256 tokenid) payable public returns(uint256){ - return addr.tokenBalance(trcToken(tokenid)); - } - - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address payable caller) public { - caller.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller).value(i)(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - nonexistentTarget.send(i); - } - - function testSendTrxRevert(uint256 i,address payable nonexistentTarget) payable public { - nonexistentTarget.send(i); - revert(); - } - - function testTransferTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - nonexistentTarget.transfer(i); - } - - function testTransferTrxrevert(uint256 i,address payable nonexistentTarget) payable public{ - nonexistentTarget.transfer(i); - revert(); - } - - function testTransferTokenNonexistentTarget(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - nonexistentTarget.transferToken(i, tokenId); - } - - function testTransferTokenRevert(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - nonexistentTarget.transferToken(i, tokenId); - revert(); - } - - function testCallTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - nonexistentTarget.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - function testSuicideRevert(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - revert(); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - address payable self = address(uint160(address(this))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - address payable self = address(uint160(address(this))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - address payable self = address(uint160(address(this))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } - function deploy2(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(300, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/TransferFailed005.sol b/framework/src/test/resources/soliditycode_0.5.15/TransferFailed005.sol deleted file mode 100644 index aa39aafa152..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TransferFailed005.sol +++ /dev/null @@ -1,90 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address payable caller) public returns (bool,bytes memory){ - return caller.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller).value(i)(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.send(i); - } - - function testTransferTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.transfer(i); - } - - function testTransferTokenNonexistentTarget(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - require(address(this).balance >= i); - nonexistentTarget.transferToken(i, tokenId); - } - - function testCallTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256 ){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/TransferFailed006.sol b/framework/src/test/resources/soliditycode_0.5.15/TransferFailed006.sol deleted file mode 100644 index aa39aafa152..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TransferFailed006.sol +++ /dev/null @@ -1,90 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address payable caller) public returns (bool,bytes memory){ - return caller.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller).value(i)(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.send(i); - } - - function testTransferTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.transfer(i); - } - - function testTransferTokenNonexistentTarget(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - require(address(this).balance >= i); - nonexistentTarget.transferToken(i, tokenId); - } - - function testCallTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256 ){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/TransferFailed007.sol b/framework/src/test/resources/soliditycode_0.5.15/TransferFailed007.sol deleted file mode 100644 index aa39aafa152..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TransferFailed007.sol +++ /dev/null @@ -1,90 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address payable caller) public returns (bool,bytes memory){ - return caller.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller).value(i)(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.send(i); - } - - function testTransferTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.transfer(i); - } - - function testTransferTokenNonexistentTarget(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - require(address(this).balance >= i); - nonexistentTarget.transferToken(i, tokenId); - } - - function testCallTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256 ){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant001.sol b/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant001.sol deleted file mode 100644 index 515b9e07724..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant001.sol +++ /dev/null @@ -1,28 +0,0 @@ -//pragma solidity ^0.4.0; - -contract testConstantContract{ - uint256 public i; - function testPayable() public payable returns (uint256 z) { - i=1; - z=i; - return z; - } - function testNoPayable() public returns (uint256 z) { - i=1; - z=i; - return z; - } - function testView() public view returns (uint256 z) { - uint256 i=1; - return i; - } - function testPure() public pure returns (uint256 z) { - uint256 i=1; - return i; - } - function testView2() public view returns (uint256 z) { - uint256 i=1; - revert(); - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant002.sol b/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant002.sol deleted file mode 100644 index 44332e58c51..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant002.sol +++ /dev/null @@ -1,10 +0,0 @@ -//pragma solidity ^0.4.0; - -contract testConstantContract{ - uint256 public i; - function testNoPayable() public returns (uint256 z) { - i=1; - z=i; - return z; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant003.sol b/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant003.sol deleted file mode 100644 index 03e29fb76b6..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant003.sol +++ /dev/null @@ -1,18 +0,0 @@ -//pragma solidity ^0.4.0; - -contract testConstantContract{ - function testView() public view returns (uint256 z) { - uint256 i=1; - return i; - } - - function testPure() public pure returns (uint256 z) { - uint256 i=1; - return i; - } - - function testPayable() public payable returns (uint256 z) { - uint256 i=1; - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant004.sol b/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant004.sol deleted file mode 100644 index fce77178ca7..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant004.sol +++ /dev/null @@ -1,8 +0,0 @@ -//pragma solidity ^0.4.0; - -contract testConstantContract{ -function testPure() public pure returns (uint256 z) { -uint256 i=1; -return i; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant015.sol b/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant015.sol deleted file mode 100644 index d926c43c824..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant015.sol +++ /dev/null @@ -1,24 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract TestConstract { - constructor () public { - } - function plusOne() public returns(uint){ - return 1; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant024.sol b/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant024.sol deleted file mode 100644 index 287b0fc9782..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TriggerConstant024.sol +++ /dev/null @@ -1,9 +0,0 @@ -//pragma solidity ^0.4.0; - -contract testConstantContract{ -function testView() public view returns (uint256 z) { -uint256 i=1; -revert(); -return i; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/TvmIsContract.sol b/framework/src/test/resources/soliditycode_0.5.15/TvmIsContract.sol deleted file mode 100644 index 4266b9e92ca..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TvmIsContract.sol +++ /dev/null @@ -1,15 +0,0 @@ -contract testIsContract{ -bool public isContrct; -constructor () public { - isContrct = address(this).isContract; -} -function testIsContractCommand(address a) public returns (bool) { -return (a.isContract); -} -function selfdestructContract(address payable a) public { - selfdestruct(a); -} -function testConstructor() public returns(bool){ - return isContrct; -} -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/TvmIsContract001.sol b/framework/src/test/resources/soliditycode_0.5.15/TvmIsContract001.sol deleted file mode 100644 index 77aae930b59..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TvmIsContract001.sol +++ /dev/null @@ -1,24 +0,0 @@ -contract testIsContract{ -bool public isContrct; -constructor () public { - isContrct = address(this).isContract; -} -function testIsContractCommand(address a) public returns (bool) { -return (a.isContract); -} - -function testIsContractView(address a) view public returns (bool) { -return (a.isContract); -} - -function selfdestructContract(address payable a) public { - selfdestruct(a); -} -function testConstructor() public returns(bool){ - return isContrct; -} - -function testConstructorView() public view returns(bool){ - return isContrct; -} -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/TvmIsContract002.sol b/framework/src/test/resources/soliditycode_0.5.15/TvmIsContract002.sol deleted file mode 100644 index 2fe474fd98c..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TvmIsContract002.sol +++ /dev/null @@ -1,5 +0,0 @@ -contract testIsContract{ -function testIsContractCommand(address a) public returns (bool) { -return (a.isContract); -} -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand043.sol b/framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand043.sol deleted file mode 100644 index 04d9f7dde28..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand043.sol +++ /dev/null @@ -1,18 +0,0 @@ -contract TestBitwiseShift { - - function shlTest(int256 num, int256 input) public returns (bytes32 out) { - assembly { - out := shl(num, input) - } - } - function shrTest(int256 num, int256 input) public returns (bytes32 out) { - assembly { - out := shr(num, input) - } - } - function sarTest(int256 num, int256 input) public returns (bytes32 out) { - assembly { - out := sar(num, input) - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand103.sol b/framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand103.sol deleted file mode 100644 index 7ad130c87c6..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand103.sol +++ /dev/null @@ -1,8 +0,0 @@ -//pragma solidity ^0.4.0; - -contract testConstantContract{ -function testView() public constant returns (uint256 z) { -uint256 i=1; -return i; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand107.sol b/framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand107.sol deleted file mode 100644 index 4dcd33ad7b0..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand107.sol +++ /dev/null @@ -1,9 +0,0 @@ -//pragma solidity ^0.4.0; - - contract testConstantContract{ - int256 public i; - function testPayable() public returns (int z) { - z=1+1; - return z; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand108.sol b/framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand108.sol deleted file mode 100644 index b44d5c82731..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand108.sol +++ /dev/null @@ -1,7 +0,0 @@ -//pragma solidity ^0.4.0; - - contract testConstantContract{ - function test() pure public returns (int z) { - return 1; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand109.sol b/framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand109.sol deleted file mode 100644 index 864f01f7fb4..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TvmNewCommand109.sol +++ /dev/null @@ -1,7 +0,0 @@ -//pragma solidity ^0.4.0; - - contract testConstantContract{ - function test() view public returns (int z) { - return 1; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/TvmOldCommand001.sol b/framework/src/test/resources/soliditycode_0.5.15/TvmOldCommand001.sol deleted file mode 100644 index 9f3cf079ea1..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/TvmOldCommand001.sol +++ /dev/null @@ -1,11 +0,0 @@ -//pragma solidity ^0.4.0; - -contract binaryRightContract{ - function binaryMoveR(int i)public returns (int z) { - return z = 5 >> i; - } - function binaryLiftR(int i)public returns (int z) { - return z = 5 << i; - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/VerifyBurnProof001.sol b/framework/src/test/resources/soliditycode_0.5.15/VerifyBurnProof001.sol deleted file mode 100644 index 4173e84de23..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/VerifyBurnProof001.sol +++ /dev/null @@ -1,20 +0,0 @@ - -contract VerifyBurnProof001Test { - // verifyBurnProof(bytes32[10],bytes32[2],uint64,bytes32[2],bytes32) - // size = 512 - // - - function VerifyBurnProofSize001(bytes32[10] memory output, bytes32[2] memory spendAuthoritySignature, uint64 value, bytes32[2] memory bindingSignature,bytes32 signHash) public returns (bool){ - return verifyBurnProof(output, spendAuthoritySignature, value, bindingSignature, signHash); - } - - function VerifyBurnProofSize002(bytes memory data) public returns (bool, bytes memory){ - // bytes memory empty = ""; - return address(0x1000003).delegatecall(data); - } - - function VerifyBurnProofSize003() public returns (bool, bytes memory){ - bytes memory empty = ""; - return address(0x1000003).delegatecall(empty); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/VerifyMintProof001.sol b/framework/src/test/resources/soliditycode_0.5.15/VerifyMintProof001.sol deleted file mode 100644 index cb0812c2ef5..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/VerifyMintProof001.sol +++ /dev/null @@ -1,33 +0,0 @@ - -contract VerifyMintProof001Test { - // verifyMintProof(bytes32[9],bytes32[2],uint64,bytes32,bytes32[33],uint256) - - function VerifyMintProofSize001(bytes32[9] memory output, bytes32[2] memory bindingSignature, uint64 value, bytes32 signHash, bytes32[33] memory frontier,uint256 leafCount) public returns (bytes32[] memory){ - return verifyMintProof(output, bindingSignature, value, signHash, frontier, leafCount); - } - - function VerifyMintProofSize002(bytes memory data) public returns (bool, bytes memory){ -// address verifyMint = address (0x1000001); -// -// assembly { -// let succeeded := delegatecall(sub(gas, 5000), verifyMint, add(data, 0x20), mload(data), 0, 0) -// let size := returndatasize -// let response := mload(0x40) -// mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f)))) -// mstore(response, size) -// returndatacopy(add(response, 0x20), 0, size) -// switch iszero(succeeded) -// case 1 { -// // throw if delegatecall failed -// revert(add(response, 0x20), size) -// } -// } - - return address(0x1000001).delegatecall(data); - } - - function VerifyMintProofSize003() public returns (bool, bytes memory){ - bytes memory empty = ""; - return address(0x1000001).call(empty); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/abiencode.sol b/framework/src/test/resources/soliditycode_0.5.15/abiencode.sol deleted file mode 100644 index 38fad3454d6..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/abiencode.sol +++ /dev/null @@ -1,16 +0,0 @@ -pragma experimental ABIEncoderV2; - -// tests encoding from storage arrays - -contract AbiEncode { - int256[2][] tmp_h; - function h(int256[2][] calldata s) external returns (bytes memory) { - tmp_h = s; - return abi.encode(tmp_h); - } - int256[2][2] tmp_i; - function i(int256[2][2] calldata s) external returns (bytes memory) { - tmp_i = s; - return abi.encode(tmp_i); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/addMsg001Nonpayable.sol b/framework/src/test/resources/soliditycode_0.5.15/addMsg001Nonpayable.sol deleted file mode 100644 index d1294f2336a..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/addMsg001Nonpayable.sol +++ /dev/null @@ -1,20 +0,0 @@ -//pragma solidity ^0.4.24; - -contract IllegalDecorate { - -event log(uint256); -constructor() payable public{} - -function() payable external{} - -function transferTokenWithOutPayable(address payable toAddress, uint256 tokenValue)public { -// function transferTokenWithValue(address toAddress, uint256 tokenValue) payable public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); - -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/addMsg002View.sol b/framework/src/test/resources/soliditycode_0.5.15/addMsg002View.sol deleted file mode 100644 index 423bb68e3ed..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/addMsg002View.sol +++ /dev/null @@ -1,20 +0,0 @@ -//pragma solidity ^0.4.24; - -contract IllegalDecorate { - -constructor() payable public{} - -function() payable external{} - -event log(uint256); - -function transferTokenWithView(address payable toAddress, uint256 tokenValue) public view{ -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} - diff --git a/framework/src/test/resources/soliditycode_0.5.15/addMsg003Constant.sol b/framework/src/test/resources/soliditycode_0.5.15/addMsg003Constant.sol deleted file mode 100644 index 0f0ab7553e0..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/addMsg003Constant.sol +++ /dev/null @@ -1,19 +0,0 @@ -//pragma solidity ^0.4.24; - -contract IllegalDecorate { - -constructor() payable public{} - -function() payable external{} - -event log(uint256); - -function transferTokenWithConstant(address payable toAddress, uint256 tokenValue) public constant{ -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/addMsg004Pure.sol b/framework/src/test/resources/soliditycode_0.5.15/addMsg004Pure.sol deleted file mode 100644 index b5d3a4e4aee..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/addMsg004Pure.sol +++ /dev/null @@ -1,19 +0,0 @@ -//pragma solidity ^0.4.24; - -contract IllegalDecorate { - -constructor() payable public{} - -function() payable external{} - -event log(uint256); - -function transferTokenWithPure(address payable toAddress, uint256 tokenValue) public pure{ -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/addTransferToken001Nonpayable.sol b/framework/src/test/resources/soliditycode_0.5.15/addTransferToken001Nonpayable.sol deleted file mode 100644 index c8d0dcc7560..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/addTransferToken001Nonpayable.sol +++ /dev/null @@ -1,13 +0,0 @@ -//pragma solidity ^0.4.24; - - contract IllegalDecorate { - - constructor() payable public{} - - function() payable external{} - - function transferTokenWithOutPayable(address payable toAddress,trcToken id, uint256 tokenValue)public { - - toAddress.transferToken(tokenValue, id); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/addTransferToken001payable.sol b/framework/src/test/resources/soliditycode_0.5.15/addTransferToken001payable.sol deleted file mode 100644 index 803d66ad75e..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/addTransferToken001payable.sol +++ /dev/null @@ -1,13 +0,0 @@ -//pragma solidity ^0.4.24; - - contract IllegalDecorate { - - constructor() payable public{} - - function() payable external{} - - function transferTokenWithOutPayable(address payable toAddress,trcToken id, uint256 tokenValue) public payable{ - - toAddress.transferToken(tokenValue, id); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/addTransferToken002View.sol b/framework/src/test/resources/soliditycode_0.5.15/addTransferToken002View.sol deleted file mode 100644 index 109f46386ce..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/addTransferToken002View.sol +++ /dev/null @@ -1,15 +0,0 @@ -//pragma solidity ^0.4.24; - -contract IllegalDecorate { - - constructor() payable public{} - - function() payable external{} - - function transferTokenWithView(address payable toAddress,trcToken id, uint256 tokenValue) public view{ - - toAddress.transferToken(tokenValue, id); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/addTransferToken003Constant.sol b/framework/src/test/resources/soliditycode_0.5.15/addTransferToken003Constant.sol deleted file mode 100644 index fb1a2cbbbb4..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/addTransferToken003Constant.sol +++ /dev/null @@ -1,15 +0,0 @@ -//pragma solidity ^0.4.24; - -contract IllegalDecorate { - - constructor() payable public{} - - function() payable external{} - - function transferTokenWithConstant(address payable toAddress, uint256 tokenValue) public constant{ - - toAddress.transferToken(tokenValue, 0x6e6d62); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/addTransferToken004Pure.sol b/framework/src/test/resources/soliditycode_0.5.15/addTransferToken004Pure.sol deleted file mode 100644 index 7ea2bf0a40b..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/addTransferToken004Pure.sol +++ /dev/null @@ -1,15 +0,0 @@ -//pragma solidity ^0.4.24; - -contract IllegalDecorate { - - constructor() payable public{} - - function() payable external{} - - function transferTokenWithPure(address payable toAddress, uint256 tokenValue) public pure{ - - toAddress.transferToken(tokenValue, 0x6e6d62); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/addTrcToken001Assemble.sol b/framework/src/test/resources/soliditycode_0.5.15/addTrcToken001Assemble.sol deleted file mode 100644 index a93d9046a3f..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/addTrcToken001Assemble.sol +++ /dev/null @@ -1,62 +0,0 @@ -//pragma solidity ^0.4.24; - -contract InAssemble { - -mapping(trcToken => uint256) tokenCnt; -mapping(uint256 => mapping(trcToken => trcToken)) cntTokenToken; -constructor () payable public {} -function getBalance (address addr) view public returns(uint256 r) { -assembly{ -r := balance(addr) -} -} - -function getTokenBalanceConstant (address addr, trcToken tokenId) view public returns(uint256 r) { -assembly{ -r := tokenbalance(tokenId, addr) -} -} - -function getTokenBalance (address addr, trcToken tokenId) public returns(uint256 r) { -assembly{ -r := tokenbalance(tokenId, addr) -} -} - -function transferTokenInAssembly(address addr, trcToken tokenId, uint256 tokenValue) public payable { -bytes4 sig = bytes4(keccak256("()")); // function signature - -assembly { -let x := mload(0x40) // get empty storage location -mstore(x,sig) // 4 bytes - place signature in empty storage - -let ret := calltoken(gas, addr, tokenValue, tokenId, -x, // input -0x04, // input size = 4 bytes -x, // output stored at input location, save space -0x0 // output size = 0 bytes -) - -// let ret := calltoken(gas, addr, tokenValue, -// x, // input -// 0x04, // input size = 4 bytes -// x, // output stored at input location, save space -// 0x0 // output size = 0 bytes -// ) // ERROR - - -mstore(0x40, add(x,0x20)) // update free memory pointer -} - -} - -function trcTokenInMap(trcToken tokenId, uint256 tokenValue) public returns(uint256 r) { -tokenCnt[tokenId] += tokenValue; -r = tokenCnt[tokenId]; -} - -function cntTokenTokenInMap(trcToken tokenId1, trcToken tokenId2, uint256 tokenValue) public returns(trcToken r) { -cntTokenToken[tokenValue][tokenId1] = tokenId2; -r = cntTokenToken[tokenValue][tokenId1]; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/addTrcToken002Cat.sol b/framework/src/test/resources/soliditycode_0.5.15/addTrcToken002Cat.sol deleted file mode 100644 index 6d9c169330d..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/addTrcToken002Cat.sol +++ /dev/null @@ -1,2051 +0,0 @@ -//pragma solidity ^0.4.11; - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) public onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address payable public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address payable _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() public onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - emit Transfer(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(now), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - uint256 newKittenId = kitties.push(_kitty) - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - emit Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(address(0), _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -contract ERC721 { - // Required methods - function totalSupply() public view returns (uint256 total); - function balanceOf(address _owner) public view returns (uint256 balance); - function ownerOf(uint256 _tokenId) external view returns (address owner); - function approve(address _to, uint256 _tokenId) external; - function transfer(address _to, uint256 _tokenId) external; - function transferFrom(address _from, address _to, uint256 _tokenId) external; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) external view returns (bool); -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is ERC721, KittyBase { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public view returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - emit Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() public view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - external - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] memory _rawBytes, uint256 _stringLength) private view returns (string memory) { - string memory outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string calldata _preferredTransport) external view returns (string memory infoUrl) { - require( address(erc721Metadata) != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2 sun; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty memory _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty memory _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - emit Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.transfer(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, address(saleAuction)); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, address(siringAuction)); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid.value(msg.value - autoBirthFee)(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10 sun; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, address(saleAuction)); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(uint160(address(this))) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - constructor() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - emit ContractUpgrade(_v2Address); - } - - /// @notice No tipping! - /// @dev Reject all Ether from being sent here, unless it's from one of the - /// two auction contracts. (Hopefully, we can prevent user accidents.) - function() external payable { - require( - msg.sender == address(saleAuction) || - msg.sender == address(siringAuction) - ); - } - - /// @notice Returns all the relevant information about a specific kitty. - /// @param _id The ID of the kitty of interest. - function getKitty(uint256 _id) - external - view - returns ( - bool isGestating, - bool isReady, - uint256 cooldownIndex, - uint256 nextActionAt, - uint256 siringWithId, - uint256 birthTime, - uint256 matronId, - uint256 sireId, - uint256 generation, - uint256 genes - ) { - Kitty storage kit = kitties[_id]; - - // if this variable is 0 then it's not gestating - isGestating = (kit.siringWithId != 0); - isReady = (kit.cooldownEndBlock <= block.number); - cooldownIndex = uint256(kit.cooldownIndex); - nextActionAt = uint256(kit.cooldownEndBlock); - siringWithId = uint256(kit.siringWithId); - birthTime = uint256(kit.birthTime); - matronId = uint256(kit.matronId); - sireId = uint256(kit.sireId); - generation = uint256(kit.generation); - genes = kit.genes; - } - - /// @dev Override unpause so it requires all external contract addresses - /// to be set before contract can be unpaused. Also, we can't have - /// newContractAddress set either, because then the contract was upgraded. - /// @notice This is public rather than external so we can call super.unpause - /// without using an expensive CALL. - - function unpause(address payable toAddress, uint256 tokenValue, trcToken tokenId) public onlyCEO whenPaused returns (uint256 r) { - require(address(saleAuction) != address(0)); - require(address(siringAuction) != address(0)); - require(address(geneScience) != address(0)); - require(address(newContractAddress) == address(0)); - toAddress.transferToken(tokenValue, tokenId); - r = address(this).tokenBalance(tokenId); - // Actually unpause the contract. - super.unpause(); - } - - // @dev Allows the CFO to capture the balance available to the contract. - function withdrawBalance() external onlyCFO { - uint256 balance = address(this).balance; - // Subtract all the currently pregnant kittens we have, plus 1 of margin. - uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - - if (balance > subtractFees) { - cfoAddress.transfer(balance - subtractFees); - } - } -} - - - - - - - - - - - - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - - function isGeneScience() public pure returns (bool){ - return true; - } - - /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor - /// @param genes1 genes of mom - /// @param genes2 genes of sire - /// @return the genes that are supposed to be passed down the child - function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - - return (genes1+genes2+targetBlock)/2; - - -} -} - - - - - - - - - - - - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { - /// @dev Given a token Id, returns a byte array that is supposed to be converted into string. - function getMetadata(uint256 _tokenId, string memory) public view returns (bytes32[4] memory buffer, uint256 count) { - if (_tokenId == 1) { - buffer[0] = "Hello World! :D"; - count = 15; - } else if (_tokenId == 2) { - buffer[0] = "I would definitely choose a medi"; - buffer[1] = "um length string."; - count = 49; - } else if (_tokenId == 3) { - buffer[0] = "Lorem ipsum dolor sit amet, mi e"; - buffer[1] = "st accumsan dapibus augue lorem,"; - buffer[2] = " tristique vestibulum id, libero"; - buffer[3] = " suscipit varius sapien aliquam."; - count = 128; - } - } -} - - - - - - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - - // Represents an auction on an NFT - struct Auction { - // Current owner of NFT - address payable seller; - // Price (in wei) at beginning of auction - uint128 startingPrice; - // Price (in wei) at end of auction - uint128 endingPrice; - // Duration (in seconds) of auction - uint64 duration; - // Time when auction started - // NOTE: 0 if this auction has been concluded - uint64 startedAt; - } - - // Reference to contract tracking NFT ownership - ERC721 public nonFungibleContract; - - // Cut owner takes on each auction, measured in basis points (1/100 of a percent). - // Values 0-10,000 map to 0%-100% - uint256 public ownerCut; - - // Map from token ID to their corresponding auction. - mapping (uint256 => Auction) tokenIdToAuction; - - event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); - event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); - event AuctionCancelled(uint256 tokenId); - - /// @dev Returns true if the claimant owns the token. - /// @param _claimant - Address claiming to own the token. - /// @param _tokenId - ID of token whose ownership to verify. - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return (nonFungibleContract.ownerOf(_tokenId) == _claimant); - } - - /// @dev Escrows the NFT, assigning ownership to this contract. - /// Throws if the escrow fails. - /// @param _owner - Current owner address of token to escrow. - /// @param _tokenId - ID of token whose approval to verify. - function _escrow(address _owner, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transferFrom(_owner, address(this), _tokenId); - } - - /// @dev Transfers an NFT owned by this contract to another address. - /// Returns true if the transfer succeeds. - /// @param _receiver - Address to transfer NFT to. - /// @param _tokenId - ID of token to transfer. - function _transfer(address _receiver, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transfer(_receiver, _tokenId); - } - - /// @dev Adds an auction to the list of open auctions. Also fires the - /// AuctionCreated event. - /// @param _tokenId The ID of the token to be put on auction. - /// @param _auction Auction to add. - function _addAuction(uint256 _tokenId, Auction memory _auction) internal { - // Require that all auctions have a duration of - // at least one minute. (Keeps our math from getting hairy!) - require(_auction.duration >= 1 minutes); - - tokenIdToAuction[_tokenId] = _auction; - - emit AuctionCreated( - uint256(_tokenId), - uint256(_auction.startingPrice), - uint256(_auction.endingPrice), - uint256(_auction.duration) - ); - } - - /// @dev Cancels an auction unconditionally. - function _cancelAuction(uint256 _tokenId, address _seller) internal { - _removeAuction(_tokenId); - _transfer(_seller, _tokenId); - emit AuctionCancelled(_tokenId); - } - - /// @dev Computes the price and transfers winnings. - /// Does NOT transfer ownership of token. - function _bid(uint256 _tokenId, uint256 _bidAmount) - internal - returns (uint256) - { - // Get a reference to the auction struct - Auction storage auction = tokenIdToAuction[_tokenId]; - - // Explicitly check that this auction is currently live. - // (Because of how Ethereum mappings work, we can't just count - // on the lookup above failing. An invalid _tokenId will just - // return an auction object that is all zeros.) - require(_isOnAuction(auction)); - - // Check that the bid is greater than or equal to the current price - uint256 price = _currentPrice(auction); - require(_bidAmount >= price); - - // Grab a reference to the seller before the auction struct - // gets deleted. - address payable seller = auction.seller; - - // The bid is good! Remove the auction before sending the fees - // to the sender so we can't have a reentrancy attack. - _removeAuction(_tokenId); - - // Transfer proceeds to seller (if there are any!) - if (price > 0) { - // Calculate the auctioneer's cut. - // (NOTE: _computeCut() is guaranteed to return a - // value <= price, so this subtraction can't go negative.) - uint256 auctioneerCut = _computeCut(price); - uint256 sellerProceeds = price - auctioneerCut; - - // NOTE: Doing a transfer() in the middle of a complex - // method like this is generally discouraged because of - // reentrancy attacks and DoS attacks if the seller is - // a contract with an invalid fallback function. We explicitly - // guard against reentrancy attacks by removing the auction - // before calling transfer(), and the only thing the seller - // can DoS is the sale of their own asset! (And if it's an - // accident, they can call cancelAuction(). ) - seller.transfer(sellerProceeds); - } - - // Calculate any excess funds included with the bid. If the excess - // is anything worth worrying about, transfer it back to bidder. - // NOTE: We checked above that the bid amount is greater than or - // equal to the price so this cannot underflow. - uint256 bidExcess = _bidAmount - price; - - // Return the funds. Similar to the previous transfer, this is - // not susceptible to a re-entry attack because the auction is - // removed before any transfers occur. - msg.sender.transfer(bidExcess); - - // Tell the world! - emit AuctionSuccessful(_tokenId, price, msg.sender); - - return price; - } - - /// @dev Removes an auction from the list of open auctions. - /// @param _tokenId - ID of NFT on auction. - function _removeAuction(uint256 _tokenId) internal { - delete tokenIdToAuction[_tokenId]; - } - - /// @dev Returns true if the NFT is on auction. - /// @param _auction - Auction to check. - function _isOnAuction(Auction storage _auction) internal view returns (bool) { - return (_auction.startedAt > 0); - } - - /// @dev Returns current price of an NFT on auction. Broken into two - /// functions (this one, that computes the duration from the auction - /// structure, and the other that does the price computation) so we - /// can easily test that the price computation works correctly. - function _currentPrice(Auction storage _auction) - internal - view - returns (uint256) - { - uint256 secondsPassed = 0; - - // A bit of insurance against negative values (or wraparound). - // Probably not necessary (since Ethereum guarnatees that the - // now variable doesn't ever go backwards). - if (now > _auction.startedAt) { - secondsPassed = now - _auction.startedAt; - } - - return _computeCurrentPrice( - _auction.startingPrice, - _auction.endingPrice, - _auction.duration, - secondsPassed - ); - } - - /// @dev Computes the current price of an auction. Factored out - /// from _currentPrice so we can run extensive unit tests. - /// When testing, make this function public and turn on - /// `Current price computation` test suite. - function _computeCurrentPrice( - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - uint256 _secondsPassed - ) - internal - pure - returns (uint256) - { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our public functions carefully cap the maximum values for - // time (at 64-bits) and currency (at 128-bits). _duration is - // also known to be non-zero (see the require() statement in - // _addAuction()) - if (_secondsPassed >= _duration) { - // We've reached the end of the dynamic pricing portion - // of the auction, just return the end price. - return _endingPrice; - } else { - // Starting price can be higher than ending price (and often is!), so - // this delta can be negative. - int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - - // This multiplication can't overflow, _secondsPassed will easily fit within - // 64-bits, and totalPriceChange will easily fit within 128-bits, their product - // will always fit within 256-bits. - int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - - // currentPriceChange can be negative, but if so, will have a magnitude - // less that _startingPrice. Thus, this result will always end up positive. - int256 currentPrice = int256(_startingPrice) + currentPriceChange; - - return uint256(currentPrice); - } - } - - /// @dev Computes owner's cut of a sale. - /// @param _price - Sale price of NFT. - function _computeCut(uint256 _price) internal view returns (uint256) { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our entry functions carefully cap the maximum values for - // currency (at 128-bits), and ownerCut <= 10000 (see the require() - // statement in the ClockAuction constructor). The result of this - // function is always guaranteed to be <= _price. - return _price * ownerCut / 10000; - } - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { - event Pause(); - event Unpause(); - - bool public paused = false; - - - /** - * @dev modifier to allow actions only when the contract IS paused - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev modifier to allow actions only when the contract IS NOT paused - */ - modifier whenPaused { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyOwner whenNotPaused public returns (bool) { - paused = true; - emit Pause(); - return true; - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyOwner whenPaused public returns (bool) { - paused = false; - emit Unpause(); - return true; - } -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - - /// @dev The ERC-165 interface signature for ERC-721. - /// Ref: https://github.com/ethereum/EIPs/issues/165 - /// Ref: https://github.com/ethereum/EIPs/issues/721 - bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - - /// @dev Constructor creates a reference to the NFT ownership contract - /// and verifies the owner cut is in the valid range. - /// @param _nftAddress - address of a deployed contract implementing - /// the Nonfungible Interface. - /// @param _cut - percent cut the owner takes on each auction, must be - /// between 0-10,000. - constructor(address _nftAddress, uint256 _cut) public { - require(_cut <= 10000); - ownerCut = _cut; - - ERC721 candidateContract = ERC721(_nftAddress); - require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); - nonFungibleContract = candidateContract; - } - - /// @dev Remove all Ether from the contract, which is the owner's cuts - /// as well as any Ether sent directly to the contract address. - /// Always transfers to the NFT contract, but can be called either by - /// the owner or the NFT contract. - function withdrawBalance() external { - address payable nftAddress = address(uint160(address(nonFungibleContract))); - - require( - msg.sender == owner || - msg.sender == nftAddress - ); - // We are using this boolean method to make sure that even if one fails it will still work - bool res = nftAddress.send(address(this).balance); - } - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of time to move between starting - /// price and ending price (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - whenNotPaused - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(_owns(msg.sender, _tokenId)); - _escrow(msg.sender, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Bids on an open auction, completing the auction and transferring - /// ownership of the NFT if enough Ether is supplied. - /// @param _tokenId - ID of token to bid on. - function bid(uint256 _tokenId) - external - payable - whenNotPaused - { - // _bid will throw if the bid or funds transfer fails - _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - } - - /// @dev Cancels an auction that hasn't been won yet. - /// Returns the NFT to original owner. - /// @notice This is a state-modifying function that can - /// be called while the contract is paused. - /// @param _tokenId - ID of token on auction - function cancelAuction(uint256 _tokenId) - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - address seller = auction.seller; - require(msg.sender == seller); - _cancelAuction(_tokenId, seller); - } - - /// @dev Cancels an auction when the contract is paused. - /// Only the owner may do this, and NFTs are returned to - /// the seller. This should only be used in emergencies. - /// @param _tokenId - ID of the NFT on auction to cancel. - function cancelAuctionWhenPaused(uint256 _tokenId) - whenPaused - onlyOwner - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - _cancelAuction(_tokenId, auction.seller); - } - - /// @dev Returns auction info for an NFT on auction. - /// @param _tokenId - ID of NFT on auction. - function getAuction(uint256 _tokenId) - external - view - returns - ( - address seller, - uint256 startingPrice, - uint256 endingPrice, - uint256 duration, - uint256 startedAt - ) { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return ( - auction.seller, - auction.startingPrice, - auction.endingPrice, - auction.duration, - auction.startedAt - ); - } - - /// @dev Returns the current price of an auction. - /// @param _tokenId - ID of the token price we are checking. - function getCurrentPrice(uint256 _tokenId) - external - view - returns (uint256) - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return _currentPrice(auction); - } - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSiringAuctionAddress() call. - bool public isSiringClockAuction = true; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. Since this function is wrapped, - /// require sender to be KittyCore contract. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Places a bid for siring. Requires the sender - /// is the KittyCore contract because all bid methods - /// should be wrapped. Also returns the kitty to the - /// seller rather than the winner. - function bid(uint256 _tokenId) - external - payable - { - require(msg.sender == address(nonFungibleContract)); - address seller = tokenIdToAuction[_tokenId].seller; - // _bid checks that token ID is valid and will throw if bid fails - _bid(_tokenId, msg.value); - // We transfer the kitty back to the seller, the winner will get - // the offspring - _transfer(seller, _tokenId); - } - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSaleAuctionAddress() call. - bool public isSaleClockAuction = true; - - // Tracks last 5 sale price of gen0 kitty sales - uint256 public gen0SaleCount; - uint256[5] public lastGen0SalePrices; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Updates lastSalePrice if seller is the nft contract - /// Otherwise, works the same as default bid method. - function bid(uint256 _tokenId) - external - payable - { - // _bid verifies token ID size - address seller = tokenIdToAuction[_tokenId].seller; - uint256 price = _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - - // If not a gen0 auction, exit - if (seller == address(nonFungibleContract)) { - // Track gen0 sale prices - lastGen0SalePrices[gen0SaleCount % 5] = price; - gen0SaleCount++; - } - } - - function averageGen0SalePrice() external view returns (uint256) { - uint256 sum = 0; - for (uint256 i = 0; i < 5; i++) { - sum += lastGen0SalePrices[i]; - } - return sum / 5; - } - -} - - - - - - - diff --git a/framework/src/test/resources/soliditycode_0.5.15/addTrcToken002Cat_withFinny.sol b/framework/src/test/resources/soliditycode_0.5.15/addTrcToken002Cat_withFinny.sol deleted file mode 100644 index 2acebceddda..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/addTrcToken002Cat_withFinny.sol +++ /dev/null @@ -1,2051 +0,0 @@ -//pragma solidity ^0.4.11; - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) public onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address payable public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address payable _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() public onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - emit Transfer(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(now), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - uint256 newKittenId = kitties.push(_kitty) - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - emit Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(address(0), _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -contract ERC721 { - // Required methods - function totalSupply() public view returns (uint256 total); - function balanceOf(address _owner) public view returns (uint256 balance); - function ownerOf(uint256 _tokenId) external view returns (address owner); - function approve(address _to, uint256 _tokenId) external; - function transfer(address _to, uint256 _tokenId) external; - function transferFrom(address _from, address _to, uint256 _tokenId) external; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) external view returns (bool); -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is ERC721, KittyBase { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public view returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - emit Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() public view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - external - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] memory _rawBytes, uint256 _stringLength) private view returns (string memory) { - string memory outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string calldata _preferredTransport) external view returns (string memory infoUrl) { - require( address(erc721Metadata) != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2 finney; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty memory _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty memory _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - emit Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.transfer(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, address(saleAuction)); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, address(siringAuction)); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid.value(msg.value - autoBirthFee)(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10 finney; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, address(saleAuction)); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(uint160(address(this))) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - constructor() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - emit ContractUpgrade(_v2Address); - } - - /// @notice No tipping! - /// @dev Reject all Ether from being sent here, unless it's from one of the - /// two auction contracts. (Hopefully, we can prevent user accidents.) - function() external payable { - require( - msg.sender == address(saleAuction) || - msg.sender == address(siringAuction) - ); - } - - /// @notice Returns all the relevant information about a specific kitty. - /// @param _id The ID of the kitty of interest. - function getKitty(uint256 _id) - external - view - returns ( - bool isGestating, - bool isReady, - uint256 cooldownIndex, - uint256 nextActionAt, - uint256 siringWithId, - uint256 birthTime, - uint256 matronId, - uint256 sireId, - uint256 generation, - uint256 genes - ) { - Kitty storage kit = kitties[_id]; - - // if this variable is 0 then it's not gestating - isGestating = (kit.siringWithId != 0); - isReady = (kit.cooldownEndBlock <= block.number); - cooldownIndex = uint256(kit.cooldownIndex); - nextActionAt = uint256(kit.cooldownEndBlock); - siringWithId = uint256(kit.siringWithId); - birthTime = uint256(kit.birthTime); - matronId = uint256(kit.matronId); - sireId = uint256(kit.sireId); - generation = uint256(kit.generation); - genes = kit.genes; - } - - /// @dev Override unpause so it requires all external contract addresses - /// to be set before contract can be unpaused. Also, we can't have - /// newContractAddress set either, because then the contract was upgraded. - /// @notice This is public rather than external so we can call super.unpause - /// without using an expensive CALL. - - function unpause(address payable toAddress, uint256 tokenValue, trcToken tokenId) public onlyCEO whenPaused returns (uint256 r) { - require(address(saleAuction) != address(0)); - require(address(siringAuction) != address(0)); - require(address(geneScience) != address(0)); - require(address(newContractAddress) == address(0)); - toAddress.transferToken(tokenValue, tokenId); - r = address(this).tokenBalance(tokenId); - // Actually unpause the contract. - super.unpause(); - } - - // @dev Allows the CFO to capture the balance available to the contract. - function withdrawBalance() external onlyCFO { - uint256 balance = address(this).balance; - // Subtract all the currently pregnant kittens we have, plus 1 of margin. - uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - - if (balance > subtractFees) { - cfoAddress.transfer(balance - subtractFees); - } - } -} - - - - - - - - - - - - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - - function isGeneScience() public pure returns (bool){ - return true; - } - - /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor - /// @param genes1 genes of mom - /// @param genes2 genes of sire - /// @return the genes that are supposed to be passed down the child - function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - - return (genes1+genes2+targetBlock)/2; - - -} -} - - - - - - - - - - - - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { - /// @dev Given a token Id, returns a byte array that is supposed to be converted into string. - function getMetadata(uint256 _tokenId, string memory) public view returns (bytes32[4] memory buffer, uint256 count) { - if (_tokenId == 1) { - buffer[0] = "Hello World! :D"; - count = 15; - } else if (_tokenId == 2) { - buffer[0] = "I would definitely choose a medi"; - buffer[1] = "um length string."; - count = 49; - } else if (_tokenId == 3) { - buffer[0] = "Lorem ipsum dolor sit amet, mi e"; - buffer[1] = "st accumsan dapibus augue lorem,"; - buffer[2] = " tristique vestibulum id, libero"; - buffer[3] = " suscipit varius sapien aliquam."; - count = 128; - } - } -} - - - - - - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - - // Represents an auction on an NFT - struct Auction { - // Current owner of NFT - address payable seller; - // Price (in wei) at beginning of auction - uint128 startingPrice; - // Price (in wei) at end of auction - uint128 endingPrice; - // Duration (in seconds) of auction - uint64 duration; - // Time when auction started - // NOTE: 0 if this auction has been concluded - uint64 startedAt; - } - - // Reference to contract tracking NFT ownership - ERC721 public nonFungibleContract; - - // Cut owner takes on each auction, measured in basis points (1/100 of a percent). - // Values 0-10,000 map to 0%-100% - uint256 public ownerCut; - - // Map from token ID to their corresponding auction. - mapping (uint256 => Auction) tokenIdToAuction; - - event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); - event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); - event AuctionCancelled(uint256 tokenId); - - /// @dev Returns true if the claimant owns the token. - /// @param _claimant - Address claiming to own the token. - /// @param _tokenId - ID of token whose ownership to verify. - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return (nonFungibleContract.ownerOf(_tokenId) == _claimant); - } - - /// @dev Escrows the NFT, assigning ownership to this contract. - /// Throws if the escrow fails. - /// @param _owner - Current owner address of token to escrow. - /// @param _tokenId - ID of token whose approval to verify. - function _escrow(address _owner, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transferFrom(_owner, address(this), _tokenId); - } - - /// @dev Transfers an NFT owned by this contract to another address. - /// Returns true if the transfer succeeds. - /// @param _receiver - Address to transfer NFT to. - /// @param _tokenId - ID of token to transfer. - function _transfer(address _receiver, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transfer(_receiver, _tokenId); - } - - /// @dev Adds an auction to the list of open auctions. Also fires the - /// AuctionCreated event. - /// @param _tokenId The ID of the token to be put on auction. - /// @param _auction Auction to add. - function _addAuction(uint256 _tokenId, Auction memory _auction) internal { - // Require that all auctions have a duration of - // at least one minute. (Keeps our math from getting hairy!) - require(_auction.duration >= 1 minutes); - - tokenIdToAuction[_tokenId] = _auction; - - emit AuctionCreated( - uint256(_tokenId), - uint256(_auction.startingPrice), - uint256(_auction.endingPrice), - uint256(_auction.duration) - ); - } - - /// @dev Cancels an auction unconditionally. - function _cancelAuction(uint256 _tokenId, address _seller) internal { - _removeAuction(_tokenId); - _transfer(_seller, _tokenId); - emit AuctionCancelled(_tokenId); - } - - /// @dev Computes the price and transfers winnings. - /// Does NOT transfer ownership of token. - function _bid(uint256 _tokenId, uint256 _bidAmount) - internal - returns (uint256) - { - // Get a reference to the auction struct - Auction storage auction = tokenIdToAuction[_tokenId]; - - // Explicitly check that this auction is currently live. - // (Because of how Ethereum mappings work, we can't just count - // on the lookup above failing. An invalid _tokenId will just - // return an auction object that is all zeros.) - require(_isOnAuction(auction)); - - // Check that the bid is greater than or equal to the current price - uint256 price = _currentPrice(auction); - require(_bidAmount >= price); - - // Grab a reference to the seller before the auction struct - // gets deleted. - address payable seller = auction.seller; - - // The bid is good! Remove the auction before sending the fees - // to the sender so we can't have a reentrancy attack. - _removeAuction(_tokenId); - - // Transfer proceeds to seller (if there are any!) - if (price > 0) { - // Calculate the auctioneer's cut. - // (NOTE: _computeCut() is guaranteed to return a - // value <= price, so this subtraction can't go negative.) - uint256 auctioneerCut = _computeCut(price); - uint256 sellerProceeds = price - auctioneerCut; - - // NOTE: Doing a transfer() in the middle of a complex - // method like this is generally discouraged because of - // reentrancy attacks and DoS attacks if the seller is - // a contract with an invalid fallback function. We explicitly - // guard against reentrancy attacks by removing the auction - // before calling transfer(), and the only thing the seller - // can DoS is the sale of their own asset! (And if it's an - // accident, they can call cancelAuction(). ) - seller.transfer(sellerProceeds); - } - - // Calculate any excess funds included with the bid. If the excess - // is anything worth worrying about, transfer it back to bidder. - // NOTE: We checked above that the bid amount is greater than or - // equal to the price so this cannot underflow. - uint256 bidExcess = _bidAmount - price; - - // Return the funds. Similar to the previous transfer, this is - // not susceptible to a re-entry attack because the auction is - // removed before any transfers occur. - msg.sender.transfer(bidExcess); - - // Tell the world! - emit AuctionSuccessful(_tokenId, price, msg.sender); - - return price; - } - - /// @dev Removes an auction from the list of open auctions. - /// @param _tokenId - ID of NFT on auction. - function _removeAuction(uint256 _tokenId) internal { - delete tokenIdToAuction[_tokenId]; - } - - /// @dev Returns true if the NFT is on auction. - /// @param _auction - Auction to check. - function _isOnAuction(Auction storage _auction) internal view returns (bool) { - return (_auction.startedAt > 0); - } - - /// @dev Returns current price of an NFT on auction. Broken into two - /// functions (this one, that computes the duration from the auction - /// structure, and the other that does the price computation) so we - /// can easily test that the price computation works correctly. - function _currentPrice(Auction storage _auction) - internal - view - returns (uint256) - { - uint256 secondsPassed = 0; - - // A bit of insurance against negative values (or wraparound). - // Probably not necessary (since Ethereum guarnatees that the - // now variable doesn't ever go backwards). - if (now > _auction.startedAt) { - secondsPassed = now - _auction.startedAt; - } - - return _computeCurrentPrice( - _auction.startingPrice, - _auction.endingPrice, - _auction.duration, - secondsPassed - ); - } - - /// @dev Computes the current price of an auction. Factored out - /// from _currentPrice so we can run extensive unit tests. - /// When testing, make this function public and turn on - /// `Current price computation` test suite. - function _computeCurrentPrice( - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - uint256 _secondsPassed - ) - internal - pure - returns (uint256) - { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our public functions carefully cap the maximum values for - // time (at 64-bits) and currency (at 128-bits). _duration is - // also known to be non-zero (see the require() statement in - // _addAuction()) - if (_secondsPassed >= _duration) { - // We've reached the end of the dynamic pricing portion - // of the auction, just return the end price. - return _endingPrice; - } else { - // Starting price can be higher than ending price (and often is!), so - // this delta can be negative. - int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - - // This multiplication can't overflow, _secondsPassed will easily fit within - // 64-bits, and totalPriceChange will easily fit within 128-bits, their product - // will always fit within 256-bits. - int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - - // currentPriceChange can be negative, but if so, will have a magnitude - // less that _startingPrice. Thus, this result will always end up positive. - int256 currentPrice = int256(_startingPrice) + currentPriceChange; - - return uint256(currentPrice); - } - } - - /// @dev Computes owner's cut of a sale. - /// @param _price - Sale price of NFT. - function _computeCut(uint256 _price) internal view returns (uint256) { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our entry functions carefully cap the maximum values for - // currency (at 128-bits), and ownerCut <= 10000 (see the require() - // statement in the ClockAuction constructor). The result of this - // function is always guaranteed to be <= _price. - return _price * ownerCut / 10000; - } - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { - event Pause(); - event Unpause(); - - bool public paused = false; - - - /** - * @dev modifier to allow actions only when the contract IS paused - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev modifier to allow actions only when the contract IS NOT paused - */ - modifier whenPaused { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyOwner whenNotPaused public returns (bool) { - paused = true; - emit Pause(); - return true; - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyOwner whenPaused public returns (bool) { - paused = false; - emit Unpause(); - return true; - } -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - - /// @dev The ERC-165 interface signature for ERC-721. - /// Ref: https://github.com/ethereum/EIPs/issues/165 - /// Ref: https://github.com/ethereum/EIPs/issues/721 - bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - - /// @dev Constructor creates a reference to the NFT ownership contract - /// and verifies the owner cut is in the valid range. - /// @param _nftAddress - address of a deployed contract implementing - /// the Nonfungible Interface. - /// @param _cut - percent cut the owner takes on each auction, must be - /// between 0-10,000. - constructor(address _nftAddress, uint256 _cut) public { - require(_cut <= 10000); - ownerCut = _cut; - - ERC721 candidateContract = ERC721(_nftAddress); - require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); - nonFungibleContract = candidateContract; - } - - /// @dev Remove all Ether from the contract, which is the owner's cuts - /// as well as any Ether sent directly to the contract address. - /// Always transfers to the NFT contract, but can be called either by - /// the owner or the NFT contract. - function withdrawBalance() external { - address payable nftAddress = address(uint160(address(nonFungibleContract))); - - require( - msg.sender == owner || - msg.sender == nftAddress - ); - // We are using this boolean method to make sure that even if one fails it will still work - bool res = nftAddress.send(address(this).balance); - } - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of time to move between starting - /// price and ending price (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - whenNotPaused - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(_owns(msg.sender, _tokenId)); - _escrow(msg.sender, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Bids on an open auction, completing the auction and transferring - /// ownership of the NFT if enough Ether is supplied. - /// @param _tokenId - ID of token to bid on. - function bid(uint256 _tokenId) - external - payable - whenNotPaused - { - // _bid will throw if the bid or funds transfer fails - _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - } - - /// @dev Cancels an auction that hasn't been won yet. - /// Returns the NFT to original owner. - /// @notice This is a state-modifying function that can - /// be called while the contract is paused. - /// @param _tokenId - ID of token on auction - function cancelAuction(uint256 _tokenId) - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - address seller = auction.seller; - require(msg.sender == seller); - _cancelAuction(_tokenId, seller); - } - - /// @dev Cancels an auction when the contract is paused. - /// Only the owner may do this, and NFTs are returned to - /// the seller. This should only be used in emergencies. - /// @param _tokenId - ID of the NFT on auction to cancel. - function cancelAuctionWhenPaused(uint256 _tokenId) - whenPaused - onlyOwner - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - _cancelAuction(_tokenId, auction.seller); - } - - /// @dev Returns auction info for an NFT on auction. - /// @param _tokenId - ID of NFT on auction. - function getAuction(uint256 _tokenId) - external - view - returns - ( - address seller, - uint256 startingPrice, - uint256 endingPrice, - uint256 duration, - uint256 startedAt - ) { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return ( - auction.seller, - auction.startingPrice, - auction.endingPrice, - auction.duration, - auction.startedAt - ); - } - - /// @dev Returns the current price of an auction. - /// @param _tokenId - ID of the token price we are checking. - function getCurrentPrice(uint256 _tokenId) - external - view - returns (uint256) - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return _currentPrice(auction); - } - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSiringAuctionAddress() call. - bool public isSiringClockAuction = true; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. Since this function is wrapped, - /// require sender to be KittyCore contract. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Places a bid for siring. Requires the sender - /// is the KittyCore contract because all bid methods - /// should be wrapped. Also returns the kitty to the - /// seller rather than the winner. - function bid(uint256 _tokenId) - external - payable - { - require(msg.sender == address(nonFungibleContract)); - address seller = tokenIdToAuction[_tokenId].seller; - // _bid checks that token ID is valid and will throw if bid fails - _bid(_tokenId, msg.value); - // We transfer the kitty back to the seller, the winner will get - // the offspring - _transfer(seller, _tokenId); - } - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSaleAuctionAddress() call. - bool public isSaleClockAuction = true; - - // Tracks last 5 sale price of gen0 kitty sales - uint256 public gen0SaleCount; - uint256[5] public lastGen0SalePrices; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Updates lastSalePrice if seller is the nft contract - /// Otherwise, works the same as default bid method. - function bid(uint256 _tokenId) - external - payable - { - // _bid verifies token ID size - address seller = tokenIdToAuction[_tokenId].seller; - uint256 price = _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - - // If not a gen0 auction, exit - if (seller == address(nonFungibleContract)) { - // Track gen0 sale prices - lastGen0SalePrices[gen0SaleCount % 5] = price; - gen0SaleCount++; - } - } - - function averageGen0SalePrice() external view returns (uint256) { - uint256 sum = 0; - for (uint256 i = 0; i < 5; i++) { - sum += lastGen0SalePrices[i]; - } - return sum / 5; - } - -} - - - - - - - diff --git a/framework/src/test/resources/soliditycode_0.5.15/addressCheckNew.sol b/framework/src/test/resources/soliditycode_0.5.15/addressCheckNew.sol deleted file mode 100644 index 3c10b8c680d..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/addressCheckNew.sol +++ /dev/null @@ -1,9 +0,0 @@ -pragma experimental ABIEncoderV2; -contract testIsContract{ - function checkAddress(address addr) public returns (address){ - return addr; - } - function checkAddress2(address addr) pure public returns(address){ - return addr; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/addressCheckOld.sol b/framework/src/test/resources/soliditycode_0.5.15/addressCheckOld.sol deleted file mode 100644 index 6c6b15d1736..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/addressCheckOld.sol +++ /dev/null @@ -1,8 +0,0 @@ -contract testIsContract{ - function checkAddress(address addr) public returns (address){ - return addr; - } - function checkAddress2(address addr) pure public returns (address){ - return addr; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/altbn.sol b/framework/src/test/resources/soliditycode_0.5.15/altbn.sol deleted file mode 100644 index ee6ca1a98c9..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/altbn.sol +++ /dev/null @@ -1,63 +0,0 @@ -pragma solidity ^0.5.12; - -contract AltBn128 { - constructor() public payable {} - function callBn256Add(bytes32 ax, bytes32 ay, bytes32 bx, bytes32 by) public returns (bytes32[2] memory result) { - bytes32[4] memory input; - input[0] = ax; - input[1] = ay; - input[2] = bx; - input[3] = by; - assembly { - let success := call(gas, 0x06, 0, input, 0x80, result, 0x40) - } - - } - - function callBn256AddNoValue(bytes32 ax, bytes32 ay, bytes32 bx, bytes32 by) public returns - (bytes32[2] memory result) { - bytes32[4] memory input; - input[0] = ax; - input[1] = ay; - input[2] = bx; - input[3] = by; - assembly { - let success := call(gas, 0xac, 0, input, 0x80, result, 0x40) - } - } - - function callBn256ScalarMul(bytes32 x, bytes32 y, bytes32 scalar) public returns (bytes32[2] memory result) { - bytes32[3] memory input; - input[0] = x; - input[1] = y; - input[2] = scalar; - assembly { - let success := call(gas, 0x07, 0, input, 0x60, result, 0x40) - switch success - case 0 { - revert(0,0) - } - } - } - - function callBn256Pairing(bytes memory input) public returns (bytes32 result) { - // input is a serialized bytes stream of (a1, b1, a2, b2, ..., ak, bk) from (G_1 x G_2)^k - uint256 len = input.length; - require(len % 192 == 0); - assembly { - let memPtr := mload(0x40) - let success := call(gas, 0x08, 0, add(input, 0x20), len, memPtr, 0x20) - switch success - case 0 { - revert(0,0) - } default { - result := mload(memPtr) - } - } - } - - function convert(uint256 num) public view returns(bytes32) { - return bytes32(num); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/arrayLength001.sol b/framework/src/test/resources/soliditycode_0.5.15/arrayLength001.sol deleted file mode 100644 index 1c7e4e9dac2..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/arrayLength001.sol +++ /dev/null @@ -1,16 +0,0 @@ - -contract Test { - byte[] a; - - function ChangeSize() external returns(byte[] memory) { - a.push(0x01); - a.length = 3; - - a.length ++; - a.length --; - a.length --; - - a.pop(); - return a; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/assemblyTest.sol b/framework/src/test/resources/soliditycode_0.5.15/assemblyTest.sol deleted file mode 100644 index 6da31ff7b6f..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/assemblyTest.sol +++ /dev/null @@ -1,62 +0,0 @@ -pragma solidity ^0.5.12; - -contract assemblyTest { - - uint constant x = 1; - uint constant y = x; - function getZuint() public view returns (uint) { - uint z = y + 1; - assembly { - z := y - } - return z; - } - - function getZuint2() public returns (uint) { - uint z = y + 1; - assembly { - z := y - } - return z; - } - - bool constant bool1 = true; - bool constant bool2 = bool1; - function getZbool() public view returns (bool) { - bool z; - assembly { - z := bool2 - } - return z; - } - - function getZbool2() public returns (bool) { - bool z; - assembly { - z := bool2 - } - return z; - } - - -// string constant string1 = "abc"; -// string constant string2 = string1; -// function getZstring() public view returns (string memory) { -// string memory z; -// assembly { -// z := string2 -// } -// return z; -// } - - -// address origin1 = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF; -// address origin2 = origin1; -// function getZaddress() public view returns (address) { -// address z; -// assembly { -// z := origin2 -// } -// return z; -// } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest1DivideInt.sol b/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest1DivideInt.sol deleted file mode 100644 index ca38896acee..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest1DivideInt.sol +++ /dev/null @@ -1,7 +0,0 @@ -//pragma solidity ^0.4.0; - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest2FindArgsContractMinTest.sol b/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest2FindArgsContractMinTest.sol deleted file mode 100644 index b8565d2578e..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest2FindArgsContractMinTest.sol +++ /dev/null @@ -1,10 +0,0 @@ -//pragma solidity ^0.4.0; -contract findArgsIContract{ -function findArgsByIndex1(uint i) public returns (uint z) { -uint[] memory a = new uint[](3); -a[0]=1; -a[1]=2; -a[2]=3; -return a[i]; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest3ByteMinContract.sol b/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest3ByteMinContract.sol deleted file mode 100644 index 6d846fad7f4..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest3ByteMinContract.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma solidity >0.5.0; -contract byteContract{ -bytes b; -function testBytesGet(uint i) public returns (bytes1){ -b = new bytes(3); -b[0]=0x0b; -b[1]=0x0c; -b[2]=0x0d; -return b[i]; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest4Enum.sol b/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest4Enum.sol deleted file mode 100644 index 4a740d4a089..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest4Enum.sol +++ /dev/null @@ -1,13 +0,0 @@ -//pragma solidity ^0.4.4; - -contract enumContract { - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices _choice; - function setGoStraight(ActionChoices choice) public { - _choice = choice; - } - - function getChoice() public returns (ActionChoices) { - return _choice; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest5MoveRight.sol b/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest5MoveRight.sol deleted file mode 100644 index 7194520fb09..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest5MoveRight.sol +++ /dev/null @@ -1,7 +0,0 @@ -//pragma solidity ^0.4.0; - -contract binaryRightContract{ - function binaryMoveR(int i)public returns (int z) { - return z = 5 >> i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest6UninitializedContract.sol b/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest6UninitializedContract.sol deleted file mode 100644 index 1ff2215abdb..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest6UninitializedContract.sol +++ /dev/null @@ -1,27 +0,0 @@ -//pragma solidity ^0.4.0; -contract uni { -function b(int x, int y) internal returns (int) -{ - return x * y; -} - -function test1() external returns (int) -{ - // Variable containing a function pointer - function (int, int) internal returns (int) funcPtr; - - funcPtr = b; - - // This call to funcPtr will succeed - return funcPtr(4, 5); -} - -function test2() external returns (int) -{ - // Variable containing a function pointer - function (int, int) internal returns (int) funcPtr; - - // This call will fail because funcPtr is still a zero-initialized function pointer - return funcPtr(4, 5); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest7TestAssertContract.sol b/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest7TestAssertContract.sol deleted file mode 100644 index 0bfd6fbd04e..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/assertExceptiontest7TestAssertContract.sol +++ /dev/null @@ -1,15 +0,0 @@ -pragma solidity >0.5.0; -contract TestThrowsContract{ - function testAssert() public{ - assert(1==2); - } - function testRequire() public{ - require(2==1); - } - function testRevert() public{ - revert(); - } - function testThrow() public{ - revert(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign.sol b/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign.sol deleted file mode 100644 index 9e1c1b289b5..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign.sol +++ /dev/null @@ -1,14 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - - function testArray2(bytes memory data) public returns(bool, bytes memory){ - return address(0x9).delegatecall(data); - } - - function testArray4(bytes memory data) public { - //address(0x1).delegatecall(data); - } - //function testArray3(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public { - //address(0x9).delegatecall(hash,signatures,addresses); - //} -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign001.sol b/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign001.sol deleted file mode 100644 index 57e051ce415..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign001.sol +++ /dev/null @@ -1,10 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - function testPure(bytes32 hash, bytes[] memory signatures, address[] memory addresses) pure public returns(bytes32){ - return batchvalidatesign(hash, signatures, addresses); - } - - function testArray(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public returns(bytes32){ - return batchvalidatesign(hash, signatures, addresses); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign002.sol b/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign002.sol deleted file mode 100644 index 375cec3a2a2..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign002.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - function testArray(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public returns(bytes32){ - - return batchvalidatesign(hash, signatures, addresses); - - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign003.sol b/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign003.sol deleted file mode 100644 index c43536af499..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign003.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract Demo { -bytes32 public result; -constructor (bytes32 hash, bytes[] memory signatures, address[] memory addresses) public { - result = batchvalidatesign(hash, signatures, addresses); -} -function testConstructor() public returns(bytes32){ - return result; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign005.sol b/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign005.sol deleted file mode 100644 index 3a6ca362973..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign005.sol +++ /dev/null @@ -1,14 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - - function testArray2(bytes memory data) public returns(bool, bytes memory){ - return address(0x9).delegatecall(data); - } - - function testArray4(bytes memory data) public { - //address(0x1).delegatecall(data); - } - function testArray3(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public { - //address(0x9).delegatecall(hash,signatures,addresses); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign007.sol b/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign007.sol deleted file mode 100644 index 974ffb34efe..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign007.sol +++ /dev/null @@ -1,17 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract Demo { - bytes32 public result; - - constructor (bytes32 hash, bytes[] memory signatures, address[] memory addresses) public { - result = batchvalidatesign(hash, signatures, addresses); - } - - function testConstructor() public returns(bytes32){ - return result; - } - - function testConstructorPure() public view returns(bytes32){ - return result; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign02.sol b/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign02.sol deleted file mode 100644 index 375cec3a2a2..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/batchvalidatesign02.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - function testArray(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public returns(bytes32){ - - return batchvalidatesign(hash, signatures, addresses); - - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/callValueGasPure.sol b/framework/src/test/resources/soliditycode_0.5.15/callValueGasPure.sol deleted file mode 100644 index ed4877e1ce4..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/callValueGasPure.sol +++ /dev/null @@ -1,8 +0,0 @@ - -contract C { -function check(address a) external pure returns (bool success) { - a.call.value(42).gas(42); - a.call.gas(42); - //a.call.value(1).gas(42)("fwefewf"); -} -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/calldata.sol b/framework/src/test/resources/soliditycode_0.5.15/calldata.sol deleted file mode 100644 index 6e877ac1b2f..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/calldata.sol +++ /dev/null @@ -1,33 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract C { - struct S { uint256 a; } - - function f(S calldata s) external returns (bytes memory) { - return abi.encode(s); - } - - function g(S calldata s) external returns (bytes memory) { - return this.f(s); - } - - function m(uint256[] calldata) external pure returns (bytes memory) { - return msg.data; - } - function h(uint8[] calldata s) external pure returns (bytes memory) { - return abi.encode(s); - } - function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) { - return this.h(s[which]); - } - function j(bytes calldata s) external pure returns (bytes memory) { - return abi.encode(s); - } - function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) { - return this.j(s[which]); - } - function l(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) { - assert(s.length == 3); - return (s[0](), s[1](), s[2]()); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/callvalue.sol b/framework/src/test/resources/soliditycode_0.5.15/callvalue.sol deleted file mode 100644 index ee2a30342c5..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/callvalue.sol +++ /dev/null @@ -1,9 +0,0 @@ -contract Callvalue { -function check() public payable returns(uint) { - uint256 wad; - assembly { - wad := callvalue - } - return wad; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/chainid001.sol b/framework/src/test/resources/soliditycode_0.5.15/chainid001.sol deleted file mode 100644 index c057a83b325..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/chainid001.sol +++ /dev/null @@ -1,20 +0,0 @@ -pragma solidity ^0.5.12; - -contract IstanbulTest { - constructor() public payable {} - function getId() public view returns(uint256){ - uint256 id; - assembly { - id := chainid() - } - return id; - } - - function getBalance(address src) public view returns(uint256){ - return address(src).balance; - } - - function getBalance() public view returns(uint256){ - return address(this).balance; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/codeSaftySupport.sol b/framework/src/test/resources/soliditycode_0.5.15/codeSaftySupport.sol deleted file mode 100644 index 45a4beee384..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/codeSaftySupport.sol +++ /dev/null @@ -1,19 +0,0 @@ -//pragma solidity ^0.4.24; - -contract IllegalDecorate { - -constructor() payable public{} - -function() payable external{} - -event log(uint256); - -function transferToken(address payable toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/codeSaftyUnsupport.sol b/framework/src/test/resources/soliditycode_0.5.15/codeSaftyUnsupport.sol deleted file mode 100644 index 220d66b2257..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/codeSaftyUnsupport.sol +++ /dev/null @@ -1,56 +0,0 @@ -//pragma solidity ^0.4.24; - -contract SubC { - -event log(string); - -function () payable external{} - -function receiveToken() payable public{} - -function getBalance() view public returns (uint256 r) { -r = address(this).balance; -} -} - -contract UseDot { -constructor() payable public{} -function() payable external{} -mapping(address => mapping(trcToken => uint256)) sender_tokens; - -function trigger1(address payable addr, trcToken tokenInputId) payable public { - //address(SubC(addr)).call.value(1000).tokenId(tokenInputId)(abi.encodeWithSignature("receiveToken()")); // ERROR -} - -function trigger2(address payable addr) payable public { -// addr.transferToken.value(10)(10, 0x6e6d62); // ERROR -} - -function trigger3(address payable addr) payable public { - // address(SubC(addr)).receiveToken.tokenvalue(10)(); // ERROR -} - -function trigger4(address payable addr) payable public { - //SubC(addr).receiveToken.tokenId(0x6e6d62)(); // ERROR -} - -function trigger5(address payable addr) payable public { - SubC(addr).receiveToken.value(10)(); -} - -function trigger6(address payable addr, trcToken tokenId) payable public { -address(SubC(addr)).call.value(1000)(abi.encodeWithSignature("transferToken(uint256, trcToken)", 10, tokenId)); -} - -function trigger7(address addr) payable public { - //sender_tokens[msg.sender][msg.tokenid] += msg.tokenvalue; // compile success, no necessary to trigger -} - -function trigger8(address addr) public payable returns(bytes memory r){ -// r = msg.data; // compile success, no necessary to trigger -} - -function getBalance() public returns (uint256 r){ -r = address(this).balance; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/constantCallStorage001.sol b/framework/src/test/resources/soliditycode_0.5.15/constantCallStorage001.sol deleted file mode 100644 index 1f584923a55..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/constantCallStorage001.sol +++ /dev/null @@ -1,159 +0,0 @@ -contract NotView { - uint256 public num = 123; - function setnum() public returns(uint256){ - num = num + 15; - return num; - } -} -contract NotViewInterface{ - function setnum() public returns(uint256); -} -contract UseNotView { - function setnumuseproxy(address contractAddress) public returns(uint256){ - NotViewInterface inter = NotViewInterface(contractAddress); - return inter.setnum(); - } -} -contract viewCall { - bool stopped = false; - int i = 32482989; - int i2 = -32482989; - uint ui = 23487823; - address origin = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF; - bytes32 b32 = bytes32(uint256(0xdCad3a6d3569DF655070DEd0)); - bytes bs = new bytes(3); - string s = "123qwe"; - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices choice = ActionChoices.GoRight; - int64[] b = [-1, 2, -3]; - int32[2][] tmp_h = [[1,2],[3,4],[5,6]]; - int256[2][2] tmp_i = [[11,22],[33,44]]; - mapping (address => uint256) public mapa; - constructor() payable public{ - mapa[address(0x00)] = 34; - } - event log(int); - event log(uint); - event log(bool); - event log(address); - event log(bytes32); - event log(bytes); - event log(string); - event log(ActionChoices); - event log(int64[]); - event log(int32[2][]); - event log(int256[2][2]); - function changeBool(bool param) public returns (bool){ - stopped = param; - emit log(stopped); - return stopped; - } - function getBool() public returns (bool){ - emit log(stopped); - return stopped; - } - function changeInt(int param) public returns (int){ - i = param; - emit log(i); - return i; - } - function getInt() public returns (int){ - emit log(i); - return i; - } - function changeNegativeInt(int param) public returns (int){ - i2 = param; - emit log(i2); - return i2; - } - function getNegativeInt() public returns (int){ - emit log(i2); - return i2; - } - function changeUint(uint param) public returns (uint){ - ui = param; - emit log(ui); - return ui; - } - function getUint() public returns (uint){ - emit log(ui); - return ui; - } - function changeAddress(address param) public returns (address){ - origin = param; - emit log(origin); - return origin; - } - function getAddress() public returns (address){ - emit log(origin); - return origin; - } - function changeBytes32(bytes32 param) public returns (bytes32){ - b32 = param; - emit log(b32); - return b32; - } - function getBytes32() public returns (bytes32){ - emit log(b32); - return b32; - } - function changeBytes(bytes memory param) public returns (bytes memory){ - bs = param; - emit log(bs); - return bs; - } - function getBytes() public returns (bytes memory){ - emit log(bs); - return bs; - } - function changeString(string memory param) public returns (string memory){ - s = param; - emit log(s); - return s; - } - function getString() public returns (string memory){ - emit log(s); - return s; - } - function changeActionChoices(ActionChoices param) public returns (ActionChoices){ - choice = param; - emit log(choice); - return choice; - } - function getActionChoices() public returns (ActionChoices){ - emit log(choice); - return choice; - } - function changeInt64NegativeArray(int64[] memory param) public returns (int64[] memory){ - b = param; - emit log(b); - return b; - } - function getInt64NegativeArray() public returns (int64[] memory){ - emit log(b); - return b; - } - function changeInt32Array(int32[2][] memory param) public returns (int32[2][] memory){ - tmp_h = param; - emit log(tmp_h); - return tmp_h; - } - function getInt32Array() public returns (int32[2][] memory){ - emit log(tmp_h); - return tmp_h; - } - function changeInt256Array(int256[2][2] memory param) public returns (int256[2][2] memory){ - tmp_i = param; - emit log(tmp_i); - return tmp_i; - } - function getInt256Array() public returns (int256[2][2] memory){ - emit log(tmp_i); - return tmp_i; - } - function setMapping(uint256 param) public returns (uint256){ - mapa[msg.sender] = param; - return mapa[msg.sender]; - - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/constantCallStorage002.sol b/framework/src/test/resources/soliditycode_0.5.15/constantCallStorage002.sol deleted file mode 100644 index 1ceba5e87d2..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/constantCallStorage002.sol +++ /dev/null @@ -1,16 +0,0 @@ -contract NotView { - uint256 public num = 123; - function setnum() public returns(uint256){ - num = num + 15; - return num; - } -} -contract NotViewInterface{ - function setnum() public view returns(uint256); -} -contract UseNotView { - function setnumuseproxy(address contractAddress) public view returns(uint256){ - NotViewInterface inter = NotViewInterface(contractAddress); - return inter.setnum(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/constantCallStorage0425.sol b/framework/src/test/resources/soliditycode_0.5.15/constantCallStorage0425.sol deleted file mode 100644 index 8ecf771626d..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/constantCallStorage0425.sol +++ /dev/null @@ -1,156 +0,0 @@ -contract constantCall { - bool stopped = false; - int i = 32482989; - int i2 = -32482989; - uint ui = 23487823; - address origin = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF; - bytes32 b32 = 0xb55a21aaee0ce8f1c8ffaa0dbd23105cb55a21aaee0ce8f1c8ffaa0dbd23105c; - bytes bs = new bytes(9); - string s = "123qwe"; - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices choice = ActionChoices.SitStill; - int64[] b = [91, 2, 333]; - int32[2][] tmp_h = [[1,2],[3,4],[5,6]]; - int256[2][2] tmp_i = [[11,22],[33,44]]; - mapping (address => uint256) public mapa; - - constructor() payable public{ - mapa[address(0x00)] = 88; - } - event log(int); - event log(uint); - event log(bool); - event log(address); - event log(bytes32); - event log(bytes); - event log(string); - event log(ActionChoices); - event log(int64[]); - event log(int32[2][]); - event log(int256[2][2]); - - function changeBool(bool param) public constant returns (bool){ - stopped = param; - log(stopped); - return stopped; - } - function getBool() public constant returns (bool){ - log(stopped); - return stopped; - } - - function changeInt(int param) public returns (int){ - i = param; - log(i); - return i; - } - function getInt() public returns (int){ - log(i); - return i; - } - - function changeNegativeInt(int param) public constant returns (int){ - i2 = param; - log(i2); - return i2; - } - function getNegativeInt() public constant returns (int){ - log(i2); - return i2; - } - - function changeUint(uint param) public returns (uint){ - ui = param; - log(ui); - return ui; - } - function getUint() public returns (uint){ - log(ui); - return ui; - } - - function changeAddress(address param) public constant returns (address){ - origin = param; - log(origin); - return origin; - } - function getAddress() public constant returns (address){ - log(origin); - return origin; - } - - function changeBytes32(bytes32 param) public constant returns (bytes32){ - b32 = param; - log(b32); - return b32; - } - function getBytes32() public returns (bytes32){ - log(b32); - return b32; - } - - function changeBytes(bytes param) public constant returns (bytes){ - bs = param; - log(bs); - return bs; - } - function getBytes() public constant returns (bytes){ - log(bs); - return bs; - } - - function changeString(string param) public constant returns (string){ - s = param; - log(s); - return s; - } - function getString() public returns (string){ - log(s); - return s; - } - - function changeActionChoices(ActionChoices param) public constant returns (ActionChoices){ - choice = param; - log(choice); - return choice; - } - function getActionChoices() public constant returns (ActionChoices){ - log(choice); - return choice; - } - - function changeInt64NegativeArray(int64[] param) public constant returns (int64[]){ - b = param; - log(b); - return b; - } - function getInt64NegativeArray() public constant returns (int64[]){ - log(b); - return b; - } - - function changeInt32Array(int32[2][] param) public returns (int32[2][]){ - tmp_h = param; - log(tmp_h); - return tmp_h; - } - function getInt32Array() public constant returns (int32[2][]){ - log(tmp_h); - return tmp_h; - } - - function changeInt256Array(int256[2][2] param) public returns (int256[2][2]){ - tmp_i = param; - log(tmp_i); - return tmp_i; - } - function getInt256Array() public constant returns (int256[2][2]){ - log(tmp_i); - return tmp_i; - } - function setMapping(uint256 param) public returns (uint256){ - mapa[msg.sender] = param; - return mapa[msg.sender]; - - } -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/constantContract001.sol b/framework/src/test/resources/soliditycode_0.5.15/constantContract001.sol deleted file mode 100644 index ab97b450235..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/constantContract001.sol +++ /dev/null @@ -1,8 +0,0 @@ -//pragma solidity ^0.4.0; - -contract testConstantContract{ -function testPure(uint256 x,uint256 y) public pure returns (uint256 z) { -uint256 i=1; -return i + x + y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGetterContract.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGetterContract.sol deleted file mode 100644 index ba090f061dd..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGetterContract.sol +++ /dev/null @@ -1,17 +0,0 @@ -//pragma solidity ^0.4.0; - - -contract getterContract { - -constructor() public payable{} -function() external payable{} - -uint public c = msg.value; - -function getDataUsingAccessor() public payable returns (uint){ - -return c; - -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test1Grammar001.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test1Grammar001.sol deleted file mode 100644 index 1d0ad6e3d3f..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test1Grammar001.sol +++ /dev/null @@ -1,18 +0,0 @@ -pragma solidity >0.5.0; -contract FunctionSelector { - function select(bool useB, uint x) public returns (uint z) { - //var f = a; - //if (useB) f = b; - //return f(x); - if (useB) - return b(x); - else - return a(x); - } -function a(uint x) public returns (uint z) { - return x * x; - } -function b(uint x) public returns (uint z) { - return 2 * x; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test2Grammar002.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test2Grammar002.sol deleted file mode 100644 index df9d5c88839..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test2Grammar002.sol +++ /dev/null @@ -1,44 +0,0 @@ -//pragma solidity ^0.4.16; -library Set { - // We define a new struct datatype that will be used to - // hold its data in the calling contract. - struct Data { mapping(uint => bool) flags; } - - // Note that the first parameter is of type "storage - // reference" and thus only its storage address and not - // its contents is passed as part of the call. This is a - // special feature of library functions. It is idiomatic - // to call the first parameter 'self', if the function can - // be seen as a method of that object. - function insert(Data storage self, uint value) public returns (bool) { - if (self.flags[value]) - return false; // already there - self.flags[value] = true; - return true; - } - - function remove(Data storage self, uint value) public returns (bool) { - if (!self.flags[value]) - return false; // not there - self.flags[value] = false; - return true; - } - - function contains(Data storage self, uint value) public returns (bool) { - return self.flags[value]; - } -} - - -contract C { - Set.Data knownValues; - - function register (uint value) public{ - // The library functions can be called without a - // specific instance of the library, since the - // "instance" will be the current contract. - if (!Set.insert(knownValues, value)) - revert(); - } - // In this contract, we can also directly access knownValues.flags, if we want. -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test3Grammar003.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test3Grammar003.sol deleted file mode 100644 index ce56f5c9912..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test3Grammar003.sol +++ /dev/null @@ -1,44 +0,0 @@ -//pragma solidity ^0.4.11; - -library Set { - struct Data { mapping(uint => bool) flags; } - - function insert(Data storage self, uint value) public - returns (bool) - { - if (self.flags[value]) - return false; // already there - self.flags[value] = true; - return true; - } - - function remove(Data storage self, uint value) public - returns (bool) - { - if (!self.flags[value]) - return false; // not there - self.flags[value] = false; - return true; - } - - function contains(Data storage self, uint value) public - returns (bool) - { - return self.flags[value]; - } -} - - -contract C { - using Set for Set.Data; // this is the crucial change - Set.Data knownValues; - - function register(uint value) public{ - // Here, all variables of type Set.Data have - // corresponding member functions. - // The following function call is identical to - // Set.insert(knownValues, value) - if (!knownValues.insert(value)) - revert(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test4Grammar004.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test4Grammar004.sol deleted file mode 100644 index b36d171a912..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test4Grammar004.sol +++ /dev/null @@ -1,31 +0,0 @@ -//pragma solidity ^0.4.0; - -library Search { - function indexOf(uint[] storage self, uint value) public returns (uint) { - for (uint i = 0; i < self.length; i++) - if (self[i] == value) return i; - return uint(-1); - } -} - - -contract C { - using Search for uint[]; - uint[] public data; - - function append(uint value) public{ - data.push(value); - } - - function replace(uint _old, uint _new) public{ - // This performs the library function call - uint index = data.indexOf(_old); - if (index == uint(-1)) - data.push(_new); - else - data[index] = _new; - } - function getData(uint256 index) public returns(uint256){ - return data[index]; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test5Grammar006.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test5Grammar006.sol deleted file mode 100644 index 805476a9e4a..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar001test5Grammar006.sol +++ /dev/null @@ -1,38 +0,0 @@ -// pragma solidity ^0.4.0; -contract InfoFeed { -function d1(uint x) public{ - assembly{ - function f(x) -> y { switch x case 0 { y := 1 } default { y := mul(x, f(sub(x, 1))) } } - } - } - function d2(uint x) public{ - assembly { x := mul(1, add(2, 3))} - } - function f(uint x) public{ - assembly { x := sub(x, 1) } - - } - function d(uint x) public{ - assembly{ - let x := add(2, 3) let y := mload(0x40) x := add(x, y) - } - } - function d4(uint x) public{ - // Error: The labels 'repeat' is disallowed. Please use "if", "switch", "for" or function calls instead - //assembly{let x := 10 repeat: x := sub(x, 1) jumpi(repeat, eq(x, 0)) - x = x; - //} - } - function d5(uint x) public{ - assembly{ - function f(x) -> y { switch x case 0 { y := mul(x, 2) } default { y := 0 } } - - } - } - - function d6(uint x) public{ - assembly{ - function f(x) -> y { for { let i := 0 } lt(i, x) { i := add(i, 1) } { y := mul(2, y) } } - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test1Grammar007_1.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test1Grammar007_1.sol deleted file mode 100644 index 6e3ac0bfd1e..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test1Grammar007_1.sol +++ /dev/null @@ -1,60 +0,0 @@ -//pragma solidity ^0.4.19; -contract Doug{ - mapping (bytes32 => uint) public contracts; - constructor() public{ - contracts['hww'] = 1; - contracts['brian'] = 2; - contracts['zzy'] = 7; - } - - function getDougName(string memory _name) public view returns(string memory) { - return _name; - } - - function getDougAge(uint _age) public pure returns(uint) { - return 3 ** _age; - } -} - -contract DogInterface { - function getDougAge(uint _age) public returns (uint); - function contracts(bytes32 name) public returns (uint); -} -contract main{ - - event FetchContract(address dogInterfaceAddress, address sender, bytes32 name); - - address public DOUG; - - address dogInterfaceAddress; - DogInterface dogContract ; - - function setDOUG(address _doug) public { - DOUG = _doug; - } - - constructor(address addr) public{ - dogInterfaceAddress = addr; - dogContract = DogInterface(dogInterfaceAddress); - } - - function dougOfage(uint _age) public returns(uint) { - - uint num = dogContract.getDougAge(_age); - return _age+num; - // return num; - } - - function uintOfName(bytes32 _name) public returns (uint) { - - dogContract.contracts(_name); - emit FetchContract(dogInterfaceAddress, msg.sender, _name); - - } - - // function getTest(string _name) public view returns(string) { - // string memory newName = _name ; - // DogInterface(DOUG).getDougName(newName); - // return newName; - // } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test1Grammar007_2.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test1Grammar007_2.sol deleted file mode 100644 index 6e3ac0bfd1e..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test1Grammar007_2.sol +++ /dev/null @@ -1,60 +0,0 @@ -//pragma solidity ^0.4.19; -contract Doug{ - mapping (bytes32 => uint) public contracts; - constructor() public{ - contracts['hww'] = 1; - contracts['brian'] = 2; - contracts['zzy'] = 7; - } - - function getDougName(string memory _name) public view returns(string memory) { - return _name; - } - - function getDougAge(uint _age) public pure returns(uint) { - return 3 ** _age; - } -} - -contract DogInterface { - function getDougAge(uint _age) public returns (uint); - function contracts(bytes32 name) public returns (uint); -} -contract main{ - - event FetchContract(address dogInterfaceAddress, address sender, bytes32 name); - - address public DOUG; - - address dogInterfaceAddress; - DogInterface dogContract ; - - function setDOUG(address _doug) public { - DOUG = _doug; - } - - constructor(address addr) public{ - dogInterfaceAddress = addr; - dogContract = DogInterface(dogInterfaceAddress); - } - - function dougOfage(uint _age) public returns(uint) { - - uint num = dogContract.getDougAge(_age); - return _age+num; - // return num; - } - - function uintOfName(bytes32 _name) public returns (uint) { - - dogContract.contracts(_name); - emit FetchContract(dogInterfaceAddress, msg.sender, _name); - - } - - // function getTest(string _name) public view returns(string) { - // string memory newName = _name ; - // DogInterface(DOUG).getDougName(newName); - // return newName; - // } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test2Grammar008.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test2Grammar008.sol deleted file mode 100644 index c9c5d614d2d..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test2Grammar008.sol +++ /dev/null @@ -1,14 +0,0 @@ -//pragma solidity ^0.4.19; -contract Feline { - function utterance() public returns (bytes32); - - function getContractName() public returns (string memory){ - return "Feline"; - } -} - - -contract Cat is Feline { - function utterance() public returns (bytes32) { return "miaow"; } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test3Grammar010.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test3Grammar010.sol deleted file mode 100644 index a7749dfcc71..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test3Grammar010.sol +++ /dev/null @@ -1,10 +0,0 @@ -//pragma solidity ^0.4.0; -contract InfoFeed { -function info() public payable returns (uint ret) { return 42; } -} -contract Consumer { -constructor() payable public{} -InfoFeed feed; -function setFeed(address addr) public { feed = InfoFeed(addr); } -function callFeed() public payable { feed.info.value(10).gas(800)(); } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test4Grammar011.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test4Grammar011.sol deleted file mode 100644 index 921b52a6080..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test4Grammar011.sol +++ /dev/null @@ -1,11 +0,0 @@ -//pragma solidity ^0.4.0; -contract C { -function f(uint key, uint value) public returns(uint) { -return key; -// do something -} -function g() public { -// named arguments -f({value: 2, key: 3}); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test4Grammar012.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test4Grammar012.sol deleted file mode 100644 index 45e6d3aaf6e..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test4Grammar012.sol +++ /dev/null @@ -1,24 +0,0 @@ -//pragma solidity ^0.4.24; -contract rTest { -function info() public payable returns (uint,address,bytes4,uint,uint,uint,address,uint) { -//function info() public payable returns (address ,uint,uint,uint,bytes32,uint,bytes,uint,address,bytes4,uint,uint,uint,address,uint) { -//var a = block.coinbase ; -//var b = block.difficulty; -//var c = block.gaslimit; -//var d = block.number; -//var e = block.blockhash(0); -//var e = d; -//var f = block.timestamp; -//bytes memory g = msg.data; -uint256 h = gasleft(); -address payable i = msg.sender; -bytes4 j = msg.sig; -uint256 k = msg.value; -uint256 l = now; -uint256 m = tx.gasprice; -address payable n = tx.origin; -uint256 o = address(this).balance; -return (h,i,j,k,l,m,n,o); -//return (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test6Grammar013.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test6Grammar013.sol deleted file mode 100644 index 56f97191ea0..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar002test6Grammar013.sol +++ /dev/null @@ -1,24 +0,0 @@ -//pragma solidity ^0.4.4; -contract Counter { -uint count = 0; -address payable owner; -//function Counter() public{ -constructor() public{ -owner = msg.sender; -} -function increment() public { -uint step = 10; -if (owner == msg.sender) { -count = count + step; -} -} -function getCount() public returns (uint){ -return count; -} -function kill() public{ -if (owner == msg.sender) { -selfdestruct(owner); -//selfdestruct(address(owner)); -} -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test1Grammar014.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test1Grammar014.sol deleted file mode 100644 index 9190e902056..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test1Grammar014.sol +++ /dev/null @@ -1,68 +0,0 @@ -//pragma solidity ^0.4.4; -contract A { -uint256 public numberForB; -address public senderForB; -function callTest(address bAddress, uint256 _number) public{ - -//bAddress.call(bytes4(sha3("setValue(uint256)")), _number); // B's storage is set, A is not modified -bAddress.call(abi.encodeWithSignature("setValue(uint256)",_number)); // B's storage is set, A is not modified -} -function callcodeTest(address bAddress, uint256 _number) public{ -//bAddress.callcode(bytes4(sha3("setValue(uint256)")), _number); // A's storage is set, B is not modified -bAddress.delegatecall(abi.encodeWithSignature("setValue(uint256)", _number)); // A's storage is set, B is not modified -} -function delegatecallTest(address bAddress, uint256 _number) public{ -//bAddress.delegatecall(bytes4(sha3("setValue(uint256)")), _number); // A's storage is set, B is not modified -bAddress.delegatecall(abi.encodeWithSignature("setValue(uint256)", _number)); // A's storage is set, B is not modified -} - -function callAddTest(address bAddress) public{ -//bAddress.call(bytes4(sha3("add()"))); // B's storage is set, A is not modified -bAddress.call(abi.encodeWithSignature("add()")); // B's storage is set, A is not modified -//bAddress.call(bytes4(sha3("add()"))); // B's storage is set, A is not modified -bAddress.call(abi.encodeWithSignature("add()")); // B's storage is set, A is not modified -} -function getnumberForB() public returns(uint256){ - return numberForB; - } - function getsenderForB() public returns(address){ - return senderForB; - } -} -contract B { -uint256 public numberForB; -address public senderForB; -address public addr11; -mapping(uint256=>address) public addr1; -mapping(uint256=>address) public addr2; -event ssss(uint256); -function setValue(uint256 _number) public{ - -emit ssss(_number); -numberForB = _number; -senderForB = msg.sender; -// senderForB is A if invoked by A's callTest. B's storage will be updated -// senderForB is A if invoked by A's callcodeTest. None of B's storage is updated -// senderForB is OWNER if invoked by A's delegatecallTest. None of B's storage is updated -} - -function add() public{ -numberForB=numberForB+1; -C c1 = new C(); -addr1[numberForB]=c1.getAddress(); -addr11 = c1.getAddress(); -C c2 = new C(); -addr2[numberForB] = c2.getAddress(); -} -function getnumberForB() public returns(uint256){ - return numberForB; - } - function getsenderForB() public returns(address){ - return senderForB; - } -} -contract C { -function getAddress() public view returns(address){ -return address(this); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test2Grammar015.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test2Grammar015.sol deleted file mode 100644 index 51aa0843890..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test2Grammar015.sol +++ /dev/null @@ -1,39 +0,0 @@ -//pragma solidity ^0.4.0; - -contract ExecuteFallback{ - - //回退事件,会把调用的数据打印出来 - event FallbackCalled(bytes data); - //fallback函数,注意是没有名字的,没有参数,没有返回值的 - function() external{ - emit FallbackCalled(msg.data); - } - - //调用已存在函数的事件,会把调用的原始数据,请求参数打印出来 - event ExistFuncCalled(bytes data, uint256 para); - //一个存在的函数 - function existFunc(uint256 para) public{ - emit ExistFuncCalled(msg.data, para); - } - - // 模拟从外部对一个存在的函数发起一个调用,将直接调用函数 - function callExistFunc() public{ - bytes4 funcIdentifier = bytes4(keccak256("existFunc(uint256)")); - //this.call(funcIdentifier, uint256(1)); - address(this).call(abi.encode(funcIdentifier, uint256(1))); - } - - //模拟从外部对一个不存在的函数发起一个调用,由于匹配不到函数,将调用回退函数 - function callNonExistFunc() public{ - bytes4 funcIdentifier = bytes4(keccak256("functionNotExist()")); - //this.call(funcIdentifier); - address(this).call(abi.encode(funcIdentifier)); - } - - function ExistFuncCalledTopic() view public returns(bytes32){ - return keccak256("ExistFuncCalled(bytes,uint256)"); - } - function FallbackCalledTopic() view public returns(bytes32){ - return keccak256("FallbackCalled(bytes)"); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test3Grammar016.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test3Grammar016.sol deleted file mode 100644 index 11eb8f9cc70..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test3Grammar016.sol +++ /dev/null @@ -1,23 +0,0 @@ -//pragma solidity ^0.4.0; -contract C { -uint private data; -function f(uint a) private returns(uint b) { return a + 1; } -function setData(uint a) public { data = a; } -function getData() public returns(uint) { return data; } -function compute(uint a, uint b) internal returns (uint) { return a+b; } -} -contract D { -function readData() public{ -C c = new C(); -//uint local = c.f(7); // error: member "f" is not visible -c.setData(3); -uint local = c.getData(); -// local = c.compute(3, 5); // error: member "compute" is not visible -} -} -contract E is C { -function g() public { -C c = new C(); -uint val = compute(3, 5); // access to internal member (from derived to parent contract) -} -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test4Grammar017.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test4Grammar017.sol deleted file mode 100644 index 23fcdec76f0..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test4Grammar017.sol +++ /dev/null @@ -1,50 +0,0 @@ -//pragma solidity ^0.4.0; -contract CrowdFunding{ -struct Funder{ -address addr; -uint amount; -} - -struct Campaign{ -address payable beneficiary; -uint goal; -uint amount; -uint funderNum; -mapping(uint => Funder) funders; -} - -uint compaingnID; -mapping (uint => Campaign) campaigns; - -function candidate(address payable beneficiary, uint goal) public payable returns (uint compaingnID){ -// initialize -campaigns[compaingnID++] = Campaign(beneficiary, goal, 0, 0); -} - -function vote(uint compaingnID) payable public { -Campaign storage c = campaigns[compaingnID]; - -//another way to initialize -c.funders[c.funderNum++] = Funder({addr: msg.sender, amount: msg.value}); -c.amount += msg.value; -} - -function check(uint comapingnId) public payable returns (bool){ - Campaign memory c = campaigns[comapingnId]; - - if(c.amount < c.goal){ - return false; - } - - uint amount = c.amount; - // incase send much more - c.amount = 0; - // address payable addr = address(uint160(c.beneficiary)); - //if(! addr.send(amount)){ - - if (! c.beneficiary.send(amount)){ - revert(); - } - return true; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test5Grammar018.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test5Grammar018.sol deleted file mode 100644 index ddd6deb040f..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test5Grammar018.sol +++ /dev/null @@ -1,37 +0,0 @@ -//pragma solidity ^0.4.0; - - -contract Grammar18{ - function testAddmod() public returns (uint z) { - //计算(x + y)%k,其中以任意精度执行加法,并且不在2 ** 256处围绕 - z=addmod(2, 2, 3); - return z; - } - function testMulmod() public returns (uint z) { -//计算(x * y)%k,其中乘法以任意精度执行,并且不会在2 ** 256处循环。 - z=mulmod(2, 3, 4); - return z; - } - - function testKeccak256() public returns(bytes32){ - //计算的(紧凑)参数的Ethereum-SHA-3(Keccak-256)的散列 - return keccak256("11"); - } - - function testSha256() public returns(bytes32){ - //计算(紧密包装)参数的SHA-256散列 - return sha256("11"); - } - function testSha3() public returns(bytes32){ - //计算(紧密包装)参数的SHA-256散列 - //return sha3("11"); - return keccak256("11"); - } - - function testRipemd160() public returns(bytes32){ - //计算(紧密包装)参数的RIPEMD-160哈希值 - return ripemd160("11"); - } - - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test6Grammar019.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test6Grammar019.sol deleted file mode 100644 index 30418539865..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test6Grammar019.sol +++ /dev/null @@ -1,12 +0,0 @@ -//pragma solidity ^0.4.0; -contract timetest { - -constructor() public { -require( 1 == 1 seconds); -require(1 minutes == 60 seconds); -require(1 hours == 60 minutes); -require(1 days == 24 hours); -require(1 weeks == 7 days); -//require(1 years == 365 days); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test7Grammar020.sol b/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test7Grammar020.sol deleted file mode 100644 index 1b960e6e313..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractGrammar003test7Grammar020.sol +++ /dev/null @@ -1,8 +0,0 @@ -//pragma solidity ^0.4.0; -contract trxtest { - -function test() public { -require(1 trx == 1000000 sun); - -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInnerContract.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInnerContract.sol deleted file mode 100644 index bc183931c88..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInnerContract.sol +++ /dev/null @@ -1,32 +0,0 @@ -//pragma solidity ^0.4.0; - - - -contract InnerContract { - - constructor() public payable{} - function() external payable{} - - function messageI() payable public returns (uint ret) { - - - - } - -} - - - -contract OuterContract { - - - constructor() public payable{} - function() external payable{} - - function callInner(address payable addr) payable public returns (uint) { - - return InnerContract(addr).messageI.value(1)(); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction001.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction001.sol deleted file mode 100644 index 8baba262e87..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction001.sol +++ /dev/null @@ -1,42 +0,0 @@ -//pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable external{} - function test1(address payable cAddr) public payable{ - B b1 = (new B).value(10)();//1.1 - B b2 = new B();//1.2 - address(b2).transfer(5);//1.3 - b2.callCGetZero(cAddr, 1);//1.4 - b2.callCGetZero(cAddr,2);//1.6 - } - function test2(address payable cAddress,uint256 amount) public payable{ - cAddress.call.value(amount)(abi.encodeWithSignature("newBAndTransfer()"));//2.1 - cAddress.call.value(amount + 1)(abi.encodeWithSignature("newBAndTransfer()"));//2.6 - } -} - -contract B{ - constructor() payable public{} - function() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero(address payable cAddress,uint256 amount) public{ - cAddress.call.value(amount)(abi.encodeWithSignature("getZero()"));//1.5,1.7 - } -} - -contract C{ - constructor() payable public{} - function() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - B b1 = (new B).value(7)();//2.2,2.7 - b1.getOne();//2.3,2.8 - B b2 = (new B).value(3)();//2.4,2.9 - b2.getOne();//2.5,2.10 - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction002.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction002.sol deleted file mode 100644 index 42231b7c960..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction002.sol +++ /dev/null @@ -1,21 +0,0 @@ -//pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable external{} - - function test2(address cAddress,uint256 amount) public payable{ - //cAddress.call.value(amount)();//2.1 - cAddress.call.value(amount)("");//2.1 - } -} - - -contract C{ - constructor() payable public{} - function() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction003.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction003.sol deleted file mode 100644 index 0910a0c4a2b..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction003.sol +++ /dev/null @@ -1,31 +0,0 @@ -//pragma solidity ^0.4.24; - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer() payable public{ - B b = (new B).value(10)();//1 - - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable public returns(bool) { - return true; - } - constructor() public payable {} - function payC(address payable c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - function () payable external{} - } - diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction004.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction004.sol deleted file mode 100644 index c7866dddb58..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction004.sol +++ /dev/null @@ -1,25 +0,0 @@ -//pragma solidity ^0.4.24; - -contract A{ - constructor () payable public{} - function test(address payable toAddress) public payable{ - selfdestruct(toAddress); - } - function () payable external{} - function getBalance() public view returns(uint256){ - return address(this).balance; - } -} -contract B{ - function() external payable{} - function kill(address contractAddres, address toAddress) payable public { - contractAddres.call(abi.encodeWithSignature("test(address)",address(this))); - } - function kill2() public{ - A a = new A(); - a.test(address(this)); - } - function getBalance() public view returns(uint256){ - return address(this).balance; - } -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction005.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction005.sol deleted file mode 100644 index 6e83c423b38..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction005.sol +++ /dev/null @@ -1,54 +0,0 @@ -//pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable external{} - function test1() public payable{ - B b1 = (new B).value(10)();//1.1 - b1.callCGetZero(false); - b1.callCGetZero(true);//1.4 - } - function test2() public payable{ - C c1 = (new C).value(10)();//1.1 - c1.newBAndTransfer(false); - c1.newBAndTransfer(true);//1.4 - - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract B{ - constructor() payable public{} - function() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero(bool success) public payable{ - if(!success){ - assert(1==2); - } - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract C{ - uint256 public flag=0; - constructor() payable public{} - function() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer(bool success) payable public returns(uint256){ - flag = 1; - if(!success){ - require(2==1); - } - } - function getFlag() public returns(uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction006.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction006.sol deleted file mode 100644 index 6bc548690a5..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction001testInternalTransaction006.sol +++ /dev/null @@ -1,54 +0,0 @@ -//pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable external{} - function test1() public payable{ - B b1 = (new B).value(10)();//1.1 - b1.callCGetZero(true);//1.4 - b1.callCGetZero(false); - } - function test2() public payable{ - C c1 = (new C).value(10)();//1.1 - c1.newBAndTransfer(true);//1.4 - c1.newBAndTransfer(false); - - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract B{ - constructor() payable public{} - function() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero(bool success) public payable{ - if(!success){ - assert(1==2); - } - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract C{ - uint256 public flag=0; - constructor() payable public{} - function() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer(bool success) payable public returns(uint256){ - flag = 1; - if(!success){ - require(2==1); - } - } - function getFlag() public returns(uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test1InternalTransaction007.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test1InternalTransaction007.sol deleted file mode 100644 index 229bf82fa2d..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test1InternalTransaction007.sol +++ /dev/null @@ -1,38 +0,0 @@ -//pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable external{} - function test1(address cAddr) public payable{ - B b1 = (new B).value(10)();//1.1 - B b2 = new B();//1.2 - address(b2).transfer(5);//1.3 - b2.callCGetZero();//1.4 - } - function test2(address cAddress,uint256 amount) public payable{ - cAddress.call.value(amount)(abi.encodeWithSignature("newBAndTransfer()"));//2.1 - } -} - -contract B{ - constructor() payable public{} - function() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero() public{ - assert(1==2); - - } -} - -contract C{ - constructor() payable public{} - function() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test2InternalTransaction008.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test2InternalTransaction008.sol deleted file mode 100644 index a75fba4f14b..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test2InternalTransaction008.sol +++ /dev/null @@ -1,60 +0,0 @@ -//pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable external{} - - function testAssert(address bAddress,uint256 amount) public payable{ - bAddress.call.value(amount).gas(1000000)(abi.encodeWithSignature("callCGetZero(bool)",false));//2.1 - bAddress.call.value(amount).gas(1000000)(abi.encodeWithSignature("callCGetZero(bool)",true)); - } - function testRequire(address cAddress,uint256 amount) public payable{ - cAddress.call.value(amount).gas(1000000)(abi.encodeWithSignature("newBAndTransfer(bool)",false));//2.1 - cAddress.call.value(amount).gas(1000000)(abi.encodeWithSignature("newBAndTransfer(bool)",true)); - } - function testAssert1(address bAddress,uint256 amount) public payable{ - bAddress.call.value(amount).gas(1000000)(abi.encodeWithSignature("callCGetZero(bool)",true)); - bAddress.call.value(amount).gas(1000000)(abi.encodeWithSignature("callCGetZero(bool)",false));//2.1 - } - function testtRequire2(address cAddress,uint256 amount) public payable{ - cAddress.call.value(amount).gas(1000000)(abi.encodeWithSignature("newBAndTransfer(bool)",true)); - cAddress.call.value(amount).gas(1000000)(abi.encodeWithSignature("newBAndTransfer(bool)",false));//2.1 - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract B{ - constructor() payable public{} - function() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero(bool success) payable public{ - if(!success){ - assert(1==2); - } - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract C{ - uint256 public flag=0; - constructor() payable public{} - function() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer(bool success) payable public returns(uint256){ - flag = 1; - if(!success){ - require(2==1); - } - } - function getFlag() public returns(uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test3InternalTransaction009.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test3InternalTransaction009.sol deleted file mode 100644 index 1a7df822511..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test3InternalTransaction009.sol +++ /dev/null @@ -1,47 +0,0 @@ -//pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable external{} - function test1(address cAddr,address dcontract,address baddress) public payable{ - B b1 = (new B).value(10)();//1.1 - address(b1).transfer(5);//1.3 - b1.callCGetZero(cAddr, 1);//1.4 - b1.getOne(dcontract,baddress); - } -} - -contract B{ - constructor() payable public{} - function() payable external{} - function getOne(address contractAddres, address toAddress) payable public{ - contractAddres.call(abi.encodeWithSignature("suicide1(address)",address(this))); - - } - function callCGetZero(address cAddress,uint256 amount) public{ - cAddress.call.value(amount)(abi.encodeWithSignature("getZero()"));//1.5,1.7 - } -} - -contract C{ - constructor() payable public{} - function() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public{ - B b1 = (new B).value(7)();//2.2,2.7 - B b2 = (new B).value(3)();//2.4,2.9 - } -} - -contract D{ - constructor () payable public{} - function suicide1(address payable toAddress) public payable{ - selfdestruct(toAddress); - } - function () payable external{} - function getBalance() public view returns(uint256){ - return address(this).balance; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test4InternalTransaction010.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test4InternalTransaction010.sol deleted file mode 100644 index 7f34b2bfe08..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test4InternalTransaction010.sol +++ /dev/null @@ -1,186 +0,0 @@ -//pragma solidity ^0.4.24; - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - - } - function transfer2() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - - } - function getBalance() public returns(uint256) { - return address(this).balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable public returns(bool) { - return true; - } - constructor() public payable {} - function payC(address payable c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - function () payable external{} - } - diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test4InternalTransaction010_1.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test4InternalTransaction010_1.sol deleted file mode 100644 index c77fe76f5fa..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test4InternalTransaction010_1.sol +++ /dev/null @@ -1,210 +0,0 @@ -pragma solidity ^0.4.24; - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - } - function transfer2() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - - } - function getBalance() returns(uint256){ - return this.balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable returns(bool) { - return true; - } - constructor() public payable {} - function payC(address c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() returns(uint256){ - return this.balance; - } - function () payable{} - } - - \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test5InternalTransaction012.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test5InternalTransaction012.sol deleted file mode 100644 index ce2798888fe..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction002test5InternalTransaction012.sol +++ /dev/null @@ -1,51 +0,0 @@ -//pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable external{} - function test1(address bAddr,address eAddr) public payable{ - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - } - -} - -contract B{ - constructor() payable public{} - function() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function testNN(address eAddress) public payable{ - D d1=(new D).value(1000)(); - d1.getOne(eAddress); - } -} - -contract C{ - constructor() payable public{} - function() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - function() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract D{ - constructor() payable public{} - function() payable external{} - function getOne(address eAddress) payable public returns(uint256){ - eAddress.call.value(1)(abi.encodeWithSignature("getZero()"));//2.1 - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction013.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction013.sol deleted file mode 100644 index bc1d3dbe6cd..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction013.sol +++ /dev/null @@ -1,56 +0,0 @@ -//pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable external{} - function test1(address dAddr) public payable{ - B b1 = (new B).value(10)();//1.1 - b1.testNN(dAddr,2);//1.6 - // C c1 = (new C).value(1000000000000)();//1.2 - // E e1 = (new E).value(1)();//1.2 - } - function test2(address cAddress,uint256 amount) public payable{ - cAddress.call.value(amount)(abi.encodeWithSignature("newBAndTransfer()"));//2.1 - } -} - -contract B{ - constructor() payable public{} - function() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function testNN(address dAddress,uint256 amount) public payable{ - // D d1=(new D)(); - dAddress.call.value(amount)(abi.encodeWithSignature("getOne()"));//2.1 - } -} - -contract C{ - constructor() payable public{} - function() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - function() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract D{ - constructor() payable public{} - function() payable external{} - function getOne() payable public returns(uint256){ - E e = (new E).value(5)(); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction014.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction014.sol deleted file mode 100644 index b3bbfc9a7db..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction014.sol +++ /dev/null @@ -1,38 +0,0 @@ -contract callerContract { - constructor() payable public{} - function() payable external{} - function sendToB(address called_address,address c) public payable{ - called_address.delegatecall(abi.encodeWithSignature("transferTo(address)",c)); - } - function sendToB2(address called_address,address c) public payable{ - called_address.call(abi.encodeWithSignature("transferTo(address)",c)); - } - function sendToB3(address called_address,address c) public payable{ - called_address.delegatecall(abi.encodeWithSignature("transferTo(address)",c)); - } -} - - contract calledContract { - function() payable external {} - constructor() payable public{} - function transferTo(address payable toAddress)public payable{ - toAddress.transfer(5); - } - - function setIinC(address c) public payable{ - c.call.value(5)(abi.encodeWithSignature("setI()")); - } - - } - - contract c{ - uint256 public i=0; - constructor() public payable{} - function getBalance() public view returns(uint256){ - return address(this).balance; - } - function setI() payable public{ - i=5; - } - function() payable external{} - } diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction015.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction015.sol deleted file mode 100644 index 0426d650da4..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction015.sol +++ /dev/null @@ -1,60 +0,0 @@ -//pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable external{} - function test1(address dAddr,address eAddr) public payable{ - B b1 = (new B).value(10)();//1.1 - b1.testNN(dAddr,2,eAddr);//1.6 - // C c1 = (new C).value(1000000000000)();//1.2 - // E e1 = (new E).value(1)();//1.2 - } - function test2(address cAddress,uint256 amount) public payable{ - cAddress.call.value(amount)(abi.encodeWithSignature("newBAndTransfer()"));//2.1 - } -} - -contract B{ - constructor() payable public{} - function() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function testNN(address dAddress,uint256 amount,address eAddress) public payable{ - // D d1=(new D)(); - dAddress.call.value(amount)(abi.encodeWithSignature("getOne(address)",address(this)));//2.1 - } -} - -contract C{ - constructor() payable public{} - function() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - function() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } - function suicide(address payable toAddress) public payable{ - selfdestruct(toAddress); - } -} -contract D{ - constructor() payable public{} - function() payable external{} - function getOne(address payable eAddress) payable public{ - E e = (new E).value(5)(); - e.suicide(eAddress); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction016.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction016.sol deleted file mode 100644 index f97217fe169..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction016.sol +++ /dev/null @@ -1,174 +0,0 @@ -//pragma solidity ^0.4.24; - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function () payable external{} - function transfer() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - B b1=(new B).value(1)();//1 - address payable aaa=address(this); - b1.suicide1(aaa); - } - function transfer2() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - B b1=(new B).value(1)();//1 - address payable aaa=address(this); - b1.suicide1(aaa); - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable public returns(bool) { - return true; - } - constructor() public payable {} - function payC(address payable c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - function () payable external{} - function suicide1(address payable toAddress) public payable{ - selfdestruct(toAddress); - } - } - diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction017.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction017.sol deleted file mode 100644 index ebe570fd8af..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction017.sol +++ /dev/null @@ -1,199 +0,0 @@ -//pragma solidity ^0.4.24; - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer(address payable Address) payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - - B b=(new B).value(1)();//1 - selfdestruct(Address); - } - function transfer2() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable public returns(bool) { - return true; - } - constructor() public payable {} - function payC(address payable c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - function () payable external{} - } - diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction018.sol b/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction018.sol deleted file mode 100644 index a59c587b233..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractInternalTransaction003testInternalTransaction018.sol +++ /dev/null @@ -1,97 +0,0 @@ -//pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable external{} - function test1(address payable bAddr,address eAddr) public payable{ - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - - } - -} - -contract B{ - constructor() payable public{} - function() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function testNN(address eAddress) public payable { - D d1=(new D).value(100)(); - d1.getOne(eAddress); - } -} - -contract C{ - constructor() payable public{} - function() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - function() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract D{ - constructor() payable public{} - function() payable external{} - function getOne(address eAddress) payable public returns(uint256){ - eAddress.call.value(1)(abi.encodeWithSignature("getZero()"));//2.1 - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractLinkage001.sol b/framework/src/test/resources/soliditycode_0.5.15/contractLinkage001.sol deleted file mode 100644 index 4c04cf5c6fb..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractLinkage001.sol +++ /dev/null @@ -1,9 +0,0 @@ -//pragma solidity ^0.4.0; - -contract divideIHaveArgsReturnStorage{ -constructor() payable public{} -function() payable external{} -function divideIHaveArgsReturn(int x,int y) public payable returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractLinkage002.sol b/framework/src/test/resources/soliditycode_0.5.15/contractLinkage002.sol deleted file mode 100644 index ca38896acee..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractLinkage002.sol +++ /dev/null @@ -1,7 +0,0 @@ -//pragma solidity ^0.4.0; - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractLinkage003.sol b/framework/src/test/resources/soliditycode_0.5.15/contractLinkage003.sol deleted file mode 100644 index ca38896acee..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractLinkage003.sol +++ /dev/null @@ -1,7 +0,0 @@ -//pragma solidity ^0.4.0; - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractLinkage004.sol b/framework/src/test/resources/soliditycode_0.5.15/contractLinkage004.sol deleted file mode 100644 index ca38896acee..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractLinkage004.sol +++ /dev/null @@ -1,7 +0,0 @@ -//pragma solidity ^0.4.0; - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractLinkage005.sol b/framework/src/test/resources/soliditycode_0.5.15/contractLinkage005.sol deleted file mode 100644 index 7b943aee5c1..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractLinkage005.sol +++ /dev/null @@ -1,51 +0,0 @@ -contract timeoutTest { - string public iarray1; - // cpu - function oneCpu() public { - require(1==1); - } - - function storage8Char() public { - iarray1 = "12345678"; - } - - function testUseCpu(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - } - return count; - } - - - uint256[] public iarray; - uint public calculatedFibNumber; - mapping(address=>mapping(address=>uint256)) public m; - - function testUseStorage(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - iarray.push(i); - } - return count; - } - - // stack - //uint n = 0; - uint yy = 0; - function test() public { - //n += 1; - yy += 1; - test(); - } - - function setFibonacci(uint n) public returns (uint256){ - calculatedFibNumber = fibonacci(n); - return calculatedFibNumber; - } - - function fibonacci(uint n) internal returns (uint) { - return fibonacci(n - 1) + fibonacci(n - 2); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractLinkage006.sol b/framework/src/test/resources/soliditycode_0.5.15/contractLinkage006.sol deleted file mode 100644 index 9c20c82dc02..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractLinkage006.sol +++ /dev/null @@ -1,18 +0,0 @@ -//pragma solidity ^0.4.0; -contract AA{ - uint256 public count=0; - constructor () payable public{} - function init(address payable addr, uint256 max) payable public { - count =0; - this.hack(addr,max); - } - function hack(address payable addr, uint256 max) payable public { - while (count < max) { - count = count +1; - this.hack(addr,max); - } - if (count == max) { - addr.send(20); - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractOriginEnergyLimit001.sol b/framework/src/test/resources/soliditycode_0.5.15/contractOriginEnergyLimit001.sol deleted file mode 100644 index 212614935f6..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractOriginEnergyLimit001.sol +++ /dev/null @@ -1,11 +0,0 @@ -//pragma solidity ^0.4.0; - -contract findArgsContractTest{ - function findArgsByIndexTest(uint i) public returns (uint z) { - uint[] memory a = new uint[](3); - a[0]=1; - a[1]=2; - a[2]=3; - return a[i]; - } -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractOriginEnergyLimit004.sol b/framework/src/test/resources/soliditycode_0.5.15/contractOriginEnergyLimit004.sol deleted file mode 100644 index 212614935f6..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractOriginEnergyLimit004.sol +++ /dev/null @@ -1,11 +0,0 @@ -//pragma solidity ^0.4.0; - -contract findArgsContractTest{ - function findArgsByIndexTest(uint i) public returns (uint z) { - uint[] memory a = new uint[](3); - a[0]=1; - a[1]=2; - a[2]=3; - return a[i]; - } -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractOtherToTrcToken.sol b/framework/src/test/resources/soliditycode_0.5.15/contractOtherToTrcToken.sol deleted file mode 100644 index 74afd5d0e54..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractOtherToTrcToken.sol +++ /dev/null @@ -1,41 +0,0 @@ -//pragma solidity ^0.4.24; - -contract ConvertType { - -constructor() payable public{} - -function() payable external{} - -//function stringToTrctoken(address payable toAddress, string memory tokenStr, uint256 tokenValue) public { -// trcToken t = trcToken(tokenStr); // ERROR -// toAddress.transferToken(tokenValue, tokenStr); // ERROR -//} - -function uint256ToTrctoken(address payable toAddress, uint256 tokenValue, uint256 tokenInt) public { - trcToken t = trcToken(tokenInt); // OK - toAddress.transferToken(tokenValue, t); // OK - toAddress.transferToken(tokenValue, tokenInt); // OK -} - -function addressToTrctoken(address payable toAddress, uint256 tokenValue, address adr) public { - trcToken t = trcToken(adr); // OK - toAddress.transferToken(tokenValue, t); // OK -//toAddress.transferToken(tokenValue, adr); // ERROR -} - -//function bytesToTrctoken(address payable toAddress, bytes memory b, uint256 tokenValue) public { - // trcToken t = trcToken(b); // ERROR - // toAddress.transferToken(tokenValue, b); // ERROR -//} - -function bytes32ToTrctoken(address payable toAddress, uint256 tokenValue, bytes32 b32) public { - trcToken t = trcToken(b32); // OK - toAddress.transferToken(tokenValue, t); // OK -// toAddress.transferToken(tokenValue, b32); // ERROR -} - -//function arrayToTrctoken(address payable toAddress, uint256[] memory arr, uint256 tokenValue) public { -//trcToken t = trcToken(arr); // ERROR -// toAddress.transferToken(tokenValue, arr); // ERROR -//} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractScenario001.sol b/framework/src/test/resources/soliditycode_0.5.15/contractScenario001.sol deleted file mode 100644 index ca38896acee..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractScenario001.sol +++ /dev/null @@ -1,7 +0,0 @@ -//pragma solidity ^0.4.0; - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractScenario002.sol b/framework/src/test/resources/soliditycode_0.5.15/contractScenario002.sol deleted file mode 100644 index aa9deda79ef..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractScenario002.sol +++ /dev/null @@ -1,53 +0,0 @@ -//pragma solidity ^0.4.0; -contract TronNative{ - - address public voteContractAddress= address(0x10001); - address public freezeBalanceAddress = address(0x10002); - address public unFreezeBalanceAddress = address(0x10003); - address public withdrawBalanceAddress = address(0x10004); - address public approveProposalAddress = address(0x10005); - address public createProposalAddress = address(0x10006); - address public deleteProposalAddress = address(0x10007); - constructor () payable public {} - - function voteForSingleWitness (address payable witnessAddr, uint256 voteValue) public{ - // method 1: - voteContractAddress.delegatecall(abi.encode(witnessAddr,voteValue)); - } - - function voteUsingAssembly (address witnessAddr, uint256 voteValue) public{ - // method 2: - assembly{ - mstore(0x80,witnessAddr) - mstore(0xa0,voteValue) - // gas, address, in, size, out, size - if iszero(delegatecall(0, 0x10001, 0x80, 0x40, 0x80, 0x0)) { - revert(0, 0) - } - } - } - - function freezeBalance(uint256 frozen_Balance,uint256 frozen_Duration) public { - freezeBalanceAddress.delegatecall(abi.encode(frozen_Balance,frozen_Duration)); - } - - function unFreezeBalance() public { - unFreezeBalanceAddress.delegatecall(""); - } - - function withdrawBalance() public { - withdrawBalanceAddress.delegatecall(""); - } - - function approveProposal(uint256 id, bool isApprove) public { - approveProposalAddress.delegatecall(abi.encode(id,isApprove)); - } - - function createProposal(bytes32 [] memory data) public { - createProposalAddress.delegatecall(abi.encode(data)); - } - - function deleteProposal(uint256 id) public{ - deleteProposalAddress.delegatecall(abi.encode(id)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractScenario003.sol b/framework/src/test/resources/soliditycode_0.5.15/contractScenario003.sol deleted file mode 100644 index ca38896acee..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractScenario003.sol +++ /dev/null @@ -1,7 +0,0 @@ -//pragma solidity ^0.4.0; - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractScenario004.sol b/framework/src/test/resources/soliditycode_0.5.15/contractScenario004.sol deleted file mode 100644 index b3ca2687b4c..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractScenario004.sol +++ /dev/null @@ -1,88 +0,0 @@ -//pragma solidity ^0.4.11; - -contract TronToken { - - string public name = "Tronix"; // token name - string public symbol = "TRX"; // token symbol - uint256 public decimals = 6; // token digit - - mapping (address => uint256) public balanceOf; - mapping (address => mapping (address => uint256)) public allowance; - - uint256 public totalSupply = 0; - bool public stopped = false; - - uint256 constant valueFounder = 100000000000000000; - address owner = address(0x0); - - modifier isOwner { - assert(owner == msg.sender); - _; - } - - modifier isRunning { - assert (!stopped); - _; - } - - modifier validAddress { - assert(address(0x0) != msg.sender); - _; - } - - constructor(address _addressFounder) public { - owner = msg.sender; - totalSupply = valueFounder; - balanceOf[_addressFounder] = valueFounder; - emit Transfer(address(0x0), _addressFounder, valueFounder); - } - - function transfer(address _to, uint256 _value) isRunning validAddress public returns (bool success) { - require(balanceOf[msg.sender] >= _value); - require(balanceOf[_to] + _value >= balanceOf[_to]); - balanceOf[msg.sender] -= _value; - balanceOf[_to] += _value; - emit Transfer(msg.sender, _to, _value); - return true; - } - - function transferFrom(address _from, address _to, uint256 _value) isRunning validAddress public returns (bool success) { - require(balanceOf[_from] >= _value); - require(balanceOf[_to] + _value >= balanceOf[_to]); - require(allowance[_from][msg.sender] >= _value); - balanceOf[_to] += _value; - balanceOf[_from] -= _value; - allowance[_from][msg.sender] -= _value; - emit Transfer(_from, _to, _value); - return true; - } - - function approve(address _spender, uint256 _value) isRunning validAddress public returns (bool success) { - require(_value == 0 || allowance[msg.sender][_spender] == 0); - allowance[msg.sender][_spender] = _value; - emit Approval(msg.sender, _spender, _value); - return true; - } - - function stop() isOwner public { - stopped = true; - } - - function start() isOwner public { - stopped = false; - } - - function setName(string memory _name) isOwner public { - name = _name; - } - - function burn(uint256 _value) public { - require(balanceOf[msg.sender] >= _value); - balanceOf[msg.sender] -= _value; - balanceOf[address(0x0)] += _value; - emit Transfer(msg.sender, address(0x0), _value); - } - - event Transfer(address indexed _from, address indexed _to, uint256 _value); - event Approval(address indexed _owner, address indexed _spender, uint256 _value); -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractScenario005.sol b/framework/src/test/resources/soliditycode_0.5.15/contractScenario005.sol deleted file mode 100644 index d46098cd410..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractScenario005.sol +++ /dev/null @@ -1,103 +0,0 @@ -//pragma solidity ^0.4.16; - -interface token { - function transfer(address receiver, uint amount) external; -} - -contract Crowdsale { - address payable public beneficiary = 0x1b228F5D9f934c7bb18Aaa86F90418932888E7b4; // 募资成功后的收款方 - uint public fundingGoal = 10000000; // 募资额度 - uint public amountRaised = 1000000; // 参与数量 - uint public deadline; // 募资截止期 - - uint public price; // token 与以太坊的汇率 , token卖多少钱 - token public tokenReward; // 要卖的token - - mapping(address => uint256) public balanceOf; - - bool fundingGoalReached = false; // 众筹是否达到目标 - bool crowdsaleClosed = false; // 众筹是否结束 - - /** - * 事件可以用来跟踪信息 - **/ - event GoalReached(address recipient, uint totalAmountRaised); - event FundTransfer(address backer, uint amount, bool isContribution); - - /** - * 构造函数, 设置相关属性 - */ - constructor( - address payable ifSuccessfulSendTo, - uint fundingGoalInEthers, - uint durationInMinutes, - uint finneyCostOfEachToken, - address addressOfTokenUsedAsReward) public{ - beneficiary = ifSuccessfulSendTo; - fundingGoal = fundingGoalInEthers * 1 sun; - deadline = now + durationInMinutes * 1 minutes; - price = finneyCostOfEachToken * 1 trx; - tokenReward = token(addressOfTokenUsedAsReward); // 传入已发布的 token 合约的地址来创建实例 - } - - /** - * 无函数名的Fallback函数, - * 在向合约转账时,这个函数会被调用 - */ - function () payable external{ - require(!crowdsaleClosed); - uint amount = msg.value; - balanceOf[msg.sender] += amount; - amountRaised += amount; - tokenReward.transfer(msg.sender, amount / price); - emit FundTransfer(msg.sender, amount, true); - } - - /** - * 定义函数修改器modifier(作用和Python的装饰器很相似) - * 用于在函数执行前检查某种前置条件(判断通过之后才会继续执行该方法) - * _ 表示继续执行之后的代码 - **/ - modifier afterDeadline() { if (now >= deadline) _; } - - /** - * 判断众筹是否完成融资目标, 这个方法使用了afterDeadline函数修改器 - * - */ - function checkGoalReached() afterDeadline public{ - if (amountRaised >= fundingGoal) { - fundingGoalReached = true; - emit GoalReached(beneficiary, amountRaised); - } - crowdsaleClosed = true; - } - - - /** - * 完成融资目标时,融资款发送到收款方 - * 未完成融资目标时,执行退款 - * - */ - function safeWithdrawal() afterDeadline public{ - if (!fundingGoalReached) { - uint amount = balanceOf[msg.sender]; - balanceOf[msg.sender] = 0; - if (amount > 0) { - if (msg.sender.send(amount)) { - emit FundTransfer(msg.sender, amount, false); - } else { - balanceOf[msg.sender] = amount; - } - } - } - - if (fundingGoalReached && beneficiary == msg.sender) { - if (address(beneficiary).send(amountRaised)) { - emit FundTransfer(beneficiary, amountRaised, false); - } else { - //If we fail to send the funds to beneficiary, unlock funders balance - fundingGoalReached = false; - } - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractScenario006.sol b/framework/src/test/resources/soliditycode_0.5.15/contractScenario006.sol deleted file mode 100644 index 397c62096e0..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractScenario006.sol +++ /dev/null @@ -1,1963 +0,0 @@ -//pragma solidity ^0.4.24; - -interface PlayerBookInterface { - function getPlayerID(address _addr) external returns (uint256); - function getPlayerName(uint256 _pID) external view returns (bytes32); - function getPlayerLAff(uint256 _pID) external view returns (uint256); - function getPlayerAddr(uint256 _pID) external view returns (address); - function getNameFee() external view returns (uint256); - function registerNameXIDFromDapp(address _addr, bytes32 _name, uint256 _affCode, bool _all) external payable returns(bool, uint256); - function registerNameXaddrFromDapp(address _addr, bytes32 _name, address _affCode, bool _all) external payable returns(bool, uint256); - function registerNameXnameFromDapp(address _addr, bytes32 _name, bytes32 _affCode, bool _all) external payable returns(bool, uint256); - function isDev(address _who) external view returns(bool); -} - - -/** -* @title -Name Filter- v0.1.9 -* ┌┬┐┌─┐┌─┐┌┬┐ ╦╦ ╦╔═╗╔╦╗ ┌─┐┬─┐┌─┐┌─┐┌─┐┌┐┌┌┬┐┌─┐ -* │ ├┤ ├─┤│││ ║║ ║╚═╗ ║ ├─┘├┬┘├┤ └─┐├┤ │││ │ └─┐ -* ┴ └─┘┴ ┴┴ ┴ ╚╝╚═╝╚═╝ ╩ ┴ ┴└─└─┘└─┘└─┘┘└┘ ┴ └─┘ -* _____ _____ -* (, / /) /) /) (, / /) /) -* ┌─┐ / _ (/_ // // / _ // _ __ _(/ -* ├─┤ ___/___(/_/(__(_/_(/_(/_ ___/__/_)_(/_(_(_/ (_(_(_ -* ┴ ┴ / / .-/ _____ (__ / -* (__ / (_/ (, / /)™ -* / __ __ __ __ _ __ __ _ _/_ _ _(/ -* ┌─┐┬─┐┌─┐┌┬┐┬ ┬┌─┐┌┬┐ /__/ (_(__(_)/ (_/_)_(_)/ (_(_(_(__(/_(_(_ -* ├─┘├┬┘│ │ │││ ││ │ (__ / .-/ © Jekyll Island Inc. 2018 -* ┴ ┴└─└─┘─┴┘└─┘└─┘ ┴ (_/ -* _ __ _ ____ ____ _ _ _____ ____ ___ -*=============| |\ | / /\ | |\/| | |_ =====| |_ | | | | | | | |_ | |_)==============* -*=============|_| \| /_/--\ |_| | |_|__=====|_| |_| |_|__ |_| |_|__ |_| \==============* -* -* ╔═╗┌─┐┌┐┌┌┬┐┬─┐┌─┐┌─┐┌┬┐ ╔═╗┌─┐┌┬┐┌─┐ ┌──────────┐ -* ║ │ ││││ │ ├┬┘├─┤│ │ ║ │ │ ││├┤ │ Inventor │ -* ╚═╝└─┘┘└┘ ┴ ┴└─┴ ┴└─┘ ┴ ╚═╝└─┘─┴┘└─┘ └──────────┘ -*/ - -library NameFilter { - /** - * @dev filters name strings - * -converts uppercase to lower case. - * -makes sure it does not start/end with a space - * -makes sure it does not contain multiple spaces in a row - * -cannot be only numbers - * -cannot start with 0x - * -restricts characters to A-Z, a-z, 0-9, and space. - * @return reprocessed string in bytes32 format - */ - function nameFilter(string memory _input) - internal - pure - returns(bytes32) - { - bytes memory _temp = bytes(_input); - uint256 _length = _temp.length; - - //sorry limited to 32 characters - require (_length <= 32 && _length > 0, "string must be between 1 and 32 characters"); - // make sure it doesnt start with or end with space - require(_temp[0] != 0x20 && _temp[_length-1] != 0x20, "string cannot start or end with space"); - // make sure first two characters are not 0x - if (_temp[0] == 0x30) - { - require(_temp[1] != 0x78, "string cannot start with 0x"); - require(_temp[1] != 0x58, "string cannot start with 0X"); - } - - // create a bool to track if we have a non number character - bool _hasNonNumber; - - // convert & check - for (uint256 i = 0; i < _length; i++) - { - // if its uppercase A-Z - if (_temp[i] > 0x40 && _temp[i] < 0x5b) - { - // convert to lower case a-z - _temp[i] = byte(uint8(_temp[i]) + 32); - - // we have a non number - if (_hasNonNumber == false) - _hasNonNumber = true; - } else { - require - ( - // require character is a space - _temp[i] == 0x20 || - // OR lowercase a-z - (_temp[i] > 0x60 && _temp[i] < 0x7b) || - // or 0-9 - (_temp[i] > 0x2f && _temp[i] < 0x3a), - "string contains invalid characters" - ); - // make sure theres not 2x spaces in a row - if (_temp[i] == 0x20) - require( _temp[i+1] != 0x20, "string cannot contain consecutive spaces"); - - // see if we have a character other than a number - if (_hasNonNumber == false && (_temp[i] < 0x30 || _temp[i] > 0x39)) - _hasNonNumber = true; - } - } - - require(_hasNonNumber == true, "string cannot be only numbers"); - - bytes32 _ret; - assembly { - _ret := mload(add(_temp, 32)) - } - return (_ret); - } -} - - -library SafeMath { - - /** - * @dev Multiplies two numbers, throws on overflow. - */ - function mul(uint256 a, uint256 b) - internal - pure - returns (uint256 c) - { - if (a == 0) { - return 0; - } - c = a * b; - require(c / a == b, "SafeMath mul failed"); - return c; - } - - /** - * @dev Integer division of two numbers, truncating the quotient. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - // assert(b > 0); // Solidity automatically throws when dividing by 0 - uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - return c; - } - - /** - * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). - */ - function sub(uint256 a, uint256 b) - internal - pure - returns (uint256) - { - require(b <= a, "SafeMath sub failed"); - return a - b; - } - - /** - * @dev Adds two numbers, throws on overflow. - */ - function add(uint256 a, uint256 b) - internal - pure - returns (uint256 c) - { - c = a + b; - require(c >= a, "SafeMath add failed"); - return c; - } - - /** - * @dev gives square root of given x. - */ - function sqrt(uint256 x) - internal - pure - returns (uint256 y) - { - uint256 z = ((add(x,1)) / 2); - y = x; - while (z < y) - { - y = z; - z = ((add((x / z),z)) / 2); - } - } - - /** - * @dev gives square. multiplies x by x - */ - function sq(uint256 x) - internal - pure - returns (uint256) - { - return (mul(x,x)); - } - - /** - * @dev x to the power of y - */ - function pwr(uint256 x, uint256 y) - internal - pure - returns (uint256) - { - if (x==0) - return (0); - else if (y==0) - return (1); - else - { - uint256 z = x; - for (uint256 i=1; i < y; i++) - z = mul(z,x); - return (z); - } - } -} - -//============================================================================== -// | _ _ _ | _ . -// |<(/_\/ (_(_||(_ . -//=======/====================================================================== -library F3DKeysCalcLong { - using SafeMath for *; - /** - * @dev calculates number of keys received given X eth - * @param _curEth current amount of eth in contract - * @param _newEth eth being spent - * @return amount of ticket purchased - */ - function keysRec(uint256 _curEth, uint256 _newEth) - internal - pure - returns (uint256) - { - return(keys((_curEth).add(_newEth)).sub(keys(_curEth))); - } - - /** - * @dev calculates amount of eth received if you sold X keys - * @param _curKeys current amount of keys that exist - * @param _sellKeys amount of keys you wish to sell - * @return amount of eth received - */ - function ethRec(uint256 _curKeys, uint256 _sellKeys) - internal - pure - returns (uint256) - { - return((eth(_curKeys)).sub(eth(_curKeys.sub(_sellKeys)))); - } - - /** - * @dev calculates how many keys would exist with given an amount of eth - * @param _eth eth "in contract" - * @return number of keys that would exist - */ - function keys(uint256 _eth) - internal - pure - returns(uint256) - { - return ((((((_eth).mul(1000000000000000000)).mul(312500000000000000000000000)).add(5624988281256103515625000000000000000000000000000000000000000000)).sqrt()).sub(74999921875000000000000000000000)) / (156250000); - } - - /** - * @dev calculates how much eth would be in contract given a number of keys - * @param _keys number of keys "in contract" - * @return eth that would exists - */ - function eth(uint256 _keys) - internal - pure - returns(uint256) - { - return ((78125000).mul(_keys.sq()).add(((149999843750000).mul(_keys.mul(1000000000000000000))) / (2))) / ((1000000000000000000).sq()); - } -} - -library F3Ddatasets { - //compressedData key - // [76-33][32][31][30][29][28-18][17][16-6][5-3][2][1][0] - // 0 - new player (bool) - // 1 - joined round (bool) - // 2 - new leader (bool) - // 3-5 - air drop tracker (uint 0-999) - // 6-16 - round end time - // 17 - winnerTeam - // 18 - 28 timestamp - // 29 - team - // 30 - 0 = reinvest (round), 1 = buy (round), 2 = buy (ico), 3 = reinvest (ico) - // 31 - airdrop happened bool - // 32 - airdrop tier - // 33 - airdrop amount won - //compressedIDs key - // [77-52][51-26][25-0] - // 0-25 - pID - // 26-51 - winPID - // 52-77 - rID - struct EventReturns { - uint256 compressedData; - uint256 compressedIDs; - address winnerAddr; // winner address - bytes32 winnerName; // winner name - uint256 amountWon; // amount won - uint256 newPot; // amount in new pot - uint256 P3DAmount; // amount distributed to p3d - uint256 genAmount; // amount distributed to gen - uint256 potAmount; // amount added to pot - } - struct Player { - address payable addr; // player address - bytes32 name; // player name - uint256 win; // winnings vault - uint256 gen; // general vault - uint256 aff; // affiliate vault - uint256 lrnd; // last round played - uint256 laff; // last affiliate id used - } - struct PlayerRounds { - uint256 eth; // eth player has added to round (used for eth limiter) - uint256 keys; // keys - uint256 mask; // player mask - uint256 ico; // ICO phase investment - } - struct Round { - uint256 plyr; // pID of player in lead - uint256 team; // tID of team in lead - uint256 end; // time ends/ended - bool ended; // has round end function been ran - uint256 strt; // time round started - uint256 keys; // keys - uint256 eth; // total eth in - uint256 pot; // eth to pot (during round) / final amount paid to winner (after round ends) - uint256 mask; // global mask - uint256 ico; // total eth sent in during ICO phase - uint256 icoGen; // total eth for gen during ICO phase - uint256 icoAvg; // average key price for ICO phase - } - struct TeamFee { - uint256 gen; // % of buy in thats paid to key holders of current round - uint256 p3d; // % of buy in thats paid to p3d holders - } - struct PotSplit { - uint256 gen; // % of pot thats paid to key holders of current round - uint256 p3d; // % of pot thats paid to p3d holders - } -} - -contract F3Devents { - // fired whenever a player registers a name - event onNewName - ( - uint256 indexed playerID, - address indexed playerAddress, - bytes32 indexed playerName, - bool isNewPlayer, - uint256 affiliateID, - address affiliateAddress, - bytes32 affiliateName, - uint256 amountPaid, - uint256 timeStamp - ); - - // fired at end of buy or reload - event onEndTx - ( - uint256 compressedData, - uint256 compressedIDs, - bytes32 playerName, - address playerAddress, - uint256 ethIn, - uint256 keysBought, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount, - uint256 potAmount, - uint256 airDropPot - ); - - // fired whenever theres a withdraw - event onWithdraw - ( - uint256 indexed playerID, - address playerAddress, - bytes32 playerName, - uint256 ethOut, - uint256 timeStamp - ); - - // fired whenever a withdraw forces end round to be ran - event onWithdrawAndDistribute - ( - address playerAddress, - bytes32 playerName, - uint256 ethOut, - uint256 compressedData, - uint256 compressedIDs, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount - ); - - // (fomo3d long only) fired whenever a player tries a buy after round timer - // hit zero, and causes end round to be ran. - event onBuyAndDistribute - ( - address playerAddress, - bytes32 playerName, - uint256 ethIn, - uint256 compressedData, - uint256 compressedIDs, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount - ); - - // (fomo3d long only) fired whenever a player tries a reload after round timer - // hit zero, and causes end round to be ran. - event onReLoadAndDistribute - ( - address playerAddress, - bytes32 playerName, - uint256 compressedData, - uint256 compressedIDs, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount - ); - - // fired whenever an affiliate is paid - event onAffiliatePayout - ( - uint256 indexed affiliateID, - address affiliateAddress, - bytes32 affiliateName, - uint256 indexed roundID, - uint256 indexed buyerID, - uint256 amount, - uint256 timeStamp - ); - - // received pot swap deposit - event onPotSwapDeposit - ( - uint256 roundID, - uint256 amountAddedToPot - ); -} - - - -contract FoMo3Dlong is F3Devents { - using SafeMath for *; - using NameFilter for string; - using F3DKeysCalcLong for uint256; - - address public otherF3D_; - address public Divies; - address public Jekyll_Island_Inc; - PlayerBookInterface public playerBook;// =PlayerBookInterface(0x0dcd2f752394c41875e259e00bb44fd505297caf);//new PlayerBook();// - // TeamJustInterface constant private teamJust = TeamJustInterface(0x3a5f8140b9213a0f733a6a639857c9df43ee3f5a);// new TeamJust();// - - //============================================================================== - // _ _ _ |`. _ _ _ |_ | _ _ . - // (_(_)| |~|~|(_||_|| (_||_)|(/__\ . (game settings) - //=================_|=========================================================== - string constant public name = "FoMo3D Long Official"; - string constant public symbol = "F3D"; - uint256 private rndExtra_ = 30;//extSettings.getLongExtra(); // length of the very first ICO - uint256 private rndGap_ = 30; //extSettings.getLongGap(); // length of ICO phase, set to 1 year for EOS. - uint256 constant private rndInit_ = 1 hours; // round timer starts at this - uint256 constant private rndInc_ = 30 seconds; // every full key purchased adds this much to the timer - uint256 constant private rndMax_ = 24 hours; // max length a round timer can be - //============================================================================== - // _| _ _|_ _ _ _ _|_ _ . - // (_|(_| | (_| _\(/_ | |_||_) . (data used to store game info that changes) - //=============================|================================================ - uint256 public airDropPot_; // person who gets the airdrop wins part of this pot - uint256 public airDropTracker_ = 0; // incremented each time a "qualified" tx occurs. used to determine winning air drop - uint256 public rID_; // round id number / total rounds that have happened - //**************** - // PLAYER DATA - //**************** - mapping(address => uint256) public pIDxAddr_; // (addr => pID) returns player id by address - mapping(bytes32 => uint256) public pIDxName_; // (name => pID) returns player id by name - mapping(uint256 => F3Ddatasets.Player) public plyr_; // (pID => data) player data - mapping(uint256 => mapping(uint256 => F3Ddatasets.PlayerRounds)) public plyrRnds_; // (pID => rID => data) player round data by player id & round id - mapping(uint256 => mapping(bytes32 => bool)) public plyrNames_; // (pID => name => bool) list of names a player owns. (used so you can change your display name amongst any name you own) - //**************** - // ROUND DATA - //**************** - mapping(uint256 => F3Ddatasets.Round) public round_; // (rID => data) round data - mapping(uint256 => mapping(uint256 => uint256)) public rndTmEth_; // (rID => tID => data) eth in per team, by round id and team id - //**************** - // TEAM FEE DATA - //**************** - mapping(uint256 => F3Ddatasets.TeamFee) public fees_; // (team => fees) fee distribution by team - mapping(uint256 => F3Ddatasets.PotSplit) public potSplit_; // (team => fees) pot split distribution by team - - function setPlayerBook(address _playerBook) external { - require(msg.sender == owner, 'only dev!'); - require(address(playerBook) == address(0), 'already set!'); - playerBook = PlayerBookInterface(_playerBook); - } - - address public owner; - - //============================================================================== - // _ _ _ __|_ _ __|_ _ _ . - // (_(_)| |_\ | | |_|(_ | (_)| . (initial data setup upon contract deploy) - //============================================================================== - constructor() - public - { - owner = msg.sender; - // Team allocation structures - // 0 = whales - // 1 = bears - // 2 = sneks - // 3 = bulls - - // Team allocation percentages - // (F3D, P3D) + (Pot , Referrals, Community) - // Referrals / Community rewards are mathematically designed to come from the winner's share of the pot. - fees_[0] = F3Ddatasets.TeamFee(30, 6); - //50% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - fees_[1] = F3Ddatasets.TeamFee(43, 0); - //43% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - fees_[2] = F3Ddatasets.TeamFee(56, 10); - //20% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - fees_[3] = F3Ddatasets.TeamFee(43, 8); - //35% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - - // how to split up the final pot based on which team was picked - // (F3D, P3D) - potSplit_[0] = F3Ddatasets.PotSplit(15, 10); - //48% to winner, 25% to next round, 2% to com - potSplit_[1] = F3Ddatasets.PotSplit(25, 0); - //48% to winner, 25% to next round, 2% to com - potSplit_[2] = F3Ddatasets.PotSplit(20, 20); - //48% to winner, 10% to next round, 2% to com - potSplit_[3] = F3Ddatasets.PotSplit(30, 10); - //48% to winner, 10% to next round, 2% to com - } - //============================================================================== - // _ _ _ _|. |`. _ _ _ . - // | | |(_)(_||~|~|(/_| _\ . (these are safety checks) - //============================================================================== - /** - * @dev used to make sure no one can interact with contract until it has - * been activated. - */ - modifier isActivated() { - require(activated_ == true, "its not ready yet. check ?eta in discord"); - _; - } - - /** - * @dev prevents contracts from interacting with fomo3d - */ - modifier isHuman() { - address _addr = msg.sender; - uint256 _codeLength; - - assembly {_codeLength := extcodesize(_addr)} - require(_codeLength == 0, "sorry humans only"); - _; - } - - modifier onlyDevs() - { - require(playerBook.isDev(msg.sender) == true, "msg sender is not a dev"); - _; - } - - /** - * @dev sets boundaries for incoming tx - */ - modifier isWithinLimits(uint256 _eth) { - require(_eth >= 1000000000, "pocket lint: not a valid currency"); - require(_eth <= 100000000000000000000000, "no vitalik, no"); - _; - } - - //============================================================================== - // _ |_ |. _ |` _ __|_. _ _ _ . - // |_)|_||_)||(_ ~|~|_|| |(_ | |(_)| |_\ . (use these to interact with contract) - //====|========================================================================= - /** - * @dev emergency buy uses last stored affiliate ID and team snek - */ - function() - isActivated() - isHuman() - isWithinLimits(msg.value) - external - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_ ; - _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // buy core - buyCore(_pID, plyr_[_pID].laff, 2, _eventData_); - } - - /** - * @dev converts all incoming ethereum to keys. - * -functionhash- 0x8f38f309 (using ID for affiliate) - * -functionhash- 0x98a0871d (using address for affiliate) - * -functionhash- 0xa65b37a1 (using name for affiliate) - * @param _affCode the ID/address/name of the player who gets the affiliate fee - * @param _team what team is the player playing for? - */ - function buyXid(uint256 _affCode, uint256 _team) - isActivated() - isHuman() - isWithinLimits(msg.value) - public - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_; - _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == 0 || _affCode == _pID) - { - // use last stored affiliate code - _affCode = plyr_[_pID].laff; - - // if affiliate code was given & its not the same as previously stored - } else if (_affCode != plyr_[_pID].laff) { - // update last affiliate - plyr_[_pID].laff = _affCode; - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // buy core - buyCore(_pID, _affCode, _team, _eventData_); - } - - function buyXaddr(address _affCode, uint256 _team) - isActivated() - isHuman() - isWithinLimits(msg.value) - public - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_; - _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == address(0) || _affCode == msg.sender) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxAddr_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // buy core - buyCore(_pID, _affID, _team, _eventData_); - } - - function buyXname(bytes32 _affCode, uint256 _team) - isActivated() - isHuman() - isWithinLimits(msg.value) - public - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_ ; - _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == '' || _affCode == plyr_[_pID].name) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxName_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // buy core - buyCore(_pID, _affID, _team, _eventData_); - } - - /** - * @dev essentially the same as buy, but instead of you sending ether - * from your wallet, it uses your unwithdrawn earnings. - * -functionhash- 0x349cdcac (using ID for affiliate) - * -functionhash- 0x82bfc739 (using address for affiliate) - * -functionhash- 0x079ce327 (using name for affiliate) - * @param _affCode the ID/address/name of the player who gets the affiliate fee - * @param _team what team is the player playing for? - * @param _eth amount of earnings to use (remainder returned to gen vault) - */ - function reLoadXid(uint256 _affCode, uint256 _team, uint256 _eth) - isActivated() - isHuman() - isWithinLimits(_eth) - public - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == 0 || _affCode == _pID) - { - // use last stored affiliate code - _affCode = plyr_[_pID].laff; - - // if affiliate code was given & its not the same as previously stored - } else if (_affCode != plyr_[_pID].laff) { - // update last affiliate - plyr_[_pID].laff = _affCode; - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // reload core - reLoadCore(_pID, _affCode, _team, _eth, _eventData_); - } - - function reLoadXaddr(address _affCode, uint256 _team, uint256 _eth) - isActivated() - isHuman() - isWithinLimits(_eth) - public - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == address(0) || _affCode == msg.sender) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxAddr_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // reload core - reLoadCore(_pID, _affID, _team, _eth, _eventData_); - } - - function reLoadXname(bytes32 _affCode, uint256 _team, uint256 _eth) - isActivated() - isHuman() - isWithinLimits(_eth) - public - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == '' || _affCode == plyr_[_pID].name) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxName_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // reload core - reLoadCore(_pID, _affID, _team, _eth, _eventData_); - } - - /** - * @dev withdraws all of your earnings. - * -functionhash- 0x3ccfd60b - */ - function withdraw() - isActivated() - isHuman() - public - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // setup temp var for player eth - uint256 _eth; - - // check to see if round has ended and no one has run round end yet - if (_now > round_[_rID].end && round_[_rID].ended == false && round_[_rID].plyr != 0) - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // end the round (distributes pot) - round_[_rID].ended = true; - _eventData_ = endRound(_eventData_); - - // get their earnings - _eth = withdrawEarnings(_pID); - - // gib moni - if (_eth > 0) - plyr_[_pID].addr.transfer(_eth); - - // build event data - _eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID; - - // fire withdraw and distribute event - emit F3Devents.onWithdrawAndDistribute - ( - msg.sender, - plyr_[_pID].name, - _eth, - _eventData_.compressedData, - _eventData_.compressedIDs, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount - ); - - // in any other situation - } else { - // get their earnings - _eth = withdrawEarnings(_pID); - - // gib moni - if (_eth > 0) - plyr_[_pID].addr.transfer(_eth); - - // fire withdraw event - emit F3Devents.onWithdraw(_pID, msg.sender, plyr_[_pID].name, _eth, _now); - } - } - - /** - * @dev use these to register names. they are just wrappers that will send the - * registration requests to the PlayerBook contract. So registering here is the - * same as registering there. UI will always display the last name you registered. - * but you will still own all previously registered names to use as affiliate - * links. - * - must pay a registration fee. - * - name must be unique - * - names will be converted to lowercase - * - name cannot start or end with a space - * - cannot have more than 1 space in a row - * - cannot be only numbers - * - cannot start with 0x - * - name must be at least 1 char - * - max length of 32 characters long - * - allowed characters: a-z, 0-9, and space - * -functionhash- 0x921dec21 (using ID for affiliate) - * -functionhash- 0x3ddd4698 (using address for affiliate) - * -functionhash- 0x685ffd83 (using name for affiliate) - * @param _nameString players desired name - * @param _affCode affiliate ID, address, or name of who referred you - * @param _all set to true if you want this to push your info to all games - * (this might cost a lot of gas) - */ - function registerNameXID(string memory _nameString, uint256 _affCode, bool _all) - isHuman() - public - payable - { - bytes32 _name = _nameString.nameFilter(); - address _addr = msg.sender; - uint256 _paid = msg.value; - (bool _isNewPlayer, uint256 _affID) = playerBook.registerNameXIDFromDapp.value(_paid)(_addr, _name, _affCode, _all); - - uint256 _pID = pIDxAddr_[_addr]; - - // fire event - emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, now); - } - - function registerNameXaddr(string memory _nameString, address _affCode, bool _all) - isHuman() - public - payable - { - bytes32 _name = _nameString.nameFilter(); - address _addr = msg.sender; - uint256 _paid = msg.value; - (bool _isNewPlayer, uint256 _affID) = playerBook.registerNameXaddrFromDapp.value(msg.value)(msg.sender, _name, _affCode, _all); - - uint256 _pID = pIDxAddr_[_addr]; - - // fire event - emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, now); - } - - function registerNameXname(string memory _nameString, bytes32 _affCode, bool _all) - isHuman() - public - payable - { - bytes32 _name = _nameString.nameFilter(); - address _addr = msg.sender; - uint256 _paid = msg.value; - (bool _isNewPlayer, uint256 _affID) = playerBook.registerNameXnameFromDapp.value(msg.value)(msg.sender, _name, _affCode, _all); - - uint256 _pID = pIDxAddr_[_addr]; - - // fire event - emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, now); - } - //============================================================================== - // _ _ _|__|_ _ _ _ . - // (_|(/_ | | (/_| _\ . (for UI & viewing things on etherscan) - //=====_|======================================================================= - /** - * @dev return the price buyer will pay for next 1 individual key. - * -functionhash- 0x018a25e8 - * @return price for next key bought (in wei format) - */ - function getBuyPrice() - public - view - returns (uint256) - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - // are we in a round? - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - return ((round_[_rID].keys.add(1000000000000000000)).ethRec(1000000000000000000)); - else // rounds over. need price for new round - return (75000000000000); - // init - } - - /** - * @dev returns time left. dont spam this, you'll ddos yourself from your node - * provider - * -functionhash- 0xc7e284b8 - * @return time left in seconds - */ - function getTimeLeft() - public - view - returns (uint256) - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - if (_now < round_[_rID].end) - if (_now > round_[_rID].strt + rndGap_) - return ((round_[_rID].end).sub(_now)); - else - return ((round_[_rID].strt + rndGap_).sub(_now)); - else - return (0); - } - - /** - * @dev returns player earnings per vaults - * -functionhash- 0x63066434 - * @return winnings vault - * @return general vault - * @return affiliate vault - */ - function getPlayerVaults(uint256 _pID) - public - view - returns (uint256, uint256, uint256) - { - // setup local rID - uint256 _rID = rID_; - - // if round has ended. but round end has not been run (so contract has not distributed winnings) - if (now > round_[_rID].end && round_[_rID].ended == false && round_[_rID].plyr != 0) - { - // if player is winner - if (round_[_rID].plyr == _pID) - { - return - ( - (plyr_[_pID].win).add(((round_[_rID].pot).mul(48)) / 100), - (plyr_[_pID].gen).add(getPlayerVaultsHelper(_pID, _rID).sub(plyrRnds_[_pID][_rID].mask)), - plyr_[_pID].aff - ); - // if player is not the winner - } else { - return - ( - plyr_[_pID].win, - (plyr_[_pID].gen).add(getPlayerVaultsHelper(_pID, _rID).sub(plyrRnds_[_pID][_rID].mask)), - plyr_[_pID].aff - ); - } - - // if round is still going on, or round has ended and round end has been ran - } else { - return - ( - plyr_[_pID].win, - (plyr_[_pID].gen).add(calcUnMaskedEarnings(_pID, plyr_[_pID].lrnd)), - plyr_[_pID].aff - ); - } - } - - /** - * solidity hates stack limits. this lets us avoid that hate - */ - function getPlayerVaultsHelper(uint256 _pID, uint256 _rID) - private - view - returns (uint256) - { - return (((((round_[_rID].mask).add(((((round_[_rID].pot).mul(potSplit_[round_[_rID].team].gen)) / 100).mul(1000000000000000000)) / (round_[_rID].keys))).mul(plyrRnds_[_pID][_rID].keys)) / 1000000000000000000)); - } - - /** - * @dev returns all current round info needed for front end - * -functionhash- 0x747dff42 - * @return eth invested during ICO phase - * @return round id - * @return total keys for round - * @return time round ends - * @return time round started - * @return current pot - * @return current team ID & player ID in lead - * @return current player in leads address - * @return current player in leads name - * @return whales eth in for round - * @return bears eth in for round - * @return sneks eth in for round - * @return bulls eth in for round - * @return airdrop tracker # & airdrop pot - */ - function getCurrentRoundInfo() - public - view - returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256, address, bytes32, uint256, uint256, uint256, uint256, uint256) - { - // setup local rID - uint256 _rID = rID_; - - return - ( - round_[_rID].ico, //0 - _rID, //1 - round_[_rID].keys, //2 - round_[_rID].end, //3 - round_[_rID].strt, //4 - round_[_rID].pot, //5 - (round_[_rID].team + (round_[_rID].plyr * 10)), //6 - plyr_[round_[_rID].plyr].addr, //7 - plyr_[round_[_rID].plyr].name, //8 - rndTmEth_[_rID][0], //9 - rndTmEth_[_rID][1], //10 - rndTmEth_[_rID][2], //11 - rndTmEth_[_rID][3], //12 - airDropTracker_ + (airDropPot_ * 1000) //13 - ); - } - - /** - * @dev returns player info based on address. if no address is given, it will - * use msg.sender - * -functionhash- 0xee0b5d8b - * @param _addr address of the player you want to lookup - * @return player ID - * @return player name - * @return keys owned (current round) - * @return winnings vault - * @return general vault - * @return affiliate vault - * @return player round eth - */ - function getPlayerInfoByAddress(address _addr) - public - view - returns (uint256, bytes32, uint256, uint256, uint256, uint256, uint256) - { - // setup local rID - uint256 _rID = rID_; - - if (_addr == address(0)) - { - _addr == msg.sender; - } - uint256 _pID = pIDxAddr_[_addr]; - - return - ( - _pID, //0 - plyr_[_pID].name, //1 - plyrRnds_[_pID][_rID].keys, //2 - plyr_[_pID].win, //3 - (plyr_[_pID].gen).add(calcUnMaskedEarnings(_pID, plyr_[_pID].lrnd)), //4 - plyr_[_pID].aff, //5 - plyrRnds_[_pID][_rID].eth //6 - ); - } - - //============================================================================== - // _ _ _ _ | _ _ . _ . - // (_(_)| (/_ |(_)(_||(_ . (this + tools + calcs + modules = our softwares engine) - //=====================_|======================================================= - /** - * @dev logic runs whenever a buy order is executed. determines how to handle - * incoming eth depending on if we are in an active round or not - */ - function buyCore(uint256 _pID, uint256 _affID, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) - private - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - // if round is active - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - { - // call core - core(_rID, _pID, msg.value, _affID, _team, _eventData_); - - // if round is not active - } else { - // check to see if end round needs to be ran - if (_now > round_[_rID].end && round_[_rID].ended == false) - { - // end the round (distributes pot) & start new round - round_[_rID].ended = true; - _eventData_ = endRound(_eventData_); - - // build event data - _eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID; - - // fire buy and distribute event - emit F3Devents.onBuyAndDistribute - ( - msg.sender, - plyr_[_pID].name, - msg.value, - _eventData_.compressedData, - _eventData_.compressedIDs, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount - ); - } - - // put eth in players vault - plyr_[_pID].gen = plyr_[_pID].gen.add(msg.value); - } - } - - /** - * @dev logic runs whenever a reload order is executed. determines how to handle - * incoming eth depending on if we are in an active round or not - */ - function reLoadCore(uint256 _pID, uint256 _affID, uint256 _team, uint256 _eth, F3Ddatasets.EventReturns memory _eventData_) - private - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - // if round is active - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - { - // get earnings from all vaults and return unused to gen vault - // because we use a custom safemath library. this will throw if player - // tried to spend more eth than they have. - plyr_[_pID].gen = withdrawEarnings(_pID).sub(_eth); - - // call core - core(_rID, _pID, _eth, _affID, _team, _eventData_); - - // if round is not active and end round needs to be ran - } else if (_now > round_[_rID].end && round_[_rID].ended == false) { - // end the round (distributes pot) & start new round - round_[_rID].ended = true; - _eventData_ = endRound(_eventData_); - - // build event data - _eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID; - - // fire buy and distribute event - emit F3Devents.onReLoadAndDistribute - ( - msg.sender, - plyr_[_pID].name, - _eventData_.compressedData, - _eventData_.compressedIDs, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount - ); - } - } - - /** - * @dev this is the core logic for any buy/reload that happens while a round - * is live. - */ - function core(uint256 _rID, uint256 _pID, uint256 _eth, uint256 _affID, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) - private - { - // if player is new to round - if (plyrRnds_[_pID][_rID].keys == 0) - _eventData_ = managePlayer(_pID, _eventData_); - - // early round eth limiter - if (round_[_rID].eth < 100000000000000000000 && plyrRnds_[_pID][_rID].eth.add(_eth) > 1000000000000000000) - { - uint256 _availableLimit = (1000000000000000000).sub(plyrRnds_[_pID][_rID].eth); - uint256 _refund = _eth.sub(_availableLimit); - plyr_[_pID].gen = plyr_[_pID].gen.add(_refund); - _eth = _availableLimit; - } - - // if eth left is greater than min eth allowed (sorry no pocket lint) - if (_eth > 1000000000) - { - - // mint the new keys - uint256 _keys = (round_[_rID].eth).keysRec(_eth); - - // if they bought at least 1 whole key - if (_keys >= 1000000000000000000) - { - updateTimer(_keys, _rID); - - // set new leaders - if (round_[_rID].plyr != _pID) - round_[_rID].plyr = _pID; - if (round_[_rID].team != _team) - round_[_rID].team = _team; - - // set the new leader bool to true - _eventData_.compressedData = _eventData_.compressedData + 100; - } - - // manage airdrops - if (_eth >= 100000000000000000) - { - airDropTracker_++; - if (airdrop() == true) - { - // gib muni - uint256 _prize; - if (_eth >= 10000000000000000000) - { - // calculate prize and give it to winner - _prize = ((airDropPot_).mul(75)) / 100; - plyr_[_pID].win = (plyr_[_pID].win).add(_prize); - - // adjust airDropPot - airDropPot_ = (airDropPot_).sub(_prize); - - // let event know a tier 3 prize was won - _eventData_.compressedData += 300000000000000000000000000000000; - } else if (_eth >= 1000000000000000000 && _eth < 10000000000000000000) { - // calculate prize and give it to winner - _prize = ((airDropPot_).mul(50)) / 100; - plyr_[_pID].win = (plyr_[_pID].win).add(_prize); - - // adjust airDropPot - airDropPot_ = (airDropPot_).sub(_prize); - - // let event know a tier 2 prize was won - _eventData_.compressedData += 200000000000000000000000000000000; - } else if (_eth >= 100000000000000000 && _eth < 1000000000000000000) { - // calculate prize and give it to winner - _prize = ((airDropPot_).mul(25)) / 100; - plyr_[_pID].win = (plyr_[_pID].win).add(_prize); - - // adjust airDropPot - airDropPot_ = (airDropPot_).sub(_prize); - - // let event know a tier 3 prize was won - _eventData_.compressedData += 300000000000000000000000000000000; - } - // set airdrop happened bool to true - _eventData_.compressedData += 10000000000000000000000000000000; - // let event know how much was won - _eventData_.compressedData += _prize * 1000000000000000000000000000000000; - - // reset air drop tracker - airDropTracker_ = 0; - } - } - - // store the air drop tracker number (number of buys since last airdrop) - _eventData_.compressedData = _eventData_.compressedData + (airDropTracker_ * 1000); - - // update player - plyrRnds_[_pID][_rID].keys = _keys.add(plyrRnds_[_pID][_rID].keys); - plyrRnds_[_pID][_rID].eth = _eth.add(plyrRnds_[_pID][_rID].eth); - - // update round - round_[_rID].keys = _keys.add(round_[_rID].keys); - round_[_rID].eth = _eth.add(round_[_rID].eth); - rndTmEth_[_rID][_team] = _eth.add(rndTmEth_[_rID][_team]); - - // distribute eth - _eventData_ = distributeExternal(_rID, _pID, _eth, _affID, _team, _eventData_); - _eventData_ = distributeInternal(_rID, _pID, _eth, _team, _keys, _eventData_); - - // call end tx function to fire end tx event. - endTx(_pID, _team, _eth, _keys, _eventData_); - } - } - //============================================================================== - // _ _ | _ | _ _|_ _ _ _ . - // (_(_||(_|_||(_| | (_)| _\ . - //============================================================================== - /** - * @dev calculates unmasked earnings (just calculates, does not update mask) - * @return earnings in wei format - */ - function calcUnMaskedEarnings(uint256 _pID, uint256 _rIDlast) - private - view - returns (uint256) - { - return ((((round_[_rIDlast].mask).mul(plyrRnds_[_pID][_rIDlast].keys)) / (1000000000000000000)).sub(plyrRnds_[_pID][_rIDlast].mask)); - } - - /** - * @dev returns the amount of keys you would get given an amount of eth. - * -functionhash- 0xce89c80c - * @param _rID round ID you want price for - * @param _eth amount of eth sent in - * @return keys received - */ - function calcKeysReceived(uint256 _rID, uint256 _eth) - public - view - returns (uint256) - { - // grab time - uint256 _now = now; - - // are we in a round? - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - return ((round_[_rID].eth).keysRec(_eth)); - else // rounds over. need keys for new round - return ((_eth).keys()); - } - - /** - * @dev returns current eth price for X keys. - * -functionhash- 0xcf808000 - * @param _keys number of keys desired (in 18 decimal format) - * @return amount of eth needed to send - */ - function iWantXKeys(uint256 _keys) - public - view - returns (uint256) - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - // are we in a round? - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - return ((round_[_rID].keys.add(_keys)).ethRec(_keys)); - else // rounds over. need price for new round - return ((_keys).eth()); - } - //============================================================================== - // _|_ _ _ | _ . - // | (_)(_)|_\ . - //============================================================================== - /** - * @dev receives name/player info from names contract - */ - function receivePlayerInfo(uint256 _pID, address payable _addr, bytes32 _name, uint256 _laff) - external - { - require(msg.sender == address(playerBook), "your not playerNames contract... hmmm.."); - if (pIDxAddr_[_addr] != _pID) - pIDxAddr_[_addr] = _pID; - if (pIDxName_[_name] != _pID) - pIDxName_[_name] = _pID; - if (plyr_[_pID].addr != _addr) - plyr_[_pID].addr = _addr; - if (plyr_[_pID].name != _name) - plyr_[_pID].name = _name; - if (plyr_[_pID].laff != _laff) - plyr_[_pID].laff = _laff; - if (plyrNames_[_pID][_name] == false) - plyrNames_[_pID][_name] = true; - } - - /** - * @dev receives entire player name list - */ - function receivePlayerNameList(uint256 _pID, bytes32 _name) - external - { - require(msg.sender == address(playerBook), "your not playerNames contract... hmmm.."); - if (plyrNames_[_pID][_name] == false) - plyrNames_[_pID][_name] = true; - } - - /** - * @dev gets existing or registers new pID. use this when a player may be new - * @return pID - */ - function determinePID(F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - uint256 _pID = pIDxAddr_[msg.sender]; - // if player is new to this version of fomo3d - if (_pID == 0) - { - // grab their player ID, name and last aff ID, from player names contract - _pID = playerBook.getPlayerID(msg.sender); - bytes32 _name = playerBook.getPlayerName(_pID); - uint256 _laff = playerBook.getPlayerLAff(_pID); - - // set up player account - pIDxAddr_[msg.sender] = _pID; - plyr_[_pID].addr = msg.sender; - - if (_name != "") - { - pIDxName_[_name] = _pID; - plyr_[_pID].name = _name; - plyrNames_[_pID][_name] = true; - } - - if (_laff != 0 && _laff != _pID) - plyr_[_pID].laff = _laff; - - // set the new player bool to true - _eventData_.compressedData = _eventData_.compressedData + 1; - } - return (_eventData_); - } - - /** - * @dev checks to make sure user picked a valid team. if not sets team - * to default (sneks) - */ - function verifyTeam(uint256 _team) - private - pure - returns (uint256) - { - if (_team < 0 || _team > 3) - return (2); - else - return (_team); - } - - /** - * @dev decides if round end needs to be run & new round started. and if - * player unmasked earnings from previously played rounds need to be moved. - */ - function managePlayer(uint256 _pID, F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - // if player has played a previous round, move their unmasked earnings - // from that round to gen vault. - if (plyr_[_pID].lrnd != 0) - updateGenVault(_pID, plyr_[_pID].lrnd); - - // update player's last round played - plyr_[_pID].lrnd = rID_; - - // set the joined round bool to true - _eventData_.compressedData = _eventData_.compressedData + 10; - - return (_eventData_); - } - - /** - * @dev ends the round. manages paying out winner/splitting up pot - */ - function endRound(F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - // setup local rID - uint256 _rID = rID_; - - // grab our winning player and team id's - uint256 _winPID = round_[_rID].plyr; - uint256 _winTID = round_[_rID].team; - - // grab our pot amount - uint256 _pot = round_[_rID].pot; - - // calculate our winner share, community rewards, gen share, - // p3d share, and amount reserved for next pot - uint256 _win = (_pot.mul(48)) / 100; - uint256 _com = (_pot / 50); - uint256 _gen = (_pot.mul(potSplit_[_winTID].gen)) / 100; - uint256 _p3d = (_pot.mul(potSplit_[_winTID].p3d)) / 100; - uint256 _res = (((_pot.sub(_win)).sub(_com)).sub(_gen)).sub(_p3d); - - // calculate ppt for round mask - uint256 _ppt = (_gen.mul(1000000000000000000)) / (round_[_rID].keys); - uint256 _dust = _gen.sub((_ppt.mul(round_[_rID].keys)) / 1000000000000000000); - if (_dust > 0) - { - _gen = _gen.sub(_dust); - _res = _res.add(_dust); - } - - // pay our winner - plyr_[_winPID].win = _win.add(plyr_[_winPID].win); - - // community rewards - address payable add = address(uint160(Jekyll_Island_Inc)); - if (!add.send(_com)) - { - // This ensures Team Just cannot influence the outcome of FoMo3D with - // bank migrations by breaking outgoing transactions. - // Something we would never do. But that's not the point. - // We spent 2000$ in eth re-deploying just to patch this, we hold the - // highest belief that everything we create should be trustless. - // Team JUST, The name you shouldn't have to trust. - _p3d = _p3d.add(_com); - _com = 0; - } - - // distribute gen portion to key holders - round_[_rID].mask = _ppt.add(round_[_rID].mask); - - // send share for p3d to divies - if (_p3d > 0){ - address payable addr = address(uint160(Divies)); - addr.transfer(_p3d); - } - // prepare event data - _eventData_.compressedData = _eventData_.compressedData + (round_[_rID].end * 1000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + (_winPID * 100000000000000000000000000) + (_winTID * 100000000000000000); - _eventData_.winnerAddr = plyr_[_winPID].addr; - _eventData_.winnerName = plyr_[_winPID].name; - _eventData_.amountWon = _win; - _eventData_.genAmount = _gen; - _eventData_.P3DAmount = _p3d; - _eventData_.newPot = _res; - - // start next round - rID_++; - _rID++; - round_[_rID].strt = now; - round_[_rID].end = now.add(rndInit_).add(rndGap_); - round_[_rID].pot = _res; - - return (_eventData_); - } - - /** - * @dev moves any unmasked earnings to gen vault. updates earnings mask - */ - function updateGenVault(uint256 _pID, uint256 _rIDlast) - private - { - uint256 _earnings = calcUnMaskedEarnings(_pID, _rIDlast); - if (_earnings > 0) - { - // put in gen vault - plyr_[_pID].gen = _earnings.add(plyr_[_pID].gen); - // zero out their earnings by updating mask - plyrRnds_[_pID][_rIDlast].mask = _earnings.add(plyrRnds_[_pID][_rIDlast].mask); - } - } - - /** - * @dev updates round timer based on number of whole keys bought. - */ - function updateTimer(uint256 _keys, uint256 _rID) - private - { - // grab time - uint256 _now = now; - - // calculate time based on number of keys bought - uint256 _newTime; - if (_now > round_[_rID].end && round_[_rID].plyr == 0) - _newTime = (((_keys) / (1000000000000000000)).mul(rndInc_)).add(_now); - else - _newTime = (((_keys) / (1000000000000000000)).mul(rndInc_)).add(round_[_rID].end); - - // compare to max and set new end time - if (_newTime < (rndMax_).add(_now)) - round_[_rID].end = _newTime; - else - round_[_rID].end = rndMax_.add(_now); - } - - /** - * @dev generates a random number between 0-99 and checks to see if thats - * resulted in an airdrop win - * @return do we have a winner? - */ - function airdrop() - private - view - returns (bool) - { - uint256 seed = uint256(keccak256(abi.encodePacked( - - (block.timestamp).add - (block.difficulty).add - ((uint256(keccak256(abi.encodePacked(block.coinbase)))) / (now)).add - (block.gaslimit).add - ((uint256(keccak256(abi.encodePacked(msg.sender)))) / (now)).add - (block.number) - - ))); - if ((seed - ((seed / 1000) * 1000)) < airDropTracker_) - return (true); - else - return (false); - } - - /** - * @dev distributes eth based on fees to com, aff, and p3d - */ - function distributeExternal(uint256 _rID, uint256 _pID, uint256 _eth, uint256 _affID, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - // pay 2% out to community rewards - uint256 _com = _eth / 50; - uint256 _p3d; - address payable addr = address(uint160(Jekyll_Island_Inc)); - if (!addr.send(_com)) - { - // This ensures Team Just cannot influence the outcome of FoMo3D with - // bank migrations by breaking outgoing transactions. - // Something we would never do. But that's not the point. - // We spent 2000$ in eth re-deploying just to patch this, we hold the - // highest belief that everything we create should be trustless. - // Team JUST, The name you shouldn't have to trust. - _p3d = _com; - _com = 0; - } - - // pay 1% out to FoMo3D short - _com = _eth / 100; - address payable add = address(uint160(otherF3D_)); - add.transfer(_com); - - // distribute share to affiliate - _com = _eth / 10; - - // decide what to do with affiliate share of fees - // affiliate must not be self, and must have a name registered - if (_affID != _pID && plyr_[_affID].name != '') { - plyr_[_affID].aff = _com.add(plyr_[_affID].aff); - emit F3Devents.onAffiliatePayout(_affID, plyr_[_affID].addr, plyr_[_affID].name, _rID, _pID, _com, now); - } else { - _p3d = _com; - } - - // pay out p3d - _p3d = _p3d.add((_eth.mul(fees_[_team].p3d)) / (100)); - if (_p3d > 0) - { - // deposit to divies contract - address payable add = address(uint160(Divies)); - add.transfer(_p3d); - - // set up event data - _eventData_.P3DAmount = _p3d.add(_eventData_.P3DAmount); - } - - return (_eventData_); - } - - function potSwap() - external - payable - { - // setup local rID - uint256 _rID = rID_ + 1; - - round_[_rID].pot = round_[_rID].pot.add(msg.value); - emit F3Devents.onPotSwapDeposit(_rID, msg.value); - } - - /** - * @dev distributes eth based on fees to gen and pot - */ - function distributeInternal(uint256 _rID, uint256 _pID, uint256 _eth, uint256 _team, uint256 _keys, F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - // calculate gen share - uint256 _gen = (_eth.mul(fees_[_team].gen)) / 100; - - // toss 1% into airdrop pot - uint256 _air = (_eth / 100); - airDropPot_ = airDropPot_.add(_air); - - // update eth balance (eth = eth - (com share + pot swap share + aff share + p3d share + airdrop pot share)) - _eth = _eth.sub(((_eth.mul(14)) / 100).add((_eth.mul(fees_[_team].p3d)) / 100)); - - // calculate pot - uint256 _pot = _eth.sub(_gen); - - // distribute gen share (thats what updateMasks() does) and adjust - // balances for dust. - uint256 _dust = updateMasks(_rID, _pID, _gen, _keys); - if (_dust > 0) - _gen = _gen.sub(_dust); - - // add eth to pot - round_[_rID].pot = _pot.add(_dust).add(round_[_rID].pot); - - // set up event data - _eventData_.genAmount = _gen.add(_eventData_.genAmount); - _eventData_.potAmount = _pot; - - return (_eventData_); - } - - /** - * @dev updates masks for round and player when keys are bought - * @return dust left over - */ - function updateMasks(uint256 _rID, uint256 _pID, uint256 _gen, uint256 _keys) - private - returns (uint256) - { - /* MASKING NOTES - earnings masks are a tricky thing for people to wrap their minds around. - the basic thing to understand here. is were going to have a global - tracker based on profit per share for each round, that increases in - relevant proportion to the increase in share supply. - - the player will have an additional mask that basically says "based - on the rounds mask, my shares, and how much i've already withdrawn, - how much is still owed to me?" - */ - - // calc profit per key & round mask based on this buy: (dust goes to pot) - uint256 _ppt = (_gen.mul(1000000000000000000)) / (round_[_rID].keys); - round_[_rID].mask = _ppt.add(round_[_rID].mask); - - // calculate player earning from their own buy (only based on the keys - // they just bought). & update player earnings mask - uint256 _pearn = (_ppt.mul(_keys)) / (1000000000000000000); - plyrRnds_[_pID][_rID].mask = (((round_[_rID].mask.mul(_keys)) / (1000000000000000000)).sub(_pearn)).add(plyrRnds_[_pID][_rID].mask); - - // calculate & return dust - return (_gen.sub((_ppt.mul(round_[_rID].keys)) / (1000000000000000000))); - } - - /** - * @dev adds up unmasked earnings, & vault earnings, sets them all to 0 - * @return earnings in wei format - */ - function withdrawEarnings(uint256 _pID) - private - returns (uint256) - { - // update gen vault - updateGenVault(_pID, plyr_[_pID].lrnd); - - // from vaults - uint256 _earnings = (plyr_[_pID].win).add(plyr_[_pID].gen).add(plyr_[_pID].aff); - if (_earnings > 0) - { - plyr_[_pID].win = 0; - plyr_[_pID].gen = 0; - plyr_[_pID].aff = 0; - } - - return (_earnings); - } - - /** - * @dev prepares compression data and fires event for buy or reload tx's - */ - function endTx(uint256 _pID, uint256 _team, uint256 _eth, uint256 _keys, F3Ddatasets.EventReturns memory _eventData_) - private - { - _eventData_.compressedData = _eventData_.compressedData + (now * 1000000000000000000) + (_team * 100000000000000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID + (rID_ * 10000000000000000000000000000000000000000000000000000); - - emit F3Devents.onEndTx - ( - _eventData_.compressedData, - _eventData_.compressedIDs, - plyr_[_pID].name, - msg.sender, - _eth, - _keys, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount, - _eventData_.potAmount, - airDropPot_ - ); - } - //============================================================================== - // (~ _ _ _._|_ . - // _)(/_(_|_|| | | \/ . - //====================/========================================================= - /** upon contract deploy, it will be deactivated. this is a one time - * use function that will activate the contract. we do this so devs - * have time to set things up on the web end **/ - bool public activated_ = false; - - function activate() - public - onlyDevs - { - - // can only be ran once - require(activated_ == false, "fomo3d already activated"); - - // activate the contract - activated_ = true; - - otherF3D_ = msg.sender; - Divies = msg.sender; - Jekyll_Island_Inc = msg.sender; - - // lets start first round - rID_ = 1; - round_[1].strt = now + rndExtra_ - rndGap_; - round_[1].end = now + rndInit_ + rndExtra_; - } - - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractScenario007.sol b/framework/src/test/resources/soliditycode_0.5.15/contractScenario007.sol deleted file mode 100644 index 1e6ff5d7250..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractScenario007.sol +++ /dev/null @@ -1,1433 +0,0 @@ -//pragma solidity 0.4.24; - -/** - * @title ERC165 - * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md - */ -interface ERC165 { - - /** - * @notice Query if a contract implements an interface - * @param _interfaceId The interface identifier, as specified in ERC-165 - * @dev Interface identification is specified in ERC-165. This function - * uses less than 30,000 gas. - */ - function supportsInterface(bytes4 _interfaceId) external view returns (bool); - -} - -contract ERC721Basic is ERC165 { - - event Transfer( - address indexed _from, - address indexed _to, - uint256 indexed _tokenId - ); - event Approval( - address indexed _owner, - address indexed _approved, - uint256 indexed _tokenId - ); - event ApprovalForAll( - address indexed _owner, - address indexed _operator, - bool _approved - ); - - function balanceOf(address _owner) public view returns (uint256 _balance); - function ownerOf(uint256 _tokenId) public view returns (address _owner); - function exists(uint256 _tokenId) public view returns (bool _exists); - - function approve(address _to, uint256 _tokenId) public; - function getApproved(uint256 _tokenId) - public view returns (address _operator); - - function setApprovalForAll(address _operator, bool _approved) public; - function isApprovedForAll(address _owner, address _operator) - public view returns (bool); - - function transferFrom(address _from, address _to, uint256 _tokenId) public; - function safeTransferFrom(address _from, address _to, uint256 _tokenId) - public; - - function safeTransferFrom( - address _from, - address _to, - uint256 _tokenId, - bytes memory _data - ) - public; -} - - -/** - * @title SupportsInterfaceWithLookup - * @author Matt Condon (@shrugs) - * @dev Implements ERC165 using a lookup table. - */ -contract SupportsInterfaceWithLookup is ERC165 { - bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7; - /** - * 0x01ffc9a7 === - * bytes4(keccak256('supportsInterface(bytes4)')) - */ - - /** - * @dev a mapping of interface id to whether or not it's supported - */ - mapping(bytes4 => bool) internal supportedInterfaces; - - /** - * @dev A contract implementing SupportsInterfaceWithLookup - * implement ERC165 itself - */ - constructor() public { - _registerInterface(InterfaceId_ERC165); - } - - /** - * @dev implement supportsInterface(bytes4) using a lookup table - */ - function supportsInterface(bytes4 _interfaceId) external view returns (bool) { - return supportedInterfaces[_interfaceId]; - } - - /** - * @dev private method for registering an interface - */ - function _registerInterface(bytes4 _interfaceId) internal { - require(_interfaceId != 0xffffffff); - supportedInterfaces[_interfaceId] = true; - } -} - -contract Governable { - - event Pause(); - event Unpause(); - - address public governor; - bool public paused = false; - - constructor() public { - governor = msg.sender; - } - - function setGovernor(address _gov) public onlyGovernor { - governor = _gov; - } - - modifier onlyGovernor { - require(msg.sender == governor); - _; - } - - /** - * @dev Modifier to make a function callable only when the contract is not paused. - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev Modifier to make a function callable only when the contract is paused. - */ - modifier whenPaused() { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyGovernor whenNotPaused public { - paused = true; - emit Pause(); - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyGovernor whenPaused public { - paused = false; - emit Unpause(); - } - -} - -contract CardBase is Governable { - - struct Card { - uint16 proto; - uint16 purity; - } - - function getCard(uint id) public view returns (uint16 proto, uint16 purity) { - Card memory card = cards[id]; - return (card.proto, card.purity); - } - - function getShine(uint16 purity) public pure returns (uint8) { - return uint8(purity / 1000); - } - - Card[] public cards; - -} - -contract CardProto is CardBase { - - event NewProtoCard( - uint16 id, uint8 season, uint8 god, - Rarity rarity, uint8 mana, uint8 attack, - uint8 health, uint8 cardType, uint8 tribe, bool packable - ); - - struct Limit { - uint64 limit; - bool exists; - } - - // limits for mythic cards - mapping(uint16 => Limit) public limits; - - // can only set limits once - function setLimit(uint16 id, uint64 limit) public onlyGovernor { - Limit memory l = limits[id]; - require(!l.exists); - limits[id] = Limit({ - limit: limit, - exists: true - }); - } - - function getLimit(uint16 id) public view returns (uint64 limit, bool set) { - Limit memory l = limits[id]; - return (l.limit, l.exists); - } - - // could make these arrays to save gas - // not really necessary - will be update a very limited no of times - mapping(uint8 => bool) public seasonTradable; - mapping(uint8 => bool) public seasonTradabilityLocked; - uint8 public currentSeason; - - function makeTradable(uint8 season) public onlyGovernor { - seasonTradable[season] = true; - } - - function makeUntradable(uint8 season) public onlyGovernor { - require(!seasonTradabilityLocked[season]); - seasonTradable[season] = false; - } - - function makePermanantlyTradable(uint8 season) public onlyGovernor { - require(seasonTradable[season]); - seasonTradabilityLocked[season] = true; - } - - function isTradable(uint16 proto) public view returns (bool) { - return seasonTradable[protos[proto].season]; - } - - function nextSeason() public onlyGovernor { - //Seasons shouldn't go to 0 if there is more than the uint8 should hold, the governor should know this ¯\_(ツ)_/¯ -M - require(currentSeason <= 255); - - currentSeason++; - mythic.length = 0; - legendary.length = 0; - epic.length = 0; - rare.length = 0; - common.length = 0; - } - - enum Rarity { - Common, - Rare, - Epic, - Legendary, - Mythic - } - - uint8 constant SPELL = 1; - uint8 constant MINION = 2; - uint8 constant WEAPON = 3; - uint8 constant HERO = 4; - - struct ProtoCard { - bool exists; - uint8 god; - uint8 season; - uint8 cardType; - Rarity rarity; - uint8 mana; - uint8 attack; - uint8 health; - uint8 tribe; - } - - // there is a particular design decision driving this: - // need to be able to iterate over mythics only for card generation - // don't store 5 different arrays: have to use 2 ids - // better to bear this cost (2 bytes per proto card) - // rather than 1 byte per instance - - uint16 public protoCount; - - mapping(uint16 => ProtoCard) protos; - - uint16[] public mythic; - uint16[] public legendary; - uint16[] public epic; - uint16[] public rare; - uint16[] public common; - - function addProtos( - uint16[] memory externalIDs, uint8[] memory gods, Rarity[] memory rarities, uint8[] memory manas, uint8[] memory attacks, - uint8[] memory healths, uint8[] memory cardTypes, uint8[] memory tribes, bool[] memory packable - ) public onlyGovernor returns(uint16) { - - for (uint i = 0; i < externalIDs.length; i++) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: gods[i], - season: currentSeason, - cardType: cardTypes[i], - rarity: rarities[i], - mana: manas[i], - attack: attacks[i], - health: healths[i], - tribe: tribes[i] - }); - - _addProto(externalIDs[i], card, packable[i]); - } - - } - - function addProto( - uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 cardType, uint8 tribe, bool packable - ) public onlyGovernor returns(uint16) { - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: cardType, - rarity: rarity, - mana: mana, - attack: attack, - health: health, - tribe: tribe - }); - - _addProto(externalID, card, packable); - } - - function addWeapon( - uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 durability, bool packable - ) public onlyGovernor returns(uint16) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: WEAPON, - rarity: rarity, - mana: mana, - attack: attack, - health: durability, - tribe: 0 - }); - - _addProto(externalID, card, packable); - } - - function addSpell(uint16 externalID, uint8 god, Rarity rarity, uint8 mana, bool packable) public onlyGovernor returns(uint16) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: SPELL, - rarity: rarity, - mana: mana, - attack: 0, - health: 0, - tribe: 0 - }); - - _addProto(externalID, card, packable); - } - - function addMinion( - uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 tribe, bool packable - ) public onlyGovernor returns(uint16) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: MINION, - rarity: rarity, - mana: mana, - attack: attack, - health: health, - tribe: tribe - }); - - _addProto(externalID, card, packable); - } - - function _addProto(uint16 externalID, ProtoCard memory card, bool packable) internal { - - require(!protos[externalID].exists); - - card.exists = true; - - protos[externalID] = card; - - protoCount++; - - emit NewProtoCard( - externalID, currentSeason, card.god, - card.rarity, card.mana, card.attack, - card.health, card.cardType, card.tribe, packable - ); - - if (packable) { - Rarity rarity = card.rarity; - if (rarity == Rarity.Common) { - common.push(externalID); - } else if (rarity == Rarity.Rare) { - rare.push(externalID); - } else if (rarity == Rarity.Epic) { - epic.push(externalID); - } else if (rarity == Rarity.Legendary) { - legendary.push(externalID); - } else if (rarity == Rarity.Mythic) { - mythic.push(externalID); - } else { - require(false); - } - } - } - - function getProto(uint16 id) public view returns( - bool exists, uint8 god, uint8 season, uint8 cardType, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 tribe - ) { - ProtoCard memory proto = protos[id]; - return ( - proto.exists, - proto.god, - proto.season, - proto.cardType, - proto.rarity, - proto.mana, - proto.attack, - proto.health, - proto.tribe - ); - } - - function getRandomCard(Rarity rarity, uint16 random) public view returns (uint16) { - // modulo bias is fine - creates rarity tiers etc - // will obviously revert is there are no cards of that type: this is expected - should never happen - if (rarity == Rarity.Common) { - return common[random % common.length]; - } else if (rarity == Rarity.Rare) { - return rare[random % rare.length]; - } else if (rarity == Rarity.Epic) { - return epic[random % epic.length]; - } else if (rarity == Rarity.Legendary) { - return legendary[random % legendary.length]; - } else if (rarity == Rarity.Mythic) { - // make sure a mythic is available - uint16 id; - uint64 limit; - bool set; - for (uint i = 0; i < mythic.length; i++) { - id = mythic[(random + i) % mythic.length]; - (limit, set) = getLimit(id); - if (set && limit > 0){ - return id; - } - } - // if not, they get a legendary :( - return legendary[random % legendary.length]; - } - require(false); - return 0; - } - - // can never adjust tradable cards - // each season gets a 'balancing beta' - // totally immutable: season, rarity - function replaceProto( - uint16 index, uint8 god, uint8 cardType, uint8 mana, uint8 attack, uint8 health, uint8 tribe - ) public onlyGovernor { - ProtoCard memory pc = protos[index]; - require(!seasonTradable[pc.season]); - protos[index] = ProtoCard({ - exists: true, - god: god, - season: pc.season, - cardType: cardType, - rarity: pc.rarity, - mana: mana, - attack: attack, - health: health, - tribe: tribe - }); - } - -} - -contract ERC721Receiver { - /** - * @dev Magic value to be returned upon successful reception of an NFT - * Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`, - * which can be also obtained as `ERC721Receiver(0).onERC721Received.selector` - */ - bytes4 internal constant ERC721_RECEIVED = 0x150b7a02; - - /** - * @notice Handle the receipt of an NFT - * @dev The ERC721 smart contract calls this function on the recipient - * after a `safetransfer`. This function MAY throw to revert and reject the - * transfer. Return of other than the magic value MUST result in the - * transaction being reverted. - * Note: the contract address is always the message sender. - * @param _operator The address which called `safeTransferFrom` function - * @param _from The address which previously owned the token - * @param _tokenId The NFT identifier which is being transfered - * @param _data Additional data with no specified format - * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` - */ - function onERC721Received( - address _operator, - address _from, - uint256 _tokenId, - bytes memory _data - ) - public - returns(bytes4); -} - -library AddressUtils { - - /** - * Returns whether the target address is a contract - * @dev This function will return false if invoked during the constructor of a contract, - * as the code is not actually created until after the constructor finishes. - * @param addr address to check - * @return whether the target address is a contract - */ - function isContract1(address addr) internal view returns (bool) { - uint256 size; - // XXX Currently there is no better way to check if there is a contract in an address - // than to check the size of the code at that address. - // See https://ethereum.stackexchange.com/a/14016/36603 - // for more details about how this works. - // TODO Check this again before the Serenity release, because all addresses will be - // contracts then. - // solium-disable-next-line security/no-inline-assembly - assembly { size := extcodesize(addr) } - return size > 0; - } - -} - -library SafeMath { - - /** - * @dev Multiplies two numbers, throws on overflow. - */ - function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { - // Gas optimization: this is cheaper than asserting 'a' not being zero, but the - // benefit is lost if 'b' is also tested. - // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 - if (a == 0) { - return 0; - } - - c = a * b; - assert(c / a == b); - return c; - } - - /** - * @dev Integer division of two numbers, truncating the quotient. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - // assert(b > 0); // Solidity automatically throws when dividing by 0 - // uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - return a / b; - } - - /** - * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). - */ - function sub(uint256 a, uint256 b) internal pure returns (uint256) { - assert(b <= a); - return a - b; - } - - /** - * @dev Adds two numbers, throws on overflow. - */ - function add(uint256 a, uint256 b) internal pure returns (uint256 c) { - c = a + b; - assert(c >= a); - return c; - } -} - -contract ERC721BasicToken is CardProto, SupportsInterfaceWithLookup, ERC721Basic { - - bytes4 private constant InterfaceId_ERC721 = 0x80ac58cd; - /* - * 0x80ac58cd === - * bytes4(keccak256('balanceOf(address)')) ^ - * bytes4(keccak256('ownerOf(uint256)')) ^ - * bytes4(keccak256('approve(address,uint256)')) ^ - * bytes4(keccak256('getApproved(uint256)')) ^ - * bytes4(keccak256('setApprovalForAll(address,bool)')) ^ - * bytes4(keccak256('isApprovedForAll(address,address)')) ^ - * bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^ - * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) - */ - - bytes4 private constant InterfaceId_ERC721Exists = 0x4f558e79; - /* - * 0x4f558e79 === - * bytes4(keccak256('exists(uint256)')) - */ - - using SafeMath for uint256; - using AddressUtils for address; - - // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` - // which can be also obtained as `ERC721Receiver(0).onERC721Received.selector` - bytes4 private constant ERC721_RECEIVED = 0x150b7a02; - - // Mapping from token ID to owner - mapping (uint256 => address) internal tokenOwner; - - // Mapping from token ID to approved address - mapping (uint256 => address) internal tokenApprovals; - - // Mapping from owner to number of owned token - // mapping (address => uint256) internal ownedTokensCount; - - // Mapping from owner to operator approvals - mapping (address => mapping (address => bool)) internal operatorApprovals; - - /** - * @dev Guarantees msg.sender is owner of the given token - * @param _tokenId uint256 ID of the token to validate its ownership belongs to msg.sender - */ - modifier onlyOwnerOf(uint256 _tokenId) { - require(ownerOf(_tokenId) == msg.sender); - _; - } - - /** - * @dev Checks msg.sender can transfer a token, by being owner, approved, or operator - * @param _tokenId uint256 ID of the token to validate - */ - modifier canTransfer(uint256 _tokenId) { - require(isApprovedOrOwner(msg.sender, _tokenId)); - _; - } - - constructor() - public - { - // register the supported interfaces to conform to ERC721 via ERC165 - _registerInterface(InterfaceId_ERC721); - _registerInterface(InterfaceId_ERC721Exists); - } - - /** - * @dev Gets the balance of the specified address - * @param _owner address to query the balance of - * @return uint256 representing the amount owned by the passed address - */ - function balanceOf(address _owner) public view returns (uint256); - - /** - * @dev Gets the owner of the specified token ID - * @param _tokenId uint256 ID of the token to query the owner of - * @return owner address currently marked as the owner of the given token ID - */ - function ownerOf(uint256 _tokenId) public view returns (address) { - address owner = tokenOwner[_tokenId]; - require(owner != address(0)); - return owner; - } - - /** - * @dev Returns whether the specified token exists - * @param _tokenId uint256 ID of the token to query the existence of - * @return whether the token exists - */ - function exists(uint256 _tokenId) public view returns (bool) { - address owner = tokenOwner[_tokenId]; - return owner != address(0); - } - - /** - * @dev Approves another address to transfer the given token ID - * The zero address indicates there is no approved address. - * There can only be one approved address per token at a given time. - * Can only be called by the token owner or an approved operator. - * @param _to address to be approved for the given token ID - * @param _tokenId uint256 ID of the token to be approved - */ - function approve(address _to, uint256 _tokenId) public { - address owner = ownerOf(_tokenId); - require(_to != owner); - require(msg.sender == owner || isApprovedForAll(owner, msg.sender)); - - tokenApprovals[_tokenId] = _to; - emit Approval(owner, _to, _tokenId); - } - - /** - * @dev Gets the approved address for a token ID, or zero if no address set - * @param _tokenId uint256 ID of the token to query the approval of - * @return address currently approved for the given token ID - */ - function getApproved(uint256 _tokenId) public view returns (address) { - return tokenApprovals[_tokenId]; - } - - /** - * @dev Sets or unsets the approval of a given operator - * An operator is allowed to transfer all tokens of the sender on their behalf - * @param _to operator address to set the approval - * @param _approved representing the status of the approval to be set - */ - function setApprovalForAll(address _to, bool _approved) public { - require(_to != msg.sender); - operatorApprovals[msg.sender][_to] = _approved; - emit ApprovalForAll(msg.sender, _to, _approved); - } - - /** - * @dev Tells whether an operator is approved by a given owner - * @param _owner owner address which you want to query the approval of - * @param _operator operator address which you want to query the approval of - * @return bool whether the given operator is approved by the given owner - */ - function isApprovedForAll( - address _owner, - address _operator - ) - public - view - returns (bool) - { - return operatorApprovals[_owner][_operator]; - } - - /** - * @dev Transfers the ownership of a given token ID to another address - * Usage of this method is discouraged, use `safeTransferFrom` whenever possible - * Requires the msg sender to be the owner, approved, or operator - * @param _from current owner of the token - * @param _to address to receive the ownership of the given token ID - * @param _tokenId uint256 ID of the token to be transferred - */ - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - public - canTransfer(_tokenId) - { - require(_from != address(0)); - require(_to != address(0)); - - clearApproval(_from, _tokenId); - removeTokenFrom(_from, _tokenId); - addTokenTo(_to, _tokenId); - - emit Transfer(_from, _to, _tokenId); - } - - /** - * @dev Safely transfers the ownership of a given token ID to another address - * If the target address is a contract, it must implement `onERC721Received`, - * which is called upon a safe transfer, and return the magic value - * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, - * the transfer is reverted. - * - * Requires the msg sender to be the owner, approved, or operator - * @param _from current owner of the token - * @param _to address to receive the ownership of the given token ID - * @param _tokenId uint256 ID of the token to be transferred - */ - function safeTransferFrom( - address _from, - address _to, - uint256 _tokenId - ) - public - canTransfer(_tokenId) - { - // solium-disable-next-line arg-overflow - safeTransferFrom(_from, _to, _tokenId, ""); - } - - /** - * @dev Safely transfers the ownership of a given token ID to another address - * If the target address is a contract, it must implement `onERC721Received`, - * which is called upon a safe transfer, and return the magic value - * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, - * the transfer is reverted. - * Requires the msg sender to be the owner, approved, or operator - * @param _from current owner of the token - * @param _to address to receive the ownership of the given token ID - * @param _tokenId uint256 ID of the token to be transferred - * @param _data bytes data to send along with a safe transfer check - */ - function safeTransferFrom( - address _from, - address _to, - uint256 _tokenId, - bytes memory _data - ) - public - canTransfer(_tokenId) - { - transferFrom(_from, _to, _tokenId); - // solium-disable-next-line arg-overflow - require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data)); - } - - /** - * @dev Returns whether the given spender can transfer a given token ID - * @param _spender address of the spender to query - * @param _tokenId uint256 ID of the token to be transferred - * @return bool whether the msg.sender is approved for the given token ID, - * is an operator of the owner, or is the owner of the token - */ - function isApprovedOrOwner( - address _spender, - uint256 _tokenId - ) - internal - view - returns (bool) - { - address owner = ownerOf(_tokenId); - // Disable solium check because of - // https://github.com/duaraghav8/Solium/issues/175 - // solium-disable-next-line operator-whitespace - return ( - _spender == owner || - getApproved(_tokenId) == _spender || - isApprovedForAll(owner, _spender) - ); - } - - /** - * @dev Internal function to clear current approval of a given token ID - * Reverts if the given address is not indeed the owner of the token - * @param _owner owner of the token - * @param _tokenId uint256 ID of the token to be transferred - */ - function clearApproval(address _owner, uint256 _tokenId) internal { - require(ownerOf(_tokenId) == _owner); - if (tokenApprovals[_tokenId] != address(0)) { - tokenApprovals[_tokenId] = address(0); - } - } - - /** - * @dev Internal function to mint a new token - * Reverts if the given token ID already exists - * @param _to The address that will own the minted token - * @param _tokenId uint256 ID of the token to be minted by the msg.sender - */ - function _mint(address _to, uint256 _tokenId) internal { - require(_to != address(0)); - addNewTokenTo(_to, _tokenId); - emit Transfer(address(0), _to, _tokenId); - } - - - /** - * @dev Internal function to burn a specific token - * Reverts if the token does not exist - * @param _tokenId uint256 ID of the token being burned by the msg.sender - */ - function _burn(address _owner, uint256 _tokenId) internal { - clearApproval(_owner, _tokenId); - removeTokenFrom(_owner, _tokenId); - emit Transfer(_owner, address(0), _tokenId); - } - - function addNewTokenTo(address _to, uint256 _tokenId) internal { - require(tokenOwner[_tokenId] == address(0)); - tokenOwner[_tokenId] = _to; - } - - /** - * @dev Internal function to add a token ID to the list of a given address - * @param _to address representing the new owner of the given token ID - * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address - */ - function addTokenTo(address _to, uint256 _tokenId) internal { - require(tokenOwner[_tokenId] == address(0)); - tokenOwner[_tokenId] = _to; - // ownedTokensCount[_to] = ownedTokensCount[_to].add(1); - } - - /** - * @dev Internal function to remove a token ID from the list of a given address - * @param _from address representing the previous owner of the given token ID - * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address - */ - function removeTokenFrom(address _from, uint256 _tokenId) internal { - require(ownerOf(_tokenId) == _from); - // ownedTokensCount[_from] = ownedTokensCount[_from].sub(1); - tokenOwner[_tokenId] = address(0); - } - - /** - * @dev Internal function to invoke `onERC721Received` on a target address - * The call is not executed if the target address is not a contract - * @param _from address representing the previous owner of the given token ID - * @param _to target address that will receive the tokens - * @param _tokenId uint256 ID of the token to be transferred - * @param _data bytes optional data to send along with the call - * @return whether the call correctly returned the expected magic value - */ - function checkAndCallSafeTransfer( - address _from, - address _to, - uint256 _tokenId, - bytes memory _data - ) - internal - returns (bool) - { - if (!_to.isContract1()) { - return true; - } - bytes4 retval = ERC721Receiver(_to).onERC721Received( - msg.sender, _from, _tokenId, _data); - return (retval == ERC721_RECEIVED); - } - -} - - - -contract ERC721Enumerable is ERC721Basic { - function totalSupply() public view returns (uint256); - function tokenOfOwnerByIndex( - address _owner, - uint256 _index - ) - public - view - returns (uint256 _tokenId); - - function tokenByIndex(uint256 _index) public view returns (uint256); -} - -contract ERC721Metadata is ERC721Basic { - function name() external view returns (string memory _name); - function symbol() external view returns (string memory _symbol); - function tokenURI(uint256 _tokenId) public view returns (string memory); -} - -contract ERC721 is ERC721Basic, ERC721Enumerable, ERC721Metadata { - -} - - - - -library Strings { - - // via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol - function strConcat(string memory _a, string memory _b, string memory _c, string memory _d, string memory _e) internal pure returns (string memory ) { - bytes memory _ba = bytes(_a); - bytes memory _bb = bytes(_b); - bytes memory _bc = bytes(_c); - bytes memory _bd = bytes(_d); - bytes memory _be = bytes(_e); - string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length); - bytes memory babcde = bytes(abcde); - uint k = 0; - for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i]; - for (uint i = 0; i < _bb.length; i++) babcde[k++] = _bb[i]; - for (uint i = 0; i < _bc.length; i++) babcde[k++] = _bc[i]; - for (uint i = 0; i < _bd.length; i++) babcde[k++] = _bd[i]; - for (uint i = 0; i < _be.length; i++) babcde[k++] = _be[i]; - return string(babcde); - } - - function strConcat(string memory _a, string memory _b, string memory _c, string memory _d) internal pure returns (string memory ) { - return strConcat(_a, _b, _c, _d, ""); - } - - function strConcat(string memory _a, string memory _b, string memory _c) internal pure returns (string memory ) { - return strConcat(_a, _b, _c, "", ""); - } - - function strConcat(string memory _a, string memory _b) internal pure returns (string memory ) { - return strConcat(_a, _b, "", "", ""); - } - - function uint2str(uint i) internal pure returns (string memory ) { - if (i == 0) return "0"; - uint j = i; - uint len; - while (j != 0){ - len++; - j /= 10; - } - bytes memory bstr = new bytes(len); - uint k = len - 1; - while (i != 0){ - bstr[k--] = byte(uint8(48 + i % 10)); - i /= 10; - } - return string(bstr); - } -} - -contract ERC721Token is SupportsInterfaceWithLookup, ERC721BasicToken, ERC721 { - - using Strings for string; - - bytes4 private constant InterfaceId_ERC721Enumerable = 0x780e9d63; - /** - * 0x780e9d63 === - * bytes4(keccak256('totalSupply()')) ^ - * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^ - * bytes4(keccak256('tokenByIndex(uint256)')) - */ - - bytes4 private constant InterfaceId_ERC721Metadata = 0x5b5e139f; - /** - * 0x5b5e139f === - * bytes4(keccak256('name()')) ^ - * bytes4(keccak256('symbol()')) ^ - * bytes4(keccak256('tokenURI(uint256)')) - */ - - /*** Constants ***/ - // Configure these for your own deployment - string public constant NAME = "Gods Unchained"; - string public constant SYMBOL = "GODS"; - string public tokenMetadataBaseURI = "https://api.godsunchained.com/card/"; - - // Mapping from owner to list of owned token IDs - // EDITED: limit to 2^40 (around 1T) - mapping(address => uint40[]) internal ownedTokens; - - uint32[] ownedTokensIndex; - - /** - * @dev Constructor function - */ - constructor() public { - - // register the supported interfaces to conform to ERC721 via ERC165 - _registerInterface(InterfaceId_ERC721Enumerable); - _registerInterface(InterfaceId_ERC721Metadata); - } - - /** - * @dev Gets the token name - * @return string representing the token name - */ - function name() external view returns (string memory) { - return NAME; - } - - /** - * @dev Gets the token symbol - * @return string representing the token symbol - */ - function symbol() external view returns (string memory) { - return SYMBOL; - } - - /** - * @dev Returns an URI for a given token ID - * Throws if the token ID does not exist. May return an empty string. - * @param _tokenId uint256 ID of the token to query - */ - function tokenURI(uint256 _tokenId) public view returns (string memory) { - return Strings.strConcat( - tokenMetadataBaseURI, - Strings.uint2str(_tokenId) - ); - } - - /** - * @dev Gets the token ID at a given index of the tokens list of the requested owner - * @param _owner address owning the tokens list to be accessed - * @param _index uint256 representing the index to be accessed of the requested tokens list - * @return uint256 token ID at the given index of the tokens list owned by the requested address - */ - function tokenOfOwnerByIndex( - address _owner, - uint256 _index - ) - public - view - returns (uint256) - { - require(_index < balanceOf(_owner)); - return ownedTokens[_owner][_index]; - } - - /** - * @dev Gets the total amount of tokens stored by the contract - * @return uint256 representing the total amount of tokens - */ - function totalSupply() public view returns (uint256) { - return cards.length; - } - - /** - * @dev Gets the token ID at a given index of all the tokens in this contract - * Reverts if the index is greater or equal to the total number of tokens - * @param _index uint256 representing the index to be accessed of the tokens list - * @return uint256 token ID at the given index of the tokens list - */ - function tokenByIndex(uint256 _index) public view returns (uint256) { - require(_index < totalSupply()); - return _index; - } - - /** - * @dev Internal function to add a token ID to the list of a given address - * @param _to address representing the new owner of the given token ID - * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address - */ - function addTokenTo(address _to, uint256 _tokenId) internal { - super.addTokenTo(_to, _tokenId); - uint256 length = ownedTokens[_to].length; - // EDITED: prevent overflow - require(length == uint32(length)); - ownedTokens[_to].push(uint40(_tokenId)); - - ownedTokensIndex[_tokenId] = uint32(length); - } - - // EDITED - // have to have in order to use array rather than mapping - function addNewTokenTo(address _to, uint256 _tokenId) internal { - super.addNewTokenTo(_to, _tokenId); - uint256 length = ownedTokens[_to].length; - // EDITED: prevent overflow - require(length == uint32(length)); - ownedTokens[_to].push(uint40(_tokenId)); - ownedTokensIndex.push(uint32(length)); - } - - /** - * @dev Internal function to remove a token ID from the list of a given address - * @param _from address representing the previous owner of the given token ID - * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address - */ - function removeTokenFrom(address _from, uint256 _tokenId) internal { - super.removeTokenFrom(_from, _tokenId); - - uint32 tokenIndex = ownedTokensIndex[_tokenId]; - uint256 lastTokenIndex = ownedTokens[_from].length.sub(1); - uint40 lastToken = ownedTokens[_from][lastTokenIndex]; - - ownedTokens[_from][tokenIndex] = lastToken; - ownedTokens[_from][lastTokenIndex] = 0; - // Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to - // be zero. Then we can make sure that we will remove _tokenId from the ownedTokens list since we are first swapping - // the lastToken to the first position, and then dropping the element placed in the last position of the list - - ownedTokens[_from].length--; - ownedTokensIndex[_tokenId] = 0; - ownedTokensIndex[lastToken] = tokenIndex; - } - - /** - * @dev Gets the balance of the specified address - overrriden from previous to save gas - * @param _owner address to query the balance of - * @return uint256 representing the amount owned by the passed address - */ - function balanceOf(address _owner) public view returns (uint256) { - return ownedTokens[_owner].length; - } - -} - -contract CardOwnershipTwo is ERC721Token { - - uint public burnCount; - - function getActiveCards() public view returns (uint) { - return totalSupply() - burnCount; - } - - /** - * @param to : the address to which the card will be transferred - * @param id : the id of the card to be transferred - */ - function transfer(address to, uint id) public payable onlyOwnerOf(id) { - require(isTradable(cards[id].proto)); - require(to != address(0)); - - _transfer(msg.sender, to, id); - } - - function _transfer(address from, address to, uint id) internal { - - clearApproval(from, id); - - removeTokenFrom(from, id); - - addTokenTo(to, id); - - emit Transfer(from, to, id); - } - - /** - * @param to : the address to which the cards will be transferred - * @param ids : the ids of the cards to be transferred - */ - function transferAll(address to, uint[] memory ids) public payable { - for (uint i = 0; i < ids.length; i++) { - transfer(to, ids[i]); - } - } - - /** - * @param proposed : the claimed owner of the cards - * @param ids : the ids of the cards to check - * @return whether proposed owns all of the cards - */ - function ownsAll(address proposed, uint[] memory ids) public view returns (bool) { - require(ids.length > 0); - for (uint i = 0; i < ids.length; i++) { - if (!owns(proposed, ids[i])) { - return false; - } - } - return true; - } - - /** - * @param proposed : the claimed owner of the card - * @param id : the id of the card to check - * @return whether proposed owns the card - */ - function owns(address proposed, uint id) public view returns (bool) { - return ownerOf(id) == proposed; - } - - function burn(uint id) public onlyOwnerOf(id) { - burnCount++; - _burn(msg.sender, id); - } - - /** - * @param ids : the indices of the tokens to burn - */ - function burnAll(uint[] memory ids) public { - for (uint i = 0; i < ids.length; i++){ - burn(ids[i]); - } - } - - /** - * @param to : the address to approve for transfer - * @param id : the index of the card to be approved - */ - function approve(address to, uint id) public { - require(isTradable(cards[id].proto)); - super.approve(to, id); - } - - /** - * @param to : the address to approve for transfer - * @param ids : the indices of the cards to be approved - */ - function approveAll(address to, uint[] memory ids) public { - for (uint i = 0; i < ids.length; i++) { - approve(to, ids[i]); - } - } - - /** - * @param to : the address to which the token should be transferred - * @param id : the index of the token to transfer - */ - function transferFrom(address from, address to, uint id) public { - require(isTradable(cards[id].proto)); - super.transferFrom(from, to, id); - } - - /** - * @param to : the address to which the tokens should be transferred - * @param ids : the indices of the tokens to transfer - */ - function transferAllFrom(address from, address to, uint[] memory ids) public { - for (uint i = 0; i < ids.length; i++) { - transferFrom(from, to, ids[i]); - } - } - - /** - * @return the number of cards which have been burned - */ - function getBurnCount() public view returns (uint) { - return burnCount; - } - -} - -contract CardIntegrationTwo is CardOwnershipTwo { - - address[] public packs; - - event CardCreated(uint indexed id, uint16 proto, uint16 purity, address owner); - - function addPack(address approved) public onlyGovernor { - packs.push(approved); - } - - modifier onlyApprovedPacks { - require(_isApprovedPack()); - _; - } - - function _isApprovedPack() private view returns (bool) { - for (uint i = 0; i < packs.length; i++) { - if (msg.sender == address(packs[i])) { - return true; - } - } - return false; - } - - function createCard(address owner, uint16 proto, uint16 purity) public whenNotPaused onlyApprovedPacks returns (uint) { - ProtoCard memory card = protos[proto]; - require(card.season == currentSeason); - if (card.rarity == Rarity.Mythic) { - uint64 limit; - bool exists; - (limit, exists) = getLimit(proto); - require(!exists || limit > 0); - limits[proto].limit--; - } - return _createCard(owner, proto, purity); - } - - function _createCard(address owner, uint16 proto, uint16 purity) internal returns (uint) { - Card memory card = Card({ - proto: proto, - purity: purity - }); - - uint id = cards.push(card) - 1; - - _mint(owner, id); - - emit CardCreated(id, proto, purity, owner); - - return id; - } - - /*function combineCards(uint[] ids) public whenNotPaused { - require(ids.length == 5); - require(ownsAll(msg.sender, ids)); - Card memory first = cards[ids[0]]; - uint16 proto = first.proto; - uint8 shine = _getShine(first.purity); - require(shine < shineLimit); - uint16 puritySum = first.purity - (shine * 1000); - burn(ids[0]); - for (uint i = 1; i < ids.length; i++) { - Card memory next = cards[ids[i]]; - require(next.proto == proto); - require(_getShine(next.purity) == shine); - puritySum += (next.purity - (shine * 1000)); - burn(ids[i]); - } - uint16 newPurity = uint16(((shine + 1) * 1000) + (puritySum / ids.length)); - _createCard(msg.sender, proto, newPurity); - }*/ - - - // PURITY NOTES - // currently, we only - // however, to protect rarity, you'll never be abl - // this is enforced by the restriction in the create-card function - // no cards above this point can be found in packs - - - -} - -contract PreviousInterface { - - function ownerOf(uint id) public view returns (address); - - function getCard(uint id) public view returns (uint16, uint16); - - function totalSupply() public view returns (uint); - - function burnCount() public view returns (uint); - -} - -contract CardMigration is CardIntegrationTwo { - - constructor(PreviousInterface previous) public { - old = previous; - } - - // use interface to lower deployment cost - PreviousInterface old; - - mapping(uint => bool) public migrated; - - function migrate(uint id) public { - - require(!migrated[id]); - - migrated[id] = true; - - address owner = old.ownerOf(id); - - uint16 proto; - uint16 purity; - - (proto, purity) = old.getCard(id); - - _createCard(owner, proto, purity); - } - - function migrateAll(uint[] memory ids) public { - - for (uint i = 0; i < ids.length; i++){ - migrate(ids[i]); - } - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractScenario008.sol b/framework/src/test/resources/soliditycode_0.5.15/contractScenario008.sol deleted file mode 100644 index 251b41bc6a2..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractScenario008.sol +++ /dev/null @@ -1,2050 +0,0 @@ -//pragma solidity ^0.4.11; - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) public onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address payable public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address payable _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() public onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - emit Transfer(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(now), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - uint256 newKittenId = kitties.push(_kitty) - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - emit Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(address(0), _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -contract ERC721 { - // Required methods - function totalSupply() public view returns (uint256 total); - function balanceOf(address _owner) public view returns (uint256 balance); - function ownerOf(uint256 _tokenId) external view returns (address owner); - function approve(address _to, uint256 _tokenId) external; - function transfer(address _to, uint256 _tokenId) external; - function transferFrom(address _from, address _to, uint256 _tokenId) external; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) external view returns (bool); -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is ERC721, KittyBase { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public view returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - emit Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() public view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - external - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] memory _rawBytes, uint256 _stringLength) private view returns (string memory) { - string memory outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string calldata _preferredTransport) external view returns (string memory infoUrl) { - require( address(erc721Metadata) != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2 sun; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty memory _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty memory _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - emit Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.transfer(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, address(saleAuction)); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, address(siringAuction)); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid.value(msg.value - autoBirthFee)(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10 sun; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, address(saleAuction)); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(uint160(address(this))) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - constructor() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - emit ContractUpgrade(_v2Address); - } - - /// @notice No tipping! - /// @dev Reject all Ether from being sent here, unless it's from one of the - /// two auction contracts. (Hopefully, we can prevent user accidents.) - function() external payable { - require( - msg.sender == address(saleAuction) || - msg.sender == address(siringAuction) - ); - } - - /// @notice Returns all the relevant information about a specific kitty. - /// @param _id The ID of the kitty of interest. - function getKitty(uint256 _id) - external - view - returns ( - bool isGestating, - bool isReady, - uint256 cooldownIndex, - uint256 nextActionAt, - uint256 siringWithId, - uint256 birthTime, - uint256 matronId, - uint256 sireId, - uint256 generation, - uint256 genes - ) { - Kitty storage kit = kitties[_id]; - - // if this variable is 0 then it's not gestating - isGestating = (kit.siringWithId != 0); - isReady = (kit.cooldownEndBlock <= block.number); - cooldownIndex = uint256(kit.cooldownIndex); - nextActionAt = uint256(kit.cooldownEndBlock); - siringWithId = uint256(kit.siringWithId); - birthTime = uint256(kit.birthTime); - matronId = uint256(kit.matronId); - sireId = uint256(kit.sireId); - generation = uint256(kit.generation); - genes = kit.genes; - } - - /// @dev Override unpause so it requires all external contract addresses - /// to be set before contract can be unpaused. Also, we can't have - /// newContractAddress set either, because then the contract was upgraded. - /// @notice This is public rather than external so we can call super.unpause - /// without using an expensive CALL. - - function unpause() public onlyCEO whenPaused { - require(address(saleAuction) != address(0)); - require(address(siringAuction) != address(0)); - require(address(geneScience) != address(0)); - require(newContractAddress == address(0)); - - // Actually unpause the contract. - super.unpause(); - } - - // @dev Allows the CFO to capture the balance available to the contract. - function withdrawBalance() external onlyCFO { - uint256 balance = address(this).balance; - // Subtract all the currently pregnant kittens we have, plus 1 of margin. - uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - - if (balance > subtractFees) { - cfoAddress.transfer(balance - subtractFees); - } - } -} - - - - - - - - - - - - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - - function isGeneScience() public pure returns (bool){ - return true; - } - - /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor - /// @param genes1 genes of mom - /// @param genes2 genes of sire - /// @return the genes that are supposed to be passed down the child - function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - - return (genes1+genes2+targetBlock)/2; - - -} -} - - - - - - - - - - - - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { - /// @dev Given a token Id, returns a byte array that is supposed to be converted into string. - function getMetadata(uint256 _tokenId, string memory) public view returns (bytes32[4] memory buffer, uint256 count) { - if (_tokenId == 1) { - buffer[0] = "Hello World! :D"; - count = 15; - } else if (_tokenId == 2) { - buffer[0] = "I would definitely choose a medi"; - buffer[1] = "um length string."; - count = 49; - } else if (_tokenId == 3) { - buffer[0] = "Lorem ipsum dolor sit amet, mi e"; - buffer[1] = "st accumsan dapibus augue lorem,"; - buffer[2] = " tristique vestibulum id, libero"; - buffer[3] = " suscipit varius sapien aliquam."; - count = 128; - } - } -} - - - - - - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - - // Represents an auction on an NFT - struct Auction { - // Current owner of NFT - address payable seller; - // Price (in wei) at beginning of auction - uint128 startingPrice; - // Price (in wei) at end of auction - uint128 endingPrice; - // Duration (in seconds) of auction - uint64 duration; - // Time when auction started - // NOTE: 0 if this auction has been concluded - uint64 startedAt; - } - - // Reference to contract tracking NFT ownership - ERC721 public nonFungibleContract; - - // Cut owner takes on each auction, measured in basis points (1/100 of a percent). - // Values 0-10,000 map to 0%-100% - uint256 public ownerCut; - - // Map from token ID to their corresponding auction. - mapping (uint256 => Auction) tokenIdToAuction; - - event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); - event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); - event AuctionCancelled(uint256 tokenId); - - /// @dev Returns true if the claimant owns the token. - /// @param _claimant - Address claiming to own the token. - /// @param _tokenId - ID of token whose ownership to verify. - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return (nonFungibleContract.ownerOf(_tokenId) == _claimant); - } - - /// @dev Escrows the NFT, assigning ownership to this contract. - /// Throws if the escrow fails. - /// @param _owner - Current owner address of token to escrow. - /// @param _tokenId - ID of token whose approval to verify. - function _escrow(address _owner, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transferFrom(_owner, address(this), _tokenId); - } - - /// @dev Transfers an NFT owned by this contract to another address. - /// Returns true if the transfer succeeds. - /// @param _receiver - Address to transfer NFT to. - /// @param _tokenId - ID of token to transfer. - function _transfer(address _receiver, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transfer(_receiver, _tokenId); - } - - /// @dev Adds an auction to the list of open auctions. Also fires the - /// AuctionCreated event. - /// @param _tokenId The ID of the token to be put on auction. - /// @param _auction Auction to add. - function _addAuction(uint256 _tokenId, Auction memory _auction) internal { - // Require that all auctions have a duration of - // at least one minute. (Keeps our math from getting hairy!) - require(_auction.duration >= 1 minutes); - - tokenIdToAuction[_tokenId] = _auction; - - emit AuctionCreated( - uint256(_tokenId), - uint256(_auction.startingPrice), - uint256(_auction.endingPrice), - uint256(_auction.duration) - ); - } - - /// @dev Cancels an auction unconditionally. - function _cancelAuction(uint256 _tokenId, address _seller) internal { - _removeAuction(_tokenId); - _transfer(_seller, _tokenId); - emit AuctionCancelled(_tokenId); - } - - /// @dev Computes the price and transfers winnings. - /// Does NOT transfer ownership of token. - function _bid(uint256 _tokenId, uint256 _bidAmount) - internal - returns (uint256) - { - // Get a reference to the auction struct - Auction storage auction = tokenIdToAuction[_tokenId]; - - // Explicitly check that this auction is currently live. - // (Because of how Ethereum mappings work, we can't just count - // on the lookup above failing. An invalid _tokenId will just - // return an auction object that is all zeros.) - require(_isOnAuction(auction)); - - // Check that the bid is greater than or equal to the current price - uint256 price = _currentPrice(auction); - require(_bidAmount >= price); - - // Grab a reference to the seller before the auction struct - // gets deleted. - address payable seller = auction.seller; - - // The bid is good! Remove the auction before sending the fees - // to the sender so we can't have a reentrancy attack. - _removeAuction(_tokenId); - - // Transfer proceeds to seller (if there are any!) - if (price > 0) { - // Calculate the auctioneer's cut. - // (NOTE: _computeCut() is guaranteed to return a - // value <= price, so this subtraction can't go negative.) - uint256 auctioneerCut = _computeCut(price); - uint256 sellerProceeds = price - auctioneerCut; - - // NOTE: Doing a transfer() in the middle of a complex - // method like this is generally discouraged because of - // reentrancy attacks and DoS attacks if the seller is - // a contract with an invalid fallback function. We explicitly - // guard against reentrancy attacks by removing the auction - // before calling transfer(), and the only thing the seller - // can DoS is the sale of their own asset! (And if it's an - // accident, they can call cancelAuction(). ) - seller.transfer(sellerProceeds); - } - - // Calculate any excess funds included with the bid. If the excess - // is anything worth worrying about, transfer it back to bidder. - // NOTE: We checked above that the bid amount is greater than or - // equal to the price so this cannot underflow. - uint256 bidExcess = _bidAmount - price; - - // Return the funds. Similar to the previous transfer, this is - // not susceptible to a re-entry attack because the auction is - // removed before any transfers occur. - msg.sender.transfer(bidExcess); - - // Tell the world! - emit AuctionSuccessful(_tokenId, price, msg.sender); - - return price; - } - - /// @dev Removes an auction from the list of open auctions. - /// @param _tokenId - ID of NFT on auction. - function _removeAuction(uint256 _tokenId) internal { - delete tokenIdToAuction[_tokenId]; - } - - /// @dev Returns true if the NFT is on auction. - /// @param _auction - Auction to check. - function _isOnAuction(Auction storage _auction) internal view returns (bool) { - return (_auction.startedAt > 0); - } - - /// @dev Returns current price of an NFT on auction. Broken into two - /// functions (this one, that computes the duration from the auction - /// structure, and the other that does the price computation) so we - /// can easily test that the price computation works correctly. - function _currentPrice(Auction storage _auction) - internal - view - returns (uint256) - { - uint256 secondsPassed = 0; - - // A bit of insurance against negative values (or wraparound). - // Probably not necessary (since Ethereum guarnatees that the - // now variable doesn't ever go backwards). - if (now > _auction.startedAt) { - secondsPassed = now - _auction.startedAt; - } - - return _computeCurrentPrice( - _auction.startingPrice, - _auction.endingPrice, - _auction.duration, - secondsPassed - ); - } - - /// @dev Computes the current price of an auction. Factored out - /// from _currentPrice so we can run extensive unit tests. - /// When testing, make this function public and turn on - /// `Current price computation` test suite. - function _computeCurrentPrice( - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - uint256 _secondsPassed - ) - internal - pure - returns (uint256) - { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our public functions carefully cap the maximum values for - // time (at 64-bits) and currency (at 128-bits). _duration is - // also known to be non-zero (see the require() statement in - // _addAuction()) - if (_secondsPassed >= _duration) { - // We've reached the end of the dynamic pricing portion - // of the auction, just return the end price. - return _endingPrice; - } else { - // Starting price can be higher than ending price (and often is!), so - // this delta can be negative. - int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - - // This multiplication can't overflow, _secondsPassed will easily fit within - // 64-bits, and totalPriceChange will easily fit within 128-bits, their product - // will always fit within 256-bits. - int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - - // currentPriceChange can be negative, but if so, will have a magnitude - // less that _startingPrice. Thus, this result will always end up positive. - int256 currentPrice = int256(_startingPrice) + currentPriceChange; - - return uint256(currentPrice); - } - } - - /// @dev Computes owner's cut of a sale. - /// @param _price - Sale price of NFT. - function _computeCut(uint256 _price) internal view returns (uint256) { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our entry functions carefully cap the maximum values for - // currency (at 128-bits), and ownerCut <= 10000 (see the require() - // statement in the ClockAuction constructor). The result of this - // function is always guaranteed to be <= _price. - return _price * ownerCut / 10000; - } - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { - event Pause(); - event Unpause(); - - bool public paused = false; - - - /** - * @dev modifier to allow actions only when the contract IS paused - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev modifier to allow actions only when the contract IS NOT paused - */ - modifier whenPaused { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyOwner whenNotPaused public returns (bool) { - paused = true; - emit Pause(); - return true; - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyOwner whenPaused public returns (bool) { - paused = false; - emit Unpause(); - return true; - } -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - - /// @dev The ERC-165 interface signature for ERC-721. - /// Ref: https://github.com/ethereum/EIPs/issues/165 - /// Ref: https://github.com/ethereum/EIPs/issues/721 - bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - - /// @dev Constructor creates a reference to the NFT ownership contract - /// and verifies the owner cut is in the valid range. - /// @param _nftAddress - address of a deployed contract implementing - /// the Nonfungible Interface. - /// @param _cut - percent cut the owner takes on each auction, must be - /// between 0-10,000. - constructor(address _nftAddress, uint256 _cut) public { - require(_cut <= 10000); - ownerCut = _cut; - - ERC721 candidateContract = ERC721(_nftAddress); - require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); - nonFungibleContract = candidateContract; - } - - /// @dev Remove all Ether from the contract, which is the owner's cuts - /// as well as any Ether sent directly to the contract address. - /// Always transfers to the NFT contract, but can be called either by - /// the owner or the NFT contract. - function withdrawBalance() external { - address payable nftAddress = address(uint160(address(nonFungibleContract))); - - require( - msg.sender == owner || - msg.sender == nftAddress - ); - // We are using this boolean method to make sure that even if one fails it will still work - bool res = nftAddress.send(address(this).balance); - } - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of time to move between starting - /// price and ending price (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - whenNotPaused - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(_owns(msg.sender, _tokenId)); - _escrow(msg.sender, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Bids on an open auction, completing the auction and transferring - /// ownership of the NFT if enough Ether is supplied. - /// @param _tokenId - ID of token to bid on. - function bid(uint256 _tokenId) - external - payable - whenNotPaused - { - // _bid will throw if the bid or funds transfer fails - _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - } - - /// @dev Cancels an auction that hasn't been won yet. - /// Returns the NFT to original owner. - /// @notice This is a state-modifying function that can - /// be called while the contract is paused. - /// @param _tokenId - ID of token on auction - function cancelAuction(uint256 _tokenId) - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - address seller = auction.seller; - require(msg.sender == seller); - _cancelAuction(_tokenId, seller); - } - - /// @dev Cancels an auction when the contract is paused. - /// Only the owner may do this, and NFTs are returned to - /// the seller. This should only be used in emergencies. - /// @param _tokenId - ID of the NFT on auction to cancel. - function cancelAuctionWhenPaused(uint256 _tokenId) - whenPaused - onlyOwner - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - _cancelAuction(_tokenId, auction.seller); - } - - /// @dev Returns auction info for an NFT on auction. - /// @param _tokenId - ID of NFT on auction. - function getAuction(uint256 _tokenId) - external - view - returns - ( - address seller, - uint256 startingPrice, - uint256 endingPrice, - uint256 duration, - uint256 startedAt - ) { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return ( - auction.seller, - auction.startingPrice, - auction.endingPrice, - auction.duration, - auction.startedAt - ); - } - - /// @dev Returns the current price of an auction. - /// @param _tokenId - ID of the token price we are checking. - function getCurrentPrice(uint256 _tokenId) - external - view - returns (uint256) - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return _currentPrice(auction); - } - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSiringAuctionAddress() call. - bool public isSiringClockAuction = true; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. Since this function is wrapped, - /// require sender to be KittyCore contract. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Places a bid for siring. Requires the sender - /// is the KittyCore contract because all bid methods - /// should be wrapped. Also returns the kitty to the - /// seller rather than the winner. - function bid(uint256 _tokenId) - external - payable - { - require(msg.sender == address(nonFungibleContract)); - address seller = tokenIdToAuction[_tokenId].seller; - // _bid checks that token ID is valid and will throw if bid fails - _bid(_tokenId, msg.value); - // We transfer the kitty back to the seller, the winner will get - // the offspring - _transfer(seller, _tokenId); - } - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSaleAuctionAddress() call. - bool public isSaleClockAuction = true; - - // Tracks last 5 sale price of gen0 kitty sales - uint256 public gen0SaleCount; - uint256[5] public lastGen0SalePrices; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Updates lastSalePrice if seller is the nft contract - /// Otherwise, works the same as default bid method. - function bid(uint256 _tokenId) - external - payable - { - // _bid verifies token ID size - address seller = tokenIdToAuction[_tokenId].seller; - uint256 price = _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - - // If not a gen0 auction, exit - if (seller == address(nonFungibleContract)) { - // Track gen0 sale prices - lastGen0SalePrices[gen0SaleCount % 5] = price; - gen0SaleCount++; - } - } - - function averageGen0SalePrice() external view returns (uint256) { - uint256 sum = 0; - for (uint256 i = 0; i < 5; i++) { - sum += lastGen0SalePrices[i]; - } - return sum / 5; - } - -} - - - - - - - diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractScenario009.sol b/framework/src/test/resources/soliditycode_0.5.15/contractScenario009.sol deleted file mode 100644 index fb0b76db240..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractScenario009.sol +++ /dev/null @@ -1,51 +0,0 @@ -//pragma solidity ^0.4.0; - -library Set { - // We define a new struct datatype that will be used to - // hold its data in the calling contract. - struct Data { mapping(uint => bool) flags; } - - // Note that the first parameter is of type "storage - // reference" and thus only its storage address and not - // its contents is passed as part of the call. This is a - // special feature of library functions. It is idiomatic - // to call the first parameter 'self', if the function can - // be seen as a method of that object. - function insert (Data storage self, uint value) public - returns (bool) - { - if (self.flags[value]) - return false; // already there - self.flags[value] = true; - return true; - } - - function remove(Data storage self, uint value) public - returns (bool) - { - if (!self.flags[value]) - return false; // not there - self.flags[value] = false; - return true; - } - - function contains(Data storage self, uint value) public - returns (bool) - { - return self.flags[value]; - } -} - - -contract C { - Set.Data knownValues; - - function register(uint value) public { - // The library functions can be called without a - // specific instance of the library, since the - // "instance" will be the current contract. - if (!Set.insert(knownValues, value)) - revert(); - } - // In this contract, we can also directly access knownValues.flags, if we want. -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractScenario010.sol b/framework/src/test/resources/soliditycode_0.5.15/contractScenario010.sol deleted file mode 100644 index f665ea9686e..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractScenario010.sol +++ /dev/null @@ -1,107 +0,0 @@ -//pragma solidity ^0.4.11; - -contract TRON_ERC721 { - //name - function name() view public returns (string memory name){ - return "Tron ERC721 Token"; - } - //symbol - function symbol() view public returns (string memory symbol){ - return "T721T"; - } - - //totalSupply - - function totalSupply() view public returns (uint256 supply){ - uint256 totalSupply = 1000000000000; - return totalSupply; - } - - mapping(address => uint) private balances; - function balanceOf(address _owner) view public returns (uint balance) - { - return balances[_owner]; - } - - - mapping(uint256 => address) private tokenOwners; - mapping(uint256 => bool) private tokenExists; - function ownerOf(uint256 _tokenId) view public returns (address owner) { - require(tokenExists[_tokenId]); - return tokenOwners[_tokenId]; - } - - - mapping(address => mapping (address => uint256)) allowed; - function approve(address _to, uint256 _tokenId) public{ - require(msg.sender == ownerOf(_tokenId)); - require(msg.sender != _to); - allowed[msg.sender][_to] = _tokenId; - emit Approval(msg.sender, _to, _tokenId); - } - - - function takeOwnership(uint256 _tokenId) public { - require(tokenExists[_tokenId]); - address oldOwner = ownerOf(_tokenId); - address newOwner = msg.sender; - require(newOwner != oldOwner); - require(allowed[oldOwner][newOwner] == _tokenId); - balances[oldOwner] -= 1; - tokenOwners[_tokenId] = newOwner; - balances[newOwner] += 1; - emit Transfer(oldOwner, newOwner, _tokenId); - } - - - mapping(address => mapping(uint256 => uint256)) private ownerTokens; - function removeFromTokenList(address owner, uint256 _tokenId) private { - for(uint256 i = 0;ownerTokens[owner][i] != _tokenId;i++){ - ownerTokens[owner][i] = 0; - } - } - - function transfer(address _to, uint256 _tokenId) public{ - address currentOwner = msg.sender; - address newOwner = _to; - require(tokenExists[_tokenId]); - require(currentOwner == ownerOf(_tokenId)); - require(currentOwner != newOwner); - require(newOwner != address(0)); - address oldOwner =currentOwner; - removeFromTokenList(oldOwner,_tokenId); - balances[oldOwner] -= 1; - tokenOwners[_tokenId] = newOwner; - balances[newOwner] += 1; - emit Transfer(oldOwner, newOwner, _tokenId); - } - - function transferFrom(address _from,address _to, uint256 _tokenId) public{ - address currentOwner = _from; - address newOwner = _to; - require(tokenExists[_tokenId]); - require(currentOwner == ownerOf(_tokenId)); - require(currentOwner != newOwner); - require(newOwner != address(0)); - address oldOwner =currentOwner; - removeFromTokenList(oldOwner,_tokenId); - balances[oldOwner] -= 1; - tokenOwners[_tokenId] = newOwner; - balances[newOwner] += 1; - emit Transfer(oldOwner, newOwner, _tokenId); - } - - - function tokenOfOwnerByIndex(address _owner, uint256 _index) view public returns (uint tokenId){ - return ownerTokens[_owner][_index]; - } - - - mapping(uint256 => string) tokenLinks; - function tokenMetadata(uint256 _tokenId) view public returns (string memory infoUrl) { - return tokenLinks[_tokenId]; - } - // Events - event Transfer(address indexed _from, address indexed _to, uint256 _tokenId); - event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId); -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractScenario011.sol b/framework/src/test/resources/soliditycode_0.5.15/contractScenario011.sol deleted file mode 100644 index 74fe819be31..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractScenario011.sol +++ /dev/null @@ -1,2050 +0,0 @@ -//pragma solidity ^0.4.11; - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) public onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address payable public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address payable _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() public onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - emit Transfer(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(now), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - uint256 newKittenId = kitties.push(_kitty) - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - emit Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(address(0), _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -contract ERC721 { - // Required methods - function totalSupply() public view returns (uint256 total); - function balanceOf(address _owner) public view returns (uint256 balance); - function ownerOf(uint256 _tokenId) external view returns (address owner); - function approve(address _to, uint256 _tokenId) external; - function transfer(address _to, uint256 _tokenId) external; - function transferFrom(address _from, address _to, uint256 _tokenId) external; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) external view returns (bool); -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is ERC721, KittyBase { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public view returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - emit Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() public view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - external - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] memory _rawBytes, uint256 _stringLength) private view returns (string memory) { - string memory outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string calldata _preferredTransport) external view returns (string memory infoUrl) { - require( address(erc721Metadata) != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2 sun; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty memory _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty memory _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - emit Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.transfer(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, address(saleAuction)); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, address(siringAuction)); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid.value(msg.value - autoBirthFee)(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10 sun; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, address(saleAuction)); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(uint160(address(this))) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - constructor() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - emit ContractUpgrade(_v2Address); - } - - /// @notice No tipping! - /// @dev Reject all Ether from being sent here, unless it's from one of the - /// two auction contracts. (Hopefully, we can prevent user accidents.) - function() external payable { - require( - msg.sender == address(saleAuction) || - msg.sender == address(siringAuction) - ); - } - - /// @notice Returns all the relevant information about a specific kitty. - /// @param _id The ID of the kitty of interest. - function getKitty(uint256 _id) - external - view - returns ( - bool isGestating, - bool isReady, - uint256 cooldownIndex, - uint256 nextActionAt, - uint256 siringWithId, - uint256 birthTime, - uint256 matronId, - uint256 sireId, - uint256 generation, - uint256 genes - ) { - Kitty storage kit = kitties[_id]; - - // if this variable is 0 then it's not gestating - isGestating = (kit.siringWithId != 0); - isReady = (kit.cooldownEndBlock <= block.number); - cooldownIndex = uint256(kit.cooldownIndex); - nextActionAt = uint256(kit.cooldownEndBlock); - siringWithId = uint256(kit.siringWithId); - birthTime = uint256(kit.birthTime); - matronId = uint256(kit.matronId); - sireId = uint256(kit.sireId); - generation = uint256(kit.generation); - genes = kit.genes; - } - - /// @dev Override unpause so it requires all external contract addresses - /// to be set before contract can be unpaused. Also, we can't have - /// newContractAddress set either, because then the contract was upgraded. - /// @notice This is public rather than external so we can call super.unpause - /// without using an expensive CALL. - - function unpause() public onlyCEO whenPaused { - require(address(saleAuction) != address(0)); - require(address(siringAuction) != address(0)); - require(address(geneScience) != address(0)); - require(newContractAddress == address(0)); - - // Actually unpause the contract. - super.unpause(); - } - - // @dev Allows the CFO to capture the balance available to the contract. - function withdrawBalance() external onlyCFO { - uint256 balance = address(this).balance; - // Subtract all the currently pregnant kittens we have, plus 1 of margin. - uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - - if (balance > subtractFees) { - cfoAddress.transfer(balance - subtractFees); - } - } -} - - - - - - - - - - - - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - - function isGeneScience() public pure returns (bool){ - return true; - } - - /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor - /// @param genes1 genes of mom - /// @param genes2 genes of sire - /// @return the genes that are supposed to be passed down the child - function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - - return (genes1+genes2+targetBlock)/2; - - -} -} - - - - - - - - - - - - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { - /// @dev Given a token Id, returns a byte array that is supposed to be converted into string. - function getMetadata(uint256 _tokenId, string memory) public view returns (bytes32[4] memory buffer, uint256 count) { - if (_tokenId == 1) { - buffer[0] = "Hello World! :D"; - count = 15; - } else if (_tokenId == 2) { - buffer[0] = "I would definitely choose a medi"; - buffer[1] = "um length string."; - count = 49; - } else if (_tokenId == 3) { - buffer[0] = "Lorem ipsum dolor sit amet, mi e"; - buffer[1] = "st accumsan dapibus augue lorem,"; - buffer[2] = " tristique vestibulum id, libero"; - buffer[3] = " suscipit varius sapien aliquam."; - count = 128; - } - } -} - - - - - - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - - // Represents an auction on an NFT - struct Auction { - // Current owner of NFT - address payable seller; - // Price (in wei) at beginning of auction - uint128 startingPrice; - // Price (in wei) at end of auction - uint128 endingPrice; - // Duration (in seconds) of auction - uint64 duration; - // Time when auction started - // NOTE: 0 if this auction has been concluded - uint64 startedAt; - } - - // Reference to contract tracking NFT ownership - ERC721 public nonFungibleContract; - - // Cut owner takes on each auction, measured in basis points (1/100 of a percent). - // Values 0-10,000 map to 0%-100% - uint256 public ownerCut; - - // Map from token ID to their corresponding auction. - mapping (uint256 => Auction) tokenIdToAuction; - - event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); - event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); - event AuctionCancelled(uint256 tokenId); - - /// @dev Returns true if the claimant owns the token. - /// @param _claimant - Address claiming to own the token. - /// @param _tokenId - ID of token whose ownership to verify. - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return (nonFungibleContract.ownerOf(_tokenId) == _claimant); - } - - /// @dev Escrows the NFT, assigning ownership to this contract. - /// Throws if the escrow fails. - /// @param _owner - Current owner address of token to escrow. - /// @param _tokenId - ID of token whose approval to verify. - function _escrow(address _owner, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transferFrom(_owner, address(this), _tokenId); - } - - /// @dev Transfers an NFT owned by this contract to another address. - /// Returns true if the transfer succeeds. - /// @param _receiver - Address to transfer NFT to. - /// @param _tokenId - ID of token to transfer. - function _transfer(address _receiver, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transfer(_receiver, _tokenId); - } - - /// @dev Adds an auction to the list of open auctions. Also fires the - /// AuctionCreated event. - /// @param _tokenId The ID of the token to be put on auction. - /// @param _auction Auction to add. - function _addAuction(uint256 _tokenId, Auction memory _auction) internal { - // Require that all auctions have a duration of - // at least one minute. (Keeps our math from getting hairy!) - require(_auction.duration >= 1 minutes); - - tokenIdToAuction[_tokenId] = _auction; - - emit AuctionCreated( - uint256(_tokenId), - uint256(_auction.startingPrice), - uint256(_auction.endingPrice), - uint256(_auction.duration) - ); - } - - /// @dev Cancels an auction unconditionally. - function _cancelAuction(uint256 _tokenId, address _seller) internal { - _removeAuction(_tokenId); - _transfer(_seller, _tokenId); - emit AuctionCancelled(_tokenId); - } - - /// @dev Computes the price and transfers winnings. - /// Does NOT transfer ownership of token. - function _bid(uint256 _tokenId, uint256 _bidAmount) - internal - returns (uint256) - { - // Get a reference to the auction struct - Auction storage auction = tokenIdToAuction[_tokenId]; - - // Explicitly check that this auction is currently live. - // (Because of how Ethereum mappings work, we can't just count - // on the lookup above failing. An invalid _tokenId will just - // return an auction object that is all zeros.) - require(_isOnAuction(auction)); - - // Check that the bid is greater than or equal to the current price - uint256 price = _currentPrice(auction); - require(_bidAmount >= price); - - // Grab a reference to the seller before the auction struct - // gets deleted. - address payable seller = auction.seller; - - // The bid is good! Remove the auction before sending the fees - // to the sender so we can't have a reentrancy attack. - _removeAuction(_tokenId); - - // Transfer proceeds to seller (if there are any!) - if (price > 0) { - // Calculate the auctioneer's cut. - // (NOTE: _computeCut() is guaranteed to return a - // value <= price, so this subtraction can't go negative.) - uint256 auctioneerCut = _computeCut(price); - uint256 sellerProceeds = price - auctioneerCut; - - // NOTE: Doing a transfer() in the middle of a complex - // method like this is generally discouraged because of - // reentrancy attacks and DoS attacks if the seller is - // a contract with an invalid fallback function. We explicitly - // guard against reentrancy attacks by removing the auction - // before calling transfer(), and the only thing the seller - // can DoS is the sale of their own asset! (And if it's an - // accident, they can call cancelAuction(). ) - seller.transfer(sellerProceeds); - } - - // Calculate any excess funds included with the bid. If the excess - // is anything worth worrying about, transfer it back to bidder. - // NOTE: We checked above that the bid amount is greater than or - // equal to the price so this cannot underflow. - uint256 bidExcess = _bidAmount - price; - - // Return the funds. Similar to the previous transfer, this is - // not susceptible to a re-entry attack because the auction is - // removed before any transfers occur. - msg.sender.transfer(bidExcess); - - // Tell the world! - emit AuctionSuccessful(_tokenId, price, msg.sender); - - return price; - } - - /// @dev Removes an auction from the list of open auctions. - /// @param _tokenId - ID of NFT on auction. - function _removeAuction(uint256 _tokenId) internal { - delete tokenIdToAuction[_tokenId]; - } - - /// @dev Returns true if the NFT is on auction. - /// @param _auction - Auction to check. - function _isOnAuction(Auction storage _auction) internal view returns (bool) { - return (_auction.startedAt > 0); - } - - /// @dev Returns current price of an NFT on auction. Broken into two - /// functions (this one, that computes the duration from the auction - /// structure, and the other that does the price computation) so we - /// can easily test that the price computation works correctly. - function _currentPrice(Auction storage _auction) - internal - view - returns (uint256) - { - uint256 secondsPassed = 0; - - // A bit of insurance against negative values (or wraparound). - // Probably not necessary (since Ethereum guarnatees that the - // now variable doesn't ever go backwards). - if (now > _auction.startedAt) { - secondsPassed = now - _auction.startedAt; - } - - return _computeCurrentPrice( - _auction.startingPrice, - _auction.endingPrice, - _auction.duration, - secondsPassed - ); - } - - /// @dev Computes the current price of an auction. Factored out - /// from _currentPrice so we can run extensive unit tests. - /// When testing, make this function public and turn on - /// `Current price computation` test suite. - function _computeCurrentPrice( - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - uint256 _secondsPassed - ) - internal - pure - returns (uint256) - { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our public functions carefully cap the maximum values for - // time (at 64-bits) and currency (at 128-bits). _duration is - // also known to be non-zero (see the require() statement in - // _addAuction()) - if (_secondsPassed >= _duration) { - // We've reached the end of the dynamic pricing portion - // of the auction, just return the end price. - return _endingPrice; - } else { - // Starting price can be higher than ending price (and often is!), so - // this delta can be negative. - int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - - // This multiplication can't overflow, _secondsPassed will easily fit within - // 64-bits, and totalPriceChange will easily fit within 128-bits, their product - // will always fit within 256-bits. - int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - - // currentPriceChange can be negative, but if so, will have a magnitude - // less that _startingPrice. Thus, this result will always end up positive. - int256 currentPrice = int256(_startingPrice) + currentPriceChange; - - return uint256(currentPrice); - } - } - - /// @dev Computes owner's cut of a sale. - /// @param _price - Sale price of NFT. - function _computeCut(uint256 _price) internal view returns (uint256) { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our entry functions carefully cap the maximum values for - // currency (at 128-bits), and ownerCut <= 10000 (see the require() - // statement in the ClockAuction constructor). The result of this - // function is always guaranteed to be <= _price. - return _price * ownerCut / 10000; - } - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { - event Pause(); - event Unpause(); - - bool public paused = false; - - - /** - * @dev modifier to allow actions only when the contract IS paused - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev modifier to allow actions only when the contract IS NOT paused - */ - modifier whenPaused { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyOwner whenNotPaused public returns (bool) { - paused = true; - emit Pause(); - return true; - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyOwner whenPaused public returns (bool) { - paused = false; - emit Unpause(); - return true; - } -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - - /// @dev The ERC-165 interface signature for ERC-721. - /// Ref: https://github.com/ethereum/EIPs/issues/165 - /// Ref: https://github.com/ethereum/EIPs/issues/721 - bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - - /// @dev Constructor creates a reference to the NFT ownership contract - /// and verifies the owner cut is in the valid range. - /// @param _nftAddress - address of a deployed contract implementing - /// the Nonfungible Interface. - /// @param _cut - percent cut the owner takes on each auction, must be - /// between 0-10,000. - constructor(address _nftAddress, uint256 _cut) public { - require(_cut <= 10000); - ownerCut = _cut; - - ERC721 candidateContract = ERC721(_nftAddress); - require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); - nonFungibleContract = candidateContract; - } - - /// @dev Remove all Ether from the contract, which is the owner's cuts - /// as well as any Ether sent directly to the contract address. - /// Always transfers to the NFT contract, but can be called either by - /// the owner or the NFT contract. - function withdrawBalance() external { - address payable nftAddress = address(uint160(address(nonFungibleContract))); - - require( - msg.sender == owner || - msg.sender == nftAddress - ); - // We are using this boolean method to make sure that even if one fails it will still work - bool res = nftAddress.send(address(this).balance); - } - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of time to move between starting - /// price and ending price (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - whenNotPaused - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(_owns(msg.sender, _tokenId)); - _escrow(msg.sender, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Bids on an open auction, completing the auction and transferring - /// ownership of the NFT if enough Ether is supplied. - /// @param _tokenId - ID of token to bid on. - function bid(uint256 _tokenId) - external - payable - whenNotPaused - { - // _bid will throw if the bid or funds transfer fails - _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - } - - /// @dev Cancels an auction that hasn't been won yet. - /// Returns the NFT to original owner. - /// @notice This is a state-modifying function that can - /// be called while the contract is paused. - /// @param _tokenId - ID of token on auction - function cancelAuction(uint256 _tokenId) - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - address seller = auction.seller; - require(msg.sender == seller); - _cancelAuction(_tokenId, seller); - } - - /// @dev Cancels an auction when the contract is paused. - /// Only the owner may do this, and NFTs are returned to - /// the seller. This should only be used in emergencies. - /// @param _tokenId - ID of the NFT on auction to cancel. - function cancelAuctionWhenPaused(uint256 _tokenId) - whenPaused - onlyOwner - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - _cancelAuction(_tokenId, auction.seller); - } - - /// @dev Returns auction info for an NFT on auction. - /// @param _tokenId - ID of NFT on auction. - function getAuction(uint256 _tokenId) - external - view - returns - ( - address seller, - uint256 startingPrice, - uint256 endingPrice, - uint256 duration, - uint256 startedAt - ) { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return ( - auction.seller, - auction.startingPrice, - auction.endingPrice, - auction.duration, - auction.startedAt - ); - } - - /// @dev Returns the current price of an auction. - /// @param _tokenId - ID of the token price we are checking. - function getCurrentPrice(uint256 _tokenId) - external - view - returns (uint256) - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return _currentPrice(auction); - } - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSiringAuctionAddress() call. - bool public isSiringClockAuction = true; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. Since this function is wrapped, - /// require sender to be KittyCore contract. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Places a bid for siring. Requires the sender - /// is the KittyCore contract because all bid methods - /// should be wrapped. Also returns the kitty to the - /// seller rather than the winner. - function bid(uint256 _tokenId) - external - payable - { - require(msg.sender == address(nonFungibleContract)); - address seller = tokenIdToAuction[_tokenId].seller; - // _bid checks that token ID is valid and will throw if bid fails - _bid(_tokenId, msg.value); - // We transfer the kitty back to the seller, the winner will get - // the offspring - _transfer(seller, _tokenId); - } - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSaleAuctionAddress() call. - bool public isSaleClockAuction = true; - - // Tracks last 5 sale price of gen0 kitty sales - uint256 public gen0SaleCount; - uint256[5] public lastGen0SalePrices; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Updates lastSalePrice if seller is the nft contract - /// Otherwise, works the same as default bid method. - function bid(uint256 _tokenId) - external - payable - { - // _bid verifies token ID size - address seller = tokenIdToAuction[_tokenId].seller; - uint256 price = _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - - // If not a gen0 auction, exit - if (seller == address(nonFungibleContract)) { - // Track gen0 sale prices - lastGen0SalePrices[gen0SaleCount % 5] = price; - gen0SaleCount++; - } - } - - function averageGen0SalePrice() external view returns (uint256) { - uint256 sum = 0; - for (uint256 i = 0; i < 5; i++) { - sum += lastGen0SalePrices[i]; - } - return sum / 5; - } - -} - - - - - - - diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractScenario012.sol b/framework/src/test/resources/soliditycode_0.5.15/contractScenario012.sol deleted file mode 100644 index 7bed08dd111..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractScenario012.sol +++ /dev/null @@ -1,57 +0,0 @@ -//pragma solidity ^0.4.0; -contract PayTest { - -uint256 public n; -constructor() payable public{ -n = 0; -} - -function nPlusOne() public{ -n = n+1; -} - -//get current contract balance -function getBalance() payable public returns (uint) { -return address(this).balance; -} - -function getSenderBalance() public view returns(address, uint) { -return (msg.sender, msg.sender.balance); -} - -address public user; - -//deposit 1 coin to msg.sender -function depositOneCoin() payable public returns(bool success){ -return msg.sender.send(1); -} - -// function transferOneCoin() payable public returns(){ -// address(msg.sender).transfer(1); -// } - -// function depositOneCoin() payable public returns(address addr, uint amount, bool success){ -// return (msg.sender, msg.value, msg.sender.send(1)); -// } - -//deposit coin to msg.sender -function deposit(uint256 money) payable public returns(bool success){ -return msg.sender.send(money); -} -// function deposit(uint money) payable public returns(address addr, uint amount, bool success){ -// return (msg.sender, msg.value, msg.sender.send(money)); -// } - -// function () payable { -// msg.sender.send(1); -// } - -function sendToAddress(address payable _receiver) payable public{ -_receiver.transfer(msg.value); -} - -function sendToAddress2(address payable _receiver) payable public{ -_receiver.transfer(5); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractScenario013.sol b/framework/src/test/resources/soliditycode_0.5.15/contractScenario013.sol deleted file mode 100644 index b91085d018e..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractScenario013.sol +++ /dev/null @@ -1,8 +0,0 @@ -//pragma solidity ^0.4.0; -contract timetest { - -function time() public{ -require(1 trx == 1000000 sun); - -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractScenario014.sol b/framework/src/test/resources/soliditycode_0.5.15/contractScenario014.sol deleted file mode 100644 index 41ea739e231..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractScenario014.sol +++ /dev/null @@ -1,34 +0,0 @@ -//pragma solidity ^0.4.0; -contract Contract1 { - constructor() public payable{} - function send5SunToReceiver(address payable _receiver) payable public{ - _receiver.transfer(5); - } -} -contract contract2 { - address public payContract; - - constructor(address _add) payable public{ - payContract = _add; - } - - function triggerContract1(address _receiver) payable public{ - payContract.call(abi.encodeWithSignature("send5SunToReceiver(address)",_receiver)); - } - - function triggerContract1ButRevert(address _receiver) payable public{ - payContract.call(abi.encodeWithSignature("send5SunToReceiver(address)",_receiver)); - require(1 == 2); - } - -} -contract contract3 { - address public payContract; - constructor(address _add) payable public{ - payContract = _add; - } - - function triggerContract2(address _receiver) payable public{ - payContract.call(abi.encodeWithSignature("triggerContract1(address)",_receiver)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTest.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTest.sol deleted file mode 100644 index 409545eaabb..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTest.sol +++ /dev/null @@ -1,19 +0,0 @@ -//pragma solidity ^0.4.4; - -contract Test{ - -function a() public returns (uint){ - -uint256 count = 0; - -for (uint256 i = 1; i > 0; i++) { - -count++; - -} - -return count; - -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractToMathedFeed.sol b/framework/src/test/resources/soliditycode_0.5.15/contractToMathedFeed.sol deleted file mode 100644 index a5d181ad927..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractToMathedFeed.sol +++ /dev/null @@ -1,21 +0,0 @@ -//pragma solidity ^0.4.0; - -contract ToMathedFeed { - uint public i=1; - function ToMathed (uint value) public { - i=value; - } -} - -contract ToMathedUseINContract { - function ToMathedIUseNR(address a,uint256 n) public returns(bool){ - address payContract=a; - (bool success, bytes memory data) = payContract.call(abi.encodeWithSignature("ToMathedNot(uint256)",n)); - return success; - } - function ToMathedIUseNRE(address a,uint256 value) public returns(bool){ - address payContract=a; - (bool success, bytes memory data) = payContract.call(abi.encodeWithSignature("ToMathed(uint256)",value)); - return success; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTransferToken001.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTransferToken001.sol deleted file mode 100644 index e91c0d7bf0f..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTransferToken001.sol +++ /dev/null @@ -1,22 +0,0 @@ -contract A { - address public a; - constructor() public payable{} - function kill(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - function newB() public payable returns(address){ - B bAddress=new B(); - a= address(bAddress); - return a; - - } - - } - -contract B{ - constructor() public payable {} - function() external payable {} - function kill(address payable toAddress) payable public{ - selfdestruct(toAddress); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken001.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken001.sol deleted file mode 100644 index 0db64f36336..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken001.sol +++ /dev/null @@ -1,30 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken002.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken002.sol deleted file mode 100644 index 0db64f36336..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken002.sol +++ /dev/null @@ -1,30 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken003.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken003.sol deleted file mode 100644 index 48205199eec..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken003.sol +++ /dev/null @@ -1,16 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken005.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken005.sol deleted file mode 100644 index 48205199eec..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken005.sol +++ /dev/null @@ -1,16 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken011.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken011.sol deleted file mode 100644 index f815c26b136..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken011.sol +++ /dev/null @@ -1,35 +0,0 @@ -//pragma solidity ^0.4.24; -contract transferTokenContract { - constructor() payable public{} - function() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - function() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken012.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken012.sol deleted file mode 100644 index 668f67ae205..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken012.sol +++ /dev/null @@ -1,26 +0,0 @@ -//pragma solidity ^0.4.24; -contract transferTokenContract { - constructor() payable public{} - function() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken014.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken014.sol deleted file mode 100644 index 3753770398a..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken014.sol +++ /dev/null @@ -1,34 +0,0 @@ -//pragma solidity ^0.4.24; -contract transferTokenContract { - constructor() payable public{} - function() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - function() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken018.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken018.sol deleted file mode 100644 index 668f67ae205..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken018.sol +++ /dev/null @@ -1,26 +0,0 @@ -//pragma solidity ^0.4.24; -contract transferTokenContract { - constructor() payable public{} - function() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken023.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken023.sol deleted file mode 100644 index 99b19beb107..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken023.sol +++ /dev/null @@ -1,26 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - toAddress.transferToken(amount,id); - } - } - -contract B{ - uint256 public flag = 0; - constructor() public payable {} - function() external { - flag = 1; -} - -} -//pragma solidity ^0.4.24; -contract C{ - uint256 public flag = 0; - constructor() public payable {} - function() external payable { - //flag = 1; -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken026.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken026.sol deleted file mode 100644 index 66635521150..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken026.sol +++ /dev/null @@ -1,31 +0,0 @@ -//pragma solidity ^0.4.24; - -contract token{ - constructor() payable public{} - function() payable external{} - function testInCall(address callBAddress,address callCAddress, address toAddress ,uint256 amount,trcToken id) payable public{ - //callBAddress.call(bytes4(keccak256("transC(address,address,uint256,trcToken)")),callCAddress,toAddress,amount,id); - callBAddress.call(abi.encodeWithSignature("transC(address,address,uint256,trcToken)",callCAddress,toAddress,amount,id)); - } - function testIndelegateCall(address callBddress,address callAddressC, address toAddress,uint256 amount, trcToken id) payable public{ - callBddress.delegatecall(abi.encodeWithSignature("transC(address,address,uint256,trcToken)",callAddressC,toAddress,amount,id)); - } - } - - - -contract B{ - constructor() public payable{} - function() external payable{} - function transC(address payable callCAddress,address payable toAddress,uint256 amount, trcToken id) payable public{ - callCAddress.call(abi.encodeWithSignature("trans(address,uint256,trcToken)",toAddress,amount,id)); - } -} -contract C{ - constructor() payable public{} - function() payable external{} - function trans(address payable toAddress,uint256 amount, trcToken id) payable public{ - toAddress.transferToken(amount,id); - } - -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken027.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken027.sol deleted file mode 100644 index ee9c1d3eb46..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken027.sol +++ /dev/null @@ -1,30 +0,0 @@ -//pragma solidity ^0.4.24; - -contract token{ - constructor() payable public{} - function() payable external{} - function testInCall(address callBAddress,address callCAddress, address toAddress ,uint256 amount,trcToken id) payable public{ - callBAddress.call(abi.encodeWithSignature("transC(address,address,uint256,trcToken)",callCAddress,toAddress,amount,id)); - } - function testIndelegateCall(address callBddress,address callAddressC, address toAddress,uint256 amount, trcToken id) payable public{ - callBddress.delegatecall(abi.encodeWithSignature("transC(address,address,uint256,trcToken)",callAddressC,toAddress,amount,id)); - } - } - - - -contract B{ - constructor() public payable{} - function() external payable{} - function transC(address callCAddress,address toAddress,uint256 amount, trcToken id) payable public{ - callCAddress.call(abi.encodeWithSignature("trans(address,uint256,trcToken)",toAddress,amount,id)); - } -} -contract C{ - constructor() payable public{} - function() payable external{} - function trans(address payable toAddress,uint256 amount, trcToken id) payable public{ - toAddress.transferToken(amount,id); - } - -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken028.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken028.sol deleted file mode 100644 index 957f1c3c60d..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken028.sol +++ /dev/null @@ -1,25 +0,0 @@ -//pragma solidity ^0.4.24; - -contract token{ - uint256 public a=1; - constructor() public payable{} - function tokenBalanceWithSameName(trcToken id) public payable{ - B b= new B(); - a= b.tokenBalance(id); - } - function getA() public returns(uint256){ - return a; - } -} - - -contract B{ - uint256 public flag =0; - constructor() public payable{} - function() external payable{} - function tokenBalance(trcToken id) payable public returns(uint256){ - flag =9; - return flag; - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken029.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken029.sol deleted file mode 100644 index e8f5cbc0988..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken029.sol +++ /dev/null @@ -1,24 +0,0 @@ -//pragma solidity ^0.4.24; - -contract token{ - address public a; - constructor() public payable{} - function transferTokenWithSameName(trcToken id,uint256 amount) public payable{ - B b= new B(); - b.transferToken(amount,id); - a= address(b); - } -} - - -contract B{ - uint256 public flag =0; - constructor() public payable{} - function() external payable{} - function transferToken(uint256 amount, trcToken id) payable public returns(bool){ - flag =9; - } - function getFlag() public view returns (uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken030.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken030.sol deleted file mode 100644 index 5693292d127..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken030.sol +++ /dev/null @@ -1,18 +0,0 @@ -//pragma solidity ^0.4.24; - - contract token{ - constructor() public payable{} - - // 4)suicide也会转移token - // 所有token,trx均被转移到toAddress, - // 若toAddress为合约地址本身,则所有token,trx均被烧掉进黑洞 - function kill(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - - } - -contract B{ - constructor() public payable {} - function() external payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken031.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken031.sol deleted file mode 100644 index 5693292d127..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken031.sol +++ /dev/null @@ -1,18 +0,0 @@ -//pragma solidity ^0.4.24; - - contract token{ - constructor() public payable{} - - // 4)suicide也会转移token - // 所有token,trx均被转移到toAddress, - // 若toAddress为合约地址本身,则所有token,trx均被烧掉进黑洞 - function kill(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - - } - -contract B{ - constructor() public payable {} - function() external payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken034.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken034.sol deleted file mode 100644 index 2a3d9e1fa3a..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken034.sol +++ /dev/null @@ -1,25 +0,0 @@ -//pragma solidity ^0.4.24; - - contract token{ - - constructor() public payable {} - - // 2. 异常测试 - // 1)revert, 金额回退 - function failTransferTokenRevert(address payable toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - require(1==2); - } - - // 2)Error, 金额回退, fee limit 扣光 - function failTransferTokenError(address payable toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - assert(1==2); - } - - } - contract B{ - uint256 public flag = 0; - constructor() public payable {} - function() external payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken035.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken035.sol deleted file mode 100644 index ab53daa704a..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken035.sol +++ /dev/null @@ -1,24 +0,0 @@ -//pragma solidity ^0.4.24; - - contract token{ - constructor() public payable {} - - // 2. 异常测试 - // 1)revert, 金额回退 - function failTransferTokenRevert(address payable toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - require(1==2); - } - - // 2)Error, 金额回退, fee limit 扣光 - function failTransferTokenError(address payable toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - assert(1==2); - } - - } - contract B{ - uint256 public flag = 0; - constructor() public payable {} - function() external payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036.sol deleted file mode 100644 index 6a4c61d1e07..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036.sol +++ /dev/null @@ -1,52 +0,0 @@ -//pragma solidity ^0.4.24; -contract IllegalDecorate { -constructor() payable public{} -function() payable external{} -event log(uint256); -function transferTokenWithPure(address payable toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate1 { -constructor() payable public{} -function() payable external{} -event log(uint256); -function transferTokenWithConstant(address payable toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate2 { -constructor() payable public{} -function() payable external{} -event log(uint256); -function transferTokenWithView(address payable toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate3 { -event log(uint256); -constructor() payable public{} -function() payable external{} -function transferTokenWithOutPayable(address payable toAddress, uint256 tokenValue) public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_1.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_1.sol deleted file mode 100644 index cd039f3e39d..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_1.sol +++ /dev/null @@ -1,13 +0,0 @@ -//pragma solidity ^0.4.24; -contract IllegalDecorate { -constructor() payable public{} -function() payable external{} -event log(uint256); -function transferTokenWithPure(address payable toAddress, uint256 tokenValue) public pure { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_2.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_2.sol deleted file mode 100644 index 0b4d56e086b..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_2.sol +++ /dev/null @@ -1,13 +0,0 @@ -//pragma solidity ^0.4.24; -contract IllegalDecorate { -constructor() payable public{} -function() payable external{} -event log(uint256); -function transferTokenWithConstant(address toAddress, uint256 tokenValue) public constant { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_3.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_3.sol deleted file mode 100644 index b8c7d750514..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_3.sol +++ /dev/null @@ -1,13 +0,0 @@ -//pragma solidity ^0.4.24; -contract IllegalDecorate { -constructor() payable public{} -function() payable external{} -event log(uint256); -function transferTokenWithView(address payable toAddress, uint256 tokenValue) public view { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_4.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_4.sol deleted file mode 100644 index 29c1990962b..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_4.sol +++ /dev/null @@ -1,13 +0,0 @@ -//pragma solidity ^0.4.24; -contract IllegalDecorate { -event log(uint256); -constructor() payable public{} -function() payable external{} -function transferTokenWithOutPayable(address payable toAddress, uint256 tokenValue) public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_old.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_old.sol deleted file mode 100644 index 7ea2561a1e1..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken036_old.sol +++ /dev/null @@ -1,41 +0,0 @@ -//pragma solidity ^0.4.24; - - -contract IllegalDecorate1 { -constructor() payable public{} -function() payable public{} -event log(uint256); -function transferTokenWithConstant(address toAddress, uint256 tokenValue) public constant { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate2 { -constructor() payable public{} -function() payable public{} -event log(uint256); -function transferTokenWithView(address toAddress, uint256 tokenValue) public view { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate3 { -event log(uint256); -constructor() payable public{} -function() payable public{} -function transferTokenWithOutPayable(address toAddress, uint256 tokenValue) public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken037.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken037.sol deleted file mode 100644 index 5e3fbcb8270..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken037.sol +++ /dev/null @@ -1,24 +0,0 @@ -//pragma solidity ^0.4.24; - -contract transferTrc10 { - function receive(address payable rec) public payable { - uint256 aamount=address(this).tokenBalance(msg.tokenid); - uint256 bamount=rec.tokenBalance(msg.tokenid); - require(msg.tokenvalue==aamount); - require(aamount==msg.tokenvalue); - rec.transferToken(aamount,msg.tokenid); - require(0==address(this).tokenBalance(msg.tokenid)); - require(bamount+aamount==rec.tokenBalance(msg.tokenid)); - (bool success, bytes memory data) =rec.call(abi.encodeWithSignature("checkTrc10(uint256,trcToken,uint256)",bamount+aamount,msg.tokenid,0)); - require(success); - - } -} - -contract receiveTrc10 { - function() external payable {} - function checkTrc10(uint256 amount,trcToken tid,uint256 meamount) public{ - require(amount==address(this).tokenBalance(tid)); - require(meamount==msg.sender.tokenBalance(tid)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken038.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken038.sol deleted file mode 100644 index 713d7661e84..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken038.sol +++ /dev/null @@ -1,24 +0,0 @@ -//pragma solidity ^0.4.24; - -contract transferTrc10 { - function receive(address payable rec) public payable { - uint256 aamount=address(this).tokenBalance(msg.tokenid); - uint256 bamount=rec.tokenBalance(msg.tokenid); - require(msg.tokenvalue==aamount); - require(aamount==msg.tokenvalue); - rec.transferToken(aamount,msg.tokenid); - //require(rec.call(abi.encode(bytes4(keccak256("AssertError()"))))); - (bool suc, bytes memory data) = rec.call(abi.encodeWithSignature("AssertError()")); - require(suc); - require(aamount==address(this).tokenBalance(msg.tokenid)); - require(bamount==rec.tokenBalance(msg.tokenid)); - } -} - -contract receiveTrc10 { - function() external payable { - } - function AssertError() public{ - assert(1==2); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken039.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken039.sol deleted file mode 100644 index e60b3285652..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken039.sol +++ /dev/null @@ -1,44 +0,0 @@ -//pragma solidity ^0.4.24; -/* - * 1. caller账户issue一个token - * 2. caller部署proxy, 传入1000 token,1000 trx - * 3. caller部署A - * 4. caller部署B - * 5. caller调用proxy中upgradetTo函数,传入A的地址 - * 6. caller调用proxy中不存在的trans(uint256,address,trcToken)函数,注意这时trcToken是无意义的,但也带上tokenid。address是任意另外某账户的地址 - * 7. 可以看到目标地址trx增长5,caller账户trx减少5 - * 8. caller调用proxy中upgradeTo函数,传入B的地址 - * 9. caller调用proxy中不存在的trans(uint256,address,trcToken)函数。 - * 10. 可以看到目标地址token增长5,caller账户token减少5 -*/ -contract Proxy { - constructor() payable public{} - address public implementation; - function upgradeTo(address _address) public { - implementation = _address; - } - function() payable external{ - address addr = implementation; - require(addr != address(0)); - assembly { - let freememstart := mload(0x40) - calldatacopy(freememstart, 0, calldatasize()) - let success := delegatecall(not(0), addr, freememstart, calldatasize(), freememstart, 0) - returndatacopy(freememstart, 0, returndatasize()) - switch success - case 0 { revert(freememstart, returndatasize()) } - default { return(freememstart, returndatasize()) } - } - } -} - -contract A { - function trans(uint256 amount, address payable toAddress, trcToken id) payable public { - toAddress.transfer(amount); - } -} -contract B{ - function trans(uint256 amount, address payable toAddress, trcToken id) payable public { - toAddress.transferToken(amount,id); - } -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken041.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken041.sol deleted file mode 100644 index a6272bc813d..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken041.sol +++ /dev/null @@ -1,20 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } - -contract B{ - uint256 public flag = 0; - constructor() public payable {} - function() external payable {} - - function setFlag() public payable{ - flag = 1; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken043.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken043.sol deleted file mode 100644 index f815c26b136..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken043.sol +++ /dev/null @@ -1,35 +0,0 @@ -//pragma solidity ^0.4.24; -contract transferTokenContract { - constructor() payable public{} - function() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - function() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken048.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken048.sol deleted file mode 100644 index de2844608c0..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken048.sol +++ /dev/null @@ -1,14 +0,0 @@ -//pragma solidity ^0.4.24; - - contract Test { - event log(uint256); - function testMsgTokenValue() payable public returns(uint256 value) { - emit log(msg.tokenvalue); - return msg.tokenvalue; - } - - function testMsgValue() payable public returns(uint256 value) { - emit log(msg.value); - return msg.value; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken049.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken049.sol deleted file mode 100644 index 3fd502c89fd..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken049.sol +++ /dev/null @@ -1,10 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken050.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken050.sol deleted file mode 100644 index 3fd502c89fd..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken050.sol +++ /dev/null @@ -1,10 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken051.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken051.sol deleted file mode 100644 index b5b9efd4817..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken051.sol +++ /dev/null @@ -1,11 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - function() external payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken052.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken052.sol deleted file mode 100644 index 3fd502c89fd..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken052.sol +++ /dev/null @@ -1,10 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken054.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken054.sol deleted file mode 100644 index 48205199eec..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken054.sol +++ /dev/null @@ -1,16 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken055.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken055.sol deleted file mode 100644 index 48205199eec..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken055.sol +++ /dev/null @@ -1,16 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken060.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken060.sol deleted file mode 100644 index 0db64f36336..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken060.sol +++ /dev/null @@ -1,30 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken061.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken061.sol deleted file mode 100644 index 0db64f36336..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken061.sol +++ /dev/null @@ -1,30 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken064.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken064.sol deleted file mode 100644 index cf2a6fe8097..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken064.sol +++ /dev/null @@ -1,49 +0,0 @@ -//pragma solidity ^0.4.24; -contract transferTokenContract { - constructor() payable public{} - function() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } - function transferTokenTestValueMaxBigInteger(address payable toAddress) payable public { - toAddress.transferToken(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0); - } - function transferTokenTestValueOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(9223372036854775808, 1000001); - } - function transferTokenTestValueMaxLong(address payable toAddress) payable public { - toAddress.transferToken(9223372036854775807, 1000001); - } - function transferTokenTestValue0IdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(0, 9223372036854775809); - } -} - - - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - function() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken066.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken066.sol deleted file mode 100644 index f815c26b136..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken066.sol +++ /dev/null @@ -1,35 +0,0 @@ -//pragma solidity ^0.4.24; -contract transferTokenContract { - constructor() payable public{} - function() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - function() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken067.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken067.sol deleted file mode 100644 index f815c26b136..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken067.sol +++ /dev/null @@ -1,35 +0,0 @@ -//pragma solidity ^0.4.24; -contract transferTokenContract { - constructor() payable public{} - function() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - function() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken073.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken073.sol deleted file mode 100644 index 9cb13ec7268..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken073.sol +++ /dev/null @@ -1,17 +0,0 @@ -//pragma solidity ^0.4.0; - -contract Dest { - event logFallback(uint256 indexed, uint256 indexed, uint256 indexed); - event logGetToken(uint256 indexed, uint256 indexed, uint256 indexed, uint256); - - - constructor() payable public {} - - function getToken(trcToken tokenId) payable public{ - emit logGetToken(msg.sender.tokenBalance(tokenId), msg.tokenid, msg.tokenvalue, msg.value); - } - - function () payable external{ - emit logFallback(msg.tokenid, msg.tokenvalue, msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken075.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken075.sol deleted file mode 100644 index 2a32fd7e8d3..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken075.sol +++ /dev/null @@ -1,26 +0,0 @@ -//pragma solidity ^0.4.0; - -contract Dest { - event logFallback(uint256 indexed, uint256 indexed, uint256 indexed); - event logGetToken(uint256 indexed, uint256 indexed, uint256 indexed, uint256); - - constructor() payable public {} - - function getToken(trcToken tokenId) payable public{ - emit logGetToken(msg.sender.tokenBalance(tokenId), msg.tokenid, msg.tokenvalue, msg.value); - } - - function getTokenLongMin() payable public{ - // long.min - 1000020 - emit logGetToken(msg.sender.tokenBalance(trcToken(-9223372036855775828)), msg.tokenid, msg.tokenvalue, msg.value); - } - - function getTokenLongMax() payable public{ - // long.max + 1000020 - emit logGetToken(msg.sender.tokenBalance(trcToken(9223372036855775827)), msg.tokenid, msg.tokenvalue, msg.value); - } - - function () payable external{ - emit logFallback(msg.tokenid, msg.tokenvalue, msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken076.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken076.sol deleted file mode 100644 index 9de79a327c3..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken076.sol +++ /dev/null @@ -1,19 +0,0 @@ -//pragma solidity ^0.4.24; -contract Test { - address public origin; - address public sender; - bool public result1; - bool public result2; - function test() external { - origin = tx.origin; - sender = msg.sender; - result1 = msg.sender == tx.origin; // true - result2 = origin == sender; // true - } -function getResult1() public returns(bool){ - return result1; -} -function getResult2() public returns(bool){ - return result2; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken077.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken077.sol deleted file mode 100644 index e110f24e2fc..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken077.sol +++ /dev/null @@ -1,11 +0,0 @@ -//pragma solidity ^0.4.24; - -contract trcToken077 { -function addressTest() public returns(bytes32 addressValue) { - assembly{ - let x := mload(0x40) //Find empty storage location using "free memory pointer" - mstore(x,address) //Place current contract address - addressValue := mload(x) - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken078.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken078.sol deleted file mode 100644 index f7504ea55aa..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken078.sol +++ /dev/null @@ -1,35 +0,0 @@ -//pragma solidity ^0.4.24; -contract callerContract { - constructor() public payable{} - function() external payable{} - function sendToB(address called_address, address c) public payable{ - called_address.delegatecall(abi.encodeWithSignature("transferTo(address)",c)); - } - function sendToB2(address called_address,address c) public payable{ - called_address.call(abi.encodeWithSignature("transferTo(address)",c)); - } - function sendToB3(address called_address,address c) public payable{ - called_address.delegatecall(abi.encodeWithSignature("transferTo(address)",c)); - } -} - contract calledContract { - function() external payable{} - constructor() public payable {} - function transferTo(address payable toAddress)public payable{ - toAddress.transfer(5); - } - - function setIinC(address c) public payable{ - c.call.value(5)(abi.encode(bytes4(keccak256("setI()")))); - } - - } - contract c{ - address public origin; - address public sender; - constructor() public payable{} - event log(address,address); - function() payable external{ - emit log(tx.origin,msg.sender); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken079.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken079.sol deleted file mode 100644 index 48205199eec..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken079.sol +++ /dev/null @@ -1,16 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken080.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken080.sol deleted file mode 100644 index 27529ce48e8..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcToken080.sol +++ /dev/null @@ -1,30 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - function() external payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractTrcTokenToOther.sol b/framework/src/test/resources/soliditycode_0.5.15/contractTrcTokenToOther.sol deleted file mode 100644 index 22456df9e8e..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractTrcTokenToOther.sol +++ /dev/null @@ -1,44 +0,0 @@ -//pragma solidity ^0.4.24; - -contract ConvertType { - -constructor() payable public{} - -function() payable external{} - -//function trcTokenOnStorage(trcToken storage token) internal { // ERROR: Data location can only be specified for array, struct or mapping types, but "storage" was given. -//} - -function trcTokenToString(trcToken token) public pure returns(string memory s){ -// s = token; // ERROR -// s = string(token); // ERROR -} - -function trcTokenToUint256(trcToken token) public pure returns(uint256 r){ -uint256 u = token; // OK -uint256 u2 = uint256(token); // OK -r = u2; -} - -function trcTokenToAddress(trcToken token) public pure returns(address r){ -//r = token; // ERROR -token = 0x1234567812345678123456781234567812345678123456781234567812345678; -address a2 = address(token); // OK -r = a2; -} - -function trcTokenToBytes(trcToken token) public pure returns(bytes memory r){ -//r = token; // ERROR -// r = bytes(token); // ERROR -} - -function trcTokenToBytes32(trcToken token) public pure returns(bytes32 r){ -// r = token; // ERROR -bytes32 b2 = bytes32(token); // OK -r = b2; -} - -function trcTokenToArray(trcToken token) public pure returns(uint[] memory r){ -//r = token; // ERROR -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/contractUnknownException.sol b/framework/src/test/resources/soliditycode_0.5.15/contractUnknownException.sol deleted file mode 100644 index 37c28468be1..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/contractUnknownException.sol +++ /dev/null @@ -1,65 +0,0 @@ -// pragma solidity ^0.4.24; - -contract testA { - constructor() public payable { - A a = (new A).value(10)(); - a.fun(); - } -} - -contract testB { - constructor() public payable { - B b = (new B).value(10)(); - b.fun(); - } -} - - -contract testC { - constructor() public payable{ - C c = (new C).value(10)(); - c.fun(); - } -} - -contract testD { - constructor() public payable{ - D d = (new D).value(10)(); - d.fun(); - } -} - - -contract A { - constructor() public payable{ - selfdestruct(msg.sender); - } - function fun() public { - } - -} - -contract B { - constructor() public payable { - revert(); - } - function fun() public { - } -} - - -contract C { - constructor() public payable { - assert(1==2); - } - function fun() public { - } -} - -contract D { - constructor() public payable { - require(1==2); - } - function fun() public { - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/create2CallContract.sol b/framework/src/test/resources/soliditycode_0.5.15/create2CallContract.sol deleted file mode 100644 index f2de1c7ee13..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/create2CallContract.sol +++ /dev/null @@ -1,37 +0,0 @@ -contract callerContract { - constructor() payable public{} - function() payable external{} - function delegateCallCreate2(address called_address, bytes memory code, uint256 salt) public { - called_address.delegatecall(abi.encodeWithSignature("deploy(bytes,uint256)",code,salt)); - } - function callCreate2(address called_address,bytes memory code, uint256 salt) public returns(bool,bytes memory){ - return called_address.call(abi.encodeWithSignature("deploy(bytes,uint256)",code,salt)); - } -} - - -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - -contract TestConstract { - uint public i; - constructor () public { - } - function plusOne() public returns(uint){ - i++; - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/create2Istanbul.sol b/framework/src/test/resources/soliditycode_0.5.15/create2Istanbul.sol deleted file mode 100644 index b79db6e4639..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/create2Istanbul.sol +++ /dev/null @@ -1,28 +0,0 @@ -pragma solidity ^0.5.12; - -contract create2Istanbul { - function deploy(bytes memory code, uint256 salt) public returns(address) { - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - - } - return addr; - } - - // prefix in main net is 0x41, testnet config is 0xa0 - function get(bytes1 prefix, bytes calldata code, uint256 salt) external view returns(address) { - //bytes32 hash = keccak256(abi.encodePacked(bytes1(0x41),address(this), salt, keccak256(code))); - bytes32 hash = keccak256(abi.encodePacked(prefix,address(this), salt, keccak256(code))); - address addr = address(uint160(uint256(hash))); - return addr; - } - -} - -contract B { - constructor() public payable{} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/create2contract.sol b/framework/src/test/resources/soliditycode_0.5.15/create2contract.sol deleted file mode 100644 index 0171f4d5486..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/create2contract.sol +++ /dev/null @@ -1,52 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } - - event Deployed(address addr, bytes32 salt, address sender); - function deploy(bytes memory code, bytes32 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - -contract FactoryBytes { - event Deployed(address addr, bytes32 salt, address sender); - function deploy(bytes memory code, bytes32 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - -contract TestConstract { - uint public i; - constructor () public { - } - function plusOne() public returns(uint){ - i++; - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/create2contract22.sol b/framework/src/test/resources/soliditycode_0.5.15/create2contract22.sol deleted file mode 100644 index c33cb08edc3..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/create2contract22.sol +++ /dev/null @@ -1,109 +0,0 @@ -contract Factory { - event Deployed(address addr, trcToken salt, address sender); - event Deployed1(address addr, uint8 salt, address sender); - event Deployed2(address addr, address salt, address sender); - event Deployed3(address addr, string salt, address sender); - - - function deploy(bytes memory code, trcToken salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } - - function deploy1(bytes memory code, uint8 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed1(addr, salt, msg.sender); - return addr; - } - - function deploy2(bytes memory code, address salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed2(addr, salt, msg.sender); - return addr; - } - - function deploy3(bytes memory code, string memory salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed3(addr, salt, msg.sender); - return addr; - } - -} - - -contract TestConstract { - uint public i=1; - function testTransfer(uint256 i) payable public{ - msg.sender.transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} - -contract TestConstract1 { - uint public i=2; - function testTransfer(uint256 i) payable public{ - msg.sender.transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} - -contract TestConstract2 { - uint public i=3; - function testTransfer(uint256 i) payable public{ - msg.sender.transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} - -contract TestConstract3 { - uint public i=4; - function testTransfer(uint256 i) payable public{ - msg.sender.transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/create2contractn.sol b/framework/src/test/resources/soliditycode_0.5.15/create2contractn.sol deleted file mode 100644 index e0e3ae64c16..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/create2contractn.sol +++ /dev/null @@ -1,29 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract TestConstract { - uint public i=1; - function testTransfer(uint256 i) payable public{ - msg.sender.transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/create2contractn2.sol b/framework/src/test/resources/soliditycode_0.5.15/create2contractn2.sol deleted file mode 100644 index 626988c4e04..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/create2contractn2.sol +++ /dev/null @@ -1,26 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract TestConstract { - uint public i=1; - function set() payable public { - i=5; - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/demo.sol b/framework/src/test/resources/soliditycode_0.5.15/demo.sol deleted file mode 100644 index c7f6d0d4da9..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/demo.sol +++ /dev/null @@ -1,73 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - uint256 codesize; - constructor() payable public{ - uint256 m; - address addr = address(this); - assembly { - m := extcodesize(addr) - } - codesize = m; - } - - // positive case - function pulsone() public payable{ - uint256 j = 0; - uint i = 100; - for (; i < i; i++) { - j++; - } - } - - - function getCodeSize() public returns (uint256){ - return codesize; - } - - } - - contract confirmTest{ - - uint256 codesize; - constructor() payable public{ - uint256 m; - address addr = address(this); - assembly { - m := extcodesize(addr) - - } - codesize = m; - } - - function getCodeSize() public returns (uint256){ - return codesize; - } - - function confirm(address addr) public returns (uint256){ - uint256 j; - assembly { - j := extcodesize(addr) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - return j; - } - - function at(address _addr) public returns (bytes memory o_code) { - assembly { - // retrieve the size of the code, this needs assembly - let size := extcodesize(_addr) - // allocate output byte array - this could also be done without assembly - // by using o_code = new bytes(size) - o_code := mload(0x40) - // new "memory end" including padding - mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) - // store length in memory - mstore(o_code, size) - // actually retrieve the code, this needs assembly - extcodecopy(_addr, add(o_code, 0x20), 0, size) - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/event001.sol b/framework/src/test/resources/soliditycode_0.5.15/event001.sol deleted file mode 100644 index 7662df3a5c6..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/event001.sol +++ /dev/null @@ -1,10 +0,0 @@ -contract Event { - event xixi(uint256 id) ; - event log2(uint256,uint256,uint256); - constructor() public payable{} - function messageI() payable public returns (uint ret) { - //emit log2(1,2,3); - emit xixi(1); - return 1; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/event002.sol b/framework/src/test/resources/soliditycode_0.5.15/event002.sol deleted file mode 100644 index 70a5275521c..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/event002.sol +++ /dev/null @@ -1,52 +0,0 @@ -pragma solidity >=0.4.0 <0.7.0; - -contract Event { - - event _0(); - event a_0() anonymous; - event a_4i(uint256 indexed x1, uint256 indexed x2 , uint256 indexed x3, uint256 indexed x4, uint256 x5)anonymous ; - event _3i(uint256 x1, uint256 indexed x2 , uint256 indexed x3, uint256 x4, uint256 x5) ; - event _1i(uint256 indexed x1, uint256, uint256 indexed, uint256 x4) ; - event a_1i(uint256) anonymous; - event _ai(uint8[2], uint8) ; - event a_ai(uint8[2], uint8) anonymous; - event _a1i(uint8[2] indexed, uint8) ; - event a_a1i(uint8[2] indexed, uint8) anonymous; - - constructor () public { - // emit a_0(); - // emit a_1i(123); - // emit a_4i(1,2,3,5,16); - // emit _0(); - emit _3i(1,2,3,5,16); - // emit _1i(1,2,3,5); - // emit _ai([1,2], 3); - // emit a_ai([3,4], 5); - // emit _a1i([1,2], 3); - // emit a_a1i([3,4], 5); - } - - function e() public { - emit _1i(1,2,3,4); - } - - function l() public { - emit a_1i(1); - } - - function k() public{ - emit a_4i(2,3,4,5,17); - emit _3i(2,3,4,5,16); - emit _1i(2,3,4,5); - emit a_1i(128); - emit _0(); - emit a_0(); - //selfdestruct(msg.sender); - //emit a_4i(1,2,3,5,16); - //emit _3i(1,2,3,5,16); - //emit _1i(1,2,3,5); - //emit a_1i(123); - //emit _0(); - //emit a_0(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/extCodeHash.sol b/framework/src/test/resources/soliditycode_0.5.15/extCodeHash.sol deleted file mode 100644 index d6209770682..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/extCodeHash.sol +++ /dev/null @@ -1,13 +0,0 @@ -contract TestExtCodeHash { - - function getCodeHashByAddr(address _addr) public returns (bytes32 _hash) { - assembly { - _hash := extcodehash(_addr) - } - } - function getCodeHashByUint(uint256 _addr) public returns (bytes32 _hash) { - assembly { - _hash := extcodehash(_addr) - } - } -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/extCodeHash11.sol b/framework/src/test/resources/soliditycode_0.5.15/extCodeHash11.sol deleted file mode 100644 index ad59f6cce1c..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/extCodeHash11.sol +++ /dev/null @@ -1,103 +0,0 @@ -contract Counter { -uint count = 0; -address payable owner; -event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); -constructor() public{ -owner = msg.sender; -} -function getCodeHashByAddr() public returns (bytes32 _hashBefore, bytes32 _hashAfter) { -address addr = address(this); -assembly { -_hashBefore := extcodehash(addr) -} -if (owner == msg.sender) { -selfdestruct(owner); -} -assembly { -_hashAfter := extcodehash(addr) -} -revert(); -emit LogResult(_hashBefore, _hashAfter); -} -} - -contract Counter1 { -uint count = 0; -address payable owner; -event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); -constructor() public{ -owner = msg.sender; -} -function getCodeHashByAddr() public returns (bytes32 _hashBefore, bytes32 _hashAfter) { -address addr = address(this); -assembly { -_hashBefore := extcodehash(addr) -} -if (owner == msg.sender) { -selfdestruct(owner); -} -assembly { -_hashAfter := extcodehash(addr) -} - -emit LogResult(_hashBefore, _hashAfter); -} -} - - -contract Counter2 { -uint count = 0; -address payable owner; -event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); -constructor() public{ -owner = msg.sender; -} -function getCodeHashByAddr(address c) public returns (bytes32 _hashBefore, bytes32 _hashAfter) { - TestConstract t=new TestConstract(); -address addr = address(t); -assembly { -_hashBefore := extcodehash(addr) -} - addr.call(abi.encodeWithSignature("testSuicideNonexistentTarget(address)",c)); - - -assembly { -_hashAfter := extcodehash(addr) -} - -emit LogResult(_hashBefore, _hashAfter); -} -} - - -contract Counter3 { -uint count = 0; -address payable owner; -event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); -constructor() public{ -owner = msg.sender; -} -function getCodeHashByAddr(address c) public returns (bytes32 _hashBefore, bytes32 _hashAfter) { - TestConstract t=new TestConstract(); -address addr = address(t); -assembly { -_hashBefore := extcodehash(addr) -} -if (owner == msg.sender) { -selfdestruct(owner); -} - -assembly { -_hashAfter := extcodehash(addr) -} - -emit LogResult(_hashBefore, _hashAfter); -} -} - -contract TestConstract { - uint public i=1; - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/extCodeHashConstruct.sol b/framework/src/test/resources/soliditycode_0.5.15/extCodeHashConstruct.sol deleted file mode 100644 index 6bb91b3d3b1..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/extCodeHashConstruct.sol +++ /dev/null @@ -1,14 +0,0 @@ -contract CounterConstruct { - uint count = 0; - address payable owner; - event LogResult(bytes32 _hashBefore); - constructor() public{ - owner = msg.sender; - address addr = address(this); - bytes32 _hashBefore; - assembly { - _hashBefore := extcodehash(addr) - } - emit LogResult(_hashBefore); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/extCodeHashStress.sol b/framework/src/test/resources/soliditycode_0.5.15/extCodeHashStress.sol deleted file mode 100644 index cf41f3c8106..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/extCodeHashStress.sol +++ /dev/null @@ -1,45 +0,0 @@ -contract Trigger { - function test(address addr) public returns(uint i) { - bytes32 hash; - while (gasleft() > 1000) { - assembly { - hash := extcodehash(addr) - } - i++; - } - } - - function test(address[] memory addrs) public returns(uint i) { - bytes32 hash; - uint i = 0; - for (; i < addrs.length; i++) { - address addr = addrs[i]; - assembly { - hash := extcodehash(addr) - } - } - return i; - } - } - - - - contract TriggerNormal { - function test(address addr) public returns(uint i) { - i = 0; - while (gasleft() > 100000) { - i++; - } - } - } - - contract TriggerNormal1 { - function test(address[] memory addrs) public returns(uint i) { - bytes32 hash; - uint i = 0; - for (; i < addrs.length; i++) { - address addr = addrs[i]; - addr.balance; - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/extCodeHashTestNoPayable.sol b/framework/src/test/resources/soliditycode_0.5.15/extCodeHashTestNoPayable.sol deleted file mode 100644 index c3a2ad8c6ae..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/extCodeHashTestNoPayable.sol +++ /dev/null @@ -1,8 +0,0 @@ -contract testConstantContract{ -uint256 public i; -function testNoPayable() public returns (uint256 z) { -i=1; -z=i; -return z; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/isSRCandidate.sol b/framework/src/test/resources/soliditycode_0.5.15/isSRCandidate.sol deleted file mode 100644 index 723e6d0e93a..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/isSRCandidate.sol +++ /dev/null @@ -1,35 +0,0 @@ - -pragma solidity ^0.5.0; - -contract ContractB{ - address others; -} - -contract TestIsSRCandidate{ - - ContractB contractB = new ContractB(); - - function isSRCandidateTest(address addr) public view returns (bool) { - return address(addr).isSRCandidate; - } - - function zeroAddressTest() public view returns (bool) { - return address(0x0).isSRCandidate; - } - - function localContractAddrTest() public view returns (bool) { - return address(this).isSRCandidate; - } - - function otherContractAddrTest() public view returns (bool) { - return address(contractB).isSRCandidate; - } - - function nonpayableAddrTest(address addr) public view returns (bool) { - return addr.isSRCandidate; - } - - function payableAddrTest(address payable addr) public returns (bool) { - return addr.isSRCandidate; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/mappingGetter.sol b/framework/src/test/resources/soliditycode_0.5.15/mappingGetter.sol deleted file mode 100644 index dbd473717cb..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/mappingGetter.sol +++ /dev/null @@ -1,4 +0,0 @@ -contract mappingGetter { - mapping(bytes => uint256) public balances1; - mapping(string => uint256) public balances2; -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/multiValiSignPerformance01.sol b/framework/src/test/resources/soliditycode_0.5.15/multiValiSignPerformance01.sol deleted file mode 100644 index 74baa963366..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/multiValiSignPerformance01.sol +++ /dev/null @@ -1,37 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract ecrecoverValidateSign { - - using ECVerify for bytes32; - - function validateSign(bytes32 hash,bytes[] memory sig,address[] memory signer) public returns (bool) { - for(uint256 i=0;i bytes32) public nullifiers; // store nullifiers of spent commitments - mapping(bytes32 => bytes32) public roots; // store history root - mapping(uint256 => bytes32) public tree; - mapping(bytes32 => bytes32) public noteCommitment; - bytes32[33] frontier; - bytes32[32] zeroes = [bytes32(0x0100000000000000000000000000000000000000000000000000000000000000), bytes32(0x817de36ab2d57feb077634bca77819c8e0bd298c04f6fed0e6a83cc1356ca155), bytes32(0xffe9fc03f18b176c998806439ff0bb8ad193afdb27b2ccbc88856916dd804e34), bytes32(0xd8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c), bytes32(0xe110de65c907b9dea4ae0bd83a4b0a51bea175646a64c12b4c9f931b2cb31b49), bytes32(0x912d82b2c2bca231f71efcf61737fbf0a08befa0416215aeef53e8bb6d23390a), bytes32(0x8ac9cf9c391e3fd42891d27238a81a8a5c1d3a72b1bcbea8cf44a58ce7389613), bytes32(0xd6c639ac24b46bd19341c91b13fdcab31581ddaf7f1411336a271f3d0aa52813), bytes32(0x7b99abdc3730991cc9274727d7d82d28cb794edbc7034b4f0053ff7c4b680444), bytes32(0x43ff5457f13b926b61df552d4e402ee6dc1463f99a535f9a713439264d5b616b), bytes32(0xba49b659fbd0b7334211ea6a9d9df185c757e70aa81da562fb912b84f49bce72), bytes32(0x4777c8776a3b1e69b73a62fa701fa4f7a6282d9aee2c7a6b82e7937d7081c23c), bytes32(0xec677114c27206f5debc1c1ed66f95e2b1885da5b7be3d736b1de98579473048), bytes32(0x1b77dac4d24fb7258c3c528704c59430b630718bec486421837021cf75dab651), bytes32(0xbd74b25aacb92378a871bf27d225cfc26baca344a1ea35fdd94510f3d157082c), bytes32(0xd6acdedf95f608e09fa53fb43dcd0990475726c5131210c9e5caeab97f0e642f), bytes32(0x1ea6675f9551eeb9dfaaa9247bc9858270d3d3a4c5afa7177a984d5ed1be2451), bytes32(0x6edb16d01907b759977d7650dad7e3ec049af1a3d875380b697c862c9ec5d51c), bytes32(0xcd1c8dbf6e3acc7a80439bc4962cf25b9dce7c896f3a5bd70803fc5a0e33cf00), bytes32(0x6aca8448d8263e547d5ff2950e2ed3839e998d31cbc6ac9fd57bc6002b159216), bytes32(0x8d5fa43e5a10d11605ac7430ba1f5d81fb1b68d29a640405767749e841527673), bytes32(0x08eeab0c13abd6069e6310197bf80f9c1ea6de78fd19cbae24d4a520e6cf3023), bytes32(0x0769557bc682b1bf308646fd0b22e648e8b9e98f57e29f5af40f6edb833e2c49), bytes32(0x4c6937d78f42685f84b43ad3b7b00f81285662f85c6a68ef11d62ad1a3ee0850), bytes32(0xfee0e52802cb0c46b1eb4d376c62697f4759f6c8917fa352571202fd778fd712), bytes32(0x16d6252968971a83da8521d65382e61f0176646d771c91528e3276ee45383e4a), bytes32(0xd2e1642c9a462229289e5b0e3b7f9008e0301cbb93385ee0e21da2545073cb58), bytes32(0xa5122c08ff9c161d9ca6fc462073396c7d7d38e8ee48cdb3bea7e2230134ed6a), bytes32(0x28e7b841dcbc47cceb69d7cb8d94245fb7cb2ba3a7a6bc18f13f945f7dbd6e2a), bytes32(0xe1f34b034d4a3cd28557e2907ebf990c918f64ecb50a94f01d6fda5ca5c7ef72), bytes32(0x12935f14b676509b81eb49ef25f39269ed72309238b4c145803544b646dca62d), bytes32(0xb2eed031d4d6a4f02a097f80b54cc1541d4163c6b6f5971f88b6e41d35c53814)]; - address owner; - TokenTRC20 trc20Token; - - event MintNewLeaf(uint256 position, bytes32 cm, bytes32 cv, bytes32 epk, bytes32[21] c); - event TransferNewLeaf(uint256 position, bytes32 cm, bytes32 cv, bytes32 epk, bytes32[21] c); - event BurnNewLeaf(uint256 position, bytes32 cm, bytes32 cv, bytes32 epk, bytes32[21] c); - event TokenMint(address from, uint256 value); - event TokenBurn(address to, uint256 value, bytes32[3] ciphertext); - event NoteSpent(bytes32 nf); - - constructor (address trc20ContractAddress, uint256 scalingFactorExponent) public { - require(scalingFactorExponent < 77, "The scalingFactorExponent is out of range!"); - scalingFactor = 10 ** scalingFactorExponent; - owner = msg.sender; - trc20Token = TokenTRC20(trc20ContractAddress); - } - // output: cm, cv, epk, proof - function mint(uint256 rawValue, bytes32[9] calldata output, bytes32[2] calldata bindingSignature, bytes32[21] calldata c) external { - address sender = msg.sender; - // transfer the trc20Token from the sender to this contract - bool transferResult = trc20Token.transferFrom(sender, address(this), rawValue); - require(transferResult, "TransferFrom failed!"); - - require(noteCommitment[output[0]] == 0, "Duplicate noteCommitments!"); - uint64 value = rawValueToValue(rawValue); - bytes32 signHash = sha256(abi.encodePacked(address(this), value, output, c)); - (bytes32[] memory ret) = verifyMintProof(output, bindingSignature, value, signHash, frontier, leafCount); - uint256 result = uint256(ret[0]); - require(result == 1, "The proof and signature have not been verified by the contract!"); - - uint256 slot = uint256(ret[1]); - uint256 nodeIndex = leafCount + 2 ** 32 - 1; - tree[nodeIndex] = output[0]; - if (slot == 0) { - frontier[0] = output[0]; - } - for (uint256 i = 1; i < slot + 1; i++) { - nodeIndex = (nodeIndex - 1) / 2; - tree[nodeIndex] = ret[i + 1]; - if (i == slot) { - frontier[slot] = tree[nodeIndex]; - } - } - latestRoot = ret[slot + 2]; - roots[latestRoot] = latestRoot; - noteCommitment[output[0]] = output[0]; - leafCount ++; - - emit MintNewLeaf(leafCount - 1, output[0], output[1], output[2], c); - emit TokenMint(sender, rawValue); - } - //input: nf, anchor, cv, rk, proof - //output: cm, cv, epk, proof - function transfer(bytes32[10][] calldata input, bytes32[2][] calldata spendAuthoritySignature, bytes32[9][] calldata output, bytes32[2] calldata bindingSignature, bytes32[21][] calldata c) external { - require(input.length >= 1 && input.length <= 2, "Input number must be 1 or 2!"); - require(input.length == spendAuthoritySignature.length, "Input number must be equal to spendAuthoritySignature number!"); - require(output.length >= 1 && output.length <= 2, "Output number must be 1 or 2!"); - require(output.length == c.length, "Output number must be equal to c number!"); - - for (uint256 i = 0; i < input.length; i++) { - require(nullifiers[input[i][0]] == 0, "The note has already been spent!"); - require(roots[input[i][1]] != 0, "The anchor must exist!"); - } - for (uint256 i = 0; i < output.length; i++) { - require(noteCommitment[output[i][0]] == 0, "Duplicate noteCommitment!"); - } - - bytes32 signHash = sha256(abi.encodePacked(address(this), input, output, c)); - (bytes32[] memory ret) = verifyTransferProof(input, spendAuthoritySignature, output, bindingSignature, signHash, 0, frontier, leafCount); - uint256 result = uint256(ret[0]); - require(result == 1, "The proof and signature have not been verified by the contract!"); - - uint256 offset = 1; - //ret offset - for (uint256 i = 0; i < output.length; i++) { - uint256 slot = uint256(ret[offset++]); - uint256 nodeIndex = leafCount + 2 ** 32 - 1; - tree[nodeIndex] = output[i][0]; - if (slot == 0) { - frontier[0] = output[i][0]; - } - for (uint256 k = 1; k < slot + 1; k++) { - nodeIndex = (nodeIndex - 1) / 2; - tree[nodeIndex] = ret[offset++]; - if (k == slot) { - frontier[slot] = tree[nodeIndex]; - } - } - leafCount++; - } - latestRoot = ret[offset]; - roots[latestRoot] = latestRoot; - for (uint256 i = 0; i < input.length; i++) { - bytes32 nf = input[i][0]; - nullifiers[nf] = nf; - emit NoteSpent(nf); - } - for (uint256 i = 0; i < output.length; i++) { - noteCommitment[output[i][0]] = output[i][0]; - emit TransferNewLeaf(leafCount - (output.length - i), output[i][0], output[i][1], output[i][2], c[i]); - } - } - //input: nf, anchor, cv, rk, proof - //output: cm, cv, epk, proof - function burn(bytes32[10] calldata input, bytes32[2] calldata spendAuthoritySignature, uint256 rawValue, bytes32[2] calldata bindingSignature, address payTo, bytes32[3] calldata burnCipher, bytes32[9][] calldata output, bytes32[21][] calldata c) external { - uint64 value = rawValueToValue(rawValue); - bytes32 signHash = sha256(abi.encodePacked(address(this), input, output, c, payTo, value)); - - bytes32 nf = input[0]; - bytes32 anchor = input[1]; - require(nullifiers[nf] == 0, "The note has already been spent!"); - require(roots[anchor] != 0, "The anchor must exist!"); - - require(output.length <= 1, "Output number cannot exceed 1!"); - require(output.length == c.length, "Output number must be equal to length of c!"); - - // bytes32 signHash = sha256(abi.encodePacked(address(this), input, payTo, value, output, c)); - if (output.length == 0) { - (bool result) = verifyBurnProof(input, spendAuthoritySignature, value, bindingSignature, signHash); - require(result, "The proof and signature have not been verified by the contract!"); - } else { - transferInBurn(input, spendAuthoritySignature, value, bindingSignature, signHash, output, c); - } - - nullifiers[nf] = nf; - emit NoteSpent(nf); - //Finally, transfer trc20Token from this contract to the nominated address - bool transferResult = trc20Token.transfer(payTo, rawValue); - require(transferResult, "Transfer failed!"); - - emit TokenBurn(payTo, rawValue, burnCipher); - } - - function transferInBurn(bytes32[10] memory input, bytes32[2] memory spendAuthoritySignature, uint64 value, bytes32[2] memory bindingSignature, bytes32 signHash, bytes32[9][] memory output, bytes32[21][] memory c) private { - bytes32 cm = output[0][0]; - require(noteCommitment[cm] == 0, "Duplicate noteCommitment!"); - bytes32[10][] memory inputs = new bytes32[10][](1); - inputs[0] = input; - bytes32[2][] memory spendAuthoritySignatures = new bytes32[2][](1); - spendAuthoritySignatures[0] = spendAuthoritySignature; - (bytes32[] memory ret) = verifyTransferProof(inputs, spendAuthoritySignatures, output, bindingSignature, signHash, value, frontier, leafCount); - uint256 result = uint256(ret[0]); - require(result == 1, "The proof and signature have not been verified by the contract!"); - - uint256 slot = uint256(ret[1]); - uint256 nodeIndex = leafCount + 2 ** 32 - 1; - tree[nodeIndex] = cm; - if (slot == 0) { - frontier[0] = cm; - } - for (uint256 i = 1; i < slot + 1; i++) { - nodeIndex = (nodeIndex - 1) / 2; - tree[nodeIndex] = ret[i + 1]; - if (i == slot) { - frontier[slot] = tree[nodeIndex]; - } - } - latestRoot = ret[slot + 2]; - roots[latestRoot] = latestRoot; - noteCommitment[cm] = cm; - leafCount ++; - - emit BurnNewLeaf(leafCount - 1, cm, output[0][1], output[0][2], c[0]); - } - - //position: index of leafnode, start from 0 - function getPath(uint256 position) public view returns (bytes32, bytes32[32] memory) { - require(position >= 0, "Position should be non-negative!"); - require(position < leafCount, "Position should be smaller than leafCount!"); - uint256 index = position + 2 ** 32 - 1; - bytes32[32] memory path; - uint32 level = ancestorLevel(position); - bytes32 targetNodeValue = getTargetNodeValue(position, level); - for (uint32 i = 0; i < 32; i++) { - if (i == level) { - path[31 - i] = targetNodeValue; - } else { - if (index % 2 == 0) { - path[31 - i] = tree[index - 1]; - } else { - path[31 - i] = tree[index + 1] == 0 ? zeroes[i] : tree[index + 1]; - } - } - index = (index - 1) / 2; - } - return (latestRoot, path); - } - - //position: index of leafnode, start from 0 - function getPathByValueIsZero(uint256 position) public view returns (bytes32, bytes32[32] memory) { - require(position >= 0, "Position should be non-negative!"); - require(position < leafCount, "Position should be smaller than leafCount!"); - uint256 index = position + 2 ** 32 - 1; - bytes32[32] memory path; - uint32 level = ancestorLevel(position); - bytes32 targetNodeValue = getTargetNodeValueByValueIsZero(position, level); - for (uint32 i = 0; i < 32; i++) { - if (i == level) { - path[31 - i] = targetNodeValue; - } else { - if (index % 2 == 0) { - path[31 - i] = tree[index - 1]; - } else { - path[31 - i] = tree[index + 1] == 0 ? zeroes[i] : tree[index + 1]; - } - } - index = (index - 1) / 2; - } - return (latestRoot, path); - } - - function ancestorLevel(uint256 leafIndex) private view returns (uint32) { - uint256 nodeIndex1 = leafIndex + 2 ** 32 - 1; - uint256 nodeIndex2 = leafCount + 2 ** 32 - 2; - uint32 level = 0; - while (((nodeIndex1 - 1) / 2) != ((nodeIndex2 - 1) / 2)) { - nodeIndex1 = (nodeIndex1 - 1) / 2; - nodeIndex2 = (nodeIndex2 - 1) / 2; - level = level + 1; - } - return level; - } - - function getTargetNodeValue(uint256 leafIndex, uint32 level) private view returns (bytes32) { - bytes32 left; - bytes32 right; - uint256 index = leafIndex + 2 ** 32 - 1; - uint256 nodeIndex = leafCount + 2 ** 32 - 2; - bytes32 nodeValue = tree[nodeIndex]; - if (level == 0) { - if (index < nodeIndex) { - return nodeValue; - } - if (index == nodeIndex) { - if (index % 2 == 0) { - return tree[index - 1]; - } else { - return zeroes[0]; - } - } - } - for (uint32 i = 0; i < level; i++) { - if (nodeIndex % 2 == 0) { - left = tree[nodeIndex - 1]; - right = nodeValue; - } else { - left = nodeValue; - right = zeroes[i]; - } - nodeValue = pedersenHash(i, left, right); - nodeIndex = (nodeIndex - 1) / 2; - } - return nodeValue; - } - - function getTargetNodeValueByValueIsZero(uint256 leafIndex, uint32 level) private view returns (bytes32) { - bytes32 left; - bytes32 right; - uint256 index = leafIndex + 2 ** 32 - 1; - uint256 nodeIndex = leafCount + 2 ** 32 - 2; - bytes32 nodeValue = tree[nodeIndex]; - if (level == 0) { - if (index < nodeIndex) { - return nodeValue; - } - if (index == nodeIndex) { - if (index % 2 == 0) { - return tree[index - 1]; - } else { - return zeroes[0]; - } - } - } - for (uint32 i = 0; i < level; i++) { - if (nodeIndex % 2 == 0) { - left = tree[nodeIndex - 1]; - right = nodeValue; - } else { - left = nodeValue; - right = zeroes[i]; - } - left = bytes32(0x0); - right = bytes32(0x0); - nodeValue = pedersenHash(i, left, right); - nodeIndex = (nodeIndex - 1) / 2; - } - return nodeValue; - } - - function rawValueToValue(uint256 rawValue) private view returns (uint64) { - require(rawValue > 0, "Value must be positive!"); - require(rawValue.mod(scalingFactor) == 0, "Value must be integer multiples of scalingFactor!"); - uint256 value = rawValue.div(scalingFactor); - require(value < INT64_MAX); - return uint64(value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest1TestRequireContract.sol b/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest1TestRequireContract.sol deleted file mode 100644 index dbb97ab4f04..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest1TestRequireContract.sol +++ /dev/null @@ -1,15 +0,0 @@ -//pragma solidity ^0.4.0; -contract TestThrowsContract{ - function testAssert() public { - assert(1==2); - } - function testRequire() public { - require(2==1); - } - function testRevert() public { - revert(); - } - //function testThrow(){ - // throw; - //} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest2TestThrowsContract.sol b/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest2TestThrowsContract.sol deleted file mode 100644 index abcc2d84ca2..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest2TestThrowsContract.sol +++ /dev/null @@ -1,15 +0,0 @@ -//pragma solidity ^0.4.0; -contract TestThrowsContract{ - function testAssert() public { - assert(1==2); - } - function testRequire() public { - require(2==1); - } - function testRevert() public { - revert(); - } - // function testThrow() public { - // throw; - //} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest3TestRevertContract.sol b/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest3TestRevertContract.sol deleted file mode 100644 index 229fa6a74b0..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest3TestRevertContract.sol +++ /dev/null @@ -1,15 +0,0 @@ -//pragma solidity ^0.4.0; -contract TestThrowsContract{ - function testAssert() public { - assert(1==2); - } - function testRequire() public { - require(2==1); - } - function testRevert() public { - revert(); - } - // function testThrow(){ - // throw; - // } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest4noPayableContract.sol b/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest4noPayableContract.sol deleted file mode 100644 index aa043ad9c3b..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest4noPayableContract.sol +++ /dev/null @@ -1,8 +0,0 @@ -//pragma solidity ^0.4.0; - -contract noPayableContract { - -function noPayable() public payable returns (uint){ -return msg.value; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest4noPayableContract_1.sol b/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest4noPayableContract_1.sol deleted file mode 100644 index fe7ba275736..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest4noPayableContract_1.sol +++ /dev/null @@ -1,8 +0,0 @@ -//pragma solidity ^0.4.0; - -contract noPayableContract { - -function noPayable() public returns (uint){ -return msg.value; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest5noPayableConstructor.sol b/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest5noPayableConstructor.sol deleted file mode 100644 index e1733b0562b..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest5noPayableConstructor.sol +++ /dev/null @@ -1,11 +0,0 @@ -//pragma solidity ^0.4.0; - -contract MyContract { - uint money; - - //function MyContract(uint _money) { - constructor(uint _money) public payable{ - require(msg.value >= _money); - money = _money; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest5noPayableConstructor_1.sol b/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest5noPayableConstructor_1.sol deleted file mode 100644 index 793b468d4c2..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest5noPayableConstructor_1.sol +++ /dev/null @@ -1,11 +0,0 @@ -//pragma solidity ^0.4.0; - -contract MyContract { - uint money; - - //function MyContract(uint _money) { - constructor(uint _money) public { - require(msg.value >= _money); - money = _money; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest6transferTestContract.sol b/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest6transferTestContract.sol deleted file mode 100644 index 8c64ff740cd..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest6transferTestContract.sol +++ /dev/null @@ -1,8 +0,0 @@ -//pragma solidity ^0.4.0; - -contract transferTestContract { - function tranferTest(address payable addr) public payable{ - addr.transfer(10); - - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest7payableFallbakContract.sol b/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest7payableFallbakContract.sol deleted file mode 100644 index 85cf454e08e..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest7payableFallbakContract.sol +++ /dev/null @@ -1,14 +0,0 @@ -//pragma solidity ^0.4.0; - -contract Test { - function() external { x = 1; } - uint x; -} - - -contract Caller { - function callTest(Test test) public { - //test.call(0xabcdef01); // hash does not exist - address(test).call(abi.encode(0xabcdef01)); // hash does not exist - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest8newContractGasNoenough.sol b/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest8newContractGasNoenough.sol deleted file mode 100644 index b322ac68591..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest8newContractGasNoenough.sol +++ /dev/null @@ -1,19 +0,0 @@ -//pragma solidity ^0.4.0; - -contract Account{ - uint256 public accId; - - // function Account(uint accountId) payable{ - constructor(uint accountId) payable public { - accId = accountId; - } -} - -contract Initialize{ - // Account public account = new Account(10); - - function newAccount() public { - Account account = new Account(1); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest9MessageUsedErrorFeed.sol b/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest9MessageUsedErrorFeed.sol deleted file mode 100644 index 05448bfd0ac..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontest9MessageUsedErrorFeed.sol +++ /dev/null @@ -1,18 +0,0 @@ -//pragma solidity ^0.4.0; - -contract MathedFeed { - - function divideMathed() public returns (uint ret) { - uint x=1; - uint y=0; - return x/y; - } -} - - -contract MathedUseContract { - - function MathedUse(address addr) public returns (uint) { - return MathedFeed(addr).divideMathed(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontestFunctionUsedErrorFeed.sol b/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontestFunctionUsedErrorFeed.sol deleted file mode 100644 index b7f5244954d..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/requireExceptiontestFunctionUsedErrorFeed.sol +++ /dev/null @@ -1,17 +0,0 @@ -//pragma solidity ^0.4.0; - -contract MessageFeed { - - function mValue() payable public returns (uint ret) { - return msg.value; - } -} - -contract MessageUseContract { - function inputValue() payable public returns (uint){ - return msg.value; - } - function messageUse(address addr) payable public returns (uint) { - return MessageFeed(addr).mValue.value(1)(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/selector.sol b/framework/src/test/resources/soliditycode_0.5.15/selector.sol deleted file mode 100644 index 411e36b0b8e..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/selector.sol +++ /dev/null @@ -1,21 +0,0 @@ -pragma solidity ^0; - -library A { - function getBalance(address) public view returns (uint256) { - return address(this).balance; - } - - function getamount(address) external view returns (uint256) { - return address(this).balance; - } -} - -contract testSelector { - using A for address; - - - function getselector2() public view returns (bytes4, bytes4) { - return (A.getBalance.selector, A.getamount.selector); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/stackContract001.sol b/framework/src/test/resources/soliditycode_0.5.15/stackContract001.sol deleted file mode 100644 index 19041b1e405..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/stackContract001.sol +++ /dev/null @@ -1,61 +0,0 @@ -pragma solidity ^0.5.0; - -contract A{ - event log(uint256); - constructor() payable public{ - emit log(withdrawreward()); - emit log(address(this).rewardbalance); - } - function withdrawRewardTest() public returns (uint256){ - return withdrawreward(); - } - - function test() public{ - emit log(123); - } -} - -contract B{ - event log(uint256); - constructor() payable public{ - emit log(withdrawreward()); - emit log(address(this).rewardbalance); - } - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } - function rewardBalance(address addr) public view returns (uint256){ - return addr.rewardbalance; - } - - function nullAddressTest() public view returns (uint256) { - return address(0x0).rewardbalance; - } - - function localContractAddrTest() public view returns (uint256) { - address payable localContract = address(uint160(address(this))); - return localContract.rewardbalance; - } - - function withdrawRewardTest() public returns (uint256){ - return withdrawreward(); - } - - function contractBWithdrawRewardTest(address contractB) public returns (uint) { - return B(contractB).withdrawRewardTest(); - } - - function createA() public returns (address){ - return address(new A()); - } - - function callA(address Addr) public{ - A(Addr).test(); - } -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/stackSuicide001.sol b/framework/src/test/resources/soliditycode_0.5.15/stackSuicide001.sol deleted file mode 100644 index a71816ddabd..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/stackSuicide001.sol +++ /dev/null @@ -1,84 +0,0 @@ -pragma solidity ^0.5.0; -contract testStakeSuicide{ - B b; - constructor() payable public{} - function deployB() payable public returns (B addrB){ - b = (new B).value(1000000000)(); - return b; - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } - function SelfdestructTest2(address sr, uint256 amount, address payable target) public{ - stake(sr, amount); - selfdestruct(target); - } - function Stake(address sr, uint256 amount) public payable returns (bool result){ - return stake(sr, amount); - } - function Stake2(address sr, uint256 amount) public returns (bool result){ - stake(sr, amount); - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function UnStake2() public returns (bool result){ - unstake(); - return unstake(); - } - function WithdrawReward() public { - withdrawreward(); - } - function RewardBalance(address addr) view public returns (uint256 balance) { - return addr.rewardbalance; - } - function revertTest1(address sr, uint256 amount, address payable transferAddr) public{ - transferAddr.transfer(1000000); - stake(sr, amount); - transferAddr.transfer(2000000); - stake(sr, 1000000000000000);//stake more than balance to fail - transferAddr.transfer(4000000); - } - function revertTest2(address payable transferAddr) public{ - transferAddr.transfer(1000000); - unstake(); - transferAddr.transfer(2000000); - unstake();//unstake twice to fail - transferAddr.transfer(4000000); - } - - function BStake(address sr, uint256 amount) public returns (bool result){ - return b.Stake(sr, amount); - } - function BUnStake() public returns (bool result){ - return b.UnStake(); - } - function transfer(address payable add,uint256 num) public { - return add.transfer(num); - } -} - -contract B{ - constructor() payable public{} - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } - - function deploy(bytes memory code, uint256 salt) public returns(address) { - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - return addr; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/stringSplit.sol b/framework/src/test/resources/soliditycode_0.5.15/stringSplit.sol deleted file mode 100644 index 5a7f5bdd4c9..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/stringSplit.sol +++ /dev/null @@ -1,45 +0,0 @@ -pragma solidity ^0; - -contract testStringSplit { -string s1 = "s""1""2"",./"; -string s2 = "s123?\\'."; -string s3 = hex"41"hex"42"; -string s4 = hex"4142"; - -function getS1() public view returns (string memory) { -return s1; -} - -function getS1N1() public pure returns (string memory) { -string memory n1 = "s""1""2"",./"; -return n1; -} - -function getS2() public view returns (string memory) { -return s2; -} - -function getS2N2() public pure returns (string memory) { -string memory n2 = "s123?\'."; -return n2; -} - -function getS3() public view returns (string memory) { -return s3; -} - -function getS3N3() public pure returns (string memory) { -string memory n3 = hex"41"hex"42"; -return n3; -} - -function getS4() public view returns (string memory) { -return s4; -} - -function getS4N4() public pure returns (string memory) { -string memory n4 = hex"4142"; -return n4; -} - -} diff --git a/framework/src/test/resources/soliditycode_0.5.15/suicide001.sol b/framework/src/test/resources/soliditycode_0.5.15/suicide001.sol deleted file mode 100644 index 3544f8bf84a..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/suicide001.sol +++ /dev/null @@ -1,32 +0,0 @@ -contract factory { - constructor() payable public { - } - - function create1() payable public returns (address){ - Caller add = (new Caller).value(0)(); - return address(add); - } - - function kill() payable public{ - selfdestruct(msg.sender); - } - - function create2(bytes memory code, uint256 salt) public returns(address){ - Caller addr; - Caller addr1; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - return address(addr); - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/suicide002.sol b/framework/src/test/resources/soliditycode_0.5.15/suicide002.sol deleted file mode 100644 index 160ab64f320..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/suicide002.sol +++ /dev/null @@ -1,43 +0,0 @@ -contract Factory { - uint256 public num; - event Deployed(address addr, uint256 salt, address sender); - constructor() public { - } - function deploy(bytes memory code, uint256 salt) public returns(address){ - TestConstract addr; - TestConstract addr1; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - - addr.testSuicideNonexistentTarget(msg.sender); - addr.set(); - - assembly { - addr1 := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(address(addr), salt, msg.sender); - return address(addr); - } -} - - - -contract TestConstract { - uint public i=1; - constructor () public { - } - - function set() public{ - i=9; - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/testOutOfMem.sol b/framework/src/test/resources/soliditycode_0.5.15/testOutOfMem.sol deleted file mode 100644 index 8d285b28b7d..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/testOutOfMem.sol +++ /dev/null @@ -1,7 +0,0 @@ -contract Test { - function testOutOfMem(uint256 x) public returns(bytes32 r) { - uint[] memory memVar; - memVar = new uint[](x); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/testStakeSuicide.sol b/framework/src/test/resources/soliditycode_0.5.15/testStakeSuicide.sol deleted file mode 100644 index 6f8ddfe0e3e..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/testStakeSuicide.sol +++ /dev/null @@ -1,71 +0,0 @@ -pragma solidity ^0.5.0; -contract testStakeSuicide{ - B b; - constructor() payable public{} - function deployB() payable public returns (B addrB){ - b = (new B).value(1000000000)(); - return b; - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } - function SelfdestructTest2(address sr, uint256 amount, address payable target) public{ - stake(sr, amount); - selfdestruct(target); - } - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - function Stake2(address sr, uint256 amount) public returns (bool result){ - stake(sr, amount); - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function UnStake2() public returns (bool result){ - unstake(); - return unstake(); - } - function WithdrawReward() public { - withdrawreward(); - } - function RewardBalance(address addr) view public returns (uint256 balance) { - return addr.rewardbalance; - } - function revertTest1(address sr, uint256 amount, address payable transferAddr) public{ - transferAddr.transfer(1000000); - stake(sr, amount); - transferAddr.transfer(2000000); - stake(sr, 1000000000000000);//stake more than balance to fail - transferAddr.transfer(4000000); - } - function revertTest2(address payable transferAddr) public{ - transferAddr.transfer(1000000); - unstake(); - transferAddr.transfer(2000000); - unstake();//unstake twice to fail - transferAddr.transfer(4000000); - } - function BStake(address sr, uint256 amount) public returns (bool result){ - return b.Stake(sr, amount); - } - function BUnStake() public returns (bool result){ - return b.UnStake(); - } - function BSelfdestructTest(address payable target) public{ - b.SelfdestructTest(target); - } -} -contract B{ - constructor() payable public{} - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/tryCatch001.sol b/framework/src/test/resources/soliditycode_0.5.15/tryCatch001.sol deleted file mode 100644 index 5692fe84540..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/tryCatch001.sol +++ /dev/null @@ -1,105 +0,0 @@ -pragma solidity ^0.6.0; - -enum ErrorType { - Revert_Error, //0 - RevertWithMsg_Error, //1 - Require_Error, //2 - RequirewithMsg_Error, //3 - Assert_Error, //4 - Tansfer_Error, //5 - Send_Error, //6 - Math_Error, //7 - ArrayOverFlow_Error //8 -} -contract errorContract { - uint256[] arraryUint ; - - function errorSwitch(uint256 errorType) public returns(string memory) { - if (ErrorType(errorType) == ErrorType.Revert_Error){ - revert(); - } else if (ErrorType(errorType) == ErrorType.RevertWithMsg_Error){ - revert("Revert Msg."); - } else if (ErrorType(errorType) == ErrorType.Require_Error) { - require(0>1); - } else if (ErrorType(errorType) == ErrorType.RequirewithMsg_Error) { - require(0>1,"Require Msg."); - } else if (ErrorType(errorType) == ErrorType.Assert_Error) { - assert(1<0); - } else if (ErrorType(errorType) == ErrorType.Tansfer_Error) { - payable(msg.sender).transfer(1); - } else if (ErrorType(errorType) == ErrorType.Send_Error) { - payable(msg.sender).send(1); - } else if (ErrorType(errorType) == ErrorType.Math_Error) { - uint256 a = 1; - uint256 b = 0; - uint256 n = a / b; - } else if (ErrorType(errorType) == ErrorType.ArrayOverFlow_Error) { - arraryUint.pop(); - } - return "success"; - - } - - function callFun(string memory functionStr, string memory argsStr) public{ - address(this).call(abi.encodeWithSignature(functionStr, argsStr)); - } - -} - -contract NewContract { - uint256[] arraryUint ; - - constructor(uint256 errorType) public payable{ - if (ErrorType(errorType) == ErrorType.Revert_Error){ - revert(); - } else if (ErrorType(errorType) == ErrorType.RevertWithMsg_Error){ - revert("Revert Msg."); - } else if (ErrorType(errorType) == ErrorType.Require_Error) { - require(0>1); - } else if (ErrorType(errorType) == ErrorType.RequirewithMsg_Error) { - require(0>1,"Require Msg."); - } else if (ErrorType(errorType) == ErrorType.Assert_Error) { - assert(1<0); - } else if (ErrorType(errorType) == ErrorType.Tansfer_Error) { - payable(msg.sender).transfer(1); - } else if (ErrorType(errorType) == ErrorType.Send_Error) { - payable(msg.sender).send(1); - } else if (ErrorType(errorType) == ErrorType.Math_Error) { - uint256 a = 1; - uint256 b = 0; - uint256 n = a / b; - } else if (ErrorType(errorType) == ErrorType.ArrayOverFlow_Error) { - arraryUint.pop(); - } - } -} - -contract tryTest { - function getData(errorContract inter, string memory functionStr, string memory argsStr) public payable returns(string memory) { - try inter.callFun(functionStr,argsStr) { - return "123"; - } catch Error(string memory errorMsg/* 出错原因 */) { - return errorMsg; - } catch (bytes memory) { - return "3"; - } - } - - function getErrorSwitch(errorContract add, uint256 errorType ) public payable returns(string memory) { - try add.errorSwitch(errorType) returns (string memory Msg) { - return Msg; - } catch Error(string memory errorMsg/* 出错原因 */) { - return errorMsg; - } catch (bytes memory) { - return "NoErrorMsg"; - } - } - - function catchNewErrorSwitch(uint256 errorType) public returns (address nc){ - try new NewContract(errorType) returns (NewContract nc){ - return address(nc); - }catch { - return address(0x00); - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue001.sol b/framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue001.sol deleted file mode 100644 index fd3c817421b..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue001.sol +++ /dev/null @@ -1,26 +0,0 @@ -pragma solidity ^0.5.12; - -contract tvmAssetIssue001 { - constructor() payable public{} - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - return assetissue(name, abbr, totalSupply, precision); - } - - function updateAsset(trcToken tokenId, string memory url, string memory desc) public returns (bool) { - return updateasset(tokenId, bytes(url), bytes(desc)); - } - - function updateOtherAccountAsset(string memory url, string memory desc) public returns (bool) { - trcToken tokenId = trcToken(1000004); - return updateasset(tokenId, bytes(url), bytes(desc)); - } - - function updateAssetOnBytes(trcToken tokenId, bytes memory url, bytes memory desc) public returns (bool) { - return updateasset(tokenId, url, desc); - } - - function transferToken(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue002.sol b/framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue002.sol deleted file mode 100644 index b158faf6720..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue002.sol +++ /dev/null @@ -1,15 +0,0 @@ -pragma solidity ^0.5.12; - -contract tvmAssetIssue002 { - constructor() payable public{} - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - assetissue(name, abbr, totalSupply, precision); - return assetissue(name, abbr, totalSupply, precision); - } - - function updateAsset(trcToken tokenId, string memory url1, string memory desc1, string memory url2, string memory desc2) public returns (bool) { - updateasset(tokenId, bytes(url1), bytes(desc1)); - return updateasset(tokenId, bytes(url2), bytes(desc2)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue003.sol b/framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue003.sol deleted file mode 100644 index 40390238d8f..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue003.sol +++ /dev/null @@ -1,23 +0,0 @@ -pragma solidity ^0.5.12; - -contract tvmAssetIssue003 { - constructor() payable public{} - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - return assetissue(name, abbr, totalSupply, precision); - } - - function tokenIssueAndTransfer(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision, address addr) public { - address payable newaddress = address(uint160(addr)); - newaddress.transfer(100000000); - assetissue(name, abbr, totalSupply, precision); - newaddress.transfer(100000000); - } - - function updateAssetAndTransfer(trcToken tokenId, string memory url, string memory desc, address addr) public { - address payable newaddress = address(uint160(addr)); - newaddress.transfer(100000000); - updateasset(tokenId, bytes(url), bytes(desc)); - newaddress.transfer(100000000); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue004.sol b/framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue004.sol deleted file mode 100644 index fbebdb26e68..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue004.sol +++ /dev/null @@ -1,39 +0,0 @@ -pragma solidity ^0.5.12; - -contract A { - - constructor() payable public{} - function() payable external {} - - function tokenIssueA(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint){ - return assetissue(name, abbr, totalSupply, precision); - } - - function updateAssetA(trcToken tokenId, string memory url, string memory desc) public returns (bool) { - return updateasset(tokenId, bytes(url), bytes(desc)); - } - - function transferToken(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } -} - -contract tvmAssetIssue004 { - - A a; - - constructor() payable public{} - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - return a.tokenIssueA(name, abbr, totalSupply, precision); - } - - function updateAsset(trcToken tokenId, string memory url, string memory desc) public returns (bool) { - return a.updateAssetA(tokenId, url, desc); - } - - function getContractAddress() public payable returns (address) { - a = (new A).value(1024000000)(); - return address(a); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue005.sol b/framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue005.sol deleted file mode 100644 index 20fd14944c2..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/tvmAssetIssue005.sol +++ /dev/null @@ -1,45 +0,0 @@ -pragma solidity ^0.5.12; - -contract tvmAssetIssue005 { - constructor() payable public{} - - function() external payable { - } - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - return assetissue(name, abbr, totalSupply, precision); - } - - function updateAsset(trcToken tokenId, string memory url, string memory desc) public returns (bool) { - return updateasset(tokenId, bytes(url), bytes(desc)); - } - - function updateAssetOnBytes(trcToken tokenId, bytes memory url, bytes memory desc) public returns (bool) { - return updateasset(tokenId, url, desc); - } - - function transferToken(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - - function SelfdestructTest(address payable target) public { - selfdestruct(target); - } -} - -contract B { - event Deployed(address addr, uint256 salt); - - function deploy(uint256 salt) public returns (address) { - address addr; - bytes memory code = type(tvmAssetIssue005).creationCode; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt); - return addr; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/typeName.sol b/framework/src/test/resources/soliditycode_0.5.15/typeName.sol deleted file mode 100644 index 5b44abd1bbb..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/typeName.sol +++ /dev/null @@ -1,5 +0,0 @@ -contract TypeName { - function testTypeName() public returns (string memory){ - return type(TypeName).name; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/unStake001.sol b/framework/src/test/resources/soliditycode_0.5.15/unStake001.sol deleted file mode 100644 index 54a9829cd40..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/unStake001.sol +++ /dev/null @@ -1,90 +0,0 @@ -pragma solidity ^0.5.0; - -contract unStakeTest { - B b; - constructor() payable public{} - function deployB() payable public returns (B addrB){ - b = (new B).value(1000000000)(); - return b; - } - - function selfdestructTest(address payable target) public { - selfdestruct(target); - } - - function selfdestructTest2(address sr, uint256 amount, address payable target) public { - stake(sr, amount); - selfdestruct(target); - } - - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - - function stake2(address sr, uint256 amount) public returns (bool result){ - stake(sr, amount); - return stake(sr, amount); - } - - function unStake() public returns (bool result){ - return unstake(); - } - - function unStake2() public returns (bool result){ - unstake(); - return unstake(); - } - - function withdrawReward() public returns (uint256 amount) { - return withdrawreward(); - } - - function rewardBalance(address addr) view public returns (uint256 balance) { - return addr.rewardbalance; - } - - function revertTest1(address sr, uint256 amount, address payable transferAddr) public { - transferAddr.transfer(1000000); - stake(sr, amount); - transferAddr.transfer(2000000); - stake(sr, 1000000000000000); - //stake more than balance to fail - transferAddr.transfer(4000000); - } - - function revertTest2(address payable transferAddr) public { - transferAddr.transfer(1000000); - unstake(); - transferAddr.transfer(2000000); - unstake(); - //unstake twice to fail - transferAddr.transfer(4000000); - } - - function BStake(address sr, uint256 amount) public returns (bool result){ - return b.Stake(sr, amount); - } - - function BUnStake() public returns (bool result){ - return b.UnStake(); - } - - function BSelfdestructTest(address payable target) public { - b.SelfdestructTest(target); - } -} - -contract B { - constructor() payable public{} - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - - function UnStake() public returns (bool result){ - return unstake(); - } - - function SelfdestructTest(address payable target) public { - selfdestruct(target); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/validatemultisign001.sol b/framework/src/test/resources/soliditycode_0.5.15/validatemultisign001.sol deleted file mode 100644 index cc0a742d0c5..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/validatemultisign001.sol +++ /dev/null @@ -1,15 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract validatemultisignTest { - function testmulti(address a, uint256 perid, bytes32 hash, bytes[] memory signatures) public returns (bool){ - return validatemultisign(a, perid, hash, signatures); - } - - function testbatch(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public returns (bytes32){ - return batchvalidatesign(hash, signatures, addresses); - } - - function testMultiPrecompileContract(bytes memory data) public returns(bool, bytes memory){ - return address(0xa).delegatecall(data); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/verifyTransferProof001.sol b/framework/src/test/resources/soliditycode_0.5.15/verifyTransferProof001.sol deleted file mode 100644 index 587b4defd10..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/verifyTransferProof001.sol +++ /dev/null @@ -1,15 +0,0 @@ -contract verifyTransferProofTest { - - function test1() public returns (bool, bytes memory){ - bytes memory empty = ""; - return address(0x1000002).delegatecall(empty); - } - - function test2(bytes memory data) public returns (bool, bytes memory){ - return address(0x1000002).delegatecall(data); - } - - function test3(bytes32[10][] memory input, bytes32[2][] memory spendAuthoritySignature, bytes32[9][] memory output, bytes32[2] memory bindingSignature, bytes32 signHash, uint64 valueBalance, bytes32[33] memory frontier, uint256 leafCount) public returns (bytes32[] memory){ - return verifyTransferProof(input, spendAuthoritySignature, output, bindingSignature, signHash, valueBalance, frontier, leafCount); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.5.15/walletTestMutiSign004.sol b/framework/src/test/resources/soliditycode_0.5.15/walletTestMutiSign004.sol deleted file mode 100644 index 7b943aee5c1..00000000000 --- a/framework/src/test/resources/soliditycode_0.5.15/walletTestMutiSign004.sol +++ /dev/null @@ -1,51 +0,0 @@ -contract timeoutTest { - string public iarray1; - // cpu - function oneCpu() public { - require(1==1); - } - - function storage8Char() public { - iarray1 = "12345678"; - } - - function testUseCpu(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - } - return count; - } - - - uint256[] public iarray; - uint public calculatedFibNumber; - mapping(address=>mapping(address=>uint256)) public m; - - function testUseStorage(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - iarray.push(i); - } - return count; - } - - // stack - //uint n = 0; - uint yy = 0; - function test() public { - //n += 1; - yy += 1; - test(); - } - - function setFibonacci(uint n) public returns (uint256){ - calculatedFibNumber = fibonacci(n); - return calculatedFibNumber; - } - - function fibonacci(uint n) internal returns (uint) { - return fibonacci(n - 1) + fibonacci(n - 2); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/AssertException002.sol b/framework/src/test/resources/soliditycode_0.6.12/AssertException002.sol deleted file mode 100644 index 15cc07ff984..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/AssertException002.sol +++ /dev/null @@ -1,17 +0,0 @@ - - -contract AssertException{ - function divideIHaveArgsReturn(int x,int y) public returns (int z) { - return x / y; - } - function testAssert() public { - require(2==1); - } -} -contract C { - constructor() public payable { - assert(1==2); - } - function fun() public { - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/AssignToExternal.sol b/framework/src/test/resources/soliditycode_0.6.12/AssignToExternal.sol deleted file mode 100644 index d4f09590a36..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/AssignToExternal.sol +++ /dev/null @@ -1,30 +0,0 @@ -contract AssignToExternal { - // Not allow: - // function f(uint256[] calldata x, uint256[] calldata y) external pure { - // x = y; - // } - - // allow: - - function f(uint256 a) external returns (uint){ - a = a + 1; - return a; - } - - function StringSet(string calldata a) external returns (string memory){ - return a; - } - - function ByteSet(bytes32 a) external returns (bytes32){ - return a; - } - - function UintArraySet(uint256[2] calldata a) external returns (uint256[2] memory){ - return a; - } - - function AddSet(address a) external returns (address){ - return a; - } - -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/BlockHash.sol b/framework/src/test/resources/soliditycode_0.6.12/BlockHash.sol deleted file mode 100644 index 6603da65e44..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/BlockHash.sol +++ /dev/null @@ -1,38 +0,0 @@ -contract TestBlockHash { - - function testOR1(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = blockhash(block.number - 1) | bytes32(value); - return (b1, c, blockhash(block.number - 1)); - } - - function testOR2(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = bytes32(value) | blockhash(block.number - 1); - return (b1, c, blockhash(block.number - 1)); - } - - function testAND1(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = blockhash(block.number - 1) & bytes32(value); - return (b1, c, blockhash(block.number - 1)); - } - - function testAND2(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = bytes32(value) & blockhash(block.number - 1); - return (b1, c, blockhash(block.number - 1)); - } - - function testXOR1(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = blockhash(block.number - 1) ^ bytes32(value); - return (b1, c, blockhash(block.number - 1)); - } - - function testXOR2(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = bytes32(value) ^ blockhash(block.number - 1); - return (b1, c, blockhash(block.number - 1)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/ClearAbi001.sol b/framework/src/test/resources/soliditycode_0.6.12/ClearAbi001.sol deleted file mode 100644 index 39a8e8cf005..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/ClearAbi001.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract testConstantContract{ -function testPayable() public view returns (int z) { -return 1; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/ClearAbi005.sol b/framework/src/test/resources/soliditycode_0.6.12/ClearAbi005.sol deleted file mode 100644 index a3115398386..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/ClearAbi005.sol +++ /dev/null @@ -1,26 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract TestConstract { - uint public i=0; - constructor () public { - } - function plusOne() public returns(uint){ - i++; - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/ConstructorDefaults.sol b/framework/src/test/resources/soliditycode_0.6.12/ConstructorDefaults.sol deleted file mode 100644 index 4b6186ccb95..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/ConstructorDefaults.sol +++ /dev/null @@ -1,9 +0,0 @@ -contract testIsContract{ - bool result; - constructor (bool a) public { - result = a; - } -function test( address a) public returns (bool) { -return result; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/Create2Test023.sol b/framework/src/test/resources/soliditycode_0.6.12/Create2Test023.sol deleted file mode 100644 index 4c3f8af9f2b..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/Create2Test023.sol +++ /dev/null @@ -1,31 +0,0 @@ -contract factory { - constructor() payable public { - } - - function deploy(bytes memory code, uint256 salt) public returns(address){ - Caller addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - return address(addr); - } - - function testCreate() payable public returns (address){ - Caller add = (new Caller).value(0)(); - return address(add); - } - - function kill( ) payable public{ - selfdestruct(msg.sender); - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/Create2Test024.sol b/framework/src/test/resources/soliditycode_0.6.12/Create2Test024.sol deleted file mode 100644 index f5a9d032cff..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/Create2Test024.sol +++ /dev/null @@ -1,56 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - TestConstract addr; - TestConstract addr1; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - - addr.testSuicideNonexistentTarget(msg.sender); - addr.set(); - emit Deployed(address(addr), salt, msg.sender); - return address(addr); - } - - function deploy2(bytes memory code, uint256 salt) public returns(address){ - TestConstract addr; - TestConstract addr1; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - - //addr.testSuicideNonexistentTarget(msg.sender); - //addr.set(); - - assembly { - addr1 := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(address(addr), salt, msg.sender); - return address(addr); - } -} - - - -contract TestConstract { - uint public i=1; - constructor () public { - } - - function set() public{ - i=9; - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/Create2Test025.sol b/framework/src/test/resources/soliditycode_0.6.12/Create2Test025.sol deleted file mode 100644 index 895dc43e56f..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/Create2Test025.sol +++ /dev/null @@ -1,34 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - constructor() public { - } - - function create2(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } - - function get(bytes1 prefix, bytes calldata code, uint256 salt) external view returns(address) { - //bytes32 hash = keccak256(abi.encodePacked(bytes1(0x41),address(this), salt, keccak256(code))); - bytes32 hash = keccak256(abi.encodePacked(prefix,address(this), salt, keccak256(code))); - address addr = address(uint160(uint256(hash))); - return addr; - } -} - -contract TestContract{ - uint256 public num; - constructor(uint256 j) public{ - num = j; - } - function getNum() public returns (uint256){ - return num; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/ExtCodeHashTest010.sol b/framework/src/test/resources/soliditycode_0.6.12/ExtCodeHashTest010.sol deleted file mode 100644 index bfa8a7fa0d8..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/ExtCodeHashTest010.sol +++ /dev/null @@ -1,46 +0,0 @@ -contract Counter { - uint count = 0; - address payable owner; - event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); - constructor() public{ - owner = msg.sender; - } - function getCodeHashSuicide(address addr) public returns (bytes32 _hashBefore){ - assembly{ - _hashBefore := extcodehash(addr) - } - selfdestruct(owner); - return _hashBefore; - } - - function getCodeHashRevert() public returns (bytes32 _hashBefore, bytes32 _hashAfter) { - address addr = address(this); - assembly { - _hashBefore := extcodehash(addr) - } - if (owner == msg.sender) { - selfdestruct(owner); - } - assembly { - _hashAfter := extcodehash(addr) - } - revert(); - emit LogResult(_hashBefore, _hashAfter); - } - - function getCodeHashCreate() public returns (bytes32 _hashBefore){ - TestContract A = (new TestContract).value(0)(); - address addr = address(A); - assembly{ - _hashBefore := extcodehash(addr) - } - revert(); - return _hashBefore; - } -} - -contract TestContract{ - uint256 count = 1; - constructor() public payable{ - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/ExternalSelector.sol b/framework/src/test/resources/soliditycode_0.6.12/ExternalSelector.sol deleted file mode 100644 index 0359813e275..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/ExternalSelector.sol +++ /dev/null @@ -1,92 +0,0 @@ -pragma solidity ^0.6.0; - -contract selectorContract { - function testSelectorNoParam() external pure returns(uint) { - return 11; - } - - function testSelectorWithParam(uint x) external pure returns(uint) { - return 22; - } -} - -interface interfaceSelector { - function getSelector() external pure returns(uint); -} - -interface B is interfaceSelector { - // interface现在可以继承自其他interface - function testImplemention() external pure returns(uint); -} - -contract implementContract is B{ - function getSelector() external override pure returns(uint) { - return 66; - } - - function testImplemention() external override pure returns(uint) { - return 77; - } - - constructor() public payable {} -} - -contract basicContract{ - function testNewUse() external payable returns(uint) { - return 345; - } - - constructor() public payable {} -} - -contract TestGasValue{ - constructor() public payable {} - - function testNewUse() external payable returns(uint) { - return 123; - } - basicContract bc = new basicContract(); - // external方法在调用时可以采用c.f{gas: 10000, value: 4 trx}()的形式 - function callWithGasAndValue(uint x,uint y) external returns(uint) { - return bc.testNewUse{gas:x, value:y}(); - } - - function callThisNoGasAnd1Value() external returns(uint) { - return this.testNewUse{gas:0, value:1}(); - } - - // inline assembly中允许true和false字面量 - function testAssemblyTrue() public pure returns(uint x) { - assembly { - x := true - } - } - - // inline assembly中允许true和false字面量 - function testAssemblyFalse() public pure returns(uint x) { - assembly { - x := false - } - } - - // create2的high-level用法new C{salt: 0x1234, value: 1 ether}(arg1, arg2) - function testCreate2() public returns(address) { - basicContract c = new basicContract{salt: bytes32(bytes1(0x01)), value: 1 trx}(); - return address(c); - } - - - function getContractSelectorNoParam() public pure returns(bytes4) { - return selectorContract.testSelectorNoParam.selector; - } - - function getContractSelectorWithParam() public pure returns(bytes4) { - return selectorContract.testSelectorWithParam.selector; - } - - function getInterfaceSelectorNoParam() public pure returns(bytes4) { - return interfaceSelector.getSelector.selector; - } - -} - diff --git a/framework/src/test/resources/soliditycode_0.6.12/NewFeature068.sol b/framework/src/test/resources/soliditycode_0.6.12/NewFeature068.sol deleted file mode 100644 index f5c19435f7c..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/NewFeature068.sol +++ /dev/null @@ -1,126 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.6.8; - -abstract contract testModifier { - modifier isOwner() virtual; -} - -abstract contract testInterfaceId { - function getValue() external view virtual returns(uint); - function getOwner() external view virtual returns(uint); - -} - -interface a { - function getValue() external view returns(uint); - function getOwner() external view returns(uint); -} - -contract testMapKey is testModifier{ - - enum size{ - SMALL, - LARGE - } - - mapping(size => uint) public enums; - - mapping(testMapKey => uint) public contracts; - - function setEnumValue(uint value) public { - enums[size.SMALL] = value; - } - - function getEnumValue() public view returns(uint) { - return enums[size.SMALL]; - } - - function setContractValue() public { - contracts[this] = 2; - } - - function getContractValue() public view returns(uint) { - return contracts[this]; - } - - bytes4 constant functionSelector = this.getEnumValue.selector; - - function getfunctionSelector() public pure returns(bytes4) { - return functionSelector; - } - - uint immutable x; - address immutable owner = msg.sender; - - constructor() public { - x = 5; - } - - string b = "test"; - - function testStorage() public view returns(string memory) { - string storage aa; - aa = b; - return aa; - - } - - function getImmutableVal() public view returns(uint) { - return x; - } - - function getOwner() public view returns(address) { - return owner; - } - - function getInterfaceId() public pure returns(bytes4,bytes4) { - return (type(a).interfaceId, type(testInterfaceId).interfaceId); - } - - modifier isOwner() override { - require(msg.sender == owner); - _; - } - - function requireOwner() public view isOwner returns(uint) { - return 6; - } - - - function getUint256MinAndMax() public pure returns(uint, uint) { - return (type(uint).min, type(uint).max); - } - - - function getUint8MinAndMax() public pure returns(uint8, uint8) { - return (type(uint8).min, type(uint8).max); - } - -} - - -abstract contract base { - function abstractfun() virtual public returns(uint); -} - -abstract contract callEmptyFunction is base { - function callfun() public returns(uint) { - return abstractfun(); - } -} - - - - - - - - - - - - - - - - diff --git a/framework/src/test/resources/soliditycode_0.6.12/ParentTypeBug.sol b/framework/src/test/resources/soliditycode_0.6.12/ParentTypeBug.sol deleted file mode 100644 index 897c843ae24..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/ParentTypeBug.sol +++ /dev/null @@ -1,13 +0,0 @@ -contract Parent { - uint256 public m_aMember; - address public m_bMember; -} -contract Child is Parent { - function foo() public view returns (uint256) { return Parent.m_aMember; } - function bar() public view returns (address) { return Parent.m_bMember; } - - // complie failed - // function foo() public pure returns (uint256) { return Parent.m_aMember; } - // function bar() public pure returns (address) { return Parent.m_bMember; } - -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/SafeMath.sol b/framework/src/test/resources/soliditycode_0.6.12/SafeMath.sol deleted file mode 100644 index 1a7f1be2b8e..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/SafeMath.sol +++ /dev/null @@ -1,149 +0,0 @@ - - -/** - * @dev Wrappers over Solidity's arithmetic operations with added overflow - * checks. - * - * Arithmetic operations in Solidity wrap on overflow. This can easily result - * in bugs, because programmers usually assume that an overflow raises an - * error, which is the standard behavior in high level programming languages. - * `SafeMath` restores this intuition by reverting the transaction when an - * operation overflows. - * - * Using this library instead of the unchecked operations eliminates an entire - * class of bugs, so it's recommended to use it always. - */ -library SafeMath { - /** - * @dev Returns the addition of two unsigned integers, reverting on - * overflow. - * - * Counterpart to Solidity's `+` operator. - * - * Requirements: - * - Addition cannot overflow. - */ - function add(uint256 a, uint256 b) internal pure returns (uint256) { - uint256 c = a + b; - require(c >= a, "SafeMath: addition overflow"); - - return c; - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting on - * overflow (when the result is negative). - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - Subtraction cannot overflow. - */ - function sub(uint256 a, uint256 b) internal pure returns (uint256) { - return sub(a, b, "SafeMath: subtraction overflow"); - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting with custom message on - * overflow (when the result is negative). - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - Subtraction cannot overflow. - */ - function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b <= a, errorMessage); - uint256 c = a - b; - - return c; - } - - /** - * @dev Returns the multiplication of two unsigned integers, reverting on - * overflow. - * - * Counterpart to Solidity's `*` operator. - * - * Requirements: - * - Multiplication cannot overflow. - */ - function mul(uint256 a, uint256 b) internal pure returns (uint256) { - // Gas optimization: this is cheaper than requiring 'a' not being zero, but the - // benefit is lost if 'b' is also tested. - // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 - if (a == 0) { - return 0; - } - - uint256 c = a * b; - require(c / a == b, "SafeMath: multiplication overflow"); - - return c; - } - - /** - * @dev Returns the integer division of two unsigned integers. Reverts on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. Note: this function uses a - * `revert` opcode (which leaves remaining gas untouched) while Solidity - * uses an invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - return div(a, b, "SafeMath: division by zero"); - } - - /** - * @dev Returns the integer division of two unsigned integers. Reverts with custom message on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. Note: this function uses a - * `revert` opcode (which leaves remaining gas untouched) while Solidity - * uses an invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b > 0, errorMessage); - uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - - return c; - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * Reverts when dividing by zero. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function mod(uint256 a, uint256 b) internal pure returns (uint256) { - return mod(a, b, "SafeMath: modulo by zero"); - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * Reverts with custom message when dividing by zero. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b != 0, errorMessage); - return a % b; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/ShiftCommand001.sol b/framework/src/test/resources/soliditycode_0.6.12/ShiftCommand001.sol deleted file mode 100644 index 574ee2b571b..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/ShiftCommand001.sol +++ /dev/null @@ -1,18 +0,0 @@ -contract TestBitwiseShift { - - function shlTest(uint256 num, uint256 input) public returns (bytes32 out) { - assembly { - out := shl(num, input) - } - } - function shrTest(uint256 num, uint256 input) public returns (bytes32 out) { - assembly { - out := shr(num, input) - } - } - function sarTest(uint256 num, uint256 input) public returns (bytes32 out) { - assembly { - out := sar(num, input) - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/SolidityMappingFix.sol b/framework/src/test/resources/soliditycode_0.6.12/SolidityMappingFix.sol deleted file mode 100644 index 67692d3b4ae..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/SolidityMappingFix.sol +++ /dev/null @@ -1,9 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Tests { - mapping(address => uint) public balances; - function update(uint256 amount) public returns (address addr) - { - balances[msg.sender] = amount; - return msg.sender; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/TestMappings_array_pop.sol b/framework/src/test/resources/soliditycode_0.6.12/TestMappings_array_pop.sol deleted file mode 100644 index 0d5c4bb7013..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TestMappings_array_pop.sol +++ /dev/null @@ -1,19 +0,0 @@ -contract C { - mapping (uint256 => uint256)[] a; - - function n1(uint256 key, uint256 value) public { - a.push(); - a[a.length - 1][key] = value; - } - - - - function map(uint256 key) public view returns (uint) { - return a[a.length - 1][key]; - } - - function p() public { - a.pop(); - } -} - diff --git a/framework/src/test/resources/soliditycode_0.6.12/TransferFailed001.sol b/framework/src/test/resources/soliditycode_0.6.12/TransferFailed001.sol deleted file mode 100644 index dba043edcb3..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TransferFailed001.sol +++ /dev/null @@ -1,147 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - - function testTransferTokenCompiledLongMax() payable public{ - address(0x1).transferToken(1,9223372036855775827); - } - - function testTransferTokenCompiled() payable public{ - address(0x1).transferToken(1,1); - } - - function testTransferTokenCompiledLongMin() payable public{ - //address(0x1).transferToken(1,-9223372036855775828); - } - - function testTransferTokenCompiledLongMin1() payable public returns(uint256){ - return address(0x2).tokenBalance(trcToken(-9223372036855775828)); - } - - function testTransferTokenCompiled1() payable public returns(uint256){ - return address(0x1).tokenBalance(trcToken(1)); - } - - function testTransferTokenCompiledLongMax1() payable public returns(uint256){ - return address(0x2).tokenBalance(trcToken(9223372036855775827)); - } - - function testTransferTokenCompiledTokenId(uint256 tokenid) payable public returns(uint256){ - return address(0x1).tokenBalance(trcToken(tokenid)); - } - - function testTransferTokenTest(address addr ,uint256 tokenid) payable public returns(uint256){ - return addr.tokenBalance(trcToken(tokenid)); - } - - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address payable caller) public { - caller.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller).value(i)(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - nonexistentTarget.send(i); - } - - function testSendTrxRevert(uint256 i,address payable nonexistentTarget) payable public { - nonexistentTarget.send(i); - revert(); - } - - function testTransferTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - nonexistentTarget.transfer(i); - } - - function testTransferTrxrevert(uint256 i,address payable nonexistentTarget) payable public{ - nonexistentTarget.transfer(i); - revert(); - } - - function testTransferTokenNonexistentTarget(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - nonexistentTarget.transferToken(i, tokenId); - } - - function testTransferTokenRevert(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - nonexistentTarget.transferToken(i, tokenId); - revert(); - } - - function testCallTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - nonexistentTarget.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - function testSuicideRevert(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - revert(); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - address payable self = address(uint160(address(this))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - address payable self = address(uint160(address(this))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - address payable self = address(uint160(address(this))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } - function deploy2(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(300, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/TransferFailed005.sol b/framework/src/test/resources/soliditycode_0.6.12/TransferFailed005.sol deleted file mode 100644 index aa39aafa152..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TransferFailed005.sol +++ /dev/null @@ -1,90 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address payable caller) public returns (bool,bytes memory){ - return caller.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller).value(i)(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.send(i); - } - - function testTransferTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.transfer(i); - } - - function testTransferTokenNonexistentTarget(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - require(address(this).balance >= i); - nonexistentTarget.transferToken(i, tokenId); - } - - function testCallTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256 ){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/TransferFailed006.sol b/framework/src/test/resources/soliditycode_0.6.12/TransferFailed006.sol deleted file mode 100644 index aa39aafa152..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TransferFailed006.sol +++ /dev/null @@ -1,90 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address payable caller) public returns (bool,bytes memory){ - return caller.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller).value(i)(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.send(i); - } - - function testTransferTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.transfer(i); - } - - function testTransferTokenNonexistentTarget(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - require(address(this).balance >= i); - nonexistentTarget.transferToken(i, tokenId); - } - - function testCallTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256 ){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/TransferFailed007.sol b/framework/src/test/resources/soliditycode_0.6.12/TransferFailed007.sol deleted file mode 100644 index aa39aafa152..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TransferFailed007.sol +++ /dev/null @@ -1,90 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address payable caller) public returns (bool,bytes memory){ - return caller.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller).value(i)(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.send(i); - } - - function testTransferTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.transfer(i); - } - - function testTransferTokenNonexistentTarget(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - require(address(this).balance >= i); - nonexistentTarget.transferToken(i, tokenId); - } - - function testCallTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256 ){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant001.sol b/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant001.sol deleted file mode 100644 index b385850577d..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant001.sol +++ /dev/null @@ -1,28 +0,0 @@ - - -contract testConstantContract{ - uint256 public i; - function testPayable() public payable returns (uint256 z) { - i=1; - z=i; - return z; - } - function testNoPayable() public returns (uint256 z) { - i=1; - z=i; - return z; - } - function testView() public view returns (uint256 z) { - uint256 i=1; - return i; - } - function testPure() public pure returns (uint256 z) { - uint256 i=1; - return i; - } - function testView2() public view returns (uint256 z) { - uint256 i=1; - revert(); - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant002.sol b/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant002.sol deleted file mode 100644 index 7708d81792a..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant002.sol +++ /dev/null @@ -1,10 +0,0 @@ - - -contract testConstantContract{ - uint256 public i; - function testNoPayable() public returns (uint256 z) { - i=1; - z=i; - return z; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant003.sol b/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant003.sol deleted file mode 100644 index 947b3f610e6..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant003.sol +++ /dev/null @@ -1,18 +0,0 @@ - - -contract testConstantContract{ - function testView() public view returns (uint256 z) { - uint256 i=1; - return i; - } - - function testPure() public pure returns (uint256 z) { - uint256 i=1; - return i; - } - - function testPayable() public payable returns (uint256 z) { - uint256 i=1; - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant004.sol b/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant004.sol deleted file mode 100644 index 7fcb44950e7..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant004.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract testConstantContract{ -function testPure() public pure returns (uint256 z) { -uint256 i=1; -return i; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant015.sol b/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant015.sol deleted file mode 100644 index d926c43c824..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant015.sol +++ /dev/null @@ -1,24 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract TestConstract { - constructor () public { - } - function plusOne() public returns(uint){ - return 1; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant024.sol b/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant024.sol deleted file mode 100644 index 69ad3a2d5b5..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TriggerConstant024.sol +++ /dev/null @@ -1,9 +0,0 @@ - - -contract testConstantContract{ -function testView() public view returns (uint256 z) { -uint256 i=1; -revert(); -return i; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/TvmIsContract.sol b/framework/src/test/resources/soliditycode_0.6.12/TvmIsContract.sol deleted file mode 100644 index 4266b9e92ca..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TvmIsContract.sol +++ /dev/null @@ -1,15 +0,0 @@ -contract testIsContract{ -bool public isContrct; -constructor () public { - isContrct = address(this).isContract; -} -function testIsContractCommand(address a) public returns (bool) { -return (a.isContract); -} -function selfdestructContract(address payable a) public { - selfdestruct(a); -} -function testConstructor() public returns(bool){ - return isContrct; -} -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/TvmIsContract001.sol b/framework/src/test/resources/soliditycode_0.6.12/TvmIsContract001.sol deleted file mode 100644 index 77aae930b59..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TvmIsContract001.sol +++ /dev/null @@ -1,24 +0,0 @@ -contract testIsContract{ -bool public isContrct; -constructor () public { - isContrct = address(this).isContract; -} -function testIsContractCommand(address a) public returns (bool) { -return (a.isContract); -} - -function testIsContractView(address a) view public returns (bool) { -return (a.isContract); -} - -function selfdestructContract(address payable a) public { - selfdestruct(a); -} -function testConstructor() public returns(bool){ - return isContrct; -} - -function testConstructorView() public view returns(bool){ - return isContrct; -} -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/TvmIsContract002.sol b/framework/src/test/resources/soliditycode_0.6.12/TvmIsContract002.sol deleted file mode 100644 index 2fe474fd98c..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TvmIsContract002.sol +++ /dev/null @@ -1,5 +0,0 @@ -contract testIsContract{ -function testIsContractCommand(address a) public returns (bool) { -return (a.isContract); -} -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand043.sol b/framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand043.sol deleted file mode 100644 index 04d9f7dde28..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand043.sol +++ /dev/null @@ -1,18 +0,0 @@ -contract TestBitwiseShift { - - function shlTest(int256 num, int256 input) public returns (bytes32 out) { - assembly { - out := shl(num, input) - } - } - function shrTest(int256 num, int256 input) public returns (bytes32 out) { - assembly { - out := shr(num, input) - } - } - function sarTest(int256 num, int256 input) public returns (bytes32 out) { - assembly { - out := sar(num, input) - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand103.sol b/framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand103.sol deleted file mode 100644 index dbc7fd0f0f4..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand103.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract testConstantContract{ -function testView() public constant returns (uint256 z) { -uint256 i=1; -return i; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand107.sol b/framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand107.sol deleted file mode 100644 index 5b51cd1842c..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand107.sol +++ /dev/null @@ -1,9 +0,0 @@ - - - contract testConstantContract{ - int256 public i; - function testPayable() public returns (int z) { - z=1+1; - return z; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand108.sol b/framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand108.sol deleted file mode 100644 index 0088054faf9..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand108.sol +++ /dev/null @@ -1,7 +0,0 @@ - - - contract testConstantContract{ - function test() pure public returns (int z) { - return 1; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand109.sol b/framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand109.sol deleted file mode 100644 index dc8dd1e8399..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TvmNewCommand109.sol +++ /dev/null @@ -1,7 +0,0 @@ - - - contract testConstantContract{ - function test() view public returns (int z) { - return 1; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/TvmOldCommand001.sol b/framework/src/test/resources/soliditycode_0.6.12/TvmOldCommand001.sol deleted file mode 100644 index 1ee046babe0..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/TvmOldCommand001.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract binaryRightContract{ - function binaryMoveR(int i)public returns (int z) { - return z = 5 >> i; - } - function binaryLiftR(int i)public returns (int z) { - return z = 5 << i; - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/VerifyBurnProof001.sol b/framework/src/test/resources/soliditycode_0.6.12/VerifyBurnProof001.sol deleted file mode 100644 index 4173e84de23..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/VerifyBurnProof001.sol +++ /dev/null @@ -1,20 +0,0 @@ - -contract VerifyBurnProof001Test { - // verifyBurnProof(bytes32[10],bytes32[2],uint64,bytes32[2],bytes32) - // size = 512 - // - - function VerifyBurnProofSize001(bytes32[10] memory output, bytes32[2] memory spendAuthoritySignature, uint64 value, bytes32[2] memory bindingSignature,bytes32 signHash) public returns (bool){ - return verifyBurnProof(output, spendAuthoritySignature, value, bindingSignature, signHash); - } - - function VerifyBurnProofSize002(bytes memory data) public returns (bool, bytes memory){ - // bytes memory empty = ""; - return address(0x1000003).delegatecall(data); - } - - function VerifyBurnProofSize003() public returns (bool, bytes memory){ - bytes memory empty = ""; - return address(0x1000003).delegatecall(empty); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/VerifyMintProof001.sol b/framework/src/test/resources/soliditycode_0.6.12/VerifyMintProof001.sol deleted file mode 100644 index cb0812c2ef5..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/VerifyMintProof001.sol +++ /dev/null @@ -1,33 +0,0 @@ - -contract VerifyMintProof001Test { - // verifyMintProof(bytes32[9],bytes32[2],uint64,bytes32,bytes32[33],uint256) - - function VerifyMintProofSize001(bytes32[9] memory output, bytes32[2] memory bindingSignature, uint64 value, bytes32 signHash, bytes32[33] memory frontier,uint256 leafCount) public returns (bytes32[] memory){ - return verifyMintProof(output, bindingSignature, value, signHash, frontier, leafCount); - } - - function VerifyMintProofSize002(bytes memory data) public returns (bool, bytes memory){ -// address verifyMint = address (0x1000001); -// -// assembly { -// let succeeded := delegatecall(sub(gas, 5000), verifyMint, add(data, 0x20), mload(data), 0, 0) -// let size := returndatasize -// let response := mload(0x40) -// mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f)))) -// mstore(response, size) -// returndatacopy(add(response, 0x20), 0, size) -// switch iszero(succeeded) -// case 1 { -// // throw if delegatecall failed -// revert(add(response, 0x20), size) -// } -// } - - return address(0x1000001).delegatecall(data); - } - - function VerifyMintProofSize003() public returns (bool, bytes memory){ - bytes memory empty = ""; - return address(0x1000001).call(empty); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/abiencode.sol b/framework/src/test/resources/soliditycode_0.6.12/abiencode.sol deleted file mode 100644 index 38fad3454d6..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/abiencode.sol +++ /dev/null @@ -1,16 +0,0 @@ -pragma experimental ABIEncoderV2; - -// tests encoding from storage arrays - -contract AbiEncode { - int256[2][] tmp_h; - function h(int256[2][] calldata s) external returns (bytes memory) { - tmp_h = s; - return abi.encode(tmp_h); - } - int256[2][2] tmp_i; - function i(int256[2][2] calldata s) external returns (bytes memory) { - tmp_i = s; - return abi.encode(tmp_i); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/abstract001.sol b/framework/src/test/resources/soliditycode_0.6.12/abstract001.sol deleted file mode 100644 index 56bdc38eef4..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/abstract001.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma solidity ^0.6.0; - -interface X { - function setValue(uint _x) external; - function setBalance(uint _x) external; -} - -abstract contract abstract001 is X { - uint x; - function setX(uint _x) public { x = _x; } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/abstract002.sol b/framework/src/test/resources/soliditycode_0.6.12/abstract002.sol deleted file mode 100644 index 98bcf879f60..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/abstract002.sol +++ /dev/null @@ -1,13 +0,0 @@ -pragma solidity ^0.6.0; - -interface X { - function setValue(uint _x) external; - function setBalance(uint _x) external; -} - -abstract contract abstract002 is X { - uint x; - function setX(uint _x) public { x = _x; } - function setValue(uint _x) external override{ x = _x; } - function setBalance(uint _x) external override{ x = _x; } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/accountAssert.sol b/framework/src/test/resources/soliditycode_0.6.12/accountAssert.sol deleted file mode 100644 index 6d370f56080..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/accountAssert.sol +++ /dev/null @@ -1,94 +0,0 @@ -pragma solidity ^0.6.0; - -contract transferTokenTestA { - - // transfer trc10 to a new address or exist address in constructor - constructor(address payable toAddress, uint256 tokenValue, trcToken id) payable public{ - toAddress.transferToken(tokenValue, id); - require(toAddress.tokenBalance(id) > 0, "tokenBalance should not be 0"); - } - - fallback() payable external{} - - function transferTest(address payable toAddress, uint256 tokenValue) payable public { - toAddress.transfer(tokenValue); - } - - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - - // suicide to a new address - function selfdestructTest(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - - // transfer to a new contract - function createContractTest(uint256 tokenValue, trcToken id) payable public returns(address){ - Simple s = new Simple(); - require(address(s).tokenBalance(id)==0, "tokenBalance should be 0"); - address(s).transferToken(tokenValue, id); - require(address(s).tokenBalance(id)==tokenValue, "tokenBalance should not be 0"); - return address(s); - } - - // revert transfer to a new contract - function revertCreateContractTest(uint256 tokenValue, trcToken id) payable public { - Simple s = new Simple(); - address(s).transferToken(tokenValue, id); - revert(); - } -} - -contract transferTokenTestB { - - constructor() payable public{ - } - - fallback() payable external{} - - function transferTest(address payable toAddress, uint256 tokenValue) payable public { - toAddress.transfer(tokenValue); - } - - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - - // suicide to a new address - function selfdestructTest(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - - // transfer to a new contract - function createContractTest(uint256 tokenValue, trcToken id) payable public returns(address){ - Simple s = new Simple(); - require(address(s).tokenBalance(id)==0, "tokenBalance should be 0"); - address(s).transferToken(tokenValue, id); - require(address(s).tokenBalance(id)==tokenValue, "tokenBalance should not be 0"); - return address(s); - } - - // revert transfer to a new contract - function revertCreateContractTest(uint256 tokenValue, trcToken id) payable public { - Simple s = new Simple(); - address(s).transferToken(tokenValue, id); - revert(); - } -} - -contract transferTokenTestC { - Simple public s; - - // transfer to a new address in constructor - constructor(trcToken id) payable public{ - s = new Simple(); - require(address(s).tokenBalance(id)==0, "new contract tokenBalance should be 0"); - require(address(this).tokenBalance(id)==0, "this.tokenBalance should be 0"); - } -} - -contract Simple { - constructor() payable public{} - fallback() payable external{} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/addMsg001Nonpayable.sol b/framework/src/test/resources/soliditycode_0.6.12/addMsg001Nonpayable.sol deleted file mode 100644 index fcd40cdb521..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/addMsg001Nonpayable.sol +++ /dev/null @@ -1,20 +0,0 @@ - - -contract IllegalDecorate { - -event log(uint256); -constructor() payable public{} - -fallback() payable external{} - -function transferTokenWithOutPayable(address payable toAddress, uint256 tokenValue)public { -// function transferTokenWithValue(address toAddress, uint256 tokenValue) payable public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); - -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/addMsg002View.sol b/framework/src/test/resources/soliditycode_0.6.12/addMsg002View.sol deleted file mode 100644 index 0c04b5c0b8a..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/addMsg002View.sol +++ /dev/null @@ -1,20 +0,0 @@ - - -contract IllegalDecorate { - -constructor() payable public{} - -fallback() payable external{} - -event log(uint256); - -function transferTokenWithView(address payable toAddress, uint256 tokenValue) public view{ -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} - diff --git a/framework/src/test/resources/soliditycode_0.6.12/addMsg003Constant.sol b/framework/src/test/resources/soliditycode_0.6.12/addMsg003Constant.sol deleted file mode 100644 index 2065802bed1..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/addMsg003Constant.sol +++ /dev/null @@ -1,19 +0,0 @@ - - -contract IllegalDecorate { - -constructor() payable public{} - -fallback() payable external{} - -event log(uint256); - -function transferTokenWithConstant(address payable toAddress, uint256 tokenValue) public constant{ -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/addMsg004Pure.sol b/framework/src/test/resources/soliditycode_0.6.12/addMsg004Pure.sol deleted file mode 100644 index 25f1a36d8b7..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/addMsg004Pure.sol +++ /dev/null @@ -1,19 +0,0 @@ - - -contract IllegalDecorate { - -constructor() payable public{} - -fallback() payable external{} - -event log(uint256); - -function transferTokenWithPure(address payable toAddress, uint256 tokenValue) public pure{ -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/addTransferToken001Nonpayable.sol b/framework/src/test/resources/soliditycode_0.6.12/addTransferToken001Nonpayable.sol deleted file mode 100644 index 039b341b6ac..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/addTransferToken001Nonpayable.sol +++ /dev/null @@ -1,13 +0,0 @@ - - - contract IllegalDecorate { - - constructor() payable public{} - - fallback() payable external{} - - function transferTokenWithOutPayable(address payable toAddress,trcToken id, uint256 tokenValue)public { - - toAddress.transferToken(tokenValue, id); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/addTransferToken001payable.sol b/framework/src/test/resources/soliditycode_0.6.12/addTransferToken001payable.sol deleted file mode 100644 index 17078e30189..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/addTransferToken001payable.sol +++ /dev/null @@ -1,13 +0,0 @@ - - - contract IllegalDecorate { - - constructor() payable public{} - - fallback() payable external{} - - function transferTokenWithOutPayable(address payable toAddress,trcToken id, uint256 tokenValue) public payable{ - - toAddress.transferToken(tokenValue, id); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/addTransferToken002View.sol b/framework/src/test/resources/soliditycode_0.6.12/addTransferToken002View.sol deleted file mode 100644 index c50a16390f5..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/addTransferToken002View.sol +++ /dev/null @@ -1,15 +0,0 @@ - - -contract IllegalDecorate { - - constructor() payable public{} - - fallback() payable external{} - - function transferTokenWithView(address payable toAddress,trcToken id, uint256 tokenValue) public view{ - - toAddress.transferToken(tokenValue, id); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/addTransferToken003Constant.sol b/framework/src/test/resources/soliditycode_0.6.12/addTransferToken003Constant.sol deleted file mode 100644 index 18721d9b94c..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/addTransferToken003Constant.sol +++ /dev/null @@ -1,14 +0,0 @@ - -contract IllegalDecorate { - - constructor() payable public{} - - fallback() payable external{} - - function transferTokenWithConstant(address payable toAddress, uint256 tokenValue) public constant{ - - toAddress.transferToken(tokenValue, 0x6e6d62); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/addTransferToken004Pure.sol b/framework/src/test/resources/soliditycode_0.6.12/addTransferToken004Pure.sol deleted file mode 100644 index f7716ee3874..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/addTransferToken004Pure.sol +++ /dev/null @@ -1,15 +0,0 @@ - - -contract IllegalDecorate { - - constructor() payable public{} - - fallback() payable external{} - - function transferTokenWithPure(address payable toAddress, uint256 tokenValue) public pure{ - - toAddress.transferToken(tokenValue, 0x6e6d62); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/addTrcToken001Assemble.sol b/framework/src/test/resources/soliditycode_0.6.12/addTrcToken001Assemble.sol deleted file mode 100644 index fe7a7f4cef8..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/addTrcToken001Assemble.sol +++ /dev/null @@ -1,62 +0,0 @@ - - -contract InAssemble { - -mapping(trcToken => uint256) tokenCnt; -mapping(uint256 => mapping(trcToken => trcToken)) cntTokenToken; -constructor () payable public {} -function getBalance (address addr) view public returns(uint256 r) { -assembly{ -r := balance(addr) -} -} - -function getTokenBalanceConstant (address addr, trcToken tokenId) view public returns(uint256 r) { -assembly{ -r := tokenbalance(tokenId, addr) -} -} - -function getTokenBalance (address addr, trcToken tokenId) public returns(uint256 r) { -assembly{ -r := tokenbalance(tokenId, addr) -} -} - -function transferTokenInAssembly(address addr, trcToken tokenId, uint256 tokenValue) public payable { -bytes4 sig = bytes4(keccak256("()")); // function signature - -assembly { -let x := mload(0x40) // get empty storage location -mstore(x,sig) // 4 bytes - place signature in empty storage - -let ret := calltoken(gas, addr, tokenValue, tokenId, -x, // input -0x04, // input size = 4 bytes -x, // output stored at input location, save space -0x0 // output size = 0 bytes -) - -// let ret := calltoken(gas, addr, tokenValue, -// x, // input -// 0x04, // input size = 4 bytes -// x, // output stored at input location, save space -// 0x0 // output size = 0 bytes -// ) // ERROR - - -mstore(0x40, add(x,0x20)) // update free memory pointer -} - -} - -function trcTokenInMap(trcToken tokenId, uint256 tokenValue) public returns(uint256 r) { -tokenCnt[tokenId] += tokenValue; -r = tokenCnt[tokenId]; -} - -function cntTokenTokenInMap(trcToken tokenId1, trcToken tokenId2, uint256 tokenValue) public returns(trcToken r) { -cntTokenToken[tokenValue][tokenId1] = tokenId2; -r = cntTokenToken[tokenValue][tokenId1]; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/addTrcToken002Cat.sol b/framework/src/test/resources/soliditycode_0.6.12/addTrcToken002Cat.sol deleted file mode 100644 index 0cd407079ba..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/addTrcToken002Cat.sol +++ /dev/null @@ -1,2051 +0,0 @@ - - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) public onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address payable public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address payable _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() public onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - emit Transfer(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(now), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - uint256 newKittenId = kitties.push(_kitty) - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - emit Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(address(0), _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -contract ERC721 { - // Required methods - function totalSupply() public view returns (uint256 total); - function balanceOf(address _owner) public view returns (uint256 balance); - function ownerOf(uint256 _tokenId) external view returns (address owner); - function approve(address _to, uint256 _tokenId) external; - function transfer(address _to, uint256 _tokenId) external; - function transferFrom(address _from, address _to, uint256 _tokenId) external; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) external view returns (bool); -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is ERC721, KittyBase { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public view returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - emit Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() public view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - external - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] memory _rawBytes, uint256 _stringLength) private view returns (string memory) { - string memory outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string calldata _preferredTransport) external view returns (string memory infoUrl) { - require( address(erc721Metadata) != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2 sun; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty memory _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty memory _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - emit Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.transfer(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, address(saleAuction)); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, address(siringAuction)); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid.value(msg.value - autoBirthFee)(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10 sun; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, address(saleAuction)); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(uint160(address(this))) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - constructor() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - emit ContractUpgrade(_v2Address); - } - - /// @notice No tipping! - /// @dev Reject all Ether from being sent here, unless it's from one of the - /// two auction contracts. (Hopefully, we can prevent user accidents.) - fallback() external payable { - require( - msg.sender == address(saleAuction) || - msg.sender == address(siringAuction) - ); - } - - /// @notice Returns all the relevant information about a specific kitty. - /// @param _id The ID of the kitty of interest. - function getKitty(uint256 _id) - external - view - returns ( - bool isGestating, - bool isReady, - uint256 cooldownIndex, - uint256 nextActionAt, - uint256 siringWithId, - uint256 birthTime, - uint256 matronId, - uint256 sireId, - uint256 generation, - uint256 genes - ) { - Kitty storage kit = kitties[_id]; - - // if this variable is 0 then it's not gestating - isGestating = (kit.siringWithId != 0); - isReady = (kit.cooldownEndBlock <= block.number); - cooldownIndex = uint256(kit.cooldownIndex); - nextActionAt = uint256(kit.cooldownEndBlock); - siringWithId = uint256(kit.siringWithId); - birthTime = uint256(kit.birthTime); - matronId = uint256(kit.matronId); - sireId = uint256(kit.sireId); - generation = uint256(kit.generation); - genes = kit.genes; - } - - /// @dev Override unpause so it requires all external contract addresses - /// to be set before contract can be unpaused. Also, we can't have - /// newContractAddress set either, because then the contract was upgraded. - /// @notice This is public rather than external so we can call super.unpause - /// without using an expensive CALL. - - function unpause(address payable toAddress, uint256 tokenValue, trcToken tokenId) public onlyCEO whenPaused returns (uint256 r) { - require(address(saleAuction) != address(0)); - require(address(siringAuction) != address(0)); - require(address(geneScience) != address(0)); - require(address(newContractAddress) == address(0)); - toAddress.transferToken(tokenValue, tokenId); - r = address(this).tokenBalance(tokenId); - // Actually unpause the contract. - super.unpause(); - } - - // @dev Allows the CFO to capture the balance available to the contract. - function withdrawBalance() external onlyCFO { - uint256 balance = address(this).balance; - // Subtract all the currently pregnant kittens we have, plus 1 of margin. - uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - - if (balance > subtractFees) { - cfoAddress.transfer(balance - subtractFees); - } - } -} - - - - - - - - - - - - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - - function isGeneScience() public pure returns (bool){ - return true; - } - - /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor - /// @param genes1 genes of mom - /// @param genes2 genes of sire - /// @return the genes that are supposed to be passed down the child - function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - - return (genes1+genes2+targetBlock)/2; - - -} -} - - - - - - - - - - - - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { - /// @dev Given a token Id, returns a byte array that is supposed to be converted into string. - function getMetadata(uint256 _tokenId, string memory) public view returns (bytes32[4] memory buffer, uint256 count) { - if (_tokenId == 1) { - buffer[0] = "Hello World! :D"; - count = 15; - } else if (_tokenId == 2) { - buffer[0] = "I would definitely choose a medi"; - buffer[1] = "um length string."; - count = 49; - } else if (_tokenId == 3) { - buffer[0] = "Lorem ipsum dolor sit amet, mi e"; - buffer[1] = "st accumsan dapibus augue lorem,"; - buffer[2] = " tristique vestibulum id, libero"; - buffer[3] = " suscipit varius sapien aliquam."; - count = 128; - } - } -} - - - - - - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - - // Represents an auction on an NFT - struct Auction { - // Current owner of NFT - address payable seller; - // Price (in wei) at beginning of auction - uint128 startingPrice; - // Price (in wei) at end of auction - uint128 endingPrice; - // Duration (in seconds) of auction - uint64 duration; - // Time when auction started - // NOTE: 0 if this auction has been concluded - uint64 startedAt; - } - - // Reference to contract tracking NFT ownership - ERC721 public nonFungibleContract; - - // Cut owner takes on each auction, measured in basis points (1/100 of a percent). - // Values 0-10,000 map to 0%-100% - uint256 public ownerCut; - - // Map from token ID to their corresponding auction. - mapping (uint256 => Auction) tokenIdToAuction; - - event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); - event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); - event AuctionCancelled(uint256 tokenId); - - /// @dev Returns true if the claimant owns the token. - /// @param _claimant - Address claiming to own the token. - /// @param _tokenId - ID of token whose ownership to verify. - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return (nonFungibleContract.ownerOf(_tokenId) == _claimant); - } - - /// @dev Escrows the NFT, assigning ownership to this contract. - /// Throws if the escrow fails. - /// @param _owner - Current owner address of token to escrow. - /// @param _tokenId - ID of token whose approval to verify. - function _escrow(address _owner, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transferFrom(_owner, address(this), _tokenId); - } - - /// @dev Transfers an NFT owned by this contract to another address. - /// Returns true if the transfer succeeds. - /// @param _receiver - Address to transfer NFT to. - /// @param _tokenId - ID of token to transfer. - function _transfer(address _receiver, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transfer(_receiver, _tokenId); - } - - /// @dev Adds an auction to the list of open auctions. Also fires the - /// AuctionCreated event. - /// @param _tokenId The ID of the token to be put on auction. - /// @param _auction Auction to add. - function _addAuction(uint256 _tokenId, Auction memory _auction) internal { - // Require that all auctions have a duration of - // at least one minute. (Keeps our math from getting hairy!) - require(_auction.duration >= 1 minutes); - - tokenIdToAuction[_tokenId] = _auction; - - emit AuctionCreated( - uint256(_tokenId), - uint256(_auction.startingPrice), - uint256(_auction.endingPrice), - uint256(_auction.duration) - ); - } - - /// @dev Cancels an auction unconditionally. - function _cancelAuction(uint256 _tokenId, address _seller) internal { - _removeAuction(_tokenId); - _transfer(_seller, _tokenId); - emit AuctionCancelled(_tokenId); - } - - /// @dev Computes the price and transfers winnings. - /// Does NOT transfer ownership of token. - function _bid(uint256 _tokenId, uint256 _bidAmount) - internal - returns (uint256) - { - // Get a reference to the auction struct - Auction storage auction = tokenIdToAuction[_tokenId]; - - // Explicitly check that this auction is currently live. - // (Because of how Ethereum mappings work, we can't just count - // on the lookup above failing. An invalid _tokenId will just - // return an auction object that is all zeros.) - require(_isOnAuction(auction)); - - // Check that the bid is greater than or equal to the current price - uint256 price = _currentPrice(auction); - require(_bidAmount >= price); - - // Grab a reference to the seller before the auction struct - // gets deleted. - address payable seller = auction.seller; - - // The bid is good! Remove the auction before sending the fees - // to the sender so we can't have a reentrancy attack. - _removeAuction(_tokenId); - - // Transfer proceeds to seller (if there are any!) - if (price > 0) { - // Calculate the auctioneer's cut. - // (NOTE: _computeCut() is guaranteed to return a - // value <= price, so this subtraction can't go negative.) - uint256 auctioneerCut = _computeCut(price); - uint256 sellerProceeds = price - auctioneerCut; - - // NOTE: Doing a transfer() in the middle of a complex - // method like this is generally discouraged because of - // reentrancy attacks and DoS attacks if the seller is - // a contract with an invalid fallback function. We explicitly - // guard against reentrancy attacks by removing the auction - // before calling transfer(), and the only thing the seller - // can DoS is the sale of their own asset! (And if it's an - // accident, they can call cancelAuction(). ) - seller.transfer(sellerProceeds); - } - - // Calculate any excess funds included with the bid. If the excess - // is anything worth worrying about, transfer it back to bidder. - // NOTE: We checked above that the bid amount is greater than or - // equal to the price so this cannot underflow. - uint256 bidExcess = _bidAmount - price; - - // Return the funds. Similar to the previous transfer, this is - // not susceptible to a re-entry attack because the auction is - // removed before any transfers occur. - msg.sender.transfer(bidExcess); - - // Tell the world! - emit AuctionSuccessful(_tokenId, price, msg.sender); - - return price; - } - - /// @dev Removes an auction from the list of open auctions. - /// @param _tokenId - ID of NFT on auction. - function _removeAuction(uint256 _tokenId) internal { - delete tokenIdToAuction[_tokenId]; - } - - /// @dev Returns true if the NFT is on auction. - /// @param _auction - Auction to check. - function _isOnAuction(Auction storage _auction) internal view returns (bool) { - return (_auction.startedAt > 0); - } - - /// @dev Returns current price of an NFT on auction. Broken into two - /// functions (this one, that computes the duration from the auction - /// structure, and the other that does the price computation) so we - /// can easily test that the price computation works correctly. - function _currentPrice(Auction storage _auction) - internal - view - returns (uint256) - { - uint256 secondsPassed = 0; - - // A bit of insurance against negative values (or wraparound). - // Probably not necessary (since Ethereum guarnatees that the - // now variable doesn't ever go backwards). - if (now > _auction.startedAt) { - secondsPassed = now - _auction.startedAt; - } - - return _computeCurrentPrice( - _auction.startingPrice, - _auction.endingPrice, - _auction.duration, - secondsPassed - ); - } - - /// @dev Computes the current price of an auction. Factored out - /// from _currentPrice so we can run extensive unit tests. - /// When testing, make this function public and turn on - /// `Current price computation` test suite. - function _computeCurrentPrice( - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - uint256 _secondsPassed - ) - internal - pure - returns (uint256) - { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our public functions carefully cap the maximum values for - // time (at 64-bits) and currency (at 128-bits). _duration is - // also known to be non-zero (see the require() statement in - // _addAuction()) - if (_secondsPassed >= _duration) { - // We've reached the end of the dynamic pricing portion - // of the auction, just return the end price. - return _endingPrice; - } else { - // Starting price can be higher than ending price (and often is!), so - // this delta can be negative. - int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - - // This multiplication can't overflow, _secondsPassed will easily fit within - // 64-bits, and totalPriceChange will easily fit within 128-bits, their product - // will always fit within 256-bits. - int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - - // currentPriceChange can be negative, but if so, will have a magnitude - // less that _startingPrice. Thus, this result will always end up positive. - int256 currentPrice = int256(_startingPrice) + currentPriceChange; - - return uint256(currentPrice); - } - } - - /// @dev Computes owner's cut of a sale. - /// @param _price - Sale price of NFT. - function _computeCut(uint256 _price) internal view returns (uint256) { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our entry functions carefully cap the maximum values for - // currency (at 128-bits), and ownerCut <= 10000 (see the require() - // statement in the ClockAuction constructor). The result of this - // function is always guaranteed to be <= _price. - return _price * ownerCut / 10000; - } - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { - event Pause(); - event Unpause(); - - bool public paused = false; - - - /** - * @dev modifier to allow actions only when the contract IS paused - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev modifier to allow actions only when the contract IS NOT paused - */ - modifier whenPaused { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyOwner whenNotPaused public returns (bool) { - paused = true; - emit Pause(); - return true; - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyOwner whenPaused public returns (bool) { - paused = false; - emit Unpause(); - return true; - } -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - - /// @dev The ERC-165 interface signature for ERC-721. - /// Ref: https://github.com/ethereum/EIPs/issues/165 - /// Ref: https://github.com/ethereum/EIPs/issues/721 - bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - - /// @dev Constructor creates a reference to the NFT ownership contract - /// and verifies the owner cut is in the valid range. - /// @param _nftAddress - address of a deployed contract implementing - /// the Nonfungible Interface. - /// @param _cut - percent cut the owner takes on each auction, must be - /// between 0-10,000. - constructor(address _nftAddress, uint256 _cut) public { - require(_cut <= 10000); - ownerCut = _cut; - - ERC721 candidateContract = ERC721(_nftAddress); - require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); - nonFungibleContract = candidateContract; - } - - /// @dev Remove all Ether from the contract, which is the owner's cuts - /// as well as any Ether sent directly to the contract address. - /// Always transfers to the NFT contract, but can be called either by - /// the owner or the NFT contract. - function withdrawBalance() external { - address payable nftAddress = address(uint160(address(nonFungibleContract))); - - require( - msg.sender == owner || - msg.sender == nftAddress - ); - // We are using this boolean method to make sure that even if one fails it will still work - bool res = nftAddress.send(address(this).balance); - } - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of time to move between starting - /// price and ending price (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - whenNotPaused - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(_owns(msg.sender, _tokenId)); - _escrow(msg.sender, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Bids on an open auction, completing the auction and transferring - /// ownership of the NFT if enough Ether is supplied. - /// @param _tokenId - ID of token to bid on. - function bid(uint256 _tokenId) - external - payable - whenNotPaused - { - // _bid will throw if the bid or funds transfer fails - _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - } - - /// @dev Cancels an auction that hasn't been won yet. - /// Returns the NFT to original owner. - /// @notice This is a state-modifying function that can - /// be called while the contract is paused. - /// @param _tokenId - ID of token on auction - function cancelAuction(uint256 _tokenId) - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - address seller = auction.seller; - require(msg.sender == seller); - _cancelAuction(_tokenId, seller); - } - - /// @dev Cancels an auction when the contract is paused. - /// Only the owner may do this, and NFTs are returned to - /// the seller. This should only be used in emergencies. - /// @param _tokenId - ID of the NFT on auction to cancel. - function cancelAuctionWhenPaused(uint256 _tokenId) - whenPaused - onlyOwner - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - _cancelAuction(_tokenId, auction.seller); - } - - /// @dev Returns auction info for an NFT on auction. - /// @param _tokenId - ID of NFT on auction. - function getAuction(uint256 _tokenId) - external - view - returns - ( - address seller, - uint256 startingPrice, - uint256 endingPrice, - uint256 duration, - uint256 startedAt - ) { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return ( - auction.seller, - auction.startingPrice, - auction.endingPrice, - auction.duration, - auction.startedAt - ); - } - - /// @dev Returns the current price of an auction. - /// @param _tokenId - ID of the token price we are checking. - function getCurrentPrice(uint256 _tokenId) - external - view - returns (uint256) - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return _currentPrice(auction); - } - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSiringAuctionAddress() call. - bool public isSiringClockAuction = true; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. Since this function is wrapped, - /// require sender to be KittyCore contract. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Places a bid for siring. Requires the sender - /// is the KittyCore contract because all bid methods - /// should be wrapped. Also returns the kitty to the - /// seller rather than the winner. - function bid(uint256 _tokenId) - external - payable - { - require(msg.sender == address(nonFungibleContract)); - address seller = tokenIdToAuction[_tokenId].seller; - // _bid checks that token ID is valid and will throw if bid fails - _bid(_tokenId, msg.value); - // We transfer the kitty back to the seller, the winner will get - // the offspring - _transfer(seller, _tokenId); - } - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSaleAuctionAddress() call. - bool public isSaleClockAuction = true; - - // Tracks last 5 sale price of gen0 kitty sales - uint256 public gen0SaleCount; - uint256[5] public lastGen0SalePrices; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Updates lastSalePrice if seller is the nft contract - /// Otherwise, works the same as default bid method. - function bid(uint256 _tokenId) - external - payable - { - // _bid verifies token ID size - address seller = tokenIdToAuction[_tokenId].seller; - uint256 price = _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - - // If not a gen0 auction, exit - if (seller == address(nonFungibleContract)) { - // Track gen0 sale prices - lastGen0SalePrices[gen0SaleCount % 5] = price; - gen0SaleCount++; - } - } - - function averageGen0SalePrice() external view returns (uint256) { - uint256 sum = 0; - for (uint256 i = 0; i < 5; i++) { - sum += lastGen0SalePrices[i]; - } - return sum / 5; - } - -} - - - - - - - diff --git a/framework/src/test/resources/soliditycode_0.6.12/addTrcToken002Cat_withFinny.sol b/framework/src/test/resources/soliditycode_0.6.12/addTrcToken002Cat_withFinny.sol deleted file mode 100644 index 24117bc5e6b..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/addTrcToken002Cat_withFinny.sol +++ /dev/null @@ -1,2051 +0,0 @@ - - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) public onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address payable public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address payable _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() public onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - emit Transfer(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(now), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - uint256 newKittenId = kitties.push(_kitty) - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - emit Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(address(0), _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -contract ERC721 { - // Required methods - function totalSupply() public view returns (uint256 total); - function balanceOf(address _owner) public view returns (uint256 balance); - function ownerOf(uint256 _tokenId) external view returns (address owner); - function approve(address _to, uint256 _tokenId) external; - function transfer(address _to, uint256 _tokenId) external; - function transferFrom(address _from, address _to, uint256 _tokenId) external; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) external view returns (bool); -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is ERC721, KittyBase { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public view returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - emit Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() public view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - external - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] memory _rawBytes, uint256 _stringLength) private view returns (string memory) { - string memory outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string calldata _preferredTransport) external view returns (string memory infoUrl) { - require( address(erc721Metadata) != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2 finney; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty memory _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty memory _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - emit Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.transfer(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, address(saleAuction)); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, address(siringAuction)); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid.value(msg.value - autoBirthFee)(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10 finney; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, address(saleAuction)); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(uint160(address(this))) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - constructor() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - emit ContractUpgrade(_v2Address); - } - - /// @notice No tipping! - /// @dev Reject all Ether from being sent here, unless it's from one of the - /// two auction contracts. (Hopefully, we can prevent user accidents.) - fallback() external payable { - require( - msg.sender == address(saleAuction) || - msg.sender == address(siringAuction) - ); - } - - /// @notice Returns all the relevant information about a specific kitty. - /// @param _id The ID of the kitty of interest. - function getKitty(uint256 _id) - external - view - returns ( - bool isGestating, - bool isReady, - uint256 cooldownIndex, - uint256 nextActionAt, - uint256 siringWithId, - uint256 birthTime, - uint256 matronId, - uint256 sireId, - uint256 generation, - uint256 genes - ) { - Kitty storage kit = kitties[_id]; - - // if this variable is 0 then it's not gestating - isGestating = (kit.siringWithId != 0); - isReady = (kit.cooldownEndBlock <= block.number); - cooldownIndex = uint256(kit.cooldownIndex); - nextActionAt = uint256(kit.cooldownEndBlock); - siringWithId = uint256(kit.siringWithId); - birthTime = uint256(kit.birthTime); - matronId = uint256(kit.matronId); - sireId = uint256(kit.sireId); - generation = uint256(kit.generation); - genes = kit.genes; - } - - /// @dev Override unpause so it requires all external contract addresses - /// to be set before contract can be unpaused. Also, we can't have - /// newContractAddress set either, because then the contract was upgraded. - /// @notice This is public rather than external so we can call super.unpause - /// without using an expensive CALL. - - function unpause(address payable toAddress, uint256 tokenValue, trcToken tokenId) public onlyCEO whenPaused returns (uint256 r) { - require(address(saleAuction) != address(0)); - require(address(siringAuction) != address(0)); - require(address(geneScience) != address(0)); - require(address(newContractAddress) == address(0)); - toAddress.transferToken(tokenValue, tokenId); - r = address(this).tokenBalance(tokenId); - // Actually unpause the contract. - super.unpause(); - } - - // @dev Allows the CFO to capture the balance available to the contract. - function withdrawBalance() external onlyCFO { - uint256 balance = address(this).balance; - // Subtract all the currently pregnant kittens we have, plus 1 of margin. - uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - - if (balance > subtractFees) { - cfoAddress.transfer(balance - subtractFees); - } - } -} - - - - - - - - - - - - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - - function isGeneScience() public pure returns (bool){ - return true; - } - - /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor - /// @param genes1 genes of mom - /// @param genes2 genes of sire - /// @return the genes that are supposed to be passed down the child - function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - - return (genes1+genes2+targetBlock)/2; - - -} -} - - - - - - - - - - - - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { - /// @dev Given a token Id, returns a byte array that is supposed to be converted into string. - function getMetadata(uint256 _tokenId, string memory) public view returns (bytes32[4] memory buffer, uint256 count) { - if (_tokenId == 1) { - buffer[0] = "Hello World! :D"; - count = 15; - } else if (_tokenId == 2) { - buffer[0] = "I would definitely choose a medi"; - buffer[1] = "um length string."; - count = 49; - } else if (_tokenId == 3) { - buffer[0] = "Lorem ipsum dolor sit amet, mi e"; - buffer[1] = "st accumsan dapibus augue lorem,"; - buffer[2] = " tristique vestibulum id, libero"; - buffer[3] = " suscipit varius sapien aliquam."; - count = 128; - } - } -} - - - - - - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - - // Represents an auction on an NFT - struct Auction { - // Current owner of NFT - address payable seller; - // Price (in wei) at beginning of auction - uint128 startingPrice; - // Price (in wei) at end of auction - uint128 endingPrice; - // Duration (in seconds) of auction - uint64 duration; - // Time when auction started - // NOTE: 0 if this auction has been concluded - uint64 startedAt; - } - - // Reference to contract tracking NFT ownership - ERC721 public nonFungibleContract; - - // Cut owner takes on each auction, measured in basis points (1/100 of a percent). - // Values 0-10,000 map to 0%-100% - uint256 public ownerCut; - - // Map from token ID to their corresponding auction. - mapping (uint256 => Auction) tokenIdToAuction; - - event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); - event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); - event AuctionCancelled(uint256 tokenId); - - /// @dev Returns true if the claimant owns the token. - /// @param _claimant - Address claiming to own the token. - /// @param _tokenId - ID of token whose ownership to verify. - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return (nonFungibleContract.ownerOf(_tokenId) == _claimant); - } - - /// @dev Escrows the NFT, assigning ownership to this contract. - /// Throws if the escrow fails. - /// @param _owner - Current owner address of token to escrow. - /// @param _tokenId - ID of token whose approval to verify. - function _escrow(address _owner, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transferFrom(_owner, address(this), _tokenId); - } - - /// @dev Transfers an NFT owned by this contract to another address. - /// Returns true if the transfer succeeds. - /// @param _receiver - Address to transfer NFT to. - /// @param _tokenId - ID of token to transfer. - function _transfer(address _receiver, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transfer(_receiver, _tokenId); - } - - /// @dev Adds an auction to the list of open auctions. Also fires the - /// AuctionCreated event. - /// @param _tokenId The ID of the token to be put on auction. - /// @param _auction Auction to add. - function _addAuction(uint256 _tokenId, Auction memory _auction) internal { - // Require that all auctions have a duration of - // at least one minute. (Keeps our math from getting hairy!) - require(_auction.duration >= 1 minutes); - - tokenIdToAuction[_tokenId] = _auction; - - emit AuctionCreated( - uint256(_tokenId), - uint256(_auction.startingPrice), - uint256(_auction.endingPrice), - uint256(_auction.duration) - ); - } - - /// @dev Cancels an auction unconditionally. - function _cancelAuction(uint256 _tokenId, address _seller) internal { - _removeAuction(_tokenId); - _transfer(_seller, _tokenId); - emit AuctionCancelled(_tokenId); - } - - /// @dev Computes the price and transfers winnings. - /// Does NOT transfer ownership of token. - function _bid(uint256 _tokenId, uint256 _bidAmount) - internal - returns (uint256) - { - // Get a reference to the auction struct - Auction storage auction = tokenIdToAuction[_tokenId]; - - // Explicitly check that this auction is currently live. - // (Because of how Ethereum mappings work, we can't just count - // on the lookup above failing. An invalid _tokenId will just - // return an auction object that is all zeros.) - require(_isOnAuction(auction)); - - // Check that the bid is greater than or equal to the current price - uint256 price = _currentPrice(auction); - require(_bidAmount >= price); - - // Grab a reference to the seller before the auction struct - // gets deleted. - address payable seller = auction.seller; - - // The bid is good! Remove the auction before sending the fees - // to the sender so we can't have a reentrancy attack. - _removeAuction(_tokenId); - - // Transfer proceeds to seller (if there are any!) - if (price > 0) { - // Calculate the auctioneer's cut. - // (NOTE: _computeCut() is guaranteed to return a - // value <= price, so this subtraction can't go negative.) - uint256 auctioneerCut = _computeCut(price); - uint256 sellerProceeds = price - auctioneerCut; - - // NOTE: Doing a transfer() in the middle of a complex - // method like this is generally discouraged because of - // reentrancy attacks and DoS attacks if the seller is - // a contract with an invalid fallback function. We explicitly - // guard against reentrancy attacks by removing the auction - // before calling transfer(), and the only thing the seller - // can DoS is the sale of their own asset! (And if it's an - // accident, they can call cancelAuction(). ) - seller.transfer(sellerProceeds); - } - - // Calculate any excess funds included with the bid. If the excess - // is anything worth worrying about, transfer it back to bidder. - // NOTE: We checked above that the bid amount is greater than or - // equal to the price so this cannot underflow. - uint256 bidExcess = _bidAmount - price; - - // Return the funds. Similar to the previous transfer, this is - // not susceptible to a re-entry attack because the auction is - // removed before any transfers occur. - msg.sender.transfer(bidExcess); - - // Tell the world! - emit AuctionSuccessful(_tokenId, price, msg.sender); - - return price; - } - - /// @dev Removes an auction from the list of open auctions. - /// @param _tokenId - ID of NFT on auction. - function _removeAuction(uint256 _tokenId) internal { - delete tokenIdToAuction[_tokenId]; - } - - /// @dev Returns true if the NFT is on auction. - /// @param _auction - Auction to check. - function _isOnAuction(Auction storage _auction) internal view returns (bool) { - return (_auction.startedAt > 0); - } - - /// @dev Returns current price of an NFT on auction. Broken into two - /// functions (this one, that computes the duration from the auction - /// structure, and the other that does the price computation) so we - /// can easily test that the price computation works correctly. - function _currentPrice(Auction storage _auction) - internal - view - returns (uint256) - { - uint256 secondsPassed = 0; - - // A bit of insurance against negative values (or wraparound). - // Probably not necessary (since Ethereum guarnatees that the - // now variable doesn't ever go backwards). - if (now > _auction.startedAt) { - secondsPassed = now - _auction.startedAt; - } - - return _computeCurrentPrice( - _auction.startingPrice, - _auction.endingPrice, - _auction.duration, - secondsPassed - ); - } - - /// @dev Computes the current price of an auction. Factored out - /// from _currentPrice so we can run extensive unit tests. - /// When testing, make this function public and turn on - /// `Current price computation` test suite. - function _computeCurrentPrice( - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - uint256 _secondsPassed - ) - internal - pure - returns (uint256) - { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our public functions carefully cap the maximum values for - // time (at 64-bits) and currency (at 128-bits). _duration is - // also known to be non-zero (see the require() statement in - // _addAuction()) - if (_secondsPassed >= _duration) { - // We've reached the end of the dynamic pricing portion - // of the auction, just return the end price. - return _endingPrice; - } else { - // Starting price can be higher than ending price (and often is!), so - // this delta can be negative. - int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - - // This multiplication can't overflow, _secondsPassed will easily fit within - // 64-bits, and totalPriceChange will easily fit within 128-bits, their product - // will always fit within 256-bits. - int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - - // currentPriceChange can be negative, but if so, will have a magnitude - // less that _startingPrice. Thus, this result will always end up positive. - int256 currentPrice = int256(_startingPrice) + currentPriceChange; - - return uint256(currentPrice); - } - } - - /// @dev Computes owner's cut of a sale. - /// @param _price - Sale price of NFT. - function _computeCut(uint256 _price) internal view returns (uint256) { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our entry functions carefully cap the maximum values for - // currency (at 128-bits), and ownerCut <= 10000 (see the require() - // statement in the ClockAuction constructor). The result of this - // function is always guaranteed to be <= _price. - return _price * ownerCut / 10000; - } - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { - event Pause(); - event Unpause(); - - bool public paused = false; - - - /** - * @dev modifier to allow actions only when the contract IS paused - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev modifier to allow actions only when the contract IS NOT paused - */ - modifier whenPaused { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyOwner whenNotPaused public returns (bool) { - paused = true; - emit Pause(); - return true; - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyOwner whenPaused public returns (bool) { - paused = false; - emit Unpause(); - return true; - } -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - - /// @dev The ERC-165 interface signature for ERC-721. - /// Ref: https://github.com/ethereum/EIPs/issues/165 - /// Ref: https://github.com/ethereum/EIPs/issues/721 - bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - - /// @dev Constructor creates a reference to the NFT ownership contract - /// and verifies the owner cut is in the valid range. - /// @param _nftAddress - address of a deployed contract implementing - /// the Nonfungible Interface. - /// @param _cut - percent cut the owner takes on each auction, must be - /// between 0-10,000. - constructor(address _nftAddress, uint256 _cut) public { - require(_cut <= 10000); - ownerCut = _cut; - - ERC721 candidateContract = ERC721(_nftAddress); - require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); - nonFungibleContract = candidateContract; - } - - /// @dev Remove all Ether from the contract, which is the owner's cuts - /// as well as any Ether sent directly to the contract address. - /// Always transfers to the NFT contract, but can be called either by - /// the owner or the NFT contract. - function withdrawBalance() external { - address payable nftAddress = address(uint160(address(nonFungibleContract))); - - require( - msg.sender == owner || - msg.sender == nftAddress - ); - // We are using this boolean method to make sure that even if one fails it will still work - bool res = nftAddress.send(address(this).balance); - } - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of time to move between starting - /// price and ending price (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - whenNotPaused - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(_owns(msg.sender, _tokenId)); - _escrow(msg.sender, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Bids on an open auction, completing the auction and transferring - /// ownership of the NFT if enough Ether is supplied. - /// @param _tokenId - ID of token to bid on. - function bid(uint256 _tokenId) - external - payable - whenNotPaused - { - // _bid will throw if the bid or funds transfer fails - _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - } - - /// @dev Cancels an auction that hasn't been won yet. - /// Returns the NFT to original owner. - /// @notice This is a state-modifying function that can - /// be called while the contract is paused. - /// @param _tokenId - ID of token on auction - function cancelAuction(uint256 _tokenId) - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - address seller = auction.seller; - require(msg.sender == seller); - _cancelAuction(_tokenId, seller); - } - - /// @dev Cancels an auction when the contract is paused. - /// Only the owner may do this, and NFTs are returned to - /// the seller. This should only be used in emergencies. - /// @param _tokenId - ID of the NFT on auction to cancel. - function cancelAuctionWhenPaused(uint256 _tokenId) - whenPaused - onlyOwner - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - _cancelAuction(_tokenId, auction.seller); - } - - /// @dev Returns auction info for an NFT on auction. - /// @param _tokenId - ID of NFT on auction. - function getAuction(uint256 _tokenId) - external - view - returns - ( - address seller, - uint256 startingPrice, - uint256 endingPrice, - uint256 duration, - uint256 startedAt - ) { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return ( - auction.seller, - auction.startingPrice, - auction.endingPrice, - auction.duration, - auction.startedAt - ); - } - - /// @dev Returns the current price of an auction. - /// @param _tokenId - ID of the token price we are checking. - function getCurrentPrice(uint256 _tokenId) - external - view - returns (uint256) - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return _currentPrice(auction); - } - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSiringAuctionAddress() call. - bool public isSiringClockAuction = true; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. Since this function is wrapped, - /// require sender to be KittyCore contract. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Places a bid for siring. Requires the sender - /// is the KittyCore contract because all bid methods - /// should be wrapped. Also returns the kitty to the - /// seller rather than the winner. - function bid(uint256 _tokenId) - external - payable - { - require(msg.sender == address(nonFungibleContract)); - address seller = tokenIdToAuction[_tokenId].seller; - // _bid checks that token ID is valid and will throw if bid fails - _bid(_tokenId, msg.value); - // We transfer the kitty back to the seller, the winner will get - // the offspring - _transfer(seller, _tokenId); - } - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSaleAuctionAddress() call. - bool public isSaleClockAuction = true; - - // Tracks last 5 sale price of gen0 kitty sales - uint256 public gen0SaleCount; - uint256[5] public lastGen0SalePrices; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Updates lastSalePrice if seller is the nft contract - /// Otherwise, works the same as default bid method. - function bid(uint256 _tokenId) - external - payable - { - // _bid verifies token ID size - address seller = tokenIdToAuction[_tokenId].seller; - uint256 price = _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - - // If not a gen0 auction, exit - if (seller == address(nonFungibleContract)) { - // Track gen0 sale prices - lastGen0SalePrices[gen0SaleCount % 5] = price; - gen0SaleCount++; - } - } - - function averageGen0SalePrice() external view returns (uint256) { - uint256 sum = 0; - for (uint256 i = 0; i < 5; i++) { - sum += lastGen0SalePrices[i]; - } - return sum / 5; - } - -} - - - - - - - diff --git a/framework/src/test/resources/soliditycode_0.6.12/addressCheckNew.sol b/framework/src/test/resources/soliditycode_0.6.12/addressCheckNew.sol deleted file mode 100644 index 3c10b8c680d..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/addressCheckNew.sol +++ /dev/null @@ -1,9 +0,0 @@ -pragma experimental ABIEncoderV2; -contract testIsContract{ - function checkAddress(address addr) public returns (address){ - return addr; - } - function checkAddress2(address addr) pure public returns(address){ - return addr; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/addressCheckOld.sol b/framework/src/test/resources/soliditycode_0.6.12/addressCheckOld.sol deleted file mode 100644 index 6c6b15d1736..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/addressCheckOld.sol +++ /dev/null @@ -1,8 +0,0 @@ -contract testIsContract{ - function checkAddress(address addr) public returns (address){ - return addr; - } - function checkAddress2(address addr) pure public returns (address){ - return addr; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/altbn.sol b/framework/src/test/resources/soliditycode_0.6.12/altbn.sol deleted file mode 100644 index c3cfcdbe2b9..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/altbn.sol +++ /dev/null @@ -1,61 +0,0 @@ -contract AltBn128 { - constructor() public payable {} - function callBn256Add(bytes32 ax, bytes32 ay, bytes32 bx, bytes32 by) public returns (bytes32[2] memory result) { - bytes32[4] memory input; - input[0] = ax; - input[1] = ay; - input[2] = bx; - input[3] = by; - assembly { - let success := call(gas(), 0x06, 0, input, 0x80, result, 0x40) - } - - } - - function callBn256AddNoValue(bytes32 ax, bytes32 ay, bytes32 bx, bytes32 by) public returns - (bytes32[2] memory result) { - bytes32[4] memory input; - input[0] = ax; - input[1] = ay; - input[2] = bx; - input[3] = by; - assembly { - let success := call(gas(), 0xac, 0, input, 0x80, result, 0x40) - } - } - - function callBn256ScalarMul(bytes32 x, bytes32 y, bytes32 scalar) public returns (bytes32[2] memory result) { - bytes32[3] memory input; - input[0] = x; - input[1] = y; - input[2] = scalar; - assembly { - let success := call(gas(), 0x07, 0, input, 0x60, result, 0x40) - switch success - case 0 { - revert(0,0) - } - } - } - - function callBn256Pairing(bytes memory input) public returns (bytes32 result) { - // input is a serialized bytes stream of (a1, b1, a2, b2, ..., ak, bk) from (G_1 x G_2)^k - uint256 len = input.length; - require(len % 192 == 0); - assembly { - let memPtr := mload(0x40) - let success := call(gas(), 0x08, 0, add(input, 0x20), len, memPtr, 0x20) - switch success - case 0 { - revert(0,0) - } default { - result := mload(memPtr) - } - } - } - - function convert(uint256 num) public view returns(bytes32) { - return bytes32(num); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/arrayLength001.sol b/framework/src/test/resources/soliditycode_0.6.12/arrayLength001.sol deleted file mode 100644 index 46b2405a97e..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/arrayLength001.sol +++ /dev/null @@ -1,64 +0,0 @@ - - -contract arrayLength { - byte[] a; - uint256[] IntergerArray; - bytes bs; - - // arrary length - function arrayPushValue() public returns (byte[] memory){ - a = new byte[](1); - a.push(0x01); - return a; - } - - function arrayPush() public returns(byte[] memory){ - a = new byte[](1); - a.push(); - return a; - } - - function arrayPop() public returns(byte[] memory){ - a = new byte[](1); - a.pop(); - return a; - } - - // arrary push/pop return Value - function arrayPushValueReturn() public { - a = new byte[](1); - return a.push(0x01); - } - - function arrayPushReturn() public returns (bytes1){ - a = new byte[](1); - return a.push(); - } - - function arrayPopReturn() public{ - a = new byte[](1); - return a.pop(); - } - - function uint256ArrayPushValue() public returns (byte[] memory){ - IntergerArray = [1,2,3]; - IntergerArray.push(); - return a; - } - - - // bytes - function bytesPushValue() public { - - return bs.push(0x01); - } - - function bytesPush() public returns (bytes1){ - return bs.push(); - } - - function bytesPop() public { - return bs.pop(); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/assemblyTest.sol b/framework/src/test/resources/soliditycode_0.6.12/assemblyTest.sol deleted file mode 100644 index 519a5a85fa3..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/assemblyTest.sol +++ /dev/null @@ -1,61 +0,0 @@ - -contract assemblyTest { - - uint constant x = 1; - uint constant y = x; - function getZuint() public view returns (uint) { - uint z = y + 1; - assembly { - z := y - } - return z; - } - - function getZuint2() public returns (uint) { - uint z = y + 1; - assembly { - z := y - } - return z; - } - - bool constant bool1 = true; - bool constant bool2 = bool1; - function getZbool() public view returns (bool) { - bool z; - assembly { - z := bool2 - } - return z; - } - - function getZbool2() public returns (bool) { - bool z; - assembly { - z := bool2 - } - return z; - } - - -// string constant string1 = "abc"; -// string constant string2 = string1; -// function getZstring() public view returns (string memory) { -// string memory z; -// assembly { -// z := string2 -// } -// return z; -// } - - -// address origin1 = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF; -// address origin2 = origin1; -// function getZaddress() public view returns (address) { -// address z; -// assembly { -// z := origin2 -// } -// return z; -// } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest1DivideInt.sol b/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest1DivideInt.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest1DivideInt.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest2FindArgsContractMinTest.sol b/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest2FindArgsContractMinTest.sol deleted file mode 100644 index 75436287805..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest2FindArgsContractMinTest.sol +++ /dev/null @@ -1,10 +0,0 @@ - -contract findArgsIContract{ -function findArgsByIndex1(uint i) public returns (uint z) { -uint[] memory a = new uint[](3); -a[0]=1; -a[1]=2; -a[2]=3; -return a[i]; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest3ByteMinContract.sol b/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest3ByteMinContract.sol deleted file mode 100644 index c8a2e5e363b..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest3ByteMinContract.sol +++ /dev/null @@ -1,11 +0,0 @@ - -contract byteContract{ -bytes b; -function testBytesGet(uint i) public returns (bytes1){ -b = new bytes(3); -b[0]=0x0b; -b[1]=0x0c; -b[2]=0x0d; -return b[i]; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest4Enum.sol b/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest4Enum.sol deleted file mode 100644 index 6bd2ade2eea..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest4Enum.sol +++ /dev/null @@ -1,13 +0,0 @@ - - -contract enumContract { - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices _choice; - function setGoStraight(ActionChoices choice) public { - _choice = choice; - } - - function getChoice() public returns (ActionChoices) { - return _choice; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest5MoveRight.sol b/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest5MoveRight.sol deleted file mode 100644 index b83168d5ddc..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest5MoveRight.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract binaryRightContract{ - function binaryMoveR(int i)public returns (int z) { - return z = 5 >> i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest6UninitializedContract.sol b/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest6UninitializedContract.sol deleted file mode 100644 index c82e0f5806c..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest6UninitializedContract.sol +++ /dev/null @@ -1,27 +0,0 @@ - -contract uni { -function b(int x, int y) internal returns (int) -{ - return x * y; -} - -function test1() external returns (int) -{ - // Variable containing a function pointer - function (int, int) internal returns (int) funcPtr; - - funcPtr = b; - - // This call to funcPtr will succeed - return funcPtr(4, 5); -} - -function test2() external returns (int) -{ - // Variable containing a function pointer - function (int, int) internal returns (int) funcPtr; - - // This call will fail because funcPtr is still a zero-initialized function pointer - return funcPtr(4, 5); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest7TestAssertContract.sol b/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest7TestAssertContract.sol deleted file mode 100644 index 05b592e0682..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/assertExceptiontest7TestAssertContract.sol +++ /dev/null @@ -1,14 +0,0 @@ -contract TestThrowsContract{ - function testAssert() public{ - assert(1==2); - } - function testRequire() public{ - require(2==1); - } - function testRevert() public{ - revert(); - } - function testThrow() public{ - revert(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign.sol b/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign.sol deleted file mode 100644 index 9e1c1b289b5..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign.sol +++ /dev/null @@ -1,14 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - - function testArray2(bytes memory data) public returns(bool, bytes memory){ - return address(0x9).delegatecall(data); - } - - function testArray4(bytes memory data) public { - //address(0x1).delegatecall(data); - } - //function testArray3(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public { - //address(0x9).delegatecall(hash,signatures,addresses); - //} -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign001.sol b/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign001.sol deleted file mode 100644 index 57e051ce415..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign001.sol +++ /dev/null @@ -1,10 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - function testPure(bytes32 hash, bytes[] memory signatures, address[] memory addresses) pure public returns(bytes32){ - return batchvalidatesign(hash, signatures, addresses); - } - - function testArray(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public returns(bytes32){ - return batchvalidatesign(hash, signatures, addresses); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign002.sol b/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign002.sol deleted file mode 100644 index 375cec3a2a2..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign002.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - function testArray(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public returns(bytes32){ - - return batchvalidatesign(hash, signatures, addresses); - - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign003.sol b/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign003.sol deleted file mode 100644 index c43536af499..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign003.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract Demo { -bytes32 public result; -constructor (bytes32 hash, bytes[] memory signatures, address[] memory addresses) public { - result = batchvalidatesign(hash, signatures, addresses); -} -function testConstructor() public returns(bytes32){ - return result; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign005.sol b/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign005.sol deleted file mode 100644 index 3a6ca362973..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign005.sol +++ /dev/null @@ -1,14 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - - function testArray2(bytes memory data) public returns(bool, bytes memory){ - return address(0x9).delegatecall(data); - } - - function testArray4(bytes memory data) public { - //address(0x1).delegatecall(data); - } - function testArray3(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public { - //address(0x9).delegatecall(hash,signatures,addresses); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign007.sol b/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign007.sol deleted file mode 100644 index 974ffb34efe..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign007.sol +++ /dev/null @@ -1,17 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract Demo { - bytes32 public result; - - constructor (bytes32 hash, bytes[] memory signatures, address[] memory addresses) public { - result = batchvalidatesign(hash, signatures, addresses); - } - - function testConstructor() public returns(bytes32){ - return result; - } - - function testConstructorPure() public view returns(bytes32){ - return result; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign02.sol b/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign02.sol deleted file mode 100644 index 375cec3a2a2..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/batchvalidatesign02.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - function testArray(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public returns(bytes32){ - - return batchvalidatesign(hash, signatures, addresses); - - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/callValueGasPure.sol b/framework/src/test/resources/soliditycode_0.6.12/callValueGasPure.sol deleted file mode 100644 index ed4877e1ce4..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/callValueGasPure.sol +++ /dev/null @@ -1,8 +0,0 @@ - -contract C { -function check(address a) external pure returns (bool success) { - a.call.value(42).gas(42); - a.call.gas(42); - //a.call.value(1).gas(42)("fwefewf"); -} -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/calldata.sol b/framework/src/test/resources/soliditycode_0.6.12/calldata.sol deleted file mode 100644 index 6e877ac1b2f..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/calldata.sol +++ /dev/null @@ -1,33 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract C { - struct S { uint256 a; } - - function f(S calldata s) external returns (bytes memory) { - return abi.encode(s); - } - - function g(S calldata s) external returns (bytes memory) { - return this.f(s); - } - - function m(uint256[] calldata) external pure returns (bytes memory) { - return msg.data; - } - function h(uint8[] calldata s) external pure returns (bytes memory) { - return abi.encode(s); - } - function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) { - return this.h(s[which]); - } - function j(bytes calldata s) external pure returns (bytes memory) { - return abi.encode(s); - } - function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) { - return this.j(s[which]); - } - function l(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) { - assert(s.length == 3); - return (s[0](), s[1](), s[2]()); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/callvalue.sol b/framework/src/test/resources/soliditycode_0.6.12/callvalue.sol deleted file mode 100644 index f01dcf2b52f..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/callvalue.sol +++ /dev/null @@ -1,9 +0,0 @@ -contract Callvalue { -function check() public payable returns(uint) { - uint256 wad; - assembly { - wad := callvalue() - } - return wad; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/chainid001.sol b/framework/src/test/resources/soliditycode_0.6.12/chainid001.sol deleted file mode 100644 index 9cf24077dfb..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/chainid001.sol +++ /dev/null @@ -1,19 +0,0 @@ - -contract IstanbulTest { - constructor() public payable {} - function getId() public view returns(uint256){ - uint256 id; - assembly { - id := chainid() - } - return id; - } - - function getBalance(address src) public view returns(uint256){ - return address(src).balance; - } - - function getBalance() public view returns(uint256){ - return address(this).balance; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/codeSaftySupport.sol b/framework/src/test/resources/soliditycode_0.6.12/codeSaftySupport.sol deleted file mode 100644 index 1cee8e4646c..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/codeSaftySupport.sol +++ /dev/null @@ -1,19 +0,0 @@ - - -contract IllegalDecorate { - -constructor() payable public{} - -fallback() payable external{} - -event log(uint256); - -function transferToken(address payable toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/codeSaftyUnsupport.sol b/framework/src/test/resources/soliditycode_0.6.12/codeSaftyUnsupport.sol deleted file mode 100644 index d448f49d706..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/codeSaftyUnsupport.sol +++ /dev/null @@ -1,56 +0,0 @@ - - -contract SubC { - -event log(string); - -fallback() payable external{} - -function receiveToken() payable public{} - -function getBalance() view public returns (uint256 r) { -r = address(this).balance; -} -} - -contract UseDot { -constructor() payable public{} -fallback() payable external{} -mapping(address => mapping(trcToken => uint256)) sender_tokens; - -function trigger1(address payable addr, trcToken tokenInputId) payable public { - //address(SubC(addr)).call.value(1000).tokenId(tokenInputId)(abi.encodeWithSignature("receiveToken()")); // ERROR -} - -function trigger2(address payable addr) payable public { -// addr.transferToken.value(10)(10, 0x6e6d62); // ERROR -} - -function trigger3(address payable addr) payable public { - // address(SubC(addr)).receiveToken.tokenvalue(10)(); // ERROR -} - -function trigger4(address payable addr) payable public { - //SubC(addr).receiveToken.tokenId(0x6e6d62)(); // ERROR -} - -function trigger5(address payable addr) payable public { - SubC(addr).receiveToken.value(10)(); -} - -function trigger6(address payable addr, trcToken tokenId) payable public { -address(SubC(addr)).call.value(1000)(abi.encodeWithSignature("transferToken(uint256, trcToken)", 10, tokenId)); -} - -function trigger7(address addr) payable public { - //sender_tokens[msg.sender][msg.tokenid] += msg.tokenvalue; // compile success, no necessary to trigger -} - -function trigger8(address addr) public payable returns(bytes memory r){ -// r = msg.data; // compile success, no necessary to trigger -} - -function getBalance() public returns (uint256 r){ -r = address(this).balance; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/constantCallStorage001.sol b/framework/src/test/resources/soliditycode_0.6.12/constantCallStorage001.sol deleted file mode 100644 index 1f584923a55..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/constantCallStorage001.sol +++ /dev/null @@ -1,159 +0,0 @@ -contract NotView { - uint256 public num = 123; - function setnum() public returns(uint256){ - num = num + 15; - return num; - } -} -contract NotViewInterface{ - function setnum() public returns(uint256); -} -contract UseNotView { - function setnumuseproxy(address contractAddress) public returns(uint256){ - NotViewInterface inter = NotViewInterface(contractAddress); - return inter.setnum(); - } -} -contract viewCall { - bool stopped = false; - int i = 32482989; - int i2 = -32482989; - uint ui = 23487823; - address origin = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF; - bytes32 b32 = bytes32(uint256(0xdCad3a6d3569DF655070DEd0)); - bytes bs = new bytes(3); - string s = "123qwe"; - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices choice = ActionChoices.GoRight; - int64[] b = [-1, 2, -3]; - int32[2][] tmp_h = [[1,2],[3,4],[5,6]]; - int256[2][2] tmp_i = [[11,22],[33,44]]; - mapping (address => uint256) public mapa; - constructor() payable public{ - mapa[address(0x00)] = 34; - } - event log(int); - event log(uint); - event log(bool); - event log(address); - event log(bytes32); - event log(bytes); - event log(string); - event log(ActionChoices); - event log(int64[]); - event log(int32[2][]); - event log(int256[2][2]); - function changeBool(bool param) public returns (bool){ - stopped = param; - emit log(stopped); - return stopped; - } - function getBool() public returns (bool){ - emit log(stopped); - return stopped; - } - function changeInt(int param) public returns (int){ - i = param; - emit log(i); - return i; - } - function getInt() public returns (int){ - emit log(i); - return i; - } - function changeNegativeInt(int param) public returns (int){ - i2 = param; - emit log(i2); - return i2; - } - function getNegativeInt() public returns (int){ - emit log(i2); - return i2; - } - function changeUint(uint param) public returns (uint){ - ui = param; - emit log(ui); - return ui; - } - function getUint() public returns (uint){ - emit log(ui); - return ui; - } - function changeAddress(address param) public returns (address){ - origin = param; - emit log(origin); - return origin; - } - function getAddress() public returns (address){ - emit log(origin); - return origin; - } - function changeBytes32(bytes32 param) public returns (bytes32){ - b32 = param; - emit log(b32); - return b32; - } - function getBytes32() public returns (bytes32){ - emit log(b32); - return b32; - } - function changeBytes(bytes memory param) public returns (bytes memory){ - bs = param; - emit log(bs); - return bs; - } - function getBytes() public returns (bytes memory){ - emit log(bs); - return bs; - } - function changeString(string memory param) public returns (string memory){ - s = param; - emit log(s); - return s; - } - function getString() public returns (string memory){ - emit log(s); - return s; - } - function changeActionChoices(ActionChoices param) public returns (ActionChoices){ - choice = param; - emit log(choice); - return choice; - } - function getActionChoices() public returns (ActionChoices){ - emit log(choice); - return choice; - } - function changeInt64NegativeArray(int64[] memory param) public returns (int64[] memory){ - b = param; - emit log(b); - return b; - } - function getInt64NegativeArray() public returns (int64[] memory){ - emit log(b); - return b; - } - function changeInt32Array(int32[2][] memory param) public returns (int32[2][] memory){ - tmp_h = param; - emit log(tmp_h); - return tmp_h; - } - function getInt32Array() public returns (int32[2][] memory){ - emit log(tmp_h); - return tmp_h; - } - function changeInt256Array(int256[2][2] memory param) public returns (int256[2][2] memory){ - tmp_i = param; - emit log(tmp_i); - return tmp_i; - } - function getInt256Array() public returns (int256[2][2] memory){ - emit log(tmp_i); - return tmp_i; - } - function setMapping(uint256 param) public returns (uint256){ - mapa[msg.sender] = param; - return mapa[msg.sender]; - - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/constantCallStorage002.sol b/framework/src/test/resources/soliditycode_0.6.12/constantCallStorage002.sol deleted file mode 100644 index 1ceba5e87d2..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/constantCallStorage002.sol +++ /dev/null @@ -1,16 +0,0 @@ -contract NotView { - uint256 public num = 123; - function setnum() public returns(uint256){ - num = num + 15; - return num; - } -} -contract NotViewInterface{ - function setnum() public view returns(uint256); -} -contract UseNotView { - function setnumuseproxy(address contractAddress) public view returns(uint256){ - NotViewInterface inter = NotViewInterface(contractAddress); - return inter.setnum(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/constantCallStorage0425.sol b/framework/src/test/resources/soliditycode_0.6.12/constantCallStorage0425.sol deleted file mode 100644 index 8ecf771626d..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/constantCallStorage0425.sol +++ /dev/null @@ -1,156 +0,0 @@ -contract constantCall { - bool stopped = false; - int i = 32482989; - int i2 = -32482989; - uint ui = 23487823; - address origin = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF; - bytes32 b32 = 0xb55a21aaee0ce8f1c8ffaa0dbd23105cb55a21aaee0ce8f1c8ffaa0dbd23105c; - bytes bs = new bytes(9); - string s = "123qwe"; - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices choice = ActionChoices.SitStill; - int64[] b = [91, 2, 333]; - int32[2][] tmp_h = [[1,2],[3,4],[5,6]]; - int256[2][2] tmp_i = [[11,22],[33,44]]; - mapping (address => uint256) public mapa; - - constructor() payable public{ - mapa[address(0x00)] = 88; - } - event log(int); - event log(uint); - event log(bool); - event log(address); - event log(bytes32); - event log(bytes); - event log(string); - event log(ActionChoices); - event log(int64[]); - event log(int32[2][]); - event log(int256[2][2]); - - function changeBool(bool param) public constant returns (bool){ - stopped = param; - log(stopped); - return stopped; - } - function getBool() public constant returns (bool){ - log(stopped); - return stopped; - } - - function changeInt(int param) public returns (int){ - i = param; - log(i); - return i; - } - function getInt() public returns (int){ - log(i); - return i; - } - - function changeNegativeInt(int param) public constant returns (int){ - i2 = param; - log(i2); - return i2; - } - function getNegativeInt() public constant returns (int){ - log(i2); - return i2; - } - - function changeUint(uint param) public returns (uint){ - ui = param; - log(ui); - return ui; - } - function getUint() public returns (uint){ - log(ui); - return ui; - } - - function changeAddress(address param) public constant returns (address){ - origin = param; - log(origin); - return origin; - } - function getAddress() public constant returns (address){ - log(origin); - return origin; - } - - function changeBytes32(bytes32 param) public constant returns (bytes32){ - b32 = param; - log(b32); - return b32; - } - function getBytes32() public returns (bytes32){ - log(b32); - return b32; - } - - function changeBytes(bytes param) public constant returns (bytes){ - bs = param; - log(bs); - return bs; - } - function getBytes() public constant returns (bytes){ - log(bs); - return bs; - } - - function changeString(string param) public constant returns (string){ - s = param; - log(s); - return s; - } - function getString() public returns (string){ - log(s); - return s; - } - - function changeActionChoices(ActionChoices param) public constant returns (ActionChoices){ - choice = param; - log(choice); - return choice; - } - function getActionChoices() public constant returns (ActionChoices){ - log(choice); - return choice; - } - - function changeInt64NegativeArray(int64[] param) public constant returns (int64[]){ - b = param; - log(b); - return b; - } - function getInt64NegativeArray() public constant returns (int64[]){ - log(b); - return b; - } - - function changeInt32Array(int32[2][] param) public returns (int32[2][]){ - tmp_h = param; - log(tmp_h); - return tmp_h; - } - function getInt32Array() public constant returns (int32[2][]){ - log(tmp_h); - return tmp_h; - } - - function changeInt256Array(int256[2][2] param) public returns (int256[2][2]){ - tmp_i = param; - log(tmp_i); - return tmp_i; - } - function getInt256Array() public constant returns (int256[2][2]){ - log(tmp_i); - return tmp_i; - } - function setMapping(uint256 param) public returns (uint256){ - mapa[msg.sender] = param; - return mapa[msg.sender]; - - } -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/constantContract001.sol b/framework/src/test/resources/soliditycode_0.6.12/constantContract001.sol deleted file mode 100644 index 7d574c5a008..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/constantContract001.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract testConstantContract{ -function testPure(uint256 x,uint256 y) public pure returns (uint256 z) { -uint256 i=1; -return i + x + y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGetterContract.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGetterContract.sol deleted file mode 100644 index 365b53ebf1a..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGetterContract.sol +++ /dev/null @@ -1,17 +0,0 @@ - - - -contract getterContract { - -constructor() public payable{} -fallback() external payable{} - -uint public c = msg.value; - -function getDataUsingAccessor() public payable returns (uint){ - -return c; - -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test1Grammar001.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test1Grammar001.sol deleted file mode 100644 index 659e56c9150..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test1Grammar001.sol +++ /dev/null @@ -1,18 +0,0 @@ - -contract FunctionSelector { - function select(bool useB, uint x) public returns (uint z) { - //var f = a; - //if (useB) f = b; - //return f(x); - if (useB) - return b(x); - else - return a(x); - } -function a(uint x) public returns (uint z) { - return x * x; - } -function b(uint x) public returns (uint z) { - return 2 * x; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test2Grammar002.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test2Grammar002.sol deleted file mode 100644 index 744b17e9585..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test2Grammar002.sol +++ /dev/null @@ -1,44 +0,0 @@ - -library Set { - // We define a new struct datatype that will be used to - // hold its data in the calling contract. - struct Data { mapping(uint => bool) flags; } - - // Note that the first parameter is of type "storage - // reference" and thus only its storage address and not - // its contents is passed as part of the call. This is a - // special feature of library functions. It is idiomatic - // to call the first parameter 'self', if the function can - // be seen as a method of that object. - function insert(Data storage self, uint value) public returns (bool) { - if (self.flags[value]) - return false; // already there - self.flags[value] = true; - return true; - } - - function remove(Data storage self, uint value) public returns (bool) { - if (!self.flags[value]) - return false; // not there - self.flags[value] = false; - return true; - } - - function contains(Data storage self, uint value) public returns (bool) { - return self.flags[value]; - } -} - - -contract C { - Set.Data knownValues; - - function register (uint value) public{ - // The library functions can be called without a - // specific instance of the library, since the - // "instance" will be the current contract. - if (!Set.insert(knownValues, value)) - revert(); - } - // In this contract, we can also directly access knownValues.flags, if we want. -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test3Grammar003.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test3Grammar003.sol deleted file mode 100644 index 140ba2a8f56..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test3Grammar003.sol +++ /dev/null @@ -1,44 +0,0 @@ - - -library Set { - struct Data { mapping(uint => bool) flags; } - - function insert(Data storage self, uint value) public - returns (bool) - { - if (self.flags[value]) - return false; // already there - self.flags[value] = true; - return true; - } - - function remove(Data storage self, uint value) public - returns (bool) - { - if (!self.flags[value]) - return false; // not there - self.flags[value] = false; - return true; - } - - function contains(Data storage self, uint value) public - returns (bool) - { - return self.flags[value]; - } -} - - -contract C { - using Set for Set.Data; // this is the crucial change - Set.Data knownValues; - - function register(uint value) public{ - // Here, all variables of type Set.Data have - // corresponding member functions. - // The following function call is identical to - // Set.insert(knownValues, value) - if (!knownValues.insert(value)) - revert(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test4Grammar004.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test4Grammar004.sol deleted file mode 100644 index 772691cebc5..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test4Grammar004.sol +++ /dev/null @@ -1,31 +0,0 @@ - - -library Search { - function indexOf(uint[] storage self, uint value) public returns (uint) { - for (uint i = 0; i < self.length; i++) - if (self[i] == value) return i; - return uint(-1); - } -} - - -contract C { - using Search for uint[]; - uint[] public data; - - function append(uint value) public{ - data.push(value); - } - - function replace(uint _old, uint _new) public{ - // This performs the library function call - uint index = data.indexOf(_old); - if (index == uint(-1)) - data.push(_new); - else - data[index] = _new; - } - function getData(uint256 index) public returns(uint256){ - return data[index]; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test5Grammar006.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test5Grammar006.sol deleted file mode 100644 index 275d42d1e71..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar001test5Grammar006.sol +++ /dev/null @@ -1,45 +0,0 @@ -contract InfoFeed { -function d1(uint x1) public{ - - assembly{ - function f(x) -> y { switch x case 0 { y := 1 } default { y := mul(x, f(sub(x, 1))) } } - } - } - function d2(uint x1) public{ - assembly { - let x:=1 - x := mul(1, add(2, 3))} - } - function f(uint x) public{ - assembly { x := sub(x, 1) } - - } - // 0.6.0 Variable declarations cannot shadow declarations outside the assembly block. - function d(uint x1) public returns(uint256){ - uint256 x; - assembly{ - x := add(2, 3) - let y := mload(0x40) - x := add(x, y) - } - return x; - } - function d4(uint x) public{ - // Error: The labels 'repeat' is disallowed. Please use "if", "switch", "for" or function calls instead - //assembly{let x := 10 repeat: x := sub(x, 1) jumpi(repeat, eq(x, 0)) - x = x; - //} - } - function d5(uint x1) public{ - assembly{ - function f(x) -> y { switch x case 0 { y := mul(x, 2) } default { y := 0 } } - - } - } - - function d6(uint x1) public{ - assembly{ - function f(x) -> y { for { let i := 0 } lt(i, x) { i := add(i, 1) } { y := mul(2, y) } } - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test1Grammar007_1.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test1Grammar007_1.sol deleted file mode 100644 index 020c2a38ca4..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test1Grammar007_1.sol +++ /dev/null @@ -1,60 +0,0 @@ -contract Doug{ - mapping (bytes32 => uint) public contracts; - constructor() public{ - contracts['hww'] = 1; - contracts['brian'] = 2; - contracts['zzy'] = 7; - } - - function getDougName(string memory _name) public view returns(string memory) { - return _name; - } - - function getDougAge(uint _age) public pure returns(uint) { - return 3 ** _age; - } -} - -// -abstract contract DogInterface { - function getDougAge(uint _age) public virtual returns (uint); - function contracts(bytes32 name) public virtual returns (uint); -} -contract main{ - - event FetchContract(address dogInterfaceAddress, address sender, bytes32 name); - - address public DOUG; - - address dogInterfaceAddress; - DogInterface dogContract ; - - function setDOUG(address _doug) public { - DOUG = _doug; - } - - constructor(address addr) public{ - dogInterfaceAddress = addr; - dogContract = DogInterface(dogInterfaceAddress); - } - - function dougOfage(uint _age) public returns(uint) { - - uint num = dogContract.getDougAge(_age); - return _age+num; - // return num; - } - - function uintOfName(bytes32 _name) public returns (uint) { - - dogContract.contracts(_name); - emit FetchContract(dogInterfaceAddress, msg.sender, _name); - - } - - // function getTest(string _name) public view returns(string) { - // string memory newName = _name ; - // DogInterface(DOUG).getDougName(newName); - // return newName; - // } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test1Grammar007_2.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test1Grammar007_2.sol deleted file mode 100644 index 8945b566543..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test1Grammar007_2.sol +++ /dev/null @@ -1,60 +0,0 @@ - -contract Doug{ - mapping (bytes32 => uint) public contracts; - constructor() public{ - contracts['hww'] = 1; - contracts['brian'] = 2; - contracts['zzy'] = 7; - } - - function getDougName(string memory _name) public view returns(string memory) { - return _name; - } - - function getDougAge(uint _age) public pure returns(uint) { - return 3 ** _age; - } -} - -abstract contract DogInterface { - function getDougAge(uint _age) public virtual returns (uint); - function contracts(bytes32 name) public virtual returns (uint); -} -contract main{ - - event FetchContract(address dogInterfaceAddress, address sender, bytes32 name); - - address public DOUG; - - address dogInterfaceAddress; - DogInterface dogContract ; - - function setDOUG(address _doug) public { - DOUG = _doug; - } - - constructor(address addr) public{ - dogInterfaceAddress = addr; - dogContract = DogInterface(dogInterfaceAddress); - } - - function dougOfage(uint _age) public returns(uint) { - - uint num = dogContract.getDougAge(_age); - return _age+num; - // return num; - } - - function uintOfName(bytes32 _name) public returns (uint) { - - dogContract.contracts(_name); - emit FetchContract(dogInterfaceAddress, msg.sender, _name); - - } - - // function getTest(string _name) public view returns(string) { - // string memory newName = _name ; - // DogInterface(DOUG).getDougName(newName); - // return newName; - // } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test2Grammar008.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test2Grammar008.sol deleted file mode 100644 index 956623c3103..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test2Grammar008.sol +++ /dev/null @@ -1,18 +0,0 @@ - - -// version 0.6.0 change -// add abstract and override -abstract contract Feline { - - function utterance() public virtual returns (bytes32); - - function getContractName() public returns (string memory){ - return "Feline"; - } -} - - -contract Cat is Feline { - function utterance() public override returns (bytes32) { return "miaow"; } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test3Grammar010.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test3Grammar010.sol deleted file mode 100644 index d6845d2e336..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test3Grammar010.sol +++ /dev/null @@ -1,10 +0,0 @@ - -contract InfoFeed { -function info() public payable returns (uint ret) { return 42; } -} -contract Consumer { -constructor() payable public{} -InfoFeed feed; -function setFeed(address addr) public { feed = InfoFeed(addr); } -function callFeed() public payable { feed.info.value(10).gas(800)(); } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test4Grammar011.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test4Grammar011.sol deleted file mode 100644 index fcd18f438ef..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test4Grammar011.sol +++ /dev/null @@ -1,11 +0,0 @@ - -contract C { -function f(uint key, uint value) public returns(uint) { -return key; -// do something -} -function g() public { -// named arguments -f({value: 2, key: 3}); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test4Grammar012.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test4Grammar012.sol deleted file mode 100644 index 8fb3c750298..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test4Grammar012.sol +++ /dev/null @@ -1,24 +0,0 @@ - -contract rTest { -function info() public payable returns (uint,address,bytes4,uint,uint,uint,address,uint) { -//function info() public payable returns (address ,uint,uint,uint,bytes32,uint,bytes,uint,address,bytes4,uint,uint,uint,address,uint) { -//var a = block.coinbase ; -//var b = block.difficulty; -//var c = block.gaslimit; -//var d = block.number; -//var e = block.blockhash(0); -//var e = d; -//var f = block.timestamp; -//bytes memory g = msg.data; -uint256 h = gasleft(); -address payable i = msg.sender; -bytes4 j = msg.sig; -uint256 k = msg.value; -uint256 l = now; -uint256 m = tx.gasprice; -address payable n = tx.origin; -uint256 o = address(this).balance; -return (h,i,j,k,l,m,n,o); -//return (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test6Grammar013.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test6Grammar013.sol deleted file mode 100644 index 53de5def6bc..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar002test6Grammar013.sol +++ /dev/null @@ -1,24 +0,0 @@ - -contract Counter { -uint count = 0; -address payable owner; -//function Counter() public{ -constructor() public{ -owner = msg.sender; -} -function increment() public { -uint step = 10; -if (owner == msg.sender) { -count = count + step; -} -} -function getCount() public returns (uint){ -return count; -} -function kill() public{ -if (owner == msg.sender) { -selfdestruct(owner); -//selfdestruct(address(owner)); -} -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test1Grammar014.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test1Grammar014.sol deleted file mode 100644 index b2d70b3741c..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test1Grammar014.sol +++ /dev/null @@ -1,67 +0,0 @@ -contract A { -uint256 public numberForB; -address public senderForB; -function callTest(address bAddress, uint256 _number) public{ - -//bAddress.call(bytes4(sha3("setValue(uint256)")), _number); // B's storage is set, A is not modified -bAddress.call(abi.encodeWithSignature("setValue(uint256)",_number)); // B's storage is set, A is not modified -} -function callcodeTest(address bAddress, uint256 _number) public{ -//bAddress.callcode(bytes4(sha3("setValue(uint256)")), _number); // A's storage is set, B is not modified -bAddress.delegatecall(abi.encodeWithSignature("setValue(uint256)", _number)); // A's storage is set, B is not modified -} -function delegatecallTest(address bAddress, uint256 _number) public{ -//bAddress.delegatecall(bytes4(sha3("setValue(uint256)")), _number); // A's storage is set, B is not modified -bAddress.delegatecall(abi.encodeWithSignature("setValue(uint256)", _number)); // A's storage is set, B is not modified -} - -function callAddTest(address bAddress) public{ -//bAddress.call(bytes4(sha3("add()"))); // B's storage is set, A is not modified -bAddress.call(abi.encodeWithSignature("add()")); // B's storage is set, A is not modified -//bAddress.call(bytes4(sha3("add()"))); // B's storage is set, A is not modified -bAddress.call(abi.encodeWithSignature("add()")); // B's storage is set, A is not modified -} -function getnumberForB() public returns(uint256){ - return numberForB; - } - function getsenderForB() public returns(address){ - return senderForB; - } -} -contract B { -uint256 public numberForB; -address public senderForB; -address public addr11; -mapping(uint256=>address) public addr1; -mapping(uint256=>address) public addr2; -event ssss(uint256); -function setValue(uint256 _number) public{ - -emit ssss(_number); -numberForB = _number; -senderForB = msg.sender; -// senderForB is A if invoked by A's callTest. B's storage will be updated -// senderForB is A if invoked by A's callcodeTest. None of B's storage is updated -// senderForB is OWNER if invoked by A's delegatecallTest. None of B's storage is updated -} - -function add() public{ -numberForB=numberForB+1; -C c1 = new C(); -addr1[numberForB]=c1.getAddress(); -addr11 = c1.getAddress(); -C c2 = new C(); -addr2[numberForB] = c2.getAddress(); -} -function getnumberForB() public returns(uint256){ - return numberForB; - } - function getsenderForB() public returns(address){ - return senderForB; - } -} -contract C { -function getAddress() public view returns(address){ -return address(this); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test2Grammar015.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test2Grammar015.sol deleted file mode 100644 index 0aa93e5e94f..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test2Grammar015.sol +++ /dev/null @@ -1,40 +0,0 @@ - - -contract ExecuteFallback{ - - //回退事件,会把调用的数据打印出来 - event FallbackCalled(bytes data); - //fallback函数,注意是没有名字的,没有参数,没有返回值的 - // 0.6.0 Split unnamed fallback functions into two cases defined using fallback() and receive() - fallback() external{ - emit FallbackCalled(msg.data); - } - - //调用已存在函数的事件,会把调用的原始数据,请求参数打印出来 - event ExistFuncCalled(bytes data, uint256 para); - //一个存在的函数 - function existFunc(uint256 para) public{ - emit ExistFuncCalled(msg.data, para); - } - - // 模拟从外部对一个存在的函数发起一个调用,将直接调用函数 - function callExistFunc() public{ - bytes4 funcIdentifier = bytes4(keccak256("existFunc(uint256)")); - //this.call(funcIdentifier, uint256(1)); - address(this).call(abi.encode(funcIdentifier, uint256(1))); - } - - //模拟从外部对一个不存在的函数发起一个调用,由于匹配不到函数,将调用回退函数 - function callNonExistFunc() public{ - bytes4 funcIdentifier = bytes4(keccak256("functionNotExist()")); - //this.call(funcIdentifier); - address(this).call(abi.encode(funcIdentifier)); - } - - function ExistFuncCalledTopic() view public returns(bytes32){ - return keccak256("ExistFuncCalled(bytes,uint256)"); - } - function FallbackCalledTopic() view public returns(bytes32){ - return keccak256("FallbackCalled(bytes)"); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test3Grammar016.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test3Grammar016.sol deleted file mode 100644 index 6a73d7a8d7e..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test3Grammar016.sol +++ /dev/null @@ -1,23 +0,0 @@ - -contract C { -uint private data; -function f(uint a) private returns(uint b) { return a + 1; } -function setData(uint a) public { data = a; } -function getData() public returns(uint) { return data; } -function compute(uint a, uint b) internal returns (uint) { return a+b; } -} -contract D { -function readData() public{ -C c = new C(); -//uint local = c.f(7); // error: member "f" is not visible -c.setData(3); -uint local = c.getData(); -// local = c.compute(3, 5); // error: member "compute" is not visible -} -} -contract E is C { -function g() public { -C c = new C(); -uint val = compute(3, 5); // access to internal member (from derived to parent contract) -} -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test4Grammar017.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test4Grammar017.sol deleted file mode 100644 index fb81b6e529c..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test4Grammar017.sol +++ /dev/null @@ -1,50 +0,0 @@ - -contract CrowdFunding{ -struct Funder{ -address addr; -uint amount; -} - -struct Campaign{ -address payable beneficiary; -uint goal; -uint amount; -uint funderNum; -mapping(uint => Funder) funders; -} - -uint compaingnID; -mapping (uint => Campaign) campaigns; - -function candidate(address payable beneficiary, uint goal) public payable returns (uint compaingnID){ -// initialize -campaigns[compaingnID++] = Campaign(beneficiary, goal, 0, 0); -} - -function vote(uint compaingnID) payable public { -Campaign storage c = campaigns[compaingnID]; - -//another way to initialize -c.funders[c.funderNum++] = Funder({addr: msg.sender, amount: msg.value}); -c.amount += msg.value; -} - -function check(uint comapingnId) public payable returns (bool){ - Campaign memory c = campaigns[comapingnId]; - - if(c.amount < c.goal){ - return false; - } - - uint amount = c.amount; - // incase send much more - c.amount = 0; - // address payable addr = address(uint160(c.beneficiary)); - //if(! addr.send(amount)){ - - if (! c.beneficiary.send(amount)){ - revert(); - } - return true; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test5Grammar018.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test5Grammar018.sol deleted file mode 100644 index ec241f3eae9..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test5Grammar018.sol +++ /dev/null @@ -1,37 +0,0 @@ - - - -contract Grammar18{ - function testAddmod() public returns (uint z) { - //计算(x + y)%k,其中以任意精度执行加法,并且不在2 ** 256处围绕 - z=addmod(2, 2, 3); - return z; - } - function testMulmod() public returns (uint z) { -//计算(x * y)%k,其中乘法以任意精度执行,并且不会在2 ** 256处循环。 - z=mulmod(2, 3, 4); - return z; - } - - function testKeccak256() public returns(bytes32){ - //计算的(紧凑)参数的Ethereum-SHA-3(Keccak-256)的散列 - return keccak256("11"); - } - - function testSha256() public returns(bytes32){ - //计算(紧密包装)参数的SHA-256散列 - return sha256("11"); - } - function testSha3() public returns(bytes32){ - //计算(紧密包装)参数的SHA-256散列 - //return sha3("11"); - return keccak256("11"); - } - - function testRipemd160() public returns(bytes32){ - //计算(紧密包装)参数的RIPEMD-160哈希值 - return ripemd160("11"); - } - - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test6Grammar019.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test6Grammar019.sol deleted file mode 100644 index 727ef7091e7..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test6Grammar019.sol +++ /dev/null @@ -1,12 +0,0 @@ - -contract timetest { - -constructor() public { -require( 1 == 1 seconds); -require(1 minutes == 60 seconds); -require(1 hours == 60 minutes); -require(1 days == 24 hours); -require(1 weeks == 7 days); -//require(1 years == 365 days); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test7Grammar020.sol b/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test7Grammar020.sol deleted file mode 100644 index 39a7fddcb7e..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractGrammar003test7Grammar020.sol +++ /dev/null @@ -1,8 +0,0 @@ - -contract trxtest { - -function test() public { -require(1 trx == 1000000 sun); - -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInnerContract.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInnerContract.sol deleted file mode 100644 index 0de68bbf7da..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInnerContract.sol +++ /dev/null @@ -1,32 +0,0 @@ - - - - -contract InnerContract { - - constructor() public payable{} - fallback() external payable{} - - function messageI() payable public returns (uint ret) { - - - - } - -} - - - -contract OuterContract { - - - constructor() public payable{} - fallback() external payable{} - - function callInner(address payable addr) payable public returns (uint) { - - return InnerContract(addr).messageI.value(1)(); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction001.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction001.sol deleted file mode 100644 index 02fa51949c3..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction001.sol +++ /dev/null @@ -1,41 +0,0 @@ - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address payable cAddr) public payable{ - B b1 = (new B).value(10)();//1.1 - B b2 = new B();//1.2 - payable(address(b2)).transfer(5);//1.3 - b2.callCGetZero(cAddr, 1);//1.4 - b2.callCGetZero(cAddr,2);//1.6 - } - function test2(address payable cAddress,uint256 amount) public payable{ - cAddress.call.value(amount)(abi.encodeWithSignature("newBAndTransfer()"));//2.1 - cAddress.call.value(amount + 1)(abi.encodeWithSignature("newBAndTransfer()"));//2.6 - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero(address payable cAddress,uint256 amount) public{ - cAddress.call.value(amount)(abi.encodeWithSignature("getZero()"));//1.5,1.7 - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - B b1 = (new B).value(7)();//2.2,2.7 - b1.getOne();//2.3,2.8 - B b2 = (new B).value(3)();//2.4,2.9 - b2.getOne();//2.5,2.10 - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction002.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction002.sol deleted file mode 100644 index 92edfeb1157..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction002.sol +++ /dev/null @@ -1,20 +0,0 @@ - -contract A{ - constructor() payable public{} - fallback() payable external{} - - function test2(address cAddress,uint256 amount) public payable{ - //cAddress.call.value(amount)();//2.1 - cAddress.call.value(amount)("");//2.1 - } -} - - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction003.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction003.sol deleted file mode 100644 index 2e17d6dbc02..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction003.sol +++ /dev/null @@ -1,30 +0,0 @@ - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer() payable public{ - B b = (new B).value(10)();//1 - - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable public returns(bool) { - return true; - } - constructor() public payable {} - function payC(address payable c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - fallback() payable external{} - } - diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction004.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction004.sol deleted file mode 100644 index e8f32d7bfd9..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction004.sol +++ /dev/null @@ -1,24 +0,0 @@ - -contract A{ - constructor () payable public{} - function test(address payable toAddress) public payable{ - selfdestruct(toAddress); - } - fallback() payable external{} - function getBalance() public view returns(uint256){ - return address(this).balance; - } -} -contract B{ - fallback() external payable{} - function kill(address contractAddres, address toAddress) payable public { - contractAddres.call(abi.encodeWithSignature("test(address)",address(this))); - } - function kill2() public{ - A a = new A(); - a.test(payable(address(this))); - } - function getBalance() public view returns(uint256){ - return address(this).balance; - } -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction005.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction005.sol deleted file mode 100644 index b198d260e4d..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction005.sol +++ /dev/null @@ -1,53 +0,0 @@ - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1() public payable{ - B b1 = (new B).value(10)();//1.1 - b1.callCGetZero(false); - b1.callCGetZero(true);//1.4 - } - function test2() public payable{ - C c1 = (new C).value(10)();//1.1 - c1.newBAndTransfer(false); - c1.newBAndTransfer(true);//1.4 - - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero(bool success) public payable{ - if(!success){ - assert(1==2); - } - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract C{ - uint256 public flag=0; - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer(bool success) payable public returns(uint256){ - flag = 1; - if(!success){ - require(2==1); - } - } - function getFlag() public returns(uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction006.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction006.sol deleted file mode 100644 index ca51fda2021..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction001testInternalTransaction006.sol +++ /dev/null @@ -1,54 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1() public payable{ - B b1 = (new B).value(10)();//1.1 - b1.callCGetZero(true);//1.4 - b1.callCGetZero(false); - } - function test2() public payable{ - C c1 = (new C).value(10)();//1.1 - c1.newBAndTransfer(true);//1.4 - c1.newBAndTransfer(false); - - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero(bool success) public payable{ - if(!success){ - assert(1==2); - } - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract C{ - uint256 public flag=0; - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer(bool success) payable public returns(uint256){ - flag = 1; - if(!success){ - require(2==1); - } - } - function getFlag() public returns(uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test1InternalTransaction007.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test1InternalTransaction007.sol deleted file mode 100644 index 528fb9fa8a8..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test1InternalTransaction007.sol +++ /dev/null @@ -1,38 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address cAddr) public payable{ - B b1 = (new B).value(10)();//1.1 - B b2 = new B();//1.2 - payable(address(b2)).transfer(5);//1.3 - b2.callCGetZero();//1.4 - } - function test2(address cAddress,uint256 amount) public payable{ - cAddress.call.value(amount)(abi.encodeWithSignature("newBAndTransfer()"));//2.1 - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero() public{ - assert(1==2); - - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test2InternalTransaction008.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test2InternalTransaction008.sol deleted file mode 100644 index c1e9ea0596f..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test2InternalTransaction008.sol +++ /dev/null @@ -1,60 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - - function testAssert(address bAddress,uint256 amount) public payable{ - bAddress.call.value(amount).gas(1000000)(abi.encodeWithSignature("callCGetZero(bool)",false));//2.1 - bAddress.call.value(amount).gas(1000000)(abi.encodeWithSignature("callCGetZero(bool)",true)); - } - function testRequire(address cAddress,uint256 amount) public payable{ - cAddress.call.value(amount).gas(1000000)(abi.encodeWithSignature("newBAndTransfer(bool)",false));//2.1 - cAddress.call.value(amount).gas(1000000)(abi.encodeWithSignature("newBAndTransfer(bool)",true)); - } - function testAssert1(address bAddress,uint256 amount) public payable{ - bAddress.call.value(amount).gas(1000000)(abi.encodeWithSignature("callCGetZero(bool)",true)); - bAddress.call.value(amount).gas(1000000)(abi.encodeWithSignature("callCGetZero(bool)",false));//2.1 - } - function testtRequire2(address cAddress,uint256 amount) public payable{ - cAddress.call.value(amount).gas(1000000)(abi.encodeWithSignature("newBAndTransfer(bool)",true)); - cAddress.call.value(amount).gas(1000000)(abi.encodeWithSignature("newBAndTransfer(bool)",false));//2.1 - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero(bool success) payable public{ - if(!success){ - assert(1==2); - } - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract C{ - uint256 public flag=0; - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer(bool success) payable public returns(uint256){ - flag = 1; - if(!success){ - require(2==1); - } - } - function getFlag() public returns(uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test3InternalTransaction009.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test3InternalTransaction009.sol deleted file mode 100644 index 7c8a1f8c879..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test3InternalTransaction009.sol +++ /dev/null @@ -1,47 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address cAddr,address dcontract,address baddress) public payable{ - B b1 = (new B).value(10)();//1.1 - payable(address(b1)).transfer(5);//1.3 - b1.callCGetZero(cAddr, 1);//1.4 - b1.getOne(dcontract,baddress); - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne(address contractAddres, address toAddress) payable public{ - contractAddres.call(abi.encodeWithSignature("suicide1(address)",address(this))); - - } - function callCGetZero(address cAddress,uint256 amount) public{ - cAddress.call.value(amount)(abi.encodeWithSignature("getZero()"));//1.5,1.7 - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public{ - B b1 = (new B).value(7)();//2.2,2.7 - B b2 = (new B).value(3)();//2.4,2.9 - } -} - -contract D{ - constructor () payable public{} - function suicide1(address payable toAddress) public payable{ - selfdestruct(toAddress); - } - fallback() payable external{} - function getBalance() public view returns(uint256){ - return address(this).balance; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test4InternalTransaction010.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test4InternalTransaction010.sol deleted file mode 100644 index af2b54af172..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test4InternalTransaction010.sol +++ /dev/null @@ -1,186 +0,0 @@ - - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - - } - function transfer2() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - - } - function getBalance() public returns(uint256) { - return address(this).balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable public returns(bool) { - return true; - } - constructor() public payable {} - function payC(address payable c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - fallback() payable external{} - } - diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test4InternalTransaction010_1.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test4InternalTransaction010_1.sol deleted file mode 100644 index d0c80d14ffb..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test4InternalTransaction010_1.sol +++ /dev/null @@ -1,210 +0,0 @@ - - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - } - function transfer2() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - - } - function getBalance() returns(uint256){ - return this.balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable returns(bool) { - return true; - } - constructor() public payable {} - function payC(address c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() returns(uint256){ - return this.balance; - } - fallback() payable{} - } - - \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test5InternalTransaction012.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test5InternalTransaction012.sol deleted file mode 100644 index e9bc38b58d4..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction002test5InternalTransaction012.sol +++ /dev/null @@ -1,51 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address bAddr,address eAddr) public payable{ - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - } - -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function testNN(address eAddress) public payable{ - D d1=(new D).value(1000)(); - d1.getOne(eAddress); - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract D{ - constructor() payable public{} - fallback() payable external{} - function getOne(address eAddress) payable public returns(uint256){ - eAddress.call.value(1)(abi.encodeWithSignature("getZero()"));//2.1 - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction013.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction013.sol deleted file mode 100644 index 3ef9264ee70..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction013.sol +++ /dev/null @@ -1,56 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address dAddr) public payable{ - B b1 = (new B).value(10)();//1.1 - b1.testNN(dAddr,2);//1.6 - // C c1 = (new C).value(1000000000000)();//1.2 - // E e1 = (new E).value(1)();//1.2 - } - function test2(address cAddress,uint256 amount) public payable{ - cAddress.call.value(amount)(abi.encodeWithSignature("newBAndTransfer()"));//2.1 - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function testNN(address dAddress,uint256 amount) public payable{ - // D d1=(new D)(); - dAddress.call.value(amount)(abi.encodeWithSignature("getOne()"));//2.1 - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract D{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - E e = (new E).value(5)(); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction014.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction014.sol deleted file mode 100644 index 5647048bab3..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction014.sol +++ /dev/null @@ -1,38 +0,0 @@ -contract callerContract { - constructor() payable public{} - fallback() payable external{} - function sendToB(address called_address,address c) public payable{ - called_address.delegatecall(abi.encodeWithSignature("transferTo(address)",c)); - } - function sendToB2(address called_address,address c) public payable{ - called_address.call(abi.encodeWithSignature("transferTo(address)",c)); - } - function sendToB3(address called_address,address c) public payable{ - called_address.delegatecall(abi.encodeWithSignature("transferTo(address)",c)); - } -} - - contract calledContract { - fallback() payable external {} - constructor() payable public{} - function transferTo(address payable toAddress)public payable{ - toAddress.transfer(5); - } - - function setIinC(address c) public payable{ - c.call.value(5)(abi.encodeWithSignature("setI()")); - } - - } - - contract c{ - uint256 public i=0; - constructor() public payable{} - function getBalance() public view returns(uint256){ - return address(this).balance; - } - function setI() payable public{ - i=5; - } - fallback() payable external{} - } diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction015.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction015.sol deleted file mode 100644 index 229f79f3c96..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction015.sol +++ /dev/null @@ -1,60 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address dAddr,address eAddr) public payable{ - B b1 = (new B).value(10)();//1.1 - b1.testNN(dAddr,2,eAddr);//1.6 - // C c1 = (new C).value(1000000000000)();//1.2 - // E e1 = (new E).value(1)();//1.2 - } - function test2(address cAddress,uint256 amount) public payable{ - cAddress.call.value(amount)(abi.encodeWithSignature("newBAndTransfer()"));//2.1 - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function testNN(address dAddress,uint256 amount,address eAddress) public payable{ - // D d1=(new D)(); - dAddress.call.value(amount)(abi.encodeWithSignature("getOne(address)",address(this)));//2.1 - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } - function suicide(address payable toAddress) public payable{ - selfdestruct(toAddress); - } -} -contract D{ - constructor() payable public{} - fallback() payable external{} - function getOne(address payable eAddress) payable public{ - E e = (new E).value(5)(); - e.suicide(eAddress); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction016.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction016.sol deleted file mode 100644 index f5cbdc2f1fa..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction016.sol +++ /dev/null @@ -1,174 +0,0 @@ - - - contract A{ - uint256 public num = 0; - constructor() public payable{} - fallback() payable external{} - function transfer() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - B b1=(new B).value(1)();//1 - address payable aaa=address(this); - b1.suicide1(aaa); - } - function transfer2() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - B b1=(new B).value(1)();//1 - address payable aaa=address(this); - b1.suicide1(aaa); - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable public returns(bool) { - return true; - } - constructor() public payable {} - function payC(address payable c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - fallback() payable external{} - function suicide1(address payable toAddress) public payable{ - selfdestruct(toAddress); - } - } - diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction017.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction017.sol deleted file mode 100644 index 6847eebc546..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction017.sol +++ /dev/null @@ -1,199 +0,0 @@ - - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer(address payable Address) payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - - B b=(new B).value(1)();//1 - selfdestruct(Address); - } - function transfer2() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable public returns(bool) { - return true; - } - constructor() public payable {} - function payC(address payable c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - fallback() payable external{} - } - diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction018.sol b/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction018.sol deleted file mode 100644 index 80705ffd5e9..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractInternalTransaction003testInternalTransaction018.sol +++ /dev/null @@ -1,97 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address payable bAddr,address eAddr) public payable{ - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call.value(1)(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - - } - -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function testNN(address eAddress) public payable { - D d1=(new D).value(100)(); - d1.getOne(eAddress); - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract D{ - constructor() payable public{} - fallback() payable external{} - function getOne(address eAddress) payable public returns(uint256){ - eAddress.call.value(1)(abi.encodeWithSignature("getZero()"));//2.1 - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractLinkage001.sol b/framework/src/test/resources/soliditycode_0.6.12/contractLinkage001.sol deleted file mode 100644 index 8d441fba2da..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractLinkage001.sol +++ /dev/null @@ -1,9 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -constructor() payable public{} -fallback() payable external{} -function divideIHaveArgsReturn(int x,int y) public payable returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractLinkage002.sol b/framework/src/test/resources/soliditycode_0.6.12/contractLinkage002.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractLinkage002.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractLinkage003.sol b/framework/src/test/resources/soliditycode_0.6.12/contractLinkage003.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractLinkage003.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractLinkage004.sol b/framework/src/test/resources/soliditycode_0.6.12/contractLinkage004.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractLinkage004.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractLinkage005.sol b/framework/src/test/resources/soliditycode_0.6.12/contractLinkage005.sol deleted file mode 100644 index 7b943aee5c1..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractLinkage005.sol +++ /dev/null @@ -1,51 +0,0 @@ -contract timeoutTest { - string public iarray1; - // cpu - function oneCpu() public { - require(1==1); - } - - function storage8Char() public { - iarray1 = "12345678"; - } - - function testUseCpu(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - } - return count; - } - - - uint256[] public iarray; - uint public calculatedFibNumber; - mapping(address=>mapping(address=>uint256)) public m; - - function testUseStorage(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - iarray.push(i); - } - return count; - } - - // stack - //uint n = 0; - uint yy = 0; - function test() public { - //n += 1; - yy += 1; - test(); - } - - function setFibonacci(uint n) public returns (uint256){ - calculatedFibNumber = fibonacci(n); - return calculatedFibNumber; - } - - function fibonacci(uint n) internal returns (uint) { - return fibonacci(n - 1) + fibonacci(n - 2); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractLinkage006.sol b/framework/src/test/resources/soliditycode_0.6.12/contractLinkage006.sol deleted file mode 100644 index 53449f61ce2..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractLinkage006.sol +++ /dev/null @@ -1,18 +0,0 @@ - -contract AA{ - uint256 public count=0; - constructor () payable public{} - function init(address payable addr, uint256 max) payable public { - count =0; - this.hack(addr,max); - } - function hack(address payable addr, uint256 max) payable public { - while (count < max) { - count = count +1; - this.hack(addr,max); - } - if (count == max) { - addr.send(20); - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractOriginEnergyLimit001.sol b/framework/src/test/resources/soliditycode_0.6.12/contractOriginEnergyLimit001.sol deleted file mode 100644 index 6feb7fff3b8..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractOriginEnergyLimit001.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract findArgsContractTest{ - function findArgsByIndexTest(uint i) public returns (uint z) { - uint[] memory a = new uint[](3); - a[0]=1; - a[1]=2; - a[2]=3; - return a[i]; - } -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractOriginEnergyLimit004.sol b/framework/src/test/resources/soliditycode_0.6.12/contractOriginEnergyLimit004.sol deleted file mode 100644 index 6feb7fff3b8..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractOriginEnergyLimit004.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract findArgsContractTest{ - function findArgsByIndexTest(uint i) public returns (uint z) { - uint[] memory a = new uint[](3); - a[0]=1; - a[1]=2; - a[2]=3; - return a[i]; - } -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractOtherToTrcToken.sol b/framework/src/test/resources/soliditycode_0.6.12/contractOtherToTrcToken.sol deleted file mode 100644 index 933358e128b..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractOtherToTrcToken.sol +++ /dev/null @@ -1,41 +0,0 @@ - - -contract ConvertType { - -constructor() payable public{} - -fallback() payable external{} - -//function stringToTrctoken(address payable toAddress, string memory tokenStr, uint256 tokenValue) public { -// trcToken t = trcToken(tokenStr); // ERROR -// toAddress.transferToken(tokenValue, tokenStr); // ERROR -//} - -function uint256ToTrctoken(address payable toAddress, uint256 tokenValue, uint256 tokenInt) public { - trcToken t = trcToken(tokenInt); // OK - toAddress.transferToken(tokenValue, t); // OK - toAddress.transferToken(tokenValue, tokenInt); // OK -} - -function addressToTrctoken(address payable toAddress, uint256 tokenValue, address adr) public { - trcToken t = trcToken(adr); // OK - toAddress.transferToken(tokenValue, t); // OK -//toAddress.transferToken(tokenValue, adr); // ERROR -} - -//function bytesToTrctoken(address payable toAddress, bytes memory b, uint256 tokenValue) public { - // trcToken t = trcToken(b); // ERROR - // toAddress.transferToken(tokenValue, b); // ERROR -//} - -function bytes32ToTrctoken(address payable toAddress, uint256 tokenValue, bytes32 b32) public { - trcToken t = trcToken(b32); // OK - toAddress.transferToken(tokenValue, t); // OK -// toAddress.transferToken(tokenValue, b32); // ERROR -} - -//function arrayToTrctoken(address payable toAddress, uint256[] memory arr, uint256 tokenValue) public { -//trcToken t = trcToken(arr); // ERROR -// toAddress.transferToken(tokenValue, arr); // ERROR -//} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractScenario001.sol b/framework/src/test/resources/soliditycode_0.6.12/contractScenario001.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractScenario001.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractScenario002.sol b/framework/src/test/resources/soliditycode_0.6.12/contractScenario002.sol deleted file mode 100644 index 5b990fe36e8..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractScenario002.sol +++ /dev/null @@ -1,53 +0,0 @@ - -contract TronNative{ - - address public voteContractAddress= address(0x10001); - address public freezeBalanceAddress = address(0x10002); - address public unFreezeBalanceAddress = address(0x10003); - address public withdrawBalanceAddress = address(0x10004); - address public approveProposalAddress = address(0x10005); - address public createProposalAddress = address(0x10006); - address public deleteProposalAddress = address(0x10007); - constructor () payable public {} - - function voteForSingleWitness (address payable witnessAddr, uint256 voteValue) public{ - // method 1: - voteContractAddress.delegatecall(abi.encode(witnessAddr,voteValue)); - } - - function voteUsingAssembly (address witnessAddr, uint256 voteValue) public{ - // method 2: - assembly{ - mstore(0x80,witnessAddr) - mstore(0xa0,voteValue) - // gas, address, in, size, out, size - if iszero(delegatecall(0, 0x10001, 0x80, 0x40, 0x80, 0x0)) { - revert(0, 0) - } - } - } - - function freezeBalance(uint256 frozen_Balance,uint256 frozen_Duration) public { - freezeBalanceAddress.delegatecall(abi.encode(frozen_Balance,frozen_Duration)); - } - - function unFreezeBalance() public { - unFreezeBalanceAddress.delegatecall(""); - } - - function withdrawBalance() public { - withdrawBalanceAddress.delegatecall(""); - } - - function approveProposal(uint256 id, bool isApprove) public { - approveProposalAddress.delegatecall(abi.encode(id,isApprove)); - } - - function createProposal(bytes32 [] memory data) public { - createProposalAddress.delegatecall(abi.encode(data)); - } - - function deleteProposal(uint256 id) public{ - deleteProposalAddress.delegatecall(abi.encode(id)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractScenario003.sol b/framework/src/test/resources/soliditycode_0.6.12/contractScenario003.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractScenario003.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractScenario004.sol b/framework/src/test/resources/soliditycode_0.6.12/contractScenario004.sol deleted file mode 100644 index f6919502914..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractScenario004.sol +++ /dev/null @@ -1,88 +0,0 @@ - - -contract TronToken { - - string public name = "Tronix"; // token name - string public symbol = "TRX"; // token symbol - uint256 public decimals = 6; // token digit - - mapping (address => uint256) public balanceOf; - mapping (address => mapping (address => uint256)) public allowance; - - uint256 public totalSupply = 0; - bool public stopped = false; - - uint256 constant valueFounder = 100000000000000000; - address owner = address(0x0); - - modifier isOwner { - assert(owner == msg.sender); - _; - } - - modifier isRunning { - assert (!stopped); - _; - } - - modifier validAddress { - assert(address(0x0) != msg.sender); - _; - } - - constructor(address _addressFounder) public { - owner = msg.sender; - totalSupply = valueFounder; - balanceOf[_addressFounder] = valueFounder; - emit Transfer(address(0x0), _addressFounder, valueFounder); - } - - function transfer(address _to, uint256 _value) isRunning validAddress public returns (bool success) { - require(balanceOf[msg.sender] >= _value); - require(balanceOf[_to] + _value >= balanceOf[_to]); - balanceOf[msg.sender] -= _value; - balanceOf[_to] += _value; - emit Transfer(msg.sender, _to, _value); - return true; - } - - function transferFrom(address _from, address _to, uint256 _value) isRunning validAddress public returns (bool success) { - require(balanceOf[_from] >= _value); - require(balanceOf[_to] + _value >= balanceOf[_to]); - require(allowance[_from][msg.sender] >= _value); - balanceOf[_to] += _value; - balanceOf[_from] -= _value; - allowance[_from][msg.sender] -= _value; - emit Transfer(_from, _to, _value); - return true; - } - - function approve(address _spender, uint256 _value) isRunning validAddress public returns (bool success) { - require(_value == 0 || allowance[msg.sender][_spender] == 0); - allowance[msg.sender][_spender] = _value; - emit Approval(msg.sender, _spender, _value); - return true; - } - - function stop() isOwner public { - stopped = true; - } - - function start() isOwner public { - stopped = false; - } - - function setName(string memory _name) isOwner public { - name = _name; - } - - function burn(uint256 _value) public { - require(balanceOf[msg.sender] >= _value); - balanceOf[msg.sender] -= _value; - balanceOf[address(0x0)] += _value; - emit Transfer(msg.sender, address(0x0), _value); - } - - event Transfer(address indexed _from, address indexed _to, uint256 _value); - event Approval(address indexed _owner, address indexed _spender, uint256 _value); -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractScenario005.sol b/framework/src/test/resources/soliditycode_0.6.12/contractScenario005.sol deleted file mode 100644 index c377af7da97..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractScenario005.sol +++ /dev/null @@ -1,103 +0,0 @@ - - -interface token { - function transfer(address receiver, uint amount) external; -} - -contract Crowdsale { - address payable public beneficiary = 0x1b228F5D9f934c7bb18Aaa86F90418932888E7b4; // 募资成功后的收款方 - uint public fundingGoal = 10000000; // 募资额度 - uint public amountRaised = 1000000; // 参与数量 - uint public deadline; // 募资截止期 - - uint public price; // token 与以太坊的汇率 , token卖多少钱 - token public tokenReward; // 要卖的token - - mapping(address => uint256) public balanceOf; - - bool fundingGoalReached = false; // 众筹是否达到目标 - bool crowdsaleClosed = false; // 众筹是否结束 - - /** - * 事件可以用来跟踪信息 - **/ - event GoalReached(address recipient, uint totalAmountRaised); - event FundTransfer(address backer, uint amount, bool isContribution); - - /** - * 构造函数, 设置相关属性 - */ - constructor( - address payable ifSuccessfulSendTo, - uint fundingGoalInEthers, - uint durationInMinutes, - uint finneyCostOfEachToken, - address addressOfTokenUsedAsReward) public{ - beneficiary = ifSuccessfulSendTo; - fundingGoal = fundingGoalInEthers * 1 sun; - deadline = now + durationInMinutes * 1 minutes; - price = finneyCostOfEachToken * 1 trx; - tokenReward = token(addressOfTokenUsedAsReward); // 传入已发布的 token 合约的地址来创建实例 - } - - /** - * 无函数名的Fallback函数, - * 在向合约转账时,这个函数会被调用 - */ - fallback() payable external{ - require(!crowdsaleClosed); - uint amount = msg.value; - balanceOf[msg.sender] += amount; - amountRaised += amount; - tokenReward.transfer(msg.sender, amount / price); - emit FundTransfer(msg.sender, amount, true); - } - - /** - * 定义函数修改器modifier(作用和Python的装饰器很相似) - * 用于在函数执行前检查某种前置条件(判断通过之后才会继续执行该方法) - * _ 表示继续执行之后的代码 - **/ - modifier afterDeadline() { if (now >= deadline) _; } - - /** - * 判断众筹是否完成融资目标, 这个方法使用了afterDeadline函数修改器 - * - */ - function checkGoalReached() afterDeadline public{ - if (amountRaised >= fundingGoal) { - fundingGoalReached = true; - emit GoalReached(beneficiary, amountRaised); - } - crowdsaleClosed = true; - } - - - /** - * 完成融资目标时,融资款发送到收款方 - * 未完成融资目标时,执行退款 - * - */ - function safeWithdrawal() afterDeadline public{ - if (!fundingGoalReached) { - uint amount = balanceOf[msg.sender]; - balanceOf[msg.sender] = 0; - if (amount > 0) { - if (msg.sender.send(amount)) { - emit FundTransfer(msg.sender, amount, false); - } else { - balanceOf[msg.sender] = amount; - } - } - } - - if (fundingGoalReached && beneficiary == msg.sender) { - if (payable(beneficiary).send(amountRaised)) { - emit FundTransfer(beneficiary, amountRaised, false); - } else { - //If we fail to send the funds to beneficiary, unlock funders balance - fundingGoalReached = false; - } - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractScenario006.sol b/framework/src/test/resources/soliditycode_0.6.12/contractScenario006.sol deleted file mode 100644 index 6d6feeb8188..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractScenario006.sol +++ /dev/null @@ -1,1963 +0,0 @@ - - -interface PlayerBookInterface { - function getPlayerID(address _addr) external returns (uint256); - function getPlayerName(uint256 _pID) external view returns (bytes32); - function getPlayerLAff(uint256 _pID) external view returns (uint256); - function getPlayerAddr(uint256 _pID) external view returns (address); - function getNameFee() external view returns (uint256); - function registerNameXIDFromDapp(address _addr, bytes32 _name, uint256 _affCode, bool _all) external payable returns(bool, uint256); - function registerNameXaddrFromDapp(address _addr, bytes32 _name, address _affCode, bool _all) external payable returns(bool, uint256); - function registerNameXnameFromDapp(address _addr, bytes32 _name, bytes32 _affCode, bool _all) external payable returns(bool, uint256); - function isDev(address _who) external view returns(bool); -} - - -/** -* @title -Name Filter- v0.1.9 -* ┌┬┐┌─┐┌─┐┌┬┐ ╦╦ ╦╔═╗╔╦╗ ┌─┐┬─┐┌─┐┌─┐┌─┐┌┐┌┌┬┐┌─┐ -* │ ├┤ ├─┤│││ ║║ ║╚═╗ ║ ├─┘├┬┘├┤ └─┐├┤ │││ │ └─┐ -* ┴ └─┘┴ ┴┴ ┴ ╚╝╚═╝╚═╝ ╩ ┴ ┴└─└─┘└─┘└─┘┘└┘ ┴ └─┘ -* _____ _____ -* (, / /) /) /) (, / /) /) -* ┌─┐ / _ (/_ // // / _ // _ __ _(/ -* ├─┤ ___/___(/_/(__(_/_(/_(/_ ___/__/_)_(/_(_(_/ (_(_(_ -* ┴ ┴ / / .-/ _____ (__ / -* (__ / (_/ (, / /)™ -* / __ __ __ __ _ __ __ _ _/_ _ _(/ -* ┌─┐┬─┐┌─┐┌┬┐┬ ┬┌─┐┌┬┐ /__/ (_(__(_)/ (_/_)_(_)/ (_(_(_(__(/_(_(_ -* ├─┘├┬┘│ │ │││ ││ │ (__ / .-/ © Jekyll Island Inc. 2018 -* ┴ ┴└─└─┘─┴┘└─┘└─┘ ┴ (_/ -* _ __ _ ____ ____ _ _ _____ ____ ___ -*=============| |\ | / /\ | |\/| | |_ =====| |_ | | | | | | | |_ | |_)==============* -*=============|_| \| /_/--\ |_| | |_|__=====|_| |_| |_|__ |_| |_|__ |_| \==============* -* -* ╔═╗┌─┐┌┐┌┌┬┐┬─┐┌─┐┌─┐┌┬┐ ╔═╗┌─┐┌┬┐┌─┐ ┌──────────┐ -* ║ │ ││││ │ ├┬┘├─┤│ │ ║ │ │ ││├┤ │ Inventor │ -* ╚═╝└─┘┘└┘ ┴ ┴└─┴ ┴└─┘ ┴ ╚═╝└─┘─┴┘└─┘ └──────────┘ -*/ - -library NameFilter { - /** - * @dev filters name strings - * -converts uppercase to lower case. - * -makes sure it does not start/end with a space - * -makes sure it does not contain multiple spaces in a row - * -cannot be only numbers - * -cannot start with 0x - * -restricts characters to A-Z, a-z, 0-9, and space. - * @return reprocessed string in bytes32 format - */ - function nameFilter(string memory _input) - internal - pure - returns(bytes32) - { - bytes memory _temp = bytes(_input); - uint256 _length = _temp.length; - - //sorry limited to 32 characters - require (_length <= 32 && _length > 0, "string must be between 1 and 32 characters"); - // make sure it doesnt start with or end with space - require(_temp[0] != 0x20 && _temp[_length-1] != 0x20, "string cannot start or end with space"); - // make sure first two characters are not 0x - if (_temp[0] == 0x30) - { - require(_temp[1] != 0x78, "string cannot start with 0x"); - require(_temp[1] != 0x58, "string cannot start with 0X"); - } - - // create a bool to track if we have a non number character - bool _hasNonNumber; - - // convert & check - for (uint256 i = 0; i < _length; i++) - { - // if its uppercase A-Z - if (_temp[i] > 0x40 && _temp[i] < 0x5b) - { - // convert to lower case a-z - _temp[i] = byte(uint8(_temp[i]) + 32); - - // we have a non number - if (_hasNonNumber == false) - _hasNonNumber = true; - } else { - require - ( - // require character is a space - _temp[i] == 0x20 || - // OR lowercase a-z - (_temp[i] > 0x60 && _temp[i] < 0x7b) || - // or 0-9 - (_temp[i] > 0x2f && _temp[i] < 0x3a), - "string contains invalid characters" - ); - // make sure theres not 2x spaces in a row - if (_temp[i] == 0x20) - require( _temp[i+1] != 0x20, "string cannot contain consecutive spaces"); - - // see if we have a character other than a number - if (_hasNonNumber == false && (_temp[i] < 0x30 || _temp[i] > 0x39)) - _hasNonNumber = true; - } - } - - require(_hasNonNumber == true, "string cannot be only numbers"); - - bytes32 _ret; - assembly { - _ret := mload(add(_temp, 32)) - } - return (_ret); - } -} - - -library SafeMath { - - /** - * @dev Multiplies two numbers, throws on overflow. - */ - function mul(uint256 a, uint256 b) - internal - pure - returns (uint256 c) - { - if (a == 0) { - return 0; - } - c = a * b; - require(c / a == b, "SafeMath mul failed"); - return c; - } - - /** - * @dev Integer division of two numbers, truncating the quotient. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - // assert(b > 0); // Solidity automatically throws when dividing by 0 - uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - return c; - } - - /** - * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). - */ - function sub(uint256 a, uint256 b) - internal - pure - returns (uint256) - { - require(b <= a, "SafeMath sub failed"); - return a - b; - } - - /** - * @dev Adds two numbers, throws on overflow. - */ - function add(uint256 a, uint256 b) - internal - pure - returns (uint256 c) - { - c = a + b; - require(c >= a, "SafeMath add failed"); - return c; - } - - /** - * @dev gives square root of given x. - */ - function sqrt(uint256 x) - internal - pure - returns (uint256 y) - { - uint256 z = ((add(x,1)) / 2); - y = x; - while (z < y) - { - y = z; - z = ((add((x / z),z)) / 2); - } - } - - /** - * @dev gives square. multiplies x by x - */ - function sq(uint256 x) - internal - pure - returns (uint256) - { - return (mul(x,x)); - } - - /** - * @dev x to the power of y - */ - function pwr(uint256 x, uint256 y) - internal - pure - returns (uint256) - { - if (x==0) - return (0); - else if (y==0) - return (1); - else - { - uint256 z = x; - for (uint256 i=1; i < y; i++) - z = mul(z,x); - return (z); - } - } -} - -//============================================================================== -// | _ _ _ | _ . -// |<(/_\/ (_(_||(_ . -//=======/====================================================================== -library F3DKeysCalcLong { - using SafeMath for *; - /** - * @dev calculates number of keys received given X eth - * @param _curEth current amount of eth in contract - * @param _newEth eth being spent - * @return amount of ticket purchased - */ - function keysRec(uint256 _curEth, uint256 _newEth) - internal - pure - returns (uint256) - { - return(keys((_curEth).add(_newEth)).sub(keys(_curEth))); - } - - /** - * @dev calculates amount of eth received if you sold X keys - * @param _curKeys current amount of keys that exist - * @param _sellKeys amount of keys you wish to sell - * @return amount of eth received - */ - function ethRec(uint256 _curKeys, uint256 _sellKeys) - internal - pure - returns (uint256) - { - return((eth(_curKeys)).sub(eth(_curKeys.sub(_sellKeys)))); - } - - /** - * @dev calculates how many keys would exist with given an amount of eth - * @param _eth eth "in contract" - * @return number of keys that would exist - */ - function keys(uint256 _eth) - internal - pure - returns(uint256) - { - return ((((((_eth).mul(1000000000000000000)).mul(312500000000000000000000000)).add(5624988281256103515625000000000000000000000000000000000000000000)).sqrt()).sub(74999921875000000000000000000000)) / (156250000); - } - - /** - * @dev calculates how much eth would be in contract given a number of keys - * @param _keys number of keys "in contract" - * @return eth that would exists - */ - function eth(uint256 _keys) - internal - pure - returns(uint256) - { - return ((78125000).mul(_keys.sq()).add(((149999843750000).mul(_keys.mul(1000000000000000000))) / (2))) / ((1000000000000000000).sq()); - } -} - -library F3Ddatasets { - //compressedData key - // [76-33][32][31][30][29][28-18][17][16-6][5-3][2][1][0] - // 0 - new player (bool) - // 1 - joined round (bool) - // 2 - new leader (bool) - // 3-5 - air drop tracker (uint 0-999) - // 6-16 - round end time - // 17 - winnerTeam - // 18 - 28 timestamp - // 29 - team - // 30 - 0 = reinvest (round), 1 = buy (round), 2 = buy (ico), 3 = reinvest (ico) - // 31 - airdrop happened bool - // 32 - airdrop tier - // 33 - airdrop amount won - //compressedIDs key - // [77-52][51-26][25-0] - // 0-25 - pID - // 26-51 - winPID - // 52-77 - rID - struct EventReturns { - uint256 compressedData; - uint256 compressedIDs; - address winnerAddr; // winner address - bytes32 winnerName; // winner name - uint256 amountWon; // amount won - uint256 newPot; // amount in new pot - uint256 P3DAmount; // amount distributed to p3d - uint256 genAmount; // amount distributed to gen - uint256 potAmount; // amount added to pot - } - struct Player { - address payable addr; // player address - bytes32 name; // player name - uint256 win; // winnings vault - uint256 gen; // general vault - uint256 aff; // affiliate vault - uint256 lrnd; // last round played - uint256 laff; // last affiliate id used - } - struct PlayerRounds { - uint256 eth; // eth player has added to round (used for eth limiter) - uint256 keys; // keys - uint256 mask; // player mask - uint256 ico; // ICO phase investment - } - struct Round { - uint256 plyr; // pID of player in lead - uint256 team; // tID of team in lead - uint256 end; // time ends/ended - bool ended; // has round end function been ran - uint256 strt; // time round started - uint256 keys; // keys - uint256 eth; // total eth in - uint256 pot; // eth to pot (during round) / final amount paid to winner (after round ends) - uint256 mask; // global mask - uint256 ico; // total eth sent in during ICO phase - uint256 icoGen; // total eth for gen during ICO phase - uint256 icoAvg; // average key price for ICO phase - } - struct TeamFee { - uint256 gen; // % of buy in thats paid to key holders of current round - uint256 p3d; // % of buy in thats paid to p3d holders - } - struct PotSplit { - uint256 gen; // % of pot thats paid to key holders of current round - uint256 p3d; // % of pot thats paid to p3d holders - } -} - -contract F3Devents { - // fired whenever a player registers a name - event onNewName - ( - uint256 indexed playerID, - address indexed playerAddress, - bytes32 indexed playerName, - bool isNewPlayer, - uint256 affiliateID, - address affiliateAddress, - bytes32 affiliateName, - uint256 amountPaid, - uint256 timeStamp - ); - - // fired at end of buy or reload - event onEndTx - ( - uint256 compressedData, - uint256 compressedIDs, - bytes32 playerName, - address playerAddress, - uint256 ethIn, - uint256 keysBought, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount, - uint256 potAmount, - uint256 airDropPot - ); - - // fired whenever theres a withdraw - event onWithdraw - ( - uint256 indexed playerID, - address playerAddress, - bytes32 playerName, - uint256 ethOut, - uint256 timeStamp - ); - - // fired whenever a withdraw forces end round to be ran - event onWithdrawAndDistribute - ( - address playerAddress, - bytes32 playerName, - uint256 ethOut, - uint256 compressedData, - uint256 compressedIDs, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount - ); - - // (fomo3d long only) fired whenever a player tries a buy after round timer - // hit zero, and causes end round to be ran. - event onBuyAndDistribute - ( - address playerAddress, - bytes32 playerName, - uint256 ethIn, - uint256 compressedData, - uint256 compressedIDs, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount - ); - - // (fomo3d long only) fired whenever a player tries a reload after round timer - // hit zero, and causes end round to be ran. - event onReLoadAndDistribute - ( - address playerAddress, - bytes32 playerName, - uint256 compressedData, - uint256 compressedIDs, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount - ); - - // fired whenever an affiliate is paid - event onAffiliatePayout - ( - uint256 indexed affiliateID, - address affiliateAddress, - bytes32 affiliateName, - uint256 indexed roundID, - uint256 indexed buyerID, - uint256 amount, - uint256 timeStamp - ); - - // received pot swap deposit - event onPotSwapDeposit - ( - uint256 roundID, - uint256 amountAddedToPot - ); -} - - - -contract FoMo3Dlong is F3Devents { - using SafeMath for *; - using NameFilter for string; - using F3DKeysCalcLong for uint256; - - address public otherF3D_; - address public Divies; - address public Jekyll_Island_Inc; - PlayerBookInterface public playerBook;// =PlayerBookInterface(0x0dcd2f752394c41875e259e00bb44fd505297caf);//new PlayerBook();// - // TeamJustInterface constant private teamJust = TeamJustInterface(0x3a5f8140b9213a0f733a6a639857c9df43ee3f5a);// new TeamJust();// - - //============================================================================== - // _ _ _ |`. _ _ _ |_ | _ _ . - // (_(_)| |~|~|(_||_|| (_||_)|(/__\ . (game settings) - //=================_|=========================================================== - string constant public name = "FoMo3D Long Official"; - string constant public symbol = "F3D"; - uint256 private rndExtra_ = 30;//extSettings.getLongExtra(); // length of the very first ICO - uint256 private rndGap_ = 30; //extSettings.getLongGap(); // length of ICO phase, set to 1 year for EOS. - uint256 constant private rndInit_ = 1 hours; // round timer starts at this - uint256 constant private rndInc_ = 30 seconds; // every full key purchased adds this much to the timer - uint256 constant private rndMax_ = 24 hours; // max length a round timer can be - //============================================================================== - // _| _ _|_ _ _ _ _|_ _ . - // (_|(_| | (_| _\(/_ | |_||_) . (data used to store game info that changes) - //=============================|================================================ - uint256 public airDropPot_; // person who gets the airdrop wins part of this pot - uint256 public airDropTracker_ = 0; // incremented each time a "qualified" tx occurs. used to determine winning air drop - uint256 public rID_; // round id number / total rounds that have happened - //**************** - // PLAYER DATA - //**************** - mapping(address => uint256) public pIDxAddr_; // (addr => pID) returns player id by address - mapping(bytes32 => uint256) public pIDxName_; // (name => pID) returns player id by name - mapping(uint256 => F3Ddatasets.Player) public plyr_; // (pID => data) player data - mapping(uint256 => mapping(uint256 => F3Ddatasets.PlayerRounds)) public plyrRnds_; // (pID => rID => data) player round data by player id & round id - mapping(uint256 => mapping(bytes32 => bool)) public plyrNames_; // (pID => name => bool) list of names a player owns. (used so you can change your display name amongst any name you own) - //**************** - // ROUND DATA - //**************** - mapping(uint256 => F3Ddatasets.Round) public round_; // (rID => data) round data - mapping(uint256 => mapping(uint256 => uint256)) public rndTmEth_; // (rID => tID => data) eth in per team, by round id and team id - //**************** - // TEAM FEE DATA - //**************** - mapping(uint256 => F3Ddatasets.TeamFee) public fees_; // (team => fees) fee distribution by team - mapping(uint256 => F3Ddatasets.PotSplit) public potSplit_; // (team => fees) pot split distribution by team - - function setPlayerBook(address _playerBook) external { - require(msg.sender == owner, 'only dev!'); - require(address(playerBook) == address(0), 'already set!'); - playerBook = PlayerBookInterface(_playerBook); - } - - address public owner; - - //============================================================================== - // _ _ _ __|_ _ __|_ _ _ . - // (_(_)| |_\ | | |_|(_ | (_)| . (initial data setup upon contract deploy) - //============================================================================== - constructor() - public - { - owner = msg.sender; - // Team allocation structures - // 0 = whales - // 1 = bears - // 2 = sneks - // 3 = bulls - - // Team allocation percentages - // (F3D, P3D) + (Pot , Referrals, Community) - // Referrals / Community rewards are mathematically designed to come from the winner's share of the pot. - fees_[0] = F3Ddatasets.TeamFee(30, 6); - //50% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - fees_[1] = F3Ddatasets.TeamFee(43, 0); - //43% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - fees_[2] = F3Ddatasets.TeamFee(56, 10); - //20% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - fees_[3] = F3Ddatasets.TeamFee(43, 8); - //35% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - - // how to split up the final pot based on which team was picked - // (F3D, P3D) - potSplit_[0] = F3Ddatasets.PotSplit(15, 10); - //48% to winner, 25% to next round, 2% to com - potSplit_[1] = F3Ddatasets.PotSplit(25, 0); - //48% to winner, 25% to next round, 2% to com - potSplit_[2] = F3Ddatasets.PotSplit(20, 20); - //48% to winner, 10% to next round, 2% to com - potSplit_[3] = F3Ddatasets.PotSplit(30, 10); - //48% to winner, 10% to next round, 2% to com - } - //============================================================================== - // _ _ _ _|. |`. _ _ _ . - // | | |(_)(_||~|~|(/_| _\ . (these are safety checks) - //============================================================================== - /** - * @dev used to make sure no one can interact with contract until it has - * been activated. - */ - modifier isActivated() { - require(activated_ == true, "its not ready yet. check ?eta in discord"); - _; - } - - /** - * @dev prevents contracts from interacting with fomo3d - */ - modifier isHuman() { - address _addr = msg.sender; - uint256 _codeLength; - - assembly {_codeLength := extcodesize(_addr)} - require(_codeLength == 0, "sorry humans only"); - _; - } - - modifier onlyDevs() - { - require(playerBook.isDev(msg.sender) == true, "msg sender is not a dev"); - _; - } - - /** - * @dev sets boundaries for incoming tx - */ - modifier isWithinLimits(uint256 _eth) { - require(_eth >= 1000000000, "pocket lint: not a valid currency"); - require(_eth <= 100000000000000000000000, "no vitalik, no"); - _; - } - - //============================================================================== - // _ |_ |. _ |` _ __|_. _ _ _ . - // |_)|_||_)||(_ ~|~|_|| |(_ | |(_)| |_\ . (use these to interact with contract) - //====|========================================================================= - /** - * @dev emergency buy uses last stored affiliate ID and team snek - */ - fallback() - isActivated() - isHuman() - isWithinLimits(msg.value) - external - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_ ; - _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // buy core - buyCore(_pID, plyr_[_pID].laff, 2, _eventData_); - } - - /** - * @dev converts all incoming ethereum to keys. - * -functionhash- 0x8f38f309 (using ID for affiliate) - * -functionhash- 0x98a0871d (using address for affiliate) - * -functionhash- 0xa65b37a1 (using name for affiliate) - * @param _affCode the ID/address/name of the player who gets the affiliate fee - * @param _team what team is the player playing for? - */ - function buyXid(uint256 _affCode, uint256 _team) - isActivated() - isHuman() - isWithinLimits(msg.value) - public - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_; - _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == 0 || _affCode == _pID) - { - // use last stored affiliate code - _affCode = plyr_[_pID].laff; - - // if affiliate code was given & its not the same as previously stored - } else if (_affCode != plyr_[_pID].laff) { - // update last affiliate - plyr_[_pID].laff = _affCode; - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // buy core - buyCore(_pID, _affCode, _team, _eventData_); - } - - function buyXaddr(address _affCode, uint256 _team) - isActivated() - isHuman() - isWithinLimits(msg.value) - public - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_; - _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == address(0) || _affCode == msg.sender) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxAddr_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // buy core - buyCore(_pID, _affID, _team, _eventData_); - } - - function buyXname(bytes32 _affCode, uint256 _team) - isActivated() - isHuman() - isWithinLimits(msg.value) - public - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_ ; - _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == '' || _affCode == plyr_[_pID].name) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxName_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // buy core - buyCore(_pID, _affID, _team, _eventData_); - } - - /** - * @dev essentially the same as buy, but instead of you sending ether - * from your wallet, it uses your unwithdrawn earnings. - * -functionhash- 0x349cdcac (using ID for affiliate) - * -functionhash- 0x82bfc739 (using address for affiliate) - * -functionhash- 0x079ce327 (using name for affiliate) - * @param _affCode the ID/address/name of the player who gets the affiliate fee - * @param _team what team is the player playing for? - * @param _eth amount of earnings to use (remainder returned to gen vault) - */ - function reLoadXid(uint256 _affCode, uint256 _team, uint256 _eth) - isActivated() - isHuman() - isWithinLimits(_eth) - public - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == 0 || _affCode == _pID) - { - // use last stored affiliate code - _affCode = plyr_[_pID].laff; - - // if affiliate code was given & its not the same as previously stored - } else if (_affCode != plyr_[_pID].laff) { - // update last affiliate - plyr_[_pID].laff = _affCode; - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // reload core - reLoadCore(_pID, _affCode, _team, _eth, _eventData_); - } - - function reLoadXaddr(address _affCode, uint256 _team, uint256 _eth) - isActivated() - isHuman() - isWithinLimits(_eth) - public - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == address(0) || _affCode == msg.sender) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxAddr_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // reload core - reLoadCore(_pID, _affID, _team, _eth, _eventData_); - } - - function reLoadXname(bytes32 _affCode, uint256 _team, uint256 _eth) - isActivated() - isHuman() - isWithinLimits(_eth) - public - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == '' || _affCode == plyr_[_pID].name) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxName_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // reload core - reLoadCore(_pID, _affID, _team, _eth, _eventData_); - } - - /** - * @dev withdraws all of your earnings. - * -functionhash- 0x3ccfd60b - */ - function withdraw() - isActivated() - isHuman() - public - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // setup temp var for player eth - uint256 _eth; - - // check to see if round has ended and no one has run round end yet - if (_now > round_[_rID].end && round_[_rID].ended == false && round_[_rID].plyr != 0) - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // end the round (distributes pot) - round_[_rID].ended = true; - _eventData_ = endRound(_eventData_); - - // get their earnings - _eth = withdrawEarnings(_pID); - - // gib moni - if (_eth > 0) - plyr_[_pID].addr.transfer(_eth); - - // build event data - _eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID; - - // fire withdraw and distribute event - emit F3Devents.onWithdrawAndDistribute - ( - msg.sender, - plyr_[_pID].name, - _eth, - _eventData_.compressedData, - _eventData_.compressedIDs, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount - ); - - // in any other situation - } else { - // get their earnings - _eth = withdrawEarnings(_pID); - - // gib moni - if (_eth > 0) - plyr_[_pID].addr.transfer(_eth); - - // fire withdraw event - emit F3Devents.onWithdraw(_pID, msg.sender, plyr_[_pID].name, _eth, _now); - } - } - - /** - * @dev use these to register names. they are just wrappers that will send the - * registration requests to the PlayerBook contract. So registering here is the - * same as registering there. UI will always display the last name you registered. - * but you will still own all previously registered names to use as affiliate - * links. - * - must pay a registration fee. - * - name must be unique - * - names will be converted to lowercase - * - name cannot start or end with a space - * - cannot have more than 1 space in a row - * - cannot be only numbers - * - cannot start with 0x - * - name must be at least 1 char - * - max length of 32 characters long - * - allowed characters: a-z, 0-9, and space - * -functionhash- 0x921dec21 (using ID for affiliate) - * -functionhash- 0x3ddd4698 (using address for affiliate) - * -functionhash- 0x685ffd83 (using name for affiliate) - * @param _nameString players desired name - * @param _affCode affiliate ID, address, or name of who referred you - * @param _all set to true if you want this to push your info to all games - * (this might cost a lot of gas) - */ - function registerNameXID(string memory _nameString, uint256 _affCode, bool _all) - isHuman() - public - payable - { - bytes32 _name = _nameString.nameFilter(); - address _addr = msg.sender; - uint256 _paid = msg.value; - (bool _isNewPlayer, uint256 _affID) = playerBook.registerNameXIDFromDapp.value(_paid)(_addr, _name, _affCode, _all); - - uint256 _pID = pIDxAddr_[_addr]; - - // fire event - emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, now); - } - - function registerNameXaddr(string memory _nameString, address _affCode, bool _all) - isHuman() - public - payable - { - bytes32 _name = _nameString.nameFilter(); - address _addr = msg.sender; - uint256 _paid = msg.value; - (bool _isNewPlayer, uint256 _affID) = playerBook.registerNameXaddrFromDapp.value(msg.value)(msg.sender, _name, _affCode, _all); - - uint256 _pID = pIDxAddr_[_addr]; - - // fire event - emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, now); - } - - function registerNameXname(string memory _nameString, bytes32 _affCode, bool _all) - isHuman() - public - payable - { - bytes32 _name = _nameString.nameFilter(); - address _addr = msg.sender; - uint256 _paid = msg.value; - (bool _isNewPlayer, uint256 _affID) = playerBook.registerNameXnameFromDapp.value(msg.value)(msg.sender, _name, _affCode, _all); - - uint256 _pID = pIDxAddr_[_addr]; - - // fire event - emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, now); - } - //============================================================================== - // _ _ _|__|_ _ _ _ . - // (_|(/_ | | (/_| _\ . (for UI & viewing things on etherscan) - //=====_|======================================================================= - /** - * @dev return the price buyer will pay for next 1 individual key. - * -functionhash- 0x018a25e8 - * @return price for next key bought (in wei format) - */ - function getBuyPrice() - public - view - returns (uint256) - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - // are we in a round? - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - return ((round_[_rID].keys.add(1000000000000000000)).ethRec(1000000000000000000)); - else // rounds over. need price for new round - return (75000000000000); - // init - } - - /** - * @dev returns time left. dont spam this, you'll ddos yourself from your node - * provider - * -functionhash- 0xc7e284b8 - * @return time left in seconds - */ - function getTimeLeft() - public - view - returns (uint256) - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - if (_now < round_[_rID].end) - if (_now > round_[_rID].strt + rndGap_) - return ((round_[_rID].end).sub(_now)); - else - return ((round_[_rID].strt + rndGap_).sub(_now)); - else - return (0); - } - - /** - * @dev returns player earnings per vaults - * -functionhash- 0x63066434 - * @return winnings vault - * @return general vault - * @return affiliate vault - */ - function getPlayerVaults(uint256 _pID) - public - view - returns (uint256, uint256, uint256) - { - // setup local rID - uint256 _rID = rID_; - - // if round has ended. but round end has not been run (so contract has not distributed winnings) - if (now > round_[_rID].end && round_[_rID].ended == false && round_[_rID].plyr != 0) - { - // if player is winner - if (round_[_rID].plyr == _pID) - { - return - ( - (plyr_[_pID].win).add(((round_[_rID].pot).mul(48)) / 100), - (plyr_[_pID].gen).add(getPlayerVaultsHelper(_pID, _rID).sub(plyrRnds_[_pID][_rID].mask)), - plyr_[_pID].aff - ); - // if player is not the winner - } else { - return - ( - plyr_[_pID].win, - (plyr_[_pID].gen).add(getPlayerVaultsHelper(_pID, _rID).sub(plyrRnds_[_pID][_rID].mask)), - plyr_[_pID].aff - ); - } - - // if round is still going on, or round has ended and round end has been ran - } else { - return - ( - plyr_[_pID].win, - (plyr_[_pID].gen).add(calcUnMaskedEarnings(_pID, plyr_[_pID].lrnd)), - plyr_[_pID].aff - ); - } - } - - /** - * solidity hates stack limits. this lets us avoid that hate - */ - function getPlayerVaultsHelper(uint256 _pID, uint256 _rID) - private - view - returns (uint256) - { - return (((((round_[_rID].mask).add(((((round_[_rID].pot).mul(potSplit_[round_[_rID].team].gen)) / 100).mul(1000000000000000000)) / (round_[_rID].keys))).mul(plyrRnds_[_pID][_rID].keys)) / 1000000000000000000)); - } - - /** - * @dev returns all current round info needed for front end - * -functionhash- 0x747dff42 - * @return eth invested during ICO phase - * @return round id - * @return total keys for round - * @return time round ends - * @return time round started - * @return current pot - * @return current team ID & player ID in lead - * @return current player in leads address - * @return current player in leads name - * @return whales eth in for round - * @return bears eth in for round - * @return sneks eth in for round - * @return bulls eth in for round - * @return airdrop tracker # & airdrop pot - */ - function getCurrentRoundInfo() - public - view - returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256, address, bytes32, uint256, uint256, uint256, uint256, uint256) - { - // setup local rID - uint256 _rID = rID_; - - return - ( - round_[_rID].ico, //0 - _rID, //1 - round_[_rID].keys, //2 - round_[_rID].end, //3 - round_[_rID].strt, //4 - round_[_rID].pot, //5 - (round_[_rID].team + (round_[_rID].plyr * 10)), //6 - plyr_[round_[_rID].plyr].addr, //7 - plyr_[round_[_rID].plyr].name, //8 - rndTmEth_[_rID][0], //9 - rndTmEth_[_rID][1], //10 - rndTmEth_[_rID][2], //11 - rndTmEth_[_rID][3], //12 - airDropTracker_ + (airDropPot_ * 1000) //13 - ); - } - - /** - * @dev returns player info based on address. if no address is given, it will - * use msg.sender - * -functionhash- 0xee0b5d8b - * @param _addr address of the player you want to lookup - * @return player ID - * @return player name - * @return keys owned (current round) - * @return winnings vault - * @return general vault - * @return affiliate vault - * @return player round eth - */ - function getPlayerInfoByAddress(address _addr) - public - view - returns (uint256, bytes32, uint256, uint256, uint256, uint256, uint256) - { - // setup local rID - uint256 _rID = rID_; - - if (_addr == address(0)) - { - _addr == msg.sender; - } - uint256 _pID = pIDxAddr_[_addr]; - - return - ( - _pID, //0 - plyr_[_pID].name, //1 - plyrRnds_[_pID][_rID].keys, //2 - plyr_[_pID].win, //3 - (plyr_[_pID].gen).add(calcUnMaskedEarnings(_pID, plyr_[_pID].lrnd)), //4 - plyr_[_pID].aff, //5 - plyrRnds_[_pID][_rID].eth //6 - ); - } - - //============================================================================== - // _ _ _ _ | _ _ . _ . - // (_(_)| (/_ |(_)(_||(_ . (this + tools + calcs + modules = our softwares engine) - //=====================_|======================================================= - /** - * @dev logic runs whenever a buy order is executed. determines how to handle - * incoming eth depending on if we are in an active round or not - */ - function buyCore(uint256 _pID, uint256 _affID, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) - private - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - // if round is active - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - { - // call core - core(_rID, _pID, msg.value, _affID, _team, _eventData_); - - // if round is not active - } else { - // check to see if end round needs to be ran - if (_now > round_[_rID].end && round_[_rID].ended == false) - { - // end the round (distributes pot) & start new round - round_[_rID].ended = true; - _eventData_ = endRound(_eventData_); - - // build event data - _eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID; - - // fire buy and distribute event - emit F3Devents.onBuyAndDistribute - ( - msg.sender, - plyr_[_pID].name, - msg.value, - _eventData_.compressedData, - _eventData_.compressedIDs, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount - ); - } - - // put eth in players vault - plyr_[_pID].gen = plyr_[_pID].gen.add(msg.value); - } - } - - /** - * @dev logic runs whenever a reload order is executed. determines how to handle - * incoming eth depending on if we are in an active round or not - */ - function reLoadCore(uint256 _pID, uint256 _affID, uint256 _team, uint256 _eth, F3Ddatasets.EventReturns memory _eventData_) - private - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - // if round is active - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - { - // get earnings from all vaults and return unused to gen vault - // because we use a custom safemath library. this will throw if player - // tried to spend more eth than they have. - plyr_[_pID].gen = withdrawEarnings(_pID).sub(_eth); - - // call core - core(_rID, _pID, _eth, _affID, _team, _eventData_); - - // if round is not active and end round needs to be ran - } else if (_now > round_[_rID].end && round_[_rID].ended == false) { - // end the round (distributes pot) & start new round - round_[_rID].ended = true; - _eventData_ = endRound(_eventData_); - - // build event data - _eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID; - - // fire buy and distribute event - emit F3Devents.onReLoadAndDistribute - ( - msg.sender, - plyr_[_pID].name, - _eventData_.compressedData, - _eventData_.compressedIDs, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount - ); - } - } - - /** - * @dev this is the core logic for any buy/reload that happens while a round - * is live. - */ - function core(uint256 _rID, uint256 _pID, uint256 _eth, uint256 _affID, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) - private - { - // if player is new to round - if (plyrRnds_[_pID][_rID].keys == 0) - _eventData_ = managePlayer(_pID, _eventData_); - - // early round eth limiter - if (round_[_rID].eth < 100000000000000000000 && plyrRnds_[_pID][_rID].eth.add(_eth) > 1000000000000000000) - { - uint256 _availableLimit = (1000000000000000000).sub(plyrRnds_[_pID][_rID].eth); - uint256 _refund = _eth.sub(_availableLimit); - plyr_[_pID].gen = plyr_[_pID].gen.add(_refund); - _eth = _availableLimit; - } - - // if eth left is greater than min eth allowed (sorry no pocket lint) - if (_eth > 1000000000) - { - - // mint the new keys - uint256 _keys = (round_[_rID].eth).keysRec(_eth); - - // if they bought at least 1 whole key - if (_keys >= 1000000000000000000) - { - updateTimer(_keys, _rID); - - // set new leaders - if (round_[_rID].plyr != _pID) - round_[_rID].plyr = _pID; - if (round_[_rID].team != _team) - round_[_rID].team = _team; - - // set the new leader bool to true - _eventData_.compressedData = _eventData_.compressedData + 100; - } - - // manage airdrops - if (_eth >= 100000000000000000) - { - airDropTracker_++; - if (airdrop() == true) - { - // gib muni - uint256 _prize; - if (_eth >= 10000000000000000000) - { - // calculate prize and give it to winner - _prize = ((airDropPot_).mul(75)) / 100; - plyr_[_pID].win = (plyr_[_pID].win).add(_prize); - - // adjust airDropPot - airDropPot_ = (airDropPot_).sub(_prize); - - // let event know a tier 3 prize was won - _eventData_.compressedData += 300000000000000000000000000000000; - } else if (_eth >= 1000000000000000000 && _eth < 10000000000000000000) { - // calculate prize and give it to winner - _prize = ((airDropPot_).mul(50)) / 100; - plyr_[_pID].win = (plyr_[_pID].win).add(_prize); - - // adjust airDropPot - airDropPot_ = (airDropPot_).sub(_prize); - - // let event know a tier 2 prize was won - _eventData_.compressedData += 200000000000000000000000000000000; - } else if (_eth >= 100000000000000000 && _eth < 1000000000000000000) { - // calculate prize and give it to winner - _prize = ((airDropPot_).mul(25)) / 100; - plyr_[_pID].win = (plyr_[_pID].win).add(_prize); - - // adjust airDropPot - airDropPot_ = (airDropPot_).sub(_prize); - - // let event know a tier 3 prize was won - _eventData_.compressedData += 300000000000000000000000000000000; - } - // set airdrop happened bool to true - _eventData_.compressedData += 10000000000000000000000000000000; - // let event know how much was won - _eventData_.compressedData += _prize * 1000000000000000000000000000000000; - - // reset air drop tracker - airDropTracker_ = 0; - } - } - - // store the air drop tracker number (number of buys since last airdrop) - _eventData_.compressedData = _eventData_.compressedData + (airDropTracker_ * 1000); - - // update player - plyrRnds_[_pID][_rID].keys = _keys.add(plyrRnds_[_pID][_rID].keys); - plyrRnds_[_pID][_rID].eth = _eth.add(plyrRnds_[_pID][_rID].eth); - - // update round - round_[_rID].keys = _keys.add(round_[_rID].keys); - round_[_rID].eth = _eth.add(round_[_rID].eth); - rndTmEth_[_rID][_team] = _eth.add(rndTmEth_[_rID][_team]); - - // distribute eth - _eventData_ = distributeExternal(_rID, _pID, _eth, _affID, _team, _eventData_); - _eventData_ = distributeInternal(_rID, _pID, _eth, _team, _keys, _eventData_); - - // call end tx function to fire end tx event. - endTx(_pID, _team, _eth, _keys, _eventData_); - } - } - //============================================================================== - // _ _ | _ | _ _|_ _ _ _ . - // (_(_||(_|_||(_| | (_)| _\ . - //============================================================================== - /** - * @dev calculates unmasked earnings (just calculates, does not update mask) - * @return earnings in wei format - */ - function calcUnMaskedEarnings(uint256 _pID, uint256 _rIDlast) - private - view - returns (uint256) - { - return ((((round_[_rIDlast].mask).mul(plyrRnds_[_pID][_rIDlast].keys)) / (1000000000000000000)).sub(plyrRnds_[_pID][_rIDlast].mask)); - } - - /** - * @dev returns the amount of keys you would get given an amount of eth. - * -functionhash- 0xce89c80c - * @param _rID round ID you want price for - * @param _eth amount of eth sent in - * @return keys received - */ - function calcKeysReceived(uint256 _rID, uint256 _eth) - public - view - returns (uint256) - { - // grab time - uint256 _now = now; - - // are we in a round? - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - return ((round_[_rID].eth).keysRec(_eth)); - else // rounds over. need keys for new round - return ((_eth).keys()); - } - - /** - * @dev returns current eth price for X keys. - * -functionhash- 0xcf808000 - * @param _keys number of keys desired (in 18 decimal format) - * @return amount of eth needed to send - */ - function iWantXKeys(uint256 _keys) - public - view - returns (uint256) - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - // are we in a round? - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - return ((round_[_rID].keys.add(_keys)).ethRec(_keys)); - else // rounds over. need price for new round - return ((_keys).eth()); - } - //============================================================================== - // _|_ _ _ | _ . - // | (_)(_)|_\ . - //============================================================================== - /** - * @dev receives name/player info from names contract - */ - function receivePlayerInfo(uint256 _pID, address payable _addr, bytes32 _name, uint256 _laff) - external - { - require(msg.sender == address(playerBook), "your not playerNames contract... hmmm.."); - if (pIDxAddr_[_addr] != _pID) - pIDxAddr_[_addr] = _pID; - if (pIDxName_[_name] != _pID) - pIDxName_[_name] = _pID; - if (plyr_[_pID].addr != _addr) - plyr_[_pID].addr = _addr; - if (plyr_[_pID].name != _name) - plyr_[_pID].name = _name; - if (plyr_[_pID].laff != _laff) - plyr_[_pID].laff = _laff; - if (plyrNames_[_pID][_name] == false) - plyrNames_[_pID][_name] = true; - } - - /** - * @dev receives entire player name list - */ - function receivePlayerNameList(uint256 _pID, bytes32 _name) - external - { - require(msg.sender == address(playerBook), "your not playerNames contract... hmmm.."); - if (plyrNames_[_pID][_name] == false) - plyrNames_[_pID][_name] = true; - } - - /** - * @dev gets existing or registers new pID. use this when a player may be new - * @return pID - */ - function determinePID(F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - uint256 _pID = pIDxAddr_[msg.sender]; - // if player is new to this version of fomo3d - if (_pID == 0) - { - // grab their player ID, name and last aff ID, from player names contract - _pID = playerBook.getPlayerID(msg.sender); - bytes32 _name = playerBook.getPlayerName(_pID); - uint256 _laff = playerBook.getPlayerLAff(_pID); - - // set up player account - pIDxAddr_[msg.sender] = _pID; - plyr_[_pID].addr = msg.sender; - - if (_name != "") - { - pIDxName_[_name] = _pID; - plyr_[_pID].name = _name; - plyrNames_[_pID][_name] = true; - } - - if (_laff != 0 && _laff != _pID) - plyr_[_pID].laff = _laff; - - // set the new player bool to true - _eventData_.compressedData = _eventData_.compressedData + 1; - } - return (_eventData_); - } - - /** - * @dev checks to make sure user picked a valid team. if not sets team - * to default (sneks) - */ - function verifyTeam(uint256 _team) - private - pure - returns (uint256) - { - if (_team < 0 || _team > 3) - return (2); - else - return (_team); - } - - /** - * @dev decides if round end needs to be run & new round started. and if - * player unmasked earnings from previously played rounds need to be moved. - */ - function managePlayer(uint256 _pID, F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - // if player has played a previous round, move their unmasked earnings - // from that round to gen vault. - if (plyr_[_pID].lrnd != 0) - updateGenVault(_pID, plyr_[_pID].lrnd); - - // update player's last round played - plyr_[_pID].lrnd = rID_; - - // set the joined round bool to true - _eventData_.compressedData = _eventData_.compressedData + 10; - - return (_eventData_); - } - - /** - * @dev ends the round. manages paying out winner/splitting up pot - */ - function endRound(F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - // setup local rID - uint256 _rID = rID_; - - // grab our winning player and team id's - uint256 _winPID = round_[_rID].plyr; - uint256 _winTID = round_[_rID].team; - - // grab our pot amount - uint256 _pot = round_[_rID].pot; - - // calculate our winner share, community rewards, gen share, - // p3d share, and amount reserved for next pot - uint256 _win = (_pot.mul(48)) / 100; - uint256 _com = (_pot / 50); - uint256 _gen = (_pot.mul(potSplit_[_winTID].gen)) / 100; - uint256 _p3d = (_pot.mul(potSplit_[_winTID].p3d)) / 100; - uint256 _res = (((_pot.sub(_win)).sub(_com)).sub(_gen)).sub(_p3d); - - // calculate ppt for round mask - uint256 _ppt = (_gen.mul(1000000000000000000)) / (round_[_rID].keys); - uint256 _dust = _gen.sub((_ppt.mul(round_[_rID].keys)) / 1000000000000000000); - if (_dust > 0) - { - _gen = _gen.sub(_dust); - _res = _res.add(_dust); - } - - // pay our winner - plyr_[_winPID].win = _win.add(plyr_[_winPID].win); - - // community rewards - address payable add = address(uint160(Jekyll_Island_Inc)); - if (!add.send(_com)) - { - // This ensures Team Just cannot influence the outcome of FoMo3D with - // bank migrations by breaking outgoing transactions. - // Something we would never do. But that's not the point. - // We spent 2000$ in eth re-deploying just to patch this, we hold the - // highest belief that everything we create should be trustless. - // Team JUST, The name you shouldn't have to trust. - _p3d = _p3d.add(_com); - _com = 0; - } - - // distribute gen portion to key holders - round_[_rID].mask = _ppt.add(round_[_rID].mask); - - // send share for p3d to divies - if (_p3d > 0){ - address payable addr = address(uint160(Divies)); - addr.transfer(_p3d); - } - // prepare event data - _eventData_.compressedData = _eventData_.compressedData + (round_[_rID].end * 1000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + (_winPID * 100000000000000000000000000) + (_winTID * 100000000000000000); - _eventData_.winnerAddr = plyr_[_winPID].addr; - _eventData_.winnerName = plyr_[_winPID].name; - _eventData_.amountWon = _win; - _eventData_.genAmount = _gen; - _eventData_.P3DAmount = _p3d; - _eventData_.newPot = _res; - - // start next round - rID_++; - _rID++; - round_[_rID].strt = now; - round_[_rID].end = now.add(rndInit_).add(rndGap_); - round_[_rID].pot = _res; - - return (_eventData_); - } - - /** - * @dev moves any unmasked earnings to gen vault. updates earnings mask - */ - function updateGenVault(uint256 _pID, uint256 _rIDlast) - private - { - uint256 _earnings = calcUnMaskedEarnings(_pID, _rIDlast); - if (_earnings > 0) - { - // put in gen vault - plyr_[_pID].gen = _earnings.add(plyr_[_pID].gen); - // zero out their earnings by updating mask - plyrRnds_[_pID][_rIDlast].mask = _earnings.add(plyrRnds_[_pID][_rIDlast].mask); - } - } - - /** - * @dev updates round timer based on number of whole keys bought. - */ - function updateTimer(uint256 _keys, uint256 _rID) - private - { - // grab time - uint256 _now = now; - - // calculate time based on number of keys bought - uint256 _newTime; - if (_now > round_[_rID].end && round_[_rID].plyr == 0) - _newTime = (((_keys) / (1000000000000000000)).mul(rndInc_)).add(_now); - else - _newTime = (((_keys) / (1000000000000000000)).mul(rndInc_)).add(round_[_rID].end); - - // compare to max and set new end time - if (_newTime < (rndMax_).add(_now)) - round_[_rID].end = _newTime; - else - round_[_rID].end = rndMax_.add(_now); - } - - /** - * @dev generates a random number between 0-99 and checks to see if thats - * resulted in an airdrop win - * @return do we have a winner? - */ - function airdrop() - private - view - returns (bool) - { - uint256 seed = uint256(keccak256(abi.encodePacked( - - (block.timestamp).add - (block.difficulty).add - ((uint256(keccak256(abi.encodePacked(block.coinbase)))) / (now)).add - (block.gaslimit).add - ((uint256(keccak256(abi.encodePacked(msg.sender)))) / (now)).add - (block.number) - - ))); - if ((seed - ((seed / 1000) * 1000)) < airDropTracker_) - return (true); - else - return (false); - } - - /** - * @dev distributes eth based on fees to com, aff, and p3d - */ - function distributeExternal(uint256 _rID, uint256 _pID, uint256 _eth, uint256 _affID, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - // pay 2% out to community rewards - uint256 _com = _eth / 50; - uint256 _p3d; - address payable addr = address(uint160(Jekyll_Island_Inc)); - if (!addr.send(_com)) - { - // This ensures Team Just cannot influence the outcome of FoMo3D with - // bank migrations by breaking outgoing transactions. - // Something we would never do. But that's not the point. - // We spent 2000$ in eth re-deploying just to patch this, we hold the - // highest belief that everything we create should be trustless. - // Team JUST, The name you shouldn't have to trust. - _p3d = _com; - _com = 0; - } - - // pay 1% out to FoMo3D short - _com = _eth / 100; - address payable add = address(uint160(otherF3D_)); - add.transfer(_com); - - // distribute share to affiliate - _com = _eth / 10; - - // decide what to do with affiliate share of fees - // affiliate must not be self, and must have a name registered - if (_affID != _pID && plyr_[_affID].name != '') { - plyr_[_affID].aff = _com.add(plyr_[_affID].aff); - emit F3Devents.onAffiliatePayout(_affID, plyr_[_affID].addr, plyr_[_affID].name, _rID, _pID, _com, now); - } else { - _p3d = _com; - } - - // pay out p3d - _p3d = _p3d.add((_eth.mul(fees_[_team].p3d)) / (100)); - if (_p3d > 0) - { - // deposit to divies contract - address payable add = address(uint160(Divies)); - add.transfer(_p3d); - - // set up event data - _eventData_.P3DAmount = _p3d.add(_eventData_.P3DAmount); - } - - return (_eventData_); - } - - function potSwap() - external - payable - { - // setup local rID - uint256 _rID = rID_ + 1; - - round_[_rID].pot = round_[_rID].pot.add(msg.value); - emit F3Devents.onPotSwapDeposit(_rID, msg.value); - } - - /** - * @dev distributes eth based on fees to gen and pot - */ - function distributeInternal(uint256 _rID, uint256 _pID, uint256 _eth, uint256 _team, uint256 _keys, F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - // calculate gen share - uint256 _gen = (_eth.mul(fees_[_team].gen)) / 100; - - // toss 1% into airdrop pot - uint256 _air = (_eth / 100); - airDropPot_ = airDropPot_.add(_air); - - // update eth balance (eth = eth - (com share + pot swap share + aff share + p3d share + airdrop pot share)) - _eth = _eth.sub(((_eth.mul(14)) / 100).add((_eth.mul(fees_[_team].p3d)) / 100)); - - // calculate pot - uint256 _pot = _eth.sub(_gen); - - // distribute gen share (thats what updateMasks() does) and adjust - // balances for dust. - uint256 _dust = updateMasks(_rID, _pID, _gen, _keys); - if (_dust > 0) - _gen = _gen.sub(_dust); - - // add eth to pot - round_[_rID].pot = _pot.add(_dust).add(round_[_rID].pot); - - // set up event data - _eventData_.genAmount = _gen.add(_eventData_.genAmount); - _eventData_.potAmount = _pot; - - return (_eventData_); - } - - /** - * @dev updates masks for round and player when keys are bought - * @return dust left over - */ - function updateMasks(uint256 _rID, uint256 _pID, uint256 _gen, uint256 _keys) - private - returns (uint256) - { - /* MASKING NOTES - earnings masks are a tricky thing for people to wrap their minds around. - the basic thing to understand here. is were going to have a global - tracker based on profit per share for each round, that increases in - relevant proportion to the increase in share supply. - - the player will have an additional mask that basically says "based - on the rounds mask, my shares, and how much i've already withdrawn, - how much is still owed to me?" - */ - - // calc profit per key & round mask based on this buy: (dust goes to pot) - uint256 _ppt = (_gen.mul(1000000000000000000)) / (round_[_rID].keys); - round_[_rID].mask = _ppt.add(round_[_rID].mask); - - // calculate player earning from their own buy (only based on the keys - // they just bought). & update player earnings mask - uint256 _pearn = (_ppt.mul(_keys)) / (1000000000000000000); - plyrRnds_[_pID][_rID].mask = (((round_[_rID].mask.mul(_keys)) / (1000000000000000000)).sub(_pearn)).add(plyrRnds_[_pID][_rID].mask); - - // calculate & return dust - return (_gen.sub((_ppt.mul(round_[_rID].keys)) / (1000000000000000000))); - } - - /** - * @dev adds up unmasked earnings, & vault earnings, sets them all to 0 - * @return earnings in wei format - */ - function withdrawEarnings(uint256 _pID) - private - returns (uint256) - { - // update gen vault - updateGenVault(_pID, plyr_[_pID].lrnd); - - // from vaults - uint256 _earnings = (plyr_[_pID].win).add(plyr_[_pID].gen).add(plyr_[_pID].aff); - if (_earnings > 0) - { - plyr_[_pID].win = 0; - plyr_[_pID].gen = 0; - plyr_[_pID].aff = 0; - } - - return (_earnings); - } - - /** - * @dev prepares compression data and fires event for buy or reload tx's - */ - function endTx(uint256 _pID, uint256 _team, uint256 _eth, uint256 _keys, F3Ddatasets.EventReturns memory _eventData_) - private - { - _eventData_.compressedData = _eventData_.compressedData + (now * 1000000000000000000) + (_team * 100000000000000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID + (rID_ * 10000000000000000000000000000000000000000000000000000); - - emit F3Devents.onEndTx - ( - _eventData_.compressedData, - _eventData_.compressedIDs, - plyr_[_pID].name, - msg.sender, - _eth, - _keys, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount, - _eventData_.potAmount, - airDropPot_ - ); - } - //============================================================================== - // (~ _ _ _._|_ . - // _)(/_(_|_|| | | \/ . - //====================/========================================================= - /** upon contract deploy, it will be deactivated. this is a one time - * use function that will activate the contract. we do this so devs - * have time to set things up on the web end **/ - bool public activated_ = false; - - function activate() - public - onlyDevs - { - - // can only be ran once - require(activated_ == false, "fomo3d already activated"); - - // activate the contract - activated_ = true; - - otherF3D_ = msg.sender; - Divies = msg.sender; - Jekyll_Island_Inc = msg.sender; - - // lets start first round - rID_ = 1; - round_[1].strt = now + rndExtra_ - rndGap_; - round_[1].end = now + rndInit_ + rndExtra_; - } - - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractScenario007.sol b/framework/src/test/resources/soliditycode_0.6.12/contractScenario007.sol deleted file mode 100644 index a6fa095860f..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractScenario007.sol +++ /dev/null @@ -1,1432 +0,0 @@ - -/** - * @title ERC165 - * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md - */ -interface ERC165 { - - /** - * @notice Query if a contract implements an interface - * @param _interfaceId The interface identifier, as specified in ERC-165 - * @dev Interface identification is specified in ERC-165. This function - * uses less than 30,000 gas. - */ - function supportsInterface(bytes4 _interfaceId) external view returns (bool); - -} - -contract ERC721Basic is ERC165 { - - event Transfer( - address indexed _from, - address indexed _to, - uint256 indexed _tokenId - ); - event Approval( - address indexed _owner, - address indexed _approved, - uint256 indexed _tokenId - ); - event ApprovalForAll( - address indexed _owner, - address indexed _operator, - bool _approved - ); - - function balanceOf(address _owner) public view returns (uint256 _balance); - function ownerOf(uint256 _tokenId) public view returns (address _owner); - function exists(uint256 _tokenId) public view returns (bool _exists); - - function approve(address _to, uint256 _tokenId) public; - function getApproved(uint256 _tokenId) - public view returns (address _operator); - - function setApprovalForAll(address _operator, bool _approved) public; - function isApprovedForAll(address _owner, address _operator) - public view returns (bool); - - function transferFrom(address _from, address _to, uint256 _tokenId) public; - function safeTransferFrom(address _from, address _to, uint256 _tokenId) - public; - - function safeTransferFrom( - address _from, - address _to, - uint256 _tokenId, - bytes memory _data - ) - public; -} - - -/** - * @title SupportsInterfaceWithLookup - * @author Matt Condon (@shrugs) - * @dev Implements ERC165 using a lookup table. - */ -contract SupportsInterfaceWithLookup is ERC165 { - bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7; - /** - * 0x01ffc9a7 === - * bytes4(keccak256('supportsInterface(bytes4)')) - */ - - /** - * @dev a mapping of interface id to whether or not it's supported - */ - mapping(bytes4 => bool) internal supportedInterfaces; - - /** - * @dev A contract implementing SupportsInterfaceWithLookup - * implement ERC165 itself - */ - constructor() public { - _registerInterface(InterfaceId_ERC165); - } - - /** - * @dev implement supportsInterface(bytes4) using a lookup table - */ - function supportsInterface(bytes4 _interfaceId) external view returns (bool) { - return supportedInterfaces[_interfaceId]; - } - - /** - * @dev private method for registering an interface - */ - function _registerInterface(bytes4 _interfaceId) internal { - require(_interfaceId != 0xffffffff); - supportedInterfaces[_interfaceId] = true; - } -} - -contract Governable { - - event Pause(); - event Unpause(); - - address public governor; - bool public paused = false; - - constructor() public { - governor = msg.sender; - } - - function setGovernor(address _gov) public onlyGovernor { - governor = _gov; - } - - modifier onlyGovernor { - require(msg.sender == governor); - _; - } - - /** - * @dev Modifier to make a function callable only when the contract is not paused. - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev Modifier to make a function callable only when the contract is paused. - */ - modifier whenPaused() { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyGovernor whenNotPaused public { - paused = true; - emit Pause(); - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyGovernor whenPaused public { - paused = false; - emit Unpause(); - } - -} - -contract CardBase is Governable { - - struct Card { - uint16 proto; - uint16 purity; - } - - function getCard(uint id) public view returns (uint16 proto, uint16 purity) { - Card memory card = cards[id]; - return (card.proto, card.purity); - } - - function getShine(uint16 purity) public pure returns (uint8) { - return uint8(purity / 1000); - } - - Card[] public cards; - -} - -contract CardProto is CardBase { - - event NewProtoCard( - uint16 id, uint8 season, uint8 god, - Rarity rarity, uint8 mana, uint8 attack, - uint8 health, uint8 cardType, uint8 tribe, bool packable - ); - - struct Limit { - uint64 limit; - bool exists; - } - - // limits for mythic cards - mapping(uint16 => Limit) public limits; - - // can only set limits once - function setLimit(uint16 id, uint64 limit) public onlyGovernor { - Limit memory l = limits[id]; - require(!l.exists); - limits[id] = Limit({ - limit: limit, - exists: true - }); - } - - function getLimit(uint16 id) public view returns (uint64 limit, bool set) { - Limit memory l = limits[id]; - return (l.limit, l.exists); - } - - // could make these arrays to save gas - // not really necessary - will be update a very limited no of times - mapping(uint8 => bool) public seasonTradable; - mapping(uint8 => bool) public seasonTradabilityLocked; - uint8 public currentSeason; - - function makeTradable(uint8 season) public onlyGovernor { - seasonTradable[season] = true; - } - - function makeUntradable(uint8 season) public onlyGovernor { - require(!seasonTradabilityLocked[season]); - seasonTradable[season] = false; - } - - function makePermanantlyTradable(uint8 season) public onlyGovernor { - require(seasonTradable[season]); - seasonTradabilityLocked[season] = true; - } - - function isTradable(uint16 proto) public view returns (bool) { - return seasonTradable[protos[proto].season]; - } - - function nextSeason() public onlyGovernor { - //Seasons shouldn't go to 0 if there is more than the uint8 should hold, the governor should know this ¯\_(ツ)_/¯ -M - require(currentSeason <= 255); - - currentSeason++; - mythic.length = 0; - legendary.length = 0; - epic.length = 0; - rare.length = 0; - common.length = 0; - } - - enum Rarity { - Common, - Rare, - Epic, - Legendary, - Mythic - } - - uint8 constant SPELL = 1; - uint8 constant MINION = 2; - uint8 constant WEAPON = 3; - uint8 constant HERO = 4; - - struct ProtoCard { - bool exists; - uint8 god; - uint8 season; - uint8 cardType; - Rarity rarity; - uint8 mana; - uint8 attack; - uint8 health; - uint8 tribe; - } - - // there is a particular design decision driving this: - // need to be able to iterate over mythics only for card generation - // don't store 5 different arrays: have to use 2 ids - // better to bear this cost (2 bytes per proto card) - // rather than 1 byte per instance - - uint16 public protoCount; - - mapping(uint16 => ProtoCard) protos; - - uint16[] public mythic; - uint16[] public legendary; - uint16[] public epic; - uint16[] public rare; - uint16[] public common; - - function addProtos( - uint16[] memory externalIDs, uint8[] memory gods, Rarity[] memory rarities, uint8[] memory manas, uint8[] memory attacks, - uint8[] memory healths, uint8[] memory cardTypes, uint8[] memory tribes, bool[] memory packable - ) public onlyGovernor returns(uint16) { - - for (uint i = 0; i < externalIDs.length; i++) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: gods[i], - season: currentSeason, - cardType: cardTypes[i], - rarity: rarities[i], - mana: manas[i], - attack: attacks[i], - health: healths[i], - tribe: tribes[i] - }); - - _addProto(externalIDs[i], card, packable[i]); - } - - } - - function addProto( - uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 cardType, uint8 tribe, bool packable - ) public onlyGovernor returns(uint16) { - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: cardType, - rarity: rarity, - mana: mana, - attack: attack, - health: health, - tribe: tribe - }); - - _addProto(externalID, card, packable); - } - - function addWeapon( - uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 durability, bool packable - ) public onlyGovernor returns(uint16) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: WEAPON, - rarity: rarity, - mana: mana, - attack: attack, - health: durability, - tribe: 0 - }); - - _addProto(externalID, card, packable); - } - - function addSpell(uint16 externalID, uint8 god, Rarity rarity, uint8 mana, bool packable) public onlyGovernor returns(uint16) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: SPELL, - rarity: rarity, - mana: mana, - attack: 0, - health: 0, - tribe: 0 - }); - - _addProto(externalID, card, packable); - } - - function addMinion( - uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 tribe, bool packable - ) public onlyGovernor returns(uint16) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: MINION, - rarity: rarity, - mana: mana, - attack: attack, - health: health, - tribe: tribe - }); - - _addProto(externalID, card, packable); - } - - function _addProto(uint16 externalID, ProtoCard memory card, bool packable) internal { - - require(!protos[externalID].exists); - - card.exists = true; - - protos[externalID] = card; - - protoCount++; - - emit NewProtoCard( - externalID, currentSeason, card.god, - card.rarity, card.mana, card.attack, - card.health, card.cardType, card.tribe, packable - ); - - if (packable) { - Rarity rarity = card.rarity; - if (rarity == Rarity.Common) { - common.push(externalID); - } else if (rarity == Rarity.Rare) { - rare.push(externalID); - } else if (rarity == Rarity.Epic) { - epic.push(externalID); - } else if (rarity == Rarity.Legendary) { - legendary.push(externalID); - } else if (rarity == Rarity.Mythic) { - mythic.push(externalID); - } else { - require(false); - } - } - } - - function getProto(uint16 id) public view returns( - bool exists, uint8 god, uint8 season, uint8 cardType, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 tribe - ) { - ProtoCard memory proto = protos[id]; - return ( - proto.exists, - proto.god, - proto.season, - proto.cardType, - proto.rarity, - proto.mana, - proto.attack, - proto.health, - proto.tribe - ); - } - - function getRandomCard(Rarity rarity, uint16 random) public view returns (uint16) { - // modulo bias is fine - creates rarity tiers etc - // will obviously revert is there are no cards of that type: this is expected - should never happen - if (rarity == Rarity.Common) { - return common[random % common.length]; - } else if (rarity == Rarity.Rare) { - return rare[random % rare.length]; - } else if (rarity == Rarity.Epic) { - return epic[random % epic.length]; - } else if (rarity == Rarity.Legendary) { - return legendary[random % legendary.length]; - } else if (rarity == Rarity.Mythic) { - // make sure a mythic is available - uint16 id; - uint64 limit; - bool set; - for (uint i = 0; i < mythic.length; i++) { - id = mythic[(random + i) % mythic.length]; - (limit, set) = getLimit(id); - if (set && limit > 0){ - return id; - } - } - // if not, they get a legendary :( - return legendary[random % legendary.length]; - } - require(false); - return 0; - } - - // can never adjust tradable cards - // each season gets a 'balancing beta' - // totally immutable: season, rarity - function replaceProto( - uint16 index, uint8 god, uint8 cardType, uint8 mana, uint8 attack, uint8 health, uint8 tribe - ) public onlyGovernor { - ProtoCard memory pc = protos[index]; - require(!seasonTradable[pc.season]); - protos[index] = ProtoCard({ - exists: true, - god: god, - season: pc.season, - cardType: cardType, - rarity: pc.rarity, - mana: mana, - attack: attack, - health: health, - tribe: tribe - }); - } - -} - -contract ERC721Receiver { - /** - * @dev Magic value to be returned upon successful reception of an NFT - * Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`, - * which can be also obtained as `ERC721Receiver(0).onERC721Received.selector` - */ - bytes4 internal constant ERC721_RECEIVED = 0x150b7a02; - - /** - * @notice Handle the receipt of an NFT - * @dev The ERC721 smart contract calls this function on the recipient - * after a `safetransfer`. This function MAY throw to revert and reject the - * transfer. Return of other than the magic value MUST result in the - * transaction being reverted. - * Note: the contract address is always the message sender. - * @param _operator The address which called `safeTransferFrom` function - * @param _from The address which previously owned the token - * @param _tokenId The NFT identifier which is being transfered - * @param _data Additional data with no specified format - * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` - */ - function onERC721Received( - address _operator, - address _from, - uint256 _tokenId, - bytes memory _data - ) - public - returns(bytes4); -} - -library AddressUtils { - - /** - * Returns whether the target address is a contract - * @dev This function will return false if invoked during the constructor of a contract, - * as the code is not actually created until after the constructor finishes. - * @param addr address to check - * @return whether the target address is a contract - */ - function isContract1(address addr) internal view returns (bool) { - uint256 size; - // XXX Currently there is no better way to check if there is a contract in an address - // than to check the size of the code at that address. - // See https://ethereum.stackexchange.com/a/14016/36603 - // for more details about how this works. - // TODO Check this again before the Serenity release, because all addresses will be - // contracts then. - // solium-disable-next-line security/no-inline-assembly - assembly { size := extcodesize(addr) } - return size > 0; - } - -} - -library SafeMath { - - /** - * @dev Multiplies two numbers, throws on overflow. - */ - function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { - // Gas optimization: this is cheaper than asserting 'a' not being zero, but the - // benefit is lost if 'b' is also tested. - // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 - if (a == 0) { - return 0; - } - - c = a * b; - assert(c / a == b); - return c; - } - - /** - * @dev Integer division of two numbers, truncating the quotient. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - // assert(b > 0); // Solidity automatically throws when dividing by 0 - // uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - return a / b; - } - - /** - * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). - */ - function sub(uint256 a, uint256 b) internal pure returns (uint256) { - assert(b <= a); - return a - b; - } - - /** - * @dev Adds two numbers, throws on overflow. - */ - function add(uint256 a, uint256 b) internal pure returns (uint256 c) { - c = a + b; - assert(c >= a); - return c; - } -} - -contract ERC721BasicToken is CardProto, SupportsInterfaceWithLookup, ERC721Basic { - - bytes4 private constant InterfaceId_ERC721 = 0x80ac58cd; - /* - * 0x80ac58cd === - * bytes4(keccak256('balanceOf(address)')) ^ - * bytes4(keccak256('ownerOf(uint256)')) ^ - * bytes4(keccak256('approve(address,uint256)')) ^ - * bytes4(keccak256('getApproved(uint256)')) ^ - * bytes4(keccak256('setApprovalForAll(address,bool)')) ^ - * bytes4(keccak256('isApprovedForAll(address,address)')) ^ - * bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^ - * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) - */ - - bytes4 private constant InterfaceId_ERC721Exists = 0x4f558e79; - /* - * 0x4f558e79 === - * bytes4(keccak256('exists(uint256)')) - */ - - using SafeMath for uint256; - using AddressUtils for address; - - // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` - // which can be also obtained as `ERC721Receiver(0).onERC721Received.selector` - bytes4 private constant ERC721_RECEIVED = 0x150b7a02; - - // Mapping from token ID to owner - mapping (uint256 => address) internal tokenOwner; - - // Mapping from token ID to approved address - mapping (uint256 => address) internal tokenApprovals; - - // Mapping from owner to number of owned token - // mapping (address => uint256) internal ownedTokensCount; - - // Mapping from owner to operator approvals - mapping (address => mapping (address => bool)) internal operatorApprovals; - - /** - * @dev Guarantees msg.sender is owner of the given token - * @param _tokenId uint256 ID of the token to validate its ownership belongs to msg.sender - */ - modifier onlyOwnerOf(uint256 _tokenId) { - require(ownerOf(_tokenId) == msg.sender); - _; - } - - /** - * @dev Checks msg.sender can transfer a token, by being owner, approved, or operator - * @param _tokenId uint256 ID of the token to validate - */ - modifier canTransfer(uint256 _tokenId) { - require(isApprovedOrOwner(msg.sender, _tokenId)); - _; - } - - constructor() - public - { - // register the supported interfaces to conform to ERC721 via ERC165 - _registerInterface(InterfaceId_ERC721); - _registerInterface(InterfaceId_ERC721Exists); - } - - /** - * @dev Gets the balance of the specified address - * @param _owner address to query the balance of - * @return uint256 representing the amount owned by the passed address - */ - function balanceOf(address _owner) public view returns (uint256); - - /** - * @dev Gets the owner of the specified token ID - * @param _tokenId uint256 ID of the token to query the owner of - * @return owner address currently marked as the owner of the given token ID - */ - function ownerOf(uint256 _tokenId) public view returns (address) { - address owner = tokenOwner[_tokenId]; - require(owner != address(0)); - return owner; - } - - /** - * @dev Returns whether the specified token exists - * @param _tokenId uint256 ID of the token to query the existence of - * @return whether the token exists - */ - function exists(uint256 _tokenId) public view returns (bool) { - address owner = tokenOwner[_tokenId]; - return owner != address(0); - } - - /** - * @dev Approves another address to transfer the given token ID - * The zero address indicates there is no approved address. - * There can only be one approved address per token at a given time. - * Can only be called by the token owner or an approved operator. - * @param _to address to be approved for the given token ID - * @param _tokenId uint256 ID of the token to be approved - */ - function approve(address _to, uint256 _tokenId) public { - address owner = ownerOf(_tokenId); - require(_to != owner); - require(msg.sender == owner || isApprovedForAll(owner, msg.sender)); - - tokenApprovals[_tokenId] = _to; - emit Approval(owner, _to, _tokenId); - } - - /** - * @dev Gets the approved address for a token ID, or zero if no address set - * @param _tokenId uint256 ID of the token to query the approval of - * @return address currently approved for the given token ID - */ - function getApproved(uint256 _tokenId) public view returns (address) { - return tokenApprovals[_tokenId]; - } - - /** - * @dev Sets or unsets the approval of a given operator - * An operator is allowed to transfer all tokens of the sender on their behalf - * @param _to operator address to set the approval - * @param _approved representing the status of the approval to be set - */ - function setApprovalForAll(address _to, bool _approved) public { - require(_to != msg.sender); - operatorApprovals[msg.sender][_to] = _approved; - emit ApprovalForAll(msg.sender, _to, _approved); - } - - /** - * @dev Tells whether an operator is approved by a given owner - * @param _owner owner address which you want to query the approval of - * @param _operator operator address which you want to query the approval of - * @return bool whether the given operator is approved by the given owner - */ - function isApprovedForAll( - address _owner, - address _operator - ) - public - view - returns (bool) - { - return operatorApprovals[_owner][_operator]; - } - - /** - * @dev Transfers the ownership of a given token ID to another address - * Usage of this method is discouraged, use `safeTransferFrom` whenever possible - * Requires the msg sender to be the owner, approved, or operator - * @param _from current owner of the token - * @param _to address to receive the ownership of the given token ID - * @param _tokenId uint256 ID of the token to be transferred - */ - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - public - canTransfer(_tokenId) - { - require(_from != address(0)); - require(_to != address(0)); - - clearApproval(_from, _tokenId); - removeTokenFrom(_from, _tokenId); - addTokenTo(_to, _tokenId); - - emit Transfer(_from, _to, _tokenId); - } - - /** - * @dev Safely transfers the ownership of a given token ID to another address - * If the target address is a contract, it must implement `onERC721Received`, - * which is called upon a safe transfer, and return the magic value - * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, - * the transfer is reverted. - * - * Requires the msg sender to be the owner, approved, or operator - * @param _from current owner of the token - * @param _to address to receive the ownership of the given token ID - * @param _tokenId uint256 ID of the token to be transferred - */ - function safeTransferFrom( - address _from, - address _to, - uint256 _tokenId - ) - public - canTransfer(_tokenId) - { - // solium-disable-next-line arg-overflow - safeTransferFrom(_from, _to, _tokenId, ""); - } - - /** - * @dev Safely transfers the ownership of a given token ID to another address - * If the target address is a contract, it must implement `onERC721Received`, - * which is called upon a safe transfer, and return the magic value - * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, - * the transfer is reverted. - * Requires the msg sender to be the owner, approved, or operator - * @param _from current owner of the token - * @param _to address to receive the ownership of the given token ID - * @param _tokenId uint256 ID of the token to be transferred - * @param _data bytes data to send along with a safe transfer check - */ - function safeTransferFrom( - address _from, - address _to, - uint256 _tokenId, - bytes memory _data - ) - public - canTransfer(_tokenId) - { - transferFrom(_from, _to, _tokenId); - // solium-disable-next-line arg-overflow - require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data)); - } - - /** - * @dev Returns whether the given spender can transfer a given token ID - * @param _spender address of the spender to query - * @param _tokenId uint256 ID of the token to be transferred - * @return bool whether the msg.sender is approved for the given token ID, - * is an operator of the owner, or is the owner of the token - */ - function isApprovedOrOwner( - address _spender, - uint256 _tokenId - ) - internal - view - returns (bool) - { - address owner = ownerOf(_tokenId); - // Disable solium check because of - // https://github.com/duaraghav8/Solium/issues/175 - // solium-disable-next-line operator-whitespace - return ( - _spender == owner || - getApproved(_tokenId) == _spender || - isApprovedForAll(owner, _spender) - ); - } - - /** - * @dev Internal function to clear current approval of a given token ID - * Reverts if the given address is not indeed the owner of the token - * @param _owner owner of the token - * @param _tokenId uint256 ID of the token to be transferred - */ - function clearApproval(address _owner, uint256 _tokenId) internal { - require(ownerOf(_tokenId) == _owner); - if (tokenApprovals[_tokenId] != address(0)) { - tokenApprovals[_tokenId] = address(0); - } - } - - /** - * @dev Internal function to mint a new token - * Reverts if the given token ID already exists - * @param _to The address that will own the minted token - * @param _tokenId uint256 ID of the token to be minted by the msg.sender - */ - function _mint(address _to, uint256 _tokenId) internal { - require(_to != address(0)); - addNewTokenTo(_to, _tokenId); - emit Transfer(address(0), _to, _tokenId); - } - - - /** - * @dev Internal function to burn a specific token - * Reverts if the token does not exist - * @param _tokenId uint256 ID of the token being burned by the msg.sender - */ - function _burn(address _owner, uint256 _tokenId) internal { - clearApproval(_owner, _tokenId); - removeTokenFrom(_owner, _tokenId); - emit Transfer(_owner, address(0), _tokenId); - } - - function addNewTokenTo(address _to, uint256 _tokenId) internal { - require(tokenOwner[_tokenId] == address(0)); - tokenOwner[_tokenId] = _to; - } - - /** - * @dev Internal function to add a token ID to the list of a given address - * @param _to address representing the new owner of the given token ID - * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address - */ - function addTokenTo(address _to, uint256 _tokenId) internal { - require(tokenOwner[_tokenId] == address(0)); - tokenOwner[_tokenId] = _to; - // ownedTokensCount[_to] = ownedTokensCount[_to].add(1); - } - - /** - * @dev Internal function to remove a token ID from the list of a given address - * @param _from address representing the previous owner of the given token ID - * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address - */ - function removeTokenFrom(address _from, uint256 _tokenId) internal { - require(ownerOf(_tokenId) == _from); - // ownedTokensCount[_from] = ownedTokensCount[_from].sub(1); - tokenOwner[_tokenId] = address(0); - } - - /** - * @dev Internal function to invoke `onERC721Received` on a target address - * The call is not executed if the target address is not a contract - * @param _from address representing the previous owner of the given token ID - * @param _to target address that will receive the tokens - * @param _tokenId uint256 ID of the token to be transferred - * @param _data bytes optional data to send along with the call - * @return whether the call correctly returned the expected magic value - */ - function checkAndCallSafeTransfer( - address _from, - address _to, - uint256 _tokenId, - bytes memory _data - ) - internal - returns (bool) - { - if (!_to.isContract1()) { - return true; - } - bytes4 retval = ERC721Receiver(_to).onERC721Received( - msg.sender, _from, _tokenId, _data); - return (retval == ERC721_RECEIVED); - } - -} - - - -contract ERC721Enumerable is ERC721Basic { - function totalSupply() public view returns (uint256); - function tokenOfOwnerByIndex( - address _owner, - uint256 _index - ) - public - view - returns (uint256 _tokenId); - - function tokenByIndex(uint256 _index) public view returns (uint256); -} - -contract ERC721Metadata is ERC721Basic { - function name() external view returns (string memory _name); - function symbol() external view returns (string memory _symbol); - function tokenURI(uint256 _tokenId) public view returns (string memory); -} - -contract ERC721 is ERC721Basic, ERC721Enumerable, ERC721Metadata { - -} - - - - -library Strings { - - // via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol - function strConcat(string memory _a, string memory _b, string memory _c, string memory _d, string memory _e) internal pure returns (string memory ) { - bytes memory _ba = bytes(_a); - bytes memory _bb = bytes(_b); - bytes memory _bc = bytes(_c); - bytes memory _bd = bytes(_d); - bytes memory _be = bytes(_e); - string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length); - bytes memory babcde = bytes(abcde); - uint k = 0; - for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i]; - for (uint i = 0; i < _bb.length; i++) babcde[k++] = _bb[i]; - for (uint i = 0; i < _bc.length; i++) babcde[k++] = _bc[i]; - for (uint i = 0; i < _bd.length; i++) babcde[k++] = _bd[i]; - for (uint i = 0; i < _be.length; i++) babcde[k++] = _be[i]; - return string(babcde); - } - - function strConcat(string memory _a, string memory _b, string memory _c, string memory _d) internal pure returns (string memory ) { - return strConcat(_a, _b, _c, _d, ""); - } - - function strConcat(string memory _a, string memory _b, string memory _c) internal pure returns (string memory ) { - return strConcat(_a, _b, _c, "", ""); - } - - function strConcat(string memory _a, string memory _b) internal pure returns (string memory ) { - return strConcat(_a, _b, "", "", ""); - } - - function uint2str(uint i) internal pure returns (string memory ) { - if (i == 0) return "0"; - uint j = i; - uint len; - while (j != 0){ - len++; - j /= 10; - } - bytes memory bstr = new bytes(len); - uint k = len - 1; - while (i != 0){ - bstr[k--] = byte(uint8(48 + i % 10)); - i /= 10; - } - return string(bstr); - } -} - -contract ERC721Token is SupportsInterfaceWithLookup, ERC721BasicToken, ERC721 { - - using Strings for string; - - bytes4 private constant InterfaceId_ERC721Enumerable = 0x780e9d63; - /** - * 0x780e9d63 === - * bytes4(keccak256('totalSupply()')) ^ - * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^ - * bytes4(keccak256('tokenByIndex(uint256)')) - */ - - bytes4 private constant InterfaceId_ERC721Metadata = 0x5b5e139f; - /** - * 0x5b5e139f === - * bytes4(keccak256('name()')) ^ - * bytes4(keccak256('symbol()')) ^ - * bytes4(keccak256('tokenURI(uint256)')) - */ - - /*** Constants ***/ - // Configure these for your own deployment - string public constant NAME = "Gods Unchained"; - string public constant SYMBOL = "GODS"; - string public tokenMetadataBaseURI = "https://api.godsunchained.com/card/"; - - // Mapping from owner to list of owned token IDs - // EDITED: limit to 2^40 (around 1T) - mapping(address => uint40[]) internal ownedTokens; - - uint32[] ownedTokensIndex; - - /** - * @dev Constructor function - */ - constructor() public { - - // register the supported interfaces to conform to ERC721 via ERC165 - _registerInterface(InterfaceId_ERC721Enumerable); - _registerInterface(InterfaceId_ERC721Metadata); - } - - /** - * @dev Gets the token name - * @return string representing the token name - */ - function name() external view returns (string memory) { - return NAME; - } - - /** - * @dev Gets the token symbol - * @return string representing the token symbol - */ - function symbol() external view returns (string memory) { - return SYMBOL; - } - - /** - * @dev Returns an URI for a given token ID - * Throws if the token ID does not exist. May return an empty string. - * @param _tokenId uint256 ID of the token to query - */ - function tokenURI(uint256 _tokenId) public view returns (string memory) { - return Strings.strConcat( - tokenMetadataBaseURI, - Strings.uint2str(_tokenId) - ); - } - - /** - * @dev Gets the token ID at a given index of the tokens list of the requested owner - * @param _owner address owning the tokens list to be accessed - * @param _index uint256 representing the index to be accessed of the requested tokens list - * @return uint256 token ID at the given index of the tokens list owned by the requested address - */ - function tokenOfOwnerByIndex( - address _owner, - uint256 _index - ) - public - view - returns (uint256) - { - require(_index < balanceOf(_owner)); - return ownedTokens[_owner][_index]; - } - - /** - * @dev Gets the total amount of tokens stored by the contract - * @return uint256 representing the total amount of tokens - */ - function totalSupply() public view returns (uint256) { - return cards.length; - } - - /** - * @dev Gets the token ID at a given index of all the tokens in this contract - * Reverts if the index is greater or equal to the total number of tokens - * @param _index uint256 representing the index to be accessed of the tokens list - * @return uint256 token ID at the given index of the tokens list - */ - function tokenByIndex(uint256 _index) public view returns (uint256) { - require(_index < totalSupply()); - return _index; - } - - /** - * @dev Internal function to add a token ID to the list of a given address - * @param _to address representing the new owner of the given token ID - * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address - */ - function addTokenTo(address _to, uint256 _tokenId) internal { - super.addTokenTo(_to, _tokenId); - uint256 length = ownedTokens[_to].length; - // EDITED: prevent overflow - require(length == uint32(length)); - ownedTokens[_to].push(uint40(_tokenId)); - - ownedTokensIndex[_tokenId] = uint32(length); - } - - // EDITED - // have to have in order to use array rather than mapping - function addNewTokenTo(address _to, uint256 _tokenId) internal { - super.addNewTokenTo(_to, _tokenId); - uint256 length = ownedTokens[_to].length; - // EDITED: prevent overflow - require(length == uint32(length)); - ownedTokens[_to].push(uint40(_tokenId)); - ownedTokensIndex.push(uint32(length)); - } - - /** - * @dev Internal function to remove a token ID from the list of a given address - * @param _from address representing the previous owner of the given token ID - * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address - */ - function removeTokenFrom(address _from, uint256 _tokenId) internal { - super.removeTokenFrom(_from, _tokenId); - - uint32 tokenIndex = ownedTokensIndex[_tokenId]; - uint256 lastTokenIndex = ownedTokens[_from].length.sub(1); - uint40 lastToken = ownedTokens[_from][lastTokenIndex]; - - ownedTokens[_from][tokenIndex] = lastToken; - ownedTokens[_from][lastTokenIndex] = 0; - // Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to - // be zero. Then we can make sure that we will remove _tokenId from the ownedTokens list since we are first swapping - // the lastToken to the first position, and then dropping the element placed in the last position of the list - - ownedTokens[_from].length--; - ownedTokensIndex[_tokenId] = 0; - ownedTokensIndex[lastToken] = tokenIndex; - } - - /** - * @dev Gets the balance of the specified address - overrriden from previous to save gas - * @param _owner address to query the balance of - * @return uint256 representing the amount owned by the passed address - */ - function balanceOf(address _owner) public view returns (uint256) { - return ownedTokens[_owner].length; - } - -} - -contract CardOwnershipTwo is ERC721Token { - - uint public burnCount; - - function getActiveCards() public view returns (uint) { - return totalSupply() - burnCount; - } - - /** - * @param to : the address to which the card will be transferred - * @param id : the id of the card to be transferred - */ - function transfer(address to, uint id) public payable onlyOwnerOf(id) { - require(isTradable(cards[id].proto)); - require(to != address(0)); - - _transfer(msg.sender, to, id); - } - - function _transfer(address from, address to, uint id) internal { - - clearApproval(from, id); - - removeTokenFrom(from, id); - - addTokenTo(to, id); - - emit Transfer(from, to, id); - } - - /** - * @param to : the address to which the cards will be transferred - * @param ids : the ids of the cards to be transferred - */ - function transferAll(address to, uint[] memory ids) public payable { - for (uint i = 0; i < ids.length; i++) { - transfer(to, ids[i]); - } - } - - /** - * @param proposed : the claimed owner of the cards - * @param ids : the ids of the cards to check - * @return whether proposed owns all of the cards - */ - function ownsAll(address proposed, uint[] memory ids) public view returns (bool) { - require(ids.length > 0); - for (uint i = 0; i < ids.length; i++) { - if (!owns(proposed, ids[i])) { - return false; - } - } - return true; - } - - /** - * @param proposed : the claimed owner of the card - * @param id : the id of the card to check - * @return whether proposed owns the card - */ - function owns(address proposed, uint id) public view returns (bool) { - return ownerOf(id) == proposed; - } - - function burn(uint id) public onlyOwnerOf(id) { - burnCount++; - _burn(msg.sender, id); - } - - /** - * @param ids : the indices of the tokens to burn - */ - function burnAll(uint[] memory ids) public { - for (uint i = 0; i < ids.length; i++){ - burn(ids[i]); - } - } - - /** - * @param to : the address to approve for transfer - * @param id : the index of the card to be approved - */ - function approve(address to, uint id) public { - require(isTradable(cards[id].proto)); - super.approve(to, id); - } - - /** - * @param to : the address to approve for transfer - * @param ids : the indices of the cards to be approved - */ - function approveAll(address to, uint[] memory ids) public { - for (uint i = 0; i < ids.length; i++) { - approve(to, ids[i]); - } - } - - /** - * @param to : the address to which the token should be transferred - * @param id : the index of the token to transfer - */ - function transferFrom(address from, address to, uint id) public { - require(isTradable(cards[id].proto)); - super.transferFrom(from, to, id); - } - - /** - * @param to : the address to which the tokens should be transferred - * @param ids : the indices of the tokens to transfer - */ - function transferAllFrom(address from, address to, uint[] memory ids) public { - for (uint i = 0; i < ids.length; i++) { - transferFrom(from, to, ids[i]); - } - } - - /** - * @return the number of cards which have been burned - */ - function getBurnCount() public view returns (uint) { - return burnCount; - } - -} - -contract CardIntegrationTwo is CardOwnershipTwo { - - address[] public packs; - - event CardCreated(uint indexed id, uint16 proto, uint16 purity, address owner); - - function addPack(address approved) public onlyGovernor { - packs.push(approved); - } - - modifier onlyApprovedPacks { - require(_isApprovedPack()); - _; - } - - function _isApprovedPack() private view returns (bool) { - for (uint i = 0; i < packs.length; i++) { - if (msg.sender == address(packs[i])) { - return true; - } - } - return false; - } - - function createCard(address owner, uint16 proto, uint16 purity) public whenNotPaused onlyApprovedPacks returns (uint) { - ProtoCard memory card = protos[proto]; - require(card.season == currentSeason); - if (card.rarity == Rarity.Mythic) { - uint64 limit; - bool exists; - (limit, exists) = getLimit(proto); - require(!exists || limit > 0); - limits[proto].limit--; - } - return _createCard(owner, proto, purity); - } - - function _createCard(address owner, uint16 proto, uint16 purity) internal returns (uint) { - Card memory card = Card({ - proto: proto, - purity: purity - }); - - uint id = cards.push(card) - 1; - - _mint(owner, id); - - emit CardCreated(id, proto, purity, owner); - - return id; - } - - /*function combineCards(uint[] ids) public whenNotPaused { - require(ids.length == 5); - require(ownsAll(msg.sender, ids)); - Card memory first = cards[ids[0]]; - uint16 proto = first.proto; - uint8 shine = _getShine(first.purity); - require(shine < shineLimit); - uint16 puritySum = first.purity - (shine * 1000); - burn(ids[0]); - for (uint i = 1; i < ids.length; i++) { - Card memory next = cards[ids[i]]; - require(next.proto == proto); - require(_getShine(next.purity) == shine); - puritySum += (next.purity - (shine * 1000)); - burn(ids[i]); - } - uint16 newPurity = uint16(((shine + 1) * 1000) + (puritySum / ids.length)); - _createCard(msg.sender, proto, newPurity); - }*/ - - - // PURITY NOTES - // currently, we only - // however, to protect rarity, you'll never be abl - // this is enforced by the restriction in the create-card function - // no cards above this point can be found in packs - - - -} - -contract PreviousInterface { - - function ownerOf(uint id) public view returns (address); - - function getCard(uint id) public view returns (uint16, uint16); - - function totalSupply() public view returns (uint); - - function burnCount() public view returns (uint); - -} - -contract CardMigration is CardIntegrationTwo { - - constructor(PreviousInterface previous) public { - old = previous; - } - - // use interface to lower deployment cost - PreviousInterface old; - - mapping(uint => bool) public migrated; - - function migrate(uint id) public { - - require(!migrated[id]); - - migrated[id] = true; - - address owner = old.ownerOf(id); - - uint16 proto; - uint16 purity; - - (proto, purity) = old.getCard(id); - - _createCard(owner, proto, purity); - } - - function migrateAll(uint[] memory ids) public { - - for (uint i = 0; i < ids.length; i++){ - migrate(ids[i]); - } - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractScenario008.sol b/framework/src/test/resources/soliditycode_0.6.12/contractScenario008.sol deleted file mode 100644 index d039f7393d2..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractScenario008.sol +++ /dev/null @@ -1,2061 +0,0 @@ - - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) public onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address payable public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address payable _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() virtual public onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - emit Transfer(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(now), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - kitties.push(_kitty); - uint256 newKittenId = kitties.length - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - emit Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(address(0), _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -abstract contract ERC721 { - // Required methods - function totalSupply() virtual public view returns (uint256 total); - function balanceOf(address _owner) virtual public view returns (uint256 balance); - function ownerOf(uint256 _tokenId) virtual external view returns (address owner); - function approve(address _to, uint256 _tokenId) virtual external; - function transfer(address _to, uint256 _tokenId) virtual external; - function transferFrom(address _from, address _to, uint256 _tokenId) virtual external; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) virtual external view returns (bool); -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is ERC721, KittyBase { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external override view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public override view returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - override - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - override - external - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - emit Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - override - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() override public view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - override - external - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] memory _rawBytes, uint256 _stringLength) private view returns (string memory) { - string memory outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string calldata _preferredTransport) external view returns (string memory infoUrl) { - require( address(erc721Metadata) != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty memory _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty memory _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - emit Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.transfer(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, address(saleAuction)); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, address(siringAuction)); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid.value(msg.value - autoBirthFee)(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, address(saleAuction)); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(uint160(address(this))) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - constructor() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - emit ContractUpgrade(_v2Address); - } - -/// @notice No tipping! -/// @dev Reject all Ether from being sent here, unless it's from one of the -/// two auction contracts. (Hopefully, we can prevent user accidents.) -fallback() external payable { -require( -msg.sender == address(saleAuction) || -msg.sender == address(siringAuction) -); -} - -/// @notice Returns all the relevant information about a specific kitty. -/// @param _id The ID of the kitty of interest. -function getKitty(uint256 _id) -external -view -returns ( -bool isGestating, -bool isReady, -uint256 cooldownIndex, -uint256 nextActionAt, -uint256 siringWithId, -uint256 birthTime, -uint256 matronId, -uint256 sireId, -uint256 generation, -uint256 genes -) { -Kitty storage kit = kitties[_id]; - -// if this variable is 0 then it's not gestating -isGestating = (kit.siringWithId != 0); -isReady = (kit.cooldownEndBlock <= block.number); -cooldownIndex = uint256(kit.cooldownIndex); -nextActionAt = uint256(kit.cooldownEndBlock); -siringWithId = uint256(kit.siringWithId); -birthTime = uint256(kit.birthTime); -matronId = uint256(kit.matronId); -sireId = uint256(kit.sireId); -generation = uint256(kit.generation); -genes = kit.genes; -} - -/// @dev Override unpause so it requires all external contract addresses -/// to be set before contract can be unpaused. Also, we can't have -/// newContractAddress set either, because then the contract was upgraded. -/// @notice This is public rather than external so we can call super.unpause -/// without using an expensive CALL. - -function unpause() override public onlyCEO whenPaused { -require(address(saleAuction) != address(0)); -require(address(siringAuction) != address(0)); -require(address(geneScience) != address(0)); -require(newContractAddress == address(0)); - -// Actually unpause the contract. -super.unpause(); -} - -// @dev Allows the CFO to capture the balance available to the contract. -function withdrawBalance() external onlyCFO { -uint256 balance = address(this).balance; -// Subtract all the currently pregnant kittens we have, plus 1 of margin. -uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - -if (balance > subtractFees) { -cfoAddress.transfer(balance - subtractFees); -} -} -} - - - - - - - - - - - - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - -function isGeneScience() public pure returns (bool){ -return true; -} - -/// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor -/// @param genes1 genes of mom -/// @param genes2 genes of sire -/// @return the genes that are supposed to be passed down the child -function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - -return (genes1+genes2+targetBlock)/2; - - -} -} - - - - - - - - - - - - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { -/// @dev Given a token Id, returns a byte array that is supposed to be converted into string. -function getMetadata(uint256 _tokenId, string memory) public view returns (bytes32[4] memory buffer, uint256 count) { -if (_tokenId == 1) { -buffer[0] = "Hello World! :D"; -count = 15; -} else if (_tokenId == 2) { -buffer[0] = "I would definitely choose a medi"; -buffer[1] = "um length string."; -count = 49; -} else if (_tokenId == 3) { -buffer[0] = "Lorem ipsum dolor sit amet, mi e"; -buffer[1] = "st accumsan dapibus augue lorem,"; -buffer[2] = " tristique vestibulum id, libero"; -buffer[3] = " suscipit varius sapien aliquam."; -count = 128; -} -} -} - - - - - - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - -// Represents an auction on an NFT -struct Auction { -// Current owner of NFT -address payable seller; -// Price (in wei) at beginning of auction -uint128 startingPrice; -// Price (in wei) at end of auction -uint128 endingPrice; -// Duration (in seconds) of auction -uint64 duration; -// Time when auction started -// NOTE: 0 if this auction has been concluded -uint64 startedAt; -} - -// Reference to contract tracking NFT ownership -ERC721 public nonFungibleContract; - -// Cut owner takes on each auction, measured in basis points (1/100 of a percent). -// Values 0-10,000 map to 0%-100% -uint256 public ownerCut; - -// Map from token ID to their corresponding auction. -mapping (uint256 => Auction) tokenIdToAuction; - -event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); -event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); -event AuctionCancelled(uint256 tokenId); - -/// @dev Returns true if the claimant owns the token. -/// @param _claimant - Address claiming to own the token. -/// @param _tokenId - ID of token whose ownership to verify. -function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { -return (nonFungibleContract.ownerOf(_tokenId) == _claimant); -} - -/// @dev Escrows the NFT, assigning ownership to this contract. -/// Throws if the escrow fails. -/// @param _owner - Current owner address of token to escrow. -/// @param _tokenId - ID of token whose approval to verify. -function _escrow(address _owner, uint256 _tokenId) internal { -// it will throw if transfer fails -nonFungibleContract.transferFrom(_owner, address(this), _tokenId); -} - -/// @dev Transfers an NFT owned by this contract to another address. -/// Returns true if the transfer succeeds. -/// @param _receiver - Address to transfer NFT to. -/// @param _tokenId - ID of token to transfer. -function _transfer(address _receiver, uint256 _tokenId) internal { -// it will throw if transfer fails -nonFungibleContract.transfer(_receiver, _tokenId); -} - -/// @dev Adds an auction to the list of open auctions. Also fires the -/// AuctionCreated event. -/// @param _tokenId The ID of the token to be put on auction. -/// @param _auction Auction to add. -function _addAuction(uint256 _tokenId, Auction memory _auction) internal { -// Require that all auctions have a duration of -// at least one minute. (Keeps our math from getting hairy!) -require(_auction.duration >= 1 minutes); - -tokenIdToAuction[_tokenId] = _auction; - -emit AuctionCreated( -uint256(_tokenId), -uint256(_auction.startingPrice), -uint256(_auction.endingPrice), -uint256(_auction.duration) -); -} - -/// @dev Cancels an auction unconditionally. -function _cancelAuction(uint256 _tokenId, address _seller) internal { -_removeAuction(_tokenId); -_transfer(_seller, _tokenId); -emit AuctionCancelled(_tokenId); -} - -/// @dev Computes the price and transfers winnings. -/// Does NOT transfer ownership of token. -function _bid(uint256 _tokenId, uint256 _bidAmount) -internal -returns (uint256) -{ -// Get a reference to the auction struct -Auction storage auction = tokenIdToAuction[_tokenId]; - -// Explicitly check that this auction is currently live. -// (Because of how Ethereum mappings work, we can't just count -// on the lookup above failing. An invalid _tokenId will just -// return an auction object that is all zeros.) -require(_isOnAuction(auction)); - -// Check that the bid is greater than or equal to the current price -uint256 price = _currentPrice(auction); -require(_bidAmount >= price); - -// Grab a reference to the seller before the auction struct -// gets deleted. -address payable seller = auction.seller; - -// The bid is good! Remove the auction before sending the fees -// to the sender so we can't have a reentrancy attack. -_removeAuction(_tokenId); - -// Transfer proceeds to seller (if there are any!) -if (price > 0) { -// Calculate the auctioneer's cut. -// (NOTE: _computeCut() is guaranteed to return a -// value <= price, so this subtraction can't go negative.) -uint256 auctioneerCut = _computeCut(price); -uint256 sellerProceeds = price - auctioneerCut; - -// NOTE: Doing a transfer() in the middle of a complex -// method like this is generally discouraged because of -// reentrancy attacks and DoS attacks if the seller is -// a contract with an invalid fallback function. We explicitly -// guard against reentrancy attacks by removing the auction -// before calling transfer(), and the only thing the seller -// can DoS is the sale of their own asset! (And if it's an -// accident, they can call cancelAuction(). ) -seller.transfer(sellerProceeds); -} - -// Calculate any excess funds included with the bid. If the excess -// is anything worth worrying about, transfer it back to bidder. -// NOTE: We checked above that the bid amount is greater than or -// equal to the price so this cannot underflow. -uint256 bidExcess = _bidAmount - price; - -// Return the funds. Similar to the previous transfer, this is -// not susceptible to a re-entry attack because the auction is -// removed before any transfers occur. -msg.sender.transfer(bidExcess); - -// Tell the world! -emit AuctionSuccessful(_tokenId, price, msg.sender); - -return price; -} - -/// @dev Removes an auction from the list of open auctions. -/// @param _tokenId - ID of NFT on auction. -function _removeAuction(uint256 _tokenId) internal { -delete tokenIdToAuction[_tokenId]; -} - -/// @dev Returns true if the NFT is on auction. -/// @param _auction - Auction to check. -function _isOnAuction(Auction storage _auction) internal view returns (bool) { -return (_auction.startedAt > 0); -} - -/// @dev Returns current price of an NFT on auction. Broken into two -/// functions (this one, that computes the duration from the auction -/// structure, and the other that does the price computation) so we -/// can easily test that the price computation works correctly. -function _currentPrice(Auction storage _auction) -internal -view -returns (uint256) -{ -uint256 secondsPassed = 0; - -// A bit of insurance against negative values (or wraparound). -// Probably not necessary (since Ethereum guarnatees that the -// now variable doesn't ever go backwards). -if (now > _auction.startedAt) { -secondsPassed = now - _auction.startedAt; -} - -return _computeCurrentPrice( -_auction.startingPrice, -_auction.endingPrice, -_auction.duration, -secondsPassed -); -} - -/// @dev Computes the current price of an auction. Factored out -/// from _currentPrice so we can run extensive unit tests. -/// When testing, make this function public and turn on -/// `Current price computation` test suite. -function _computeCurrentPrice( -uint256 _startingPrice, -uint256 _endingPrice, -uint256 _duration, -uint256 _secondsPassed -) -internal -pure -returns (uint256) -{ -// NOTE: We don't use SafeMath (or similar) in this function because -// all of our public functions carefully cap the maximum values for -// time (at 64-bits) and currency (at 128-bits). _duration is -// also known to be non-zero (see the require() statement in -// _addAuction()) -if (_secondsPassed >= _duration) { -// We've reached the end of the dynamic pricing portion -// of the auction, just return the end price. -return _endingPrice; -} else { -// Starting price can be higher than ending price (and often is!), so -// this delta can be negative. -int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - -// This multiplication can't overflow, _secondsPassed will easily fit within -// 64-bits, and totalPriceChange will easily fit within 128-bits, their product -// will always fit within 256-bits. -int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - -// currentPriceChange can be negative, but if so, will have a magnitude -// less that _startingPrice. Thus, this result will always end up positive. -int256 currentPrice = int256(_startingPrice) + currentPriceChange; - -return uint256(currentPrice); -} -} - -/// @dev Computes owner's cut of a sale. -/// @param _price - Sale price of NFT. -function _computeCut(uint256 _price) internal view returns (uint256) { -// NOTE: We don't use SafeMath (or similar) in this function because -// all of our entry functions carefully cap the maximum values for -// currency (at 128-bits), and ownerCut <= 10000 (see the require() -// statement in the ClockAuction constructor). The result of this -// function is always guaranteed to be <= _price. -return _price * ownerCut / 10000; -} - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { -event Pause(); -event Unpause(); - -bool public paused = false; - - -/** - * @dev modifier to allow actions only when the contract IS paused - */ -modifier whenNotPaused() { -require(!paused); -_; -} - -/** - * @dev modifier to allow actions only when the contract IS NOT paused - */ -modifier whenPaused { -require(paused); -_; -} - -/** - * @dev called by the owner to pause, triggers stopped state - */ -function pause() onlyOwner whenNotPaused public returns (bool) { -paused = true; -emit Pause(); -return true; -} - -/** - * @dev called by the owner to unpause, returns to normal state - */ -function unpause() onlyOwner whenPaused public returns (bool) { -paused = false; -emit Unpause(); -return true; -} -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - -/// @dev The ERC-165 interface signature for ERC-721. -/// Ref: https://github.com/ethereum/EIPs/issues/165 -/// Ref: https://github.com/ethereum/EIPs/issues/721 -bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - -/// @dev Constructor creates a reference to the NFT ownership contract -/// and verifies the owner cut is in the valid range. -/// @param _nftAddress - address of a deployed contract implementing -/// the Nonfungible Interface. -/// @param _cut - percent cut the owner takes on each auction, must be -/// between 0-10,000. -constructor(address _nftAddress, uint256 _cut) public { -require(_cut <= 10000); -ownerCut = _cut; - -ERC721 candidateContract = ERC721(_nftAddress); -require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); -nonFungibleContract = candidateContract; -} - -/// @dev Remove all Ether from the contract, which is the owner's cuts -/// as well as any Ether sent directly to the contract address. -/// Always transfers to the NFT contract, but can be called either by -/// the owner or the NFT contract. -function withdrawBalance() external { -address payable nftAddress = address(uint160(address(nonFungibleContract))); - -require( -msg.sender == owner || -msg.sender == nftAddress -); -// We are using this boolean method to make sure that even if one fails it will still work -bool res = nftAddress.send(address(this).balance); -} - -/// @dev Creates and begins a new auction. -/// @param _tokenId - ID of token to auction, sender must be owner. -/// @param _startingPrice - Price of item (in wei) at beginning of auction. -/// @param _endingPrice - Price of item (in wei) at end of auction. -/// @param _duration - Length of time to move between starting -/// price and ending price (in seconds). -/// @param _seller - Seller, if not the message sender -function createAuction( -uint256 _tokenId, -uint256 _startingPrice, -uint256 _endingPrice, -uint256 _duration, -address payable _seller -) -virtual -external -whenNotPaused -{ -// Sanity check that no inputs overflow how many bits we've allocated -// to store them in the auction struct. -require(_startingPrice == uint256(uint128(_startingPrice))); -require(_endingPrice == uint256(uint128(_endingPrice))); -require(_duration == uint256(uint64(_duration))); - -require(_owns(msg.sender, _tokenId)); -_escrow(msg.sender, _tokenId); -Auction memory auction = Auction( -_seller, -uint128(_startingPrice), -uint128(_endingPrice), -uint64(_duration), -uint64(now) -); -_addAuction(_tokenId, auction); -} - -/// @dev Bids on an open auction, completing the auction and transferring -/// ownership of the NFT if enough Ether is supplied. -/// @param _tokenId - ID of token to bid on. -function bid(uint256 _tokenId) -external -payable -whenNotPaused -virtual -{ -// _bid will throw if the bid or funds transfer fails -_bid(_tokenId, msg.value); -_transfer(msg.sender, _tokenId); -} - -/// @dev Cancels an auction that hasn't been won yet. -/// Returns the NFT to original owner. -/// @notice This is a state-modifying function that can -/// be called while the contract is paused. -/// @param _tokenId - ID of token on auction -function cancelAuction(uint256 _tokenId) -external -{ -Auction storage auction = tokenIdToAuction[_tokenId]; -require(_isOnAuction(auction)); -address seller = auction.seller; -require(msg.sender == seller); -_cancelAuction(_tokenId, seller); -} - -/// @dev Cancels an auction when the contract is paused. -/// Only the owner may do this, and NFTs are returned to -/// the seller. This should only be used in emergencies. -/// @param _tokenId - ID of the NFT on auction to cancel. -function cancelAuctionWhenPaused(uint256 _tokenId) -whenPaused -onlyOwner -external -{ -Auction storage auction = tokenIdToAuction[_tokenId]; -require(_isOnAuction(auction)); -_cancelAuction(_tokenId, auction.seller); -} - -/// @dev Returns auction info for an NFT on auction. -/// @param _tokenId - ID of NFT on auction. -function getAuction(uint256 _tokenId) -external -view -returns -( -address seller, -uint256 startingPrice, -uint256 endingPrice, -uint256 duration, -uint256 startedAt -) { -Auction storage auction = tokenIdToAuction[_tokenId]; -require(_isOnAuction(auction)); -return ( -auction.seller, -auction.startingPrice, -auction.endingPrice, -auction.duration, -auction.startedAt -); -} - -/// @dev Returns the current price of an auction. -/// @param _tokenId - ID of the token price we are checking. -function getCurrentPrice(uint256 _tokenId) -external -view -returns (uint256) -{ -Auction storage auction = tokenIdToAuction[_tokenId]; -require(_isOnAuction(auction)); -return _currentPrice(auction); -} - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - -// @dev Sanity check that allows us to ensure that we are pointing to the -// right auction in our setSiringAuctionAddress() call. -bool public isSiringClockAuction = true; - -// Delegate constructor -constructor(address _nftAddr, uint256 _cut) public -ClockAuction(_nftAddr, _cut) {} - -/// @dev Creates and begins a new auction. Since this function is wrapped, -/// require sender to be KittyCore contract. -/// @param _tokenId - ID of token to auction, sender must be owner. -/// @param _startingPrice - Price of item (in wei) at beginning of auction. -/// @param _endingPrice - Price of item (in wei) at end of auction. -/// @param _duration - Length of auction (in seconds). -/// @param _seller - Seller, if not the message sender -function createAuction( -uint256 _tokenId, -uint256 _startingPrice, -uint256 _endingPrice, -uint256 _duration, -address payable _seller -) -override -external -{ -// Sanity check that no inputs overflow how many bits we've allocated -// to store them in the auction struct. -require(_startingPrice == uint256(uint128(_startingPrice))); -require(_endingPrice == uint256(uint128(_endingPrice))); -require(_duration == uint256(uint64(_duration))); - -require(msg.sender == address(nonFungibleContract)); -_escrow(_seller, _tokenId); -Auction memory auction = Auction( -_seller, -uint128(_startingPrice), -uint128(_endingPrice), -uint64(_duration), -uint64(now) -); -_addAuction(_tokenId, auction); -} - -/// @dev Places a bid for siring. Requires the sender -/// is the KittyCore contract because all bid methods -/// should be wrapped. Also returns the kitty to the -/// seller rather than the winner. -function bid(uint256 _tokenId) -external -payable -override -{ -require(msg.sender == address(nonFungibleContract)); -address seller = tokenIdToAuction[_tokenId].seller; -// _bid checks that token ID is valid and will throw if bid fails -_bid(_tokenId, msg.value); -// We transfer the kitty back to the seller, the winner will get -// the offspring -_transfer(seller, _tokenId); -} - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - -// @dev Sanity check that allows us to ensure that we are pointing to the -// right auction in our setSaleAuctionAddress() call. -bool public isSaleClockAuction = true; - -// Tracks last 5 sale price of gen0 kitty sales -uint256 public gen0SaleCount; -uint256[5] public lastGen0SalePrices; - -// Delegate constructor -constructor(address _nftAddr, uint256 _cut) public -ClockAuction(_nftAddr, _cut) {} - -/// @dev Creates and begins a new auction. -/// @param _tokenId - ID of token to auction, sender must be owner. -/// @param _startingPrice - Price of item (in wei) at beginning of auction. -/// @param _endingPrice - Price of item (in wei) at end of auction. -/// @param _duration - Length of auction (in seconds). -/// @param _seller - Seller, if not the message sender -function createAuction( -uint256 _tokenId, -uint256 _startingPrice, -uint256 _endingPrice, -uint256 _duration, -address payable _seller -) -override -external -{ -// Sanity check that no inputs overflow how many bits we've allocated -// to store them in the auction struct. -require(_startingPrice == uint256(uint128(_startingPrice))); -require(_endingPrice == uint256(uint128(_endingPrice))); -require(_duration == uint256(uint64(_duration))); - -require(msg.sender == address(nonFungibleContract)); -_escrow(_seller, _tokenId); -Auction memory auction = Auction( -_seller, -uint128(_startingPrice), -uint128(_endingPrice), -uint64(_duration), -uint64(now) -); -_addAuction(_tokenId, auction); -} - -/// @dev Updates lastSalePrice if seller is the nft contract -/// Otherwise, works the same as default bid method. -function bid(uint256 _tokenId) -external -override -payable -{ -// _bid verifies token ID size -address seller = tokenIdToAuction[_tokenId].seller; -uint256 price = _bid(_tokenId, msg.value); -_transfer(msg.sender, _tokenId); - -// If not a gen0 auction, exit -if (seller == address(nonFungibleContract)) { -// Track gen0 sale prices -lastGen0SalePrices[gen0SaleCount % 5] = price; -gen0SaleCount++; -} -} - -function averageGen0SalePrice() external view returns (uint256) { -uint256 sum = 0; -for (uint256 i = 0; i < 5; i++) { -sum += lastGen0SalePrices[i]; -} -return sum / 5; -} - -} - - - - - - - diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractScenario009.sol b/framework/src/test/resources/soliditycode_0.6.12/contractScenario009.sol deleted file mode 100644 index 52fa63e90ac..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractScenario009.sol +++ /dev/null @@ -1,51 +0,0 @@ - - -library Set { - // We define a new struct datatype that will be used to - // hold its data in the calling contract. - struct Data { mapping(uint => bool) flags; } - - // Note that the first parameter is of type "storage - // reference" and thus only its storage address and not - // its contents is passed as part of the call. This is a - // special feature of library functions. It is idiomatic - // to call the first parameter 'self', if the function can - // be seen as a method of that object. - function insert (Data storage self, uint value) public - returns (bool) - { - if (self.flags[value]) - return false; // already there - self.flags[value] = true; - return true; - } - - function remove(Data storage self, uint value) public - returns (bool) - { - if (!self.flags[value]) - return false; // not there - self.flags[value] = false; - return true; - } - - function contains(Data storage self, uint value) public - returns (bool) - { - return self.flags[value]; - } -} - - -contract C { - Set.Data knownValues; - - function register(uint value) public { - // The library functions can be called without a - // specific instance of the library, since the - // "instance" will be the current contract. - if (!Set.insert(knownValues, value)) - revert(); - } - // In this contract, we can also directly access knownValues.flags, if we want. -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractScenario010.sol b/framework/src/test/resources/soliditycode_0.6.12/contractScenario010.sol deleted file mode 100644 index 4e299efecad..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractScenario010.sol +++ /dev/null @@ -1,107 +0,0 @@ - - -contract TRON_ERC721 { - //name - function name() view public returns (string memory name){ - return "Tron ERC721 Token"; - } - //symbol - function symbol() view public returns (string memory symbol){ - return "T721T"; - } - - //totalSupply - - function totalSupply() view public returns (uint256 supply){ - uint256 totalSupply = 1000000000000; - return totalSupply; - } - - mapping(address => uint) private balances; - function balanceOf(address _owner) view public returns (uint balance) - { - return balances[_owner]; - } - - - mapping(uint256 => address) private tokenOwners; - mapping(uint256 => bool) private tokenExists; - function ownerOf(uint256 _tokenId) view public returns (address owner) { - require(tokenExists[_tokenId]); - return tokenOwners[_tokenId]; - } - - - mapping(address => mapping (address => uint256)) allowed; - function approve(address _to, uint256 _tokenId) public{ - require(msg.sender == ownerOf(_tokenId)); - require(msg.sender != _to); - allowed[msg.sender][_to] = _tokenId; - emit Approval(msg.sender, _to, _tokenId); - } - - - function takeOwnership(uint256 _tokenId) public { - require(tokenExists[_tokenId]); - address oldOwner = ownerOf(_tokenId); - address newOwner = msg.sender; - require(newOwner != oldOwner); - require(allowed[oldOwner][newOwner] == _tokenId); - balances[oldOwner] -= 1; - tokenOwners[_tokenId] = newOwner; - balances[newOwner] += 1; - emit Transfer(oldOwner, newOwner, _tokenId); - } - - - mapping(address => mapping(uint256 => uint256)) private ownerTokens; - function removeFromTokenList(address owner, uint256 _tokenId) private { - for(uint256 i = 0;ownerTokens[owner][i] != _tokenId;i++){ - ownerTokens[owner][i] = 0; - } - } - - function transfer(address _to, uint256 _tokenId) public{ - address currentOwner = msg.sender; - address newOwner = _to; - require(tokenExists[_tokenId]); - require(currentOwner == ownerOf(_tokenId)); - require(currentOwner != newOwner); - require(newOwner != address(0)); - address oldOwner =currentOwner; - removeFromTokenList(oldOwner,_tokenId); - balances[oldOwner] -= 1; - tokenOwners[_tokenId] = newOwner; - balances[newOwner] += 1; - emit Transfer(oldOwner, newOwner, _tokenId); - } - - function transferFrom(address _from,address _to, uint256 _tokenId) public{ - address currentOwner = _from; - address newOwner = _to; - require(tokenExists[_tokenId]); - require(currentOwner == ownerOf(_tokenId)); - require(currentOwner != newOwner); - require(newOwner != address(0)); - address oldOwner =currentOwner; - removeFromTokenList(oldOwner,_tokenId); - balances[oldOwner] -= 1; - tokenOwners[_tokenId] = newOwner; - balances[newOwner] += 1; - emit Transfer(oldOwner, newOwner, _tokenId); - } - - - function tokenOfOwnerByIndex(address _owner, uint256 _index) view public returns (uint tokenId){ - return ownerTokens[_owner][_index]; - } - - - mapping(uint256 => string) tokenLinks; - function tokenMetadata(uint256 _tokenId) view public returns (string memory infoUrl) { - return tokenLinks[_tokenId]; - } - // Events - event Transfer(address indexed _from, address indexed _to, uint256 _tokenId); - event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId); -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractScenario011.sol b/framework/src/test/resources/soliditycode_0.6.12/contractScenario011.sol deleted file mode 100644 index 041d298cf32..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractScenario011.sol +++ /dev/null @@ -1,2060 +0,0 @@ - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) public onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address payable public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address payable _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() public virtual onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - emit Transfer(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(now), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - kitties.push(_kitty); - uint256 newKittenId = kitties.length - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - emit Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(address(0), _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -abstract contract ERC721 { - // Required methods - function totalSupply() public virtual view returns (uint256 total); - function balanceOf(address _owner) public virtual view returns (uint256 balance); - function ownerOf(uint256 _tokenId) external virtual view returns (address owner); - function approve(address _to, uint256 _tokenId) external virtual; - function transfer(address _to, uint256 _tokenId) external virtual; - function transferFrom(address _from, address _to, uint256 _tokenId) external virtual; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) external virtual view returns (bool); -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is ERC721, KittyBase { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external override view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public view override returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - override - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - external - override - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - emit Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - external - override - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() public override view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - external - override - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] memory _rawBytes, uint256 _stringLength) private view returns (string memory) { - string memory outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string calldata _preferredTransport) external view returns (string memory infoUrl) { - require( address(erc721Metadata) != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2 ; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty memory _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty memory _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - emit Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.transfer(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, address(saleAuction)); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, address(siringAuction)); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid.value(msg.value - autoBirthFee)(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10 ; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, address(saleAuction)); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(uint160(address(this))) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - constructor() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - emit ContractUpgrade(_v2Address); - } - - /// @notice No tipping! - /// @dev Reject all Ether from being sent here, unless it's from one of the - /// two auction contracts. (Hopefully, we can prevent user accidents.) - fallback() external payable { - require( - msg.sender == address(saleAuction) || - msg.sender == address(siringAuction) - ); - } - - /// @notice Returns all the relevant information about a specific kitty. - /// @param _id The ID of the kitty of interest. - function getKitty(uint256 _id) - external - view - returns ( - bool isGestating, - bool isReady, - uint256 cooldownIndex, - uint256 nextActionAt, - uint256 siringWithId, - uint256 birthTime, - uint256 matronId, - uint256 sireId, - uint256 generation, - uint256 genes - ) { - Kitty storage kit = kitties[_id]; - - // if this variable is 0 then it's not gestating - isGestating = (kit.siringWithId != 0); - isReady = (kit.cooldownEndBlock <= block.number); - cooldownIndex = uint256(kit.cooldownIndex); - nextActionAt = uint256(kit.cooldownEndBlock); - siringWithId = uint256(kit.siringWithId); - birthTime = uint256(kit.birthTime); - matronId = uint256(kit.matronId); - sireId = uint256(kit.sireId); - generation = uint256(kit.generation); - genes = kit.genes; - } - - /// @dev Override unpause so it requires all external contract addresses - /// to be set before contract can be unpaused. Also, we can't have - /// newContractAddress set either, because then the contract was upgraded. - /// @notice This is public rather than external so we can call super.unpause - /// without using an expensive CALL. - - function unpause() public override onlyCEO whenPaused { - require(address(saleAuction) != address(0)); - require(address(siringAuction) != address(0)); - require(address(geneScience) != address(0)); - require(newContractAddress == address(0)); - - // Actually unpause the contract. - super.unpause(); - } - - // @dev Allows the CFO to capture the balance available to the contract. - function withdrawBalance() external onlyCFO { - uint256 balance = address(this).balance; - // Subtract all the currently pregnant kittens we have, plus 1 of margin. - uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - - if (balance > subtractFees) { - cfoAddress.transfer(balance - subtractFees); - } - } -} - - - - - - - - - - - - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - - function isGeneScience() public pure returns (bool){ - return true; - } - - /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor - /// @param genes1 genes of mom - /// @param genes2 genes of sire - /// @return the genes that are supposed to be passed down the child - function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - - return (genes1+genes2+targetBlock)/2; - - - } -} - - - - - - - - - - - - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { - /// @dev Given a token Id, returns a byte array that is supposed to be converted into string. - function getMetadata(uint256 _tokenId, string memory) public view returns (bytes32[4] memory buffer, uint256 count) { - if (_tokenId == 1) { - buffer[0] = "Hello World! :D"; - count = 15; - } else if (_tokenId == 2) { - buffer[0] = "I would definitely choose a medi"; - buffer[1] = "um length string."; - count = 49; - } else if (_tokenId == 3) { - buffer[0] = "Lorem ipsum dolor sit amet, mi e"; - buffer[1] = "st accumsan dapibus augue lorem,"; - buffer[2] = " tristique vestibulum id, libero"; - buffer[3] = " suscipit varius sapien aliquam."; - count = 128; - } - } -} - - - - - - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - - // Represents an auction on an NFT - struct Auction { - // Current owner of NFT - address payable seller; - // Price (in wei) at beginning of auction - uint128 startingPrice; - // Price (in wei) at end of auction - uint128 endingPrice; - // Duration (in seconds) of auction - uint64 duration; - // Time when auction started - // NOTE: 0 if this auction has been concluded - uint64 startedAt; - } - - // Reference to contract tracking NFT ownership - ERC721 public nonFungibleContract; - - // Cut owner takes on each auction, measured in basis points (1/100 of a percent). - // Values 0-10,000 map to 0%-100% - uint256 public ownerCut; - - // Map from token ID to their corresponding auction. - mapping (uint256 => Auction) tokenIdToAuction; - - event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); - event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); - event AuctionCancelled(uint256 tokenId); - - /// @dev Returns true if the claimant owns the token. - /// @param _claimant - Address claiming to own the token. - /// @param _tokenId - ID of token whose ownership to verify. - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return (nonFungibleContract.ownerOf(_tokenId) == _claimant); - } - - /// @dev Escrows the NFT, assigning ownership to this contract. - /// Throws if the escrow fails. - /// @param _owner - Current owner address of token to escrow. - /// @param _tokenId - ID of token whose approval to verify. - function _escrow(address _owner, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transferFrom(_owner, address(this), _tokenId); - } - - /// @dev Transfers an NFT owned by this contract to another address. - /// Returns true if the transfer succeeds. - /// @param _receiver - Address to transfer NFT to. - /// @param _tokenId - ID of token to transfer. - function _transfer(address _receiver, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transfer(_receiver, _tokenId); - } - - /// @dev Adds an auction to the list of open auctions. Also fires the - /// AuctionCreated event. - /// @param _tokenId The ID of the token to be put on auction. - /// @param _auction Auction to add. - function _addAuction(uint256 _tokenId, Auction memory _auction) internal { - // Require that all auctions have a duration of - // at least one minute. (Keeps our math from getting hairy!) - require(_auction.duration >= 1 minutes); - - tokenIdToAuction[_tokenId] = _auction; - - emit AuctionCreated( - uint256(_tokenId), - uint256(_auction.startingPrice), - uint256(_auction.endingPrice), - uint256(_auction.duration) - ); - } - - /// @dev Cancels an auction unconditionally. - function _cancelAuction(uint256 _tokenId, address _seller) internal { - _removeAuction(_tokenId); - _transfer(_seller, _tokenId); - emit AuctionCancelled(_tokenId); - } - - /// @dev Computes the price and transfers winnings. - /// Does NOT transfer ownership of token. - function _bid(uint256 _tokenId, uint256 _bidAmount) - internal - returns (uint256) - { - // Get a reference to the auction struct - Auction storage auction = tokenIdToAuction[_tokenId]; - - // Explicitly check that this auction is currently live. - // (Because of how Ethereum mappings work, we can't just count - // on the lookup above failing. An invalid _tokenId will just - // return an auction object that is all zeros.) - require(_isOnAuction(auction)); - - // Check that the bid is greater than or equal to the current price - uint256 price = _currentPrice(auction); - require(_bidAmount >= price); - - // Grab a reference to the seller before the auction struct - // gets deleted. - address payable seller = auction.seller; - - // The bid is good! Remove the auction before sending the fees - // to the sender so we can't have a reentrancy attack. - _removeAuction(_tokenId); - - // Transfer proceeds to seller (if there are any!) - if (price > 0) { - // Calculate the auctioneer's cut. - // (NOTE: _computeCut() is guaranteed to return a - // value <= price, so this subtraction can't go negative.) - uint256 auctioneerCut = _computeCut(price); - uint256 sellerProceeds = price - auctioneerCut; - - // NOTE: Doing a transfer() in the middle of a complex - // method like this is generally discouraged because of - // reentrancy attacks and DoS attacks if the seller is - // a contract with an invalid fallback function. We explicitly - // guard against reentrancy attacks by removing the auction - // before calling transfer(), and the only thing the seller - // can DoS is the sale of their own asset! (And if it's an - // accident, they can call cancelAuction(). ) - seller.transfer(sellerProceeds); - } - - // Calculate any excess funds included with the bid. If the excess - // is anything worth worrying about, transfer it back to bidder. - // NOTE: We checked above that the bid amount is greater than or - // equal to the price so this cannot underflow. - uint256 bidExcess = _bidAmount - price; - - // Return the funds. Similar to the previous transfer, this is - // not susceptible to a re-entry attack because the auction is - // removed before any transfers occur. - msg.sender.transfer(bidExcess); - - // Tell the world! - emit AuctionSuccessful(_tokenId, price, msg.sender); - - return price; - } - - /// @dev Removes an auction from the list of open auctions. - /// @param _tokenId - ID of NFT on auction. - function _removeAuction(uint256 _tokenId) internal { - delete tokenIdToAuction[_tokenId]; - } - - /// @dev Returns true if the NFT is on auction. - /// @param _auction - Auction to check. - function _isOnAuction(Auction storage _auction) internal view returns (bool) { - return (_auction.startedAt > 0); - } - - /// @dev Returns current price of an NFT on auction. Broken into two - /// functions (this one, that computes the duration from the auction - /// structure, and the other that does the price computation) so we - /// can easily test that the price computation works correctly. - function _currentPrice(Auction storage _auction) - internal - view - returns (uint256) - { - uint256 secondsPassed = 0; - - // A bit of insurance against negative values (or wraparound). - // Probably not necessary (since Ethereum guarnatees that the - // now variable doesn't ever go backwards). - if (now > _auction.startedAt) { - secondsPassed = now - _auction.startedAt; - } - - return _computeCurrentPrice( - _auction.startingPrice, - _auction.endingPrice, - _auction.duration, - secondsPassed - ); - } - - /// @dev Computes the current price of an auction. Factored out - /// from _currentPrice so we can run extensive unit tests. - /// When testing, make this function public and turn on - /// `Current price computation` test suite. - function _computeCurrentPrice( - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - uint256 _secondsPassed - ) - internal - pure - returns (uint256) - { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our public functions carefully cap the maximum values for - // time (at 64-bits) and currency (at 128-bits). _duration is - // also known to be non-zero (see the require() statement in - // _addAuction()) - if (_secondsPassed >= _duration) { - // We've reached the end of the dynamic pricing portion - // of the auction, just return the end price. - return _endingPrice; - } else { - // Starting price can be higher than ending price (and often is!), so - // this delta can be negative. - int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - - // This multiplication can't overflow, _secondsPassed will easily fit within - // 64-bits, and totalPriceChange will easily fit within 128-bits, their product - // will always fit within 256-bits. - int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - - // currentPriceChange can be negative, but if so, will have a magnitude - // less that _startingPrice. Thus, this result will always end up positive. - int256 currentPrice = int256(_startingPrice) + currentPriceChange; - - return uint256(currentPrice); - } - } - - /// @dev Computes owner's cut of a sale. - /// @param _price - Sale price of NFT. - function _computeCut(uint256 _price) internal view returns (uint256) { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our entry functions carefully cap the maximum values for - // currency (at 128-bits), and ownerCut <= 10000 (see the require() - // statement in the ClockAuction constructor). The result of this - // function is always guaranteed to be <= _price. - return _price * ownerCut / 10000; - } - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { - event Pause(); - event Unpause(); - - bool public paused = false; - - - /** - * @dev modifier to allow actions only when the contract IS paused - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev modifier to allow actions only when the contract IS NOT paused - */ - modifier whenPaused { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyOwner whenNotPaused public returns (bool) { - paused = true; - emit Pause(); - return true; - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyOwner whenPaused public returns (bool) { - paused = false; - emit Unpause(); - return true; - } -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - - /// @dev The ERC-165 interface signature for ERC-721. - /// Ref: https://github.com/ethereum/EIPs/issues/165 - /// Ref: https://github.com/ethereum/EIPs/issues/721 - bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - - /// @dev Constructor creates a reference to the NFT ownership contract - /// and verifies the owner cut is in the valid range. - /// @param _nftAddress - address of a deployed contract implementing - /// the Nonfungible Interface. - /// @param _cut - percent cut the owner takes on each auction, must be - /// between 0-10,000. - constructor(address _nftAddress, uint256 _cut) public { - require(_cut <= 10000); - ownerCut = _cut; - - ERC721 candidateContract = ERC721(_nftAddress); - require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); - nonFungibleContract = candidateContract; - } - - /// @dev Remove all Ether from the contract, which is the owner's cuts - /// as well as any Ether sent directly to the contract address. - /// Always transfers to the NFT contract, but can be called either by - /// the owner or the NFT contract. - function withdrawBalance() external { - address payable nftAddress = address(uint160(address(nonFungibleContract))); - - require( - msg.sender == owner || - msg.sender == nftAddress - ); - // We are using this boolean method to make sure that even if one fails it will still work - bool res = nftAddress.send(address(this).balance); - } - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of time to move between starting - /// price and ending price (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - virtual - whenNotPaused - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(_owns(msg.sender, _tokenId)); - _escrow(msg.sender, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Bids on an open auction, completing the auction and transferring - /// ownership of the NFT if enough Ether is supplied. - /// @param _tokenId - ID of token to bid on. - function bid(uint256 _tokenId) - external - payable - virtual - whenNotPaused - { - // _bid will throw if the bid or funds transfer fails - _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - } - - /// @dev Cancels an auction that hasn't been won yet. - /// Returns the NFT to original owner. - /// @notice This is a state-modifying function that can - /// be called while the contract is paused. - /// @param _tokenId - ID of token on auction - function cancelAuction(uint256 _tokenId) - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - address seller = auction.seller; - require(msg.sender == seller); - _cancelAuction(_tokenId, seller); - } - - /// @dev Cancels an auction when the contract is paused. - /// Only the owner may do this, and NFTs are returned to - /// the seller. This should only be used in emergencies. - /// @param _tokenId - ID of the NFT on auction to cancel. - function cancelAuctionWhenPaused(uint256 _tokenId) - whenPaused - onlyOwner - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - _cancelAuction(_tokenId, auction.seller); - } - - /// @dev Returns auction info for an NFT on auction. - /// @param _tokenId - ID of NFT on auction. - function getAuction(uint256 _tokenId) - external - view - returns - ( - address seller, - uint256 startingPrice, - uint256 endingPrice, - uint256 duration, - uint256 startedAt - ) { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return ( - auction.seller, - auction.startingPrice, - auction.endingPrice, - auction.duration, - auction.startedAt - ); - } - - /// @dev Returns the current price of an auction. - /// @param _tokenId - ID of the token price we are checking. - function getCurrentPrice(uint256 _tokenId) - external - view - returns (uint256) - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return _currentPrice(auction); - } - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSiringAuctionAddress() call. - bool public isSiringClockAuction = true; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. Since this function is wrapped, - /// require sender to be KittyCore contract. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - override - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Places a bid for siring. Requires the sender - /// is the KittyCore contract because all bid methods - /// should be wrapped. Also returns the kitty to the - /// seller rather than the winner. - function bid(uint256 _tokenId) - external - payable - override - { - require(msg.sender == address(nonFungibleContract)); - address seller = tokenIdToAuction[_tokenId].seller; - // _bid checks that token ID is valid and will throw if bid fails - _bid(_tokenId, msg.value); - // We transfer the kitty back to the seller, the winner will get - // the offspring - _transfer(seller, _tokenId); - } - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSaleAuctionAddress() call. - bool public isSaleClockAuction = true; - - // Tracks last 5 sale price of gen0 kitty sales - uint256 public gen0SaleCount; - uint256[5] public lastGen0SalePrices; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - override - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Updates lastSalePrice if seller is the nft contract - /// Otherwise, works the same as default bid method. - function bid(uint256 _tokenId) - external - payable - override - { - // _bid verifies token ID size - address seller = tokenIdToAuction[_tokenId].seller; - uint256 price = _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - - // If not a gen0 auction, exit - if (seller == address(nonFungibleContract)) { - // Track gen0 sale prices - lastGen0SalePrices[gen0SaleCount % 5] = price; - gen0SaleCount++; - } - } - - function averageGen0SalePrice() external view returns (uint256) { - uint256 sum = 0; - for (uint256 i = 0; i < 5; i++) { - sum += lastGen0SalePrices[i]; - } - return sum / 5; - } - -} - - - - - - - diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractScenario012.sol b/framework/src/test/resources/soliditycode_0.6.12/contractScenario012.sol deleted file mode 100644 index 7fea2b1ccf1..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractScenario012.sol +++ /dev/null @@ -1,57 +0,0 @@ - -contract PayTest { - -uint256 public n; -constructor() payable public{ -n = 0; -} - -function nPlusOne() public{ -n = n+1; -} - -//get current contract balance -function getBalance() payable public returns (uint) { -return address(this).balance; -} - -function getSenderBalance() public view returns(address, uint) { -return (msg.sender, msg.sender.balance); -} - -address public user; - -//deposit 1 coin to msg.sender -function depositOneCoin() payable public returns(bool success){ -return msg.sender.send(1); -} - -// function transferOneCoin() payable public returns(){ -// address(msg.sender).transfer(1); -// } - -// function depositOneCoin() payable public returns(address addr, uint amount, bool success){ -// return (msg.sender, msg.value, msg.sender.send(1)); -// } - -//deposit coin to msg.sender -function deposit(uint256 money) payable public returns(bool success){ -return msg.sender.send(money); -} -// function deposit(uint money) payable public returns(address addr, uint amount, bool success){ -// return (msg.sender, msg.value, msg.sender.send(money)); -// } - -// fallback() payable { -// msg.sender.send(1); -// } - -function sendToAddress(address payable _receiver) payable public{ -_receiver.transfer(msg.value); -} - -function sendToAddress2(address payable _receiver) payable public{ -_receiver.transfer(5); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractScenario013.sol b/framework/src/test/resources/soliditycode_0.6.12/contractScenario013.sol deleted file mode 100644 index 93b7905679b..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractScenario013.sol +++ /dev/null @@ -1,8 +0,0 @@ - -contract timetest { - -function time() public{ -require(1 trx == 1000000 sun); - -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractScenario014.sol b/framework/src/test/resources/soliditycode_0.6.12/contractScenario014.sol deleted file mode 100644 index 9f423d1b1ab..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractScenario014.sol +++ /dev/null @@ -1,34 +0,0 @@ - -contract Contract1 { - constructor() public payable{} - function send5SunToReceiver(address payable _receiver) payable public{ - _receiver.transfer(5); - } -} -contract contract2 { - address public payContract; - - constructor(address _add) payable public{ - payContract = _add; - } - - function triggerContract1(address _receiver) payable public{ - payContract.call(abi.encodeWithSignature("send5SunToReceiver(address)",_receiver)); - } - - function triggerContract1ButRevert(address _receiver) payable public{ - payContract.call(abi.encodeWithSignature("send5SunToReceiver(address)",_receiver)); - require(1 == 2); - } - -} -contract contract3 { - address public payContract; - constructor(address _add) payable public{ - payContract = _add; - } - - function triggerContract2(address _receiver) payable public{ - payContract.call(abi.encodeWithSignature("triggerContract1(address)",_receiver)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTest.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTest.sol deleted file mode 100644 index 9a72b4a53b4..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTest.sol +++ /dev/null @@ -1,19 +0,0 @@ - - -contract Test{ - -function a() public returns (uint){ - -uint256 count = 0; - -for (uint256 i = 1; i > 0; i++) { - -count++; - -} - -return count; - -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractToMathedFeed.sol b/framework/src/test/resources/soliditycode_0.6.12/contractToMathedFeed.sol deleted file mode 100644 index d9df9d9c10d..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractToMathedFeed.sol +++ /dev/null @@ -1,21 +0,0 @@ - - -contract ToMathedFeed { - uint public i=1; - function ToMathed (uint value) public { - i=value; - } -} - -contract ToMathedUseINContract { - function ToMathedIUseNR(address a,uint256 n) public returns(bool){ - address payContract=a; - (bool success, bytes memory data) = payContract.call(abi.encodeWithSignature("ToMathedNot(uint256)",n)); - return success; - } - function ToMathedIUseNRE(address a,uint256 value) public returns(bool){ - address payContract=a; - (bool success, bytes memory data) = payContract.call(abi.encodeWithSignature("ToMathed(uint256)",value)); - return success; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTransferToken001.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTransferToken001.sol deleted file mode 100644 index 0edbbfbb44a..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTransferToken001.sol +++ /dev/null @@ -1,22 +0,0 @@ -contract A { - address public a; - constructor() public payable{} - function kill(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - function newB() public payable returns(address){ - B bAddress=new B(); - a= address(bAddress); - return a; - - } - - } - -contract B{ - constructor() public payable {} - fallback() external payable {} - function kill(address payable toAddress) payable public{ - selfdestruct(toAddress); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken001.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken001.sol deleted file mode 100644 index ea28f4a62b6..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken001.sol +++ /dev/null @@ -1,30 +0,0 @@ - - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken002.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken002.sol deleted file mode 100644 index ea28f4a62b6..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken002.sol +++ /dev/null @@ -1,30 +0,0 @@ - - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken003.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken003.sol deleted file mode 100644 index 863429fc4f8..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken003.sol +++ /dev/null @@ -1,16 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken005.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken005.sol deleted file mode 100644 index 863429fc4f8..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken005.sol +++ /dev/null @@ -1,16 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken011.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken011.sol deleted file mode 100644 index 43e4010ec3f..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken011.sol +++ /dev/null @@ -1,35 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken012.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken012.sol deleted file mode 100644 index ab0c19767e7..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken012.sol +++ /dev/null @@ -1,26 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken014.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken014.sol deleted file mode 100644 index 589406c47c6..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken014.sol +++ /dev/null @@ -1,34 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken018.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken018.sol deleted file mode 100644 index ab0c19767e7..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken018.sol +++ /dev/null @@ -1,26 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken023.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken023.sol deleted file mode 100644 index 070acb201ff..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken023.sol +++ /dev/null @@ -1,26 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - toAddress.transferToken(amount,id); - } - } - -contract B{ - uint256 public flag = 0; - constructor() public payable {} - fallback() external { - flag = 1; -} - -} - -contract C{ - uint256 public flag = 0; - constructor() public payable {} - fallback() external payable { - //flag = 1; -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken026.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken026.sol deleted file mode 100644 index 5464265d81f..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken026.sol +++ /dev/null @@ -1,31 +0,0 @@ - - -contract token{ - constructor() payable public{} - fallback() payable external{} - function testInCall(address callBAddress,address callCAddress, address toAddress ,uint256 amount,trcToken id) payable public{ - //callBAddress.call(bytes4(keccak256("transC(address,address,uint256,trcToken)")),callCAddress,toAddress,amount,id); - callBAddress.call(abi.encodeWithSignature("transC(address,address,uint256,trcToken)",callCAddress,toAddress,amount,id)); - } - function testIndelegateCall(address callBddress,address callAddressC, address toAddress,uint256 amount, trcToken id) payable public{ - callBddress.delegatecall(abi.encodeWithSignature("transC(address,address,uint256,trcToken)",callAddressC,toAddress,amount,id)); - } - } - - - -contract B{ - constructor() public payable{} - fallback() external payable{} - function transC(address payable callCAddress,address payable toAddress,uint256 amount, trcToken id) payable public{ - callCAddress.call(abi.encodeWithSignature("trans(address,uint256,trcToken)",toAddress,amount,id)); - } -} -contract C{ - constructor() payable public{} - fallback() payable external{} - function trans(address payable toAddress,uint256 amount, trcToken id) payable public{ - toAddress.transferToken(amount,id); - } - -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken027.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken027.sol deleted file mode 100644 index e7d6ee768f3..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken027.sol +++ /dev/null @@ -1,30 +0,0 @@ - - -contract token{ - constructor() payable public{} - fallback() payable external{} - function testInCall(address callBAddress,address callCAddress, address toAddress ,uint256 amount,trcToken id) payable public{ - callBAddress.call(abi.encodeWithSignature("transC(address,address,uint256,trcToken)",callCAddress,toAddress,amount,id)); - } - function testIndelegateCall(address callBddress,address callAddressC, address toAddress,uint256 amount, trcToken id) payable public{ - callBddress.delegatecall(abi.encodeWithSignature("transC(address,address,uint256,trcToken)",callAddressC,toAddress,amount,id)); - } - } - - - -contract B{ - constructor() public payable{} - fallback() external payable{} - function transC(address callCAddress,address toAddress,uint256 amount, trcToken id) payable public{ - callCAddress.call(abi.encodeWithSignature("trans(address,uint256,trcToken)",toAddress,amount,id)); - } -} -contract C{ - constructor() payable public{} - fallback() payable external{} - function trans(address payable toAddress,uint256 amount, trcToken id) payable public{ - toAddress.transferToken(amount,id); - } - -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken028.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken028.sol deleted file mode 100644 index 0f27d89c819..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken028.sol +++ /dev/null @@ -1,25 +0,0 @@ - - -contract token{ - uint256 public a=1; - constructor() public payable{} - function tokenBalanceWithSameName(trcToken id) public payable{ - B b= new B(); - a= b.tokenBalance(id); - } - function getA() public returns(uint256){ - return a; - } -} - - -contract B{ - uint256 public flag =0; - constructor() public payable{} - fallback() external payable{} - function tokenBalance(trcToken id) payable public returns(uint256){ - flag =9; - return flag; - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken029.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken029.sol deleted file mode 100644 index 8480cf6f19d..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken029.sol +++ /dev/null @@ -1,24 +0,0 @@ - - -contract token{ - address public a; - constructor() public payable{} - function transferTokenWithSameName(trcToken id,uint256 amount) public payable{ - B b= new B(); - b.transferToken(amount,id); - a= address(b); - } -} - - -contract B{ - uint256 public flag =0; - constructor() public payable{} - fallback() external payable{} - function transferToken(uint256 amount, trcToken id) payable public returns(bool){ - flag =9; - } - function getFlag() public view returns (uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken030.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken030.sol deleted file mode 100644 index 06b8201979c..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken030.sol +++ /dev/null @@ -1,17 +0,0 @@ - - contract token{ - constructor() public payable{} - - // 4)suicide也会转移token - // 所有token,trx均被转移到toAddress, - // 若toAddress为合约地址本身,则所有token,trx均被烧掉进黑洞 - function kill(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - - } - -contract B{ - constructor() public payable {} - fallback() external payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken031.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken031.sol deleted file mode 100644 index 65ec394e8da..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken031.sol +++ /dev/null @@ -1,18 +0,0 @@ - - - contract token{ - constructor() public payable{} - - // 4)suicide也会转移token - // 所有token,trx均被转移到toAddress, - // 若toAddress为合约地址本身,则所有token,trx均被烧掉进黑洞 - function kill(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - - } - -contract B{ - constructor() public payable {} - fallback() external payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken034.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken034.sol deleted file mode 100644 index 32c55f8c84b..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken034.sol +++ /dev/null @@ -1,25 +0,0 @@ - - - contract token{ - - constructor() public payable {} - - // 2. 异常测试 - // 1)revert, 金额回退 - function failTransferTokenRevert(address payable toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - require(1==2); - } - - // 2)Error, 金额回退, fee limit 扣光 - function failTransferTokenError(address payable toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - assert(1==2); - } - - } - contract B{ - uint256 public flag = 0; - constructor() public payable {} - fallback() external payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken035.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken035.sol deleted file mode 100644 index ca45dde790d..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken035.sol +++ /dev/null @@ -1,24 +0,0 @@ - - - contract token{ - constructor() public payable {} - - // 2. 异常测试 - // 1)revert, 金额回退 - function failTransferTokenRevert(address payable toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - require(1==2); - } - - // 2)Error, 金额回退, fee limit 扣光 - function failTransferTokenError(address payable toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - assert(1==2); - } - - } - contract B{ - uint256 public flag = 0; - constructor() public payable {} - fallback() external payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036.sol deleted file mode 100644 index c1da2f7555e..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036.sol +++ /dev/null @@ -1,52 +0,0 @@ - -contract IllegalDecorate { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithPure(address payable toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate1 { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithConstant(address payable toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate2 { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithView(address payable toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate3 { -event log(uint256); -constructor() payable public{} -fallback() payable external{} -function transferTokenWithOutPayable(address payable toAddress, uint256 tokenValue) public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_1.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_1.sol deleted file mode 100644 index 327ab5a756e..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_1.sol +++ /dev/null @@ -1,13 +0,0 @@ - -contract IllegalDecorate { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithPure(address payable toAddress, uint256 tokenValue) public pure { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_2.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_2.sol deleted file mode 100644 index 817a96e3c80..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_2.sol +++ /dev/null @@ -1,13 +0,0 @@ - -contract IllegalDecorate { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithConstant(address toAddress, uint256 tokenValue) public constant { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_3.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_3.sol deleted file mode 100644 index 67400c2e8ad..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_3.sol +++ /dev/null @@ -1,13 +0,0 @@ - -contract IllegalDecorate { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithView(address payable toAddress, uint256 tokenValue) public view { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_4.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_4.sol deleted file mode 100644 index cbaca0d4b38..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_4.sol +++ /dev/null @@ -1,13 +0,0 @@ - -contract IllegalDecorate { -event log(uint256); -constructor() payable public{} -fallback() payable external{} -function transferTokenWithOutPayable(address payable toAddress, uint256 tokenValue) public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_old.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_old.sol deleted file mode 100644 index 1f03afb7636..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken036_old.sol +++ /dev/null @@ -1,41 +0,0 @@ - - - -contract IllegalDecorate1 { -constructor() payable public{} -fallback() payable public{} -event log(uint256); -function transferTokenWithConstant(address toAddress, uint256 tokenValue) public constant { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate2 { -constructor() payable public{} -fallback() payable public{} -event log(uint256); -function transferTokenWithView(address toAddress, uint256 tokenValue) public view { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate3 { -event log(uint256); -constructor() payable public{} -fallback() payable public{} -function transferTokenWithOutPayable(address toAddress, uint256 tokenValue) public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken037.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken037.sol deleted file mode 100644 index 7cdd91702e8..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken037.sol +++ /dev/null @@ -1,24 +0,0 @@ - - -contract transferTrc10 { - function receive(address payable rec) public payable { - uint256 aamount=address(this).tokenBalance(msg.tokenid); - uint256 bamount=rec.tokenBalance(msg.tokenid); - require(msg.tokenvalue==aamount); - require(aamount==msg.tokenvalue); - rec.transferToken(aamount,msg.tokenid); - require(0==address(this).tokenBalance(msg.tokenid)); - require(bamount+aamount==rec.tokenBalance(msg.tokenid)); - (bool success, bytes memory data) =rec.call(abi.encodeWithSignature("checkTrc10(uint256,trcToken,uint256)",bamount+aamount,msg.tokenid,0)); - require(success); - - } -} - -contract receiveTrc10 { - fallback() external payable {} - function checkTrc10(uint256 amount,trcToken tid,uint256 meamount) public{ - require(amount==address(this).tokenBalance(tid)); - require(meamount==msg.sender.tokenBalance(tid)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken038.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken038.sol deleted file mode 100644 index eeb5ae744cf..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken038.sol +++ /dev/null @@ -1,24 +0,0 @@ - - -contract transferTrc10 { - function receive(address payable rec) public payable { - uint256 aamount=address(this).tokenBalance(msg.tokenid); - uint256 bamount=rec.tokenBalance(msg.tokenid); - require(msg.tokenvalue==aamount); - require(aamount==msg.tokenvalue); - rec.transferToken(aamount,msg.tokenid); - //require(rec.call(abi.encode(bytes4(keccak256("AssertError()"))))); - (bool suc, bytes memory data) = rec.call(abi.encodeWithSignature("AssertError()")); - require(suc); - require(aamount==address(this).tokenBalance(msg.tokenid)); - require(bamount==rec.tokenBalance(msg.tokenid)); - } -} - -contract receiveTrc10 { - fallback() external payable { - } - function AssertError() public{ - assert(1==2); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken039.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken039.sol deleted file mode 100644 index ebf6fb932ed..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken039.sol +++ /dev/null @@ -1,44 +0,0 @@ - -/* - * 1. caller账户issue一个token - * 2. caller部署proxy, 传入1000 token,1000 trx - * 3. caller部署A - * 4. caller部署B - * 5. caller调用proxy中upgradetTo函数,传入A的地址 - * 6. caller调用proxy中不存在的trans(uint256,address,trcToken)函数,注意这时trcToken是无意义的,但也带上tokenid。address是任意另外某账户的地址 - * 7. 可以看到目标地址trx增长5,caller账户trx减少5 - * 8. caller调用proxy中upgradeTo函数,传入B的地址 - * 9. caller调用proxy中不存在的trans(uint256,address,trcToken)函数。 - * 10. 可以看到目标地址token增长5,caller账户token减少5 -*/ -contract Proxy { - constructor() payable public{} - address public implementation; - function upgradeTo(address _address) public { - implementation = _address; - } - fallback() payable external{ - address addr = implementation; - require(addr != address(0)); - assembly { - let freememstart := mload(0x40) - calldatacopy(freememstart, 0, calldatasize()) - let success := delegatecall(not(0), addr, freememstart, calldatasize(), freememstart, 0) - returndatacopy(freememstart, 0, returndatasize()) - switch success - case 0 { revert(freememstart, returndatasize()) } - default { return(freememstart, returndatasize()) } - } - } -} - -contract A { - function trans(uint256 amount, address payable toAddress, trcToken id) payable public { - toAddress.transfer(amount); - } -} -contract B{ - function trans(uint256 amount, address payable toAddress, trcToken id) payable public { - toAddress.transferToken(amount,id); - } -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken041.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken041.sol deleted file mode 100644 index 6284253d1d5..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken041.sol +++ /dev/null @@ -1,20 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } - -contract B{ - uint256 public flag = 0; - constructor() public payable {} - fallback() external payable {} - - function setFlag() public payable{ - flag = 1; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken043.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken043.sol deleted file mode 100644 index 43e4010ec3f..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken043.sol +++ /dev/null @@ -1,35 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken048.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken048.sol deleted file mode 100644 index e705f696c1d..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken048.sol +++ /dev/null @@ -1,14 +0,0 @@ - - - contract Test { - event log(uint256); - function testMsgTokenValue() payable public returns(uint256 value) { - emit log(msg.tokenvalue); - return msg.tokenvalue; - } - - function testMsgValue() payable public returns(uint256 value) { - emit log(msg.value); - return msg.value; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken049.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken049.sol deleted file mode 100644 index d40480720df..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken049.sol +++ /dev/null @@ -1,9 +0,0 @@ - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken050.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken050.sol deleted file mode 100644 index 6bc6d956898..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken050.sol +++ /dev/null @@ -1,10 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken051.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken051.sol deleted file mode 100644 index 493016b777f..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken051.sol +++ /dev/null @@ -1,11 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - fallback() external payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken052.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken052.sol deleted file mode 100644 index 6bc6d956898..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken052.sol +++ /dev/null @@ -1,10 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken054.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken054.sol deleted file mode 100644 index 863429fc4f8..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken054.sol +++ /dev/null @@ -1,16 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken055.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken055.sol deleted file mode 100644 index 863429fc4f8..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken055.sol +++ /dev/null @@ -1,16 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken060.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken060.sol deleted file mode 100644 index ea28f4a62b6..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken060.sol +++ /dev/null @@ -1,30 +0,0 @@ - - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken061.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken061.sol deleted file mode 100644 index ea28f4a62b6..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken061.sol +++ /dev/null @@ -1,30 +0,0 @@ - - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken064.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken064.sol deleted file mode 100644 index 43e0da8a510..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken064.sol +++ /dev/null @@ -1,49 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } - function transferTokenTestValueMaxBigInteger(address payable toAddress) payable public { - toAddress.transferToken(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0); - } - function transferTokenTestValueOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(9223372036854775808, 1000001); - } - function transferTokenTestValueMaxLong(address payable toAddress) payable public { - toAddress.transferToken(9223372036854775807, 1000001); - } - function transferTokenTestValue0IdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(0, 9223372036854775809); - } -} - - - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken066.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken066.sol deleted file mode 100644 index 43e4010ec3f..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken066.sol +++ /dev/null @@ -1,35 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken067.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken067.sol deleted file mode 100644 index 43e4010ec3f..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken067.sol +++ /dev/null @@ -1,35 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken073.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken073.sol deleted file mode 100644 index a9ee8ea412b..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken073.sol +++ /dev/null @@ -1,16 +0,0 @@ - -contract Dest { - event logFallback(uint256 indexed, uint256 indexed, uint256 indexed); - event logGetToken(uint256 indexed, uint256 indexed, uint256 indexed, uint256); - - - constructor() payable public {} - - function getToken(trcToken tokenId) payable public{ - emit logGetToken(msg.sender.tokenBalance(tokenId), msg.tokenid, msg.tokenvalue, msg.value); - } - - fallback() payable external{ - emit logFallback(msg.tokenid, msg.tokenvalue, msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken075.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken075.sol deleted file mode 100644 index 9f201900295..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken075.sol +++ /dev/null @@ -1,26 +0,0 @@ - - -contract Dest { - event logFallback(uint256 indexed, uint256 indexed, uint256 indexed); - event logGetToken(uint256 indexed, uint256 indexed, uint256 indexed, uint256); - - constructor() payable public {} - - function getToken(trcToken tokenId) payable public{ - emit logGetToken(msg.sender.tokenBalance(tokenId), msg.tokenid, msg.tokenvalue, msg.value); - } - - function getTokenLongMin() payable public{ - // long.min - 1000020 - emit logGetToken(msg.sender.tokenBalance(trcToken(-9223372036855775828)), msg.tokenid, msg.tokenvalue, msg.value); - } - - function getTokenLongMax() payable public{ - // long.max + 1000020 - emit logGetToken(msg.sender.tokenBalance(trcToken(9223372036855775827)), msg.tokenid, msg.tokenvalue, msg.value); - } - - fallback() payable external{ - emit logFallback(msg.tokenid, msg.tokenvalue, msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken076.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken076.sol deleted file mode 100644 index a9decbee320..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken076.sol +++ /dev/null @@ -1,19 +0,0 @@ - -contract Test { - address public origin; - address public sender; - bool public result1; - bool public result2; - function test() external { - origin = tx.origin; - sender = msg.sender; - result1 = msg.sender == tx.origin; // true - result2 = origin == sender; // true - } -function getResult1() public returns(bool){ - return result1; -} -function getResult2() public returns(bool){ - return result2; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken077.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken077.sol deleted file mode 100644 index aeecf9cb9a5..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken077.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract trcToken077 { -function addressTest() public returns(bytes32 addressValue) { - assembly{ - let x := mload(0x40) //Find empty storage location using "free memory pointer" - mstore(x,address) //Place current contract address - addressValue := mload(x) - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken078.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken078.sol deleted file mode 100644 index 02ba4a79699..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken078.sol +++ /dev/null @@ -1,35 +0,0 @@ - -contract callerContract { - constructor() public payable{} - fallback() external payable{} - function sendToB(address called_address, address c) public payable{ - called_address.delegatecall(abi.encodeWithSignature("transferTo(address)",c)); - } - function sendToB2(address called_address,address c) public payable{ - called_address.call(abi.encodeWithSignature("transferTo(address)",c)); - } - function sendToB3(address called_address,address c) public payable{ - called_address.delegatecall(abi.encodeWithSignature("transferTo(address)",c)); - } -} - contract calledContract { - fallback() external payable{} - constructor() public payable {} - function transferTo(address payable toAddress)public payable{ - toAddress.transfer(5); - } - - function setIinC(address c) public payable{ - c.call.value(5)(abi.encode(bytes4(keccak256("setI()")))); - } - - } - contract c{ - address public origin; - address public sender; - constructor() public payable{} - event log(address,address); - fallback() payable external{ - emit log(tx.origin,msg.sender); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken079.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken079.sol deleted file mode 100644 index 863429fc4f8..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken079.sol +++ /dev/null @@ -1,16 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken080.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken080.sol deleted file mode 100644 index 2d2688b74a4..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcToken080.sol +++ /dev/null @@ -1,30 +0,0 @@ - - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - fallback() external payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractTrcTokenToOther.sol b/framework/src/test/resources/soliditycode_0.6.12/contractTrcTokenToOther.sol deleted file mode 100644 index 8e926d3ba17..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractTrcTokenToOther.sol +++ /dev/null @@ -1,44 +0,0 @@ - - -contract ConvertType { - -constructor() payable public{} - -fallback() payable external{} - -//function trcTokenOnStorage(trcToken storage token) internal { // ERROR: Data location can only be specified for array, struct or mapping types, but "storage" was given. -//} - -function trcTokenToString(trcToken token) public pure returns(string memory s){ -// s = token; // ERROR -// s = string(token); // ERROR -} - -function trcTokenToUint256(trcToken token) public pure returns(uint256 r){ -uint256 u = token; // OK -uint256 u2 = uint256(token); // OK -r = u2; -} - -function trcTokenToAddress(trcToken token) public pure returns(address r){ -//r = token; // ERROR -token = 0x1234567812345678123456781234567812345678123456781234567812345678; -address a2 = address(token); // OK -r = a2; -} - -function trcTokenToBytes(trcToken token) public pure returns(bytes memory r){ -//r = token; // ERROR -// r = bytes(token); // ERROR -} - -function trcTokenToBytes32(trcToken token) public pure returns(bytes32 r){ -// r = token; // ERROR -bytes32 b2 = bytes32(token); // OK -r = b2; -} - -function trcTokenToArray(trcToken token) public pure returns(uint[] memory r){ -//r = token; // ERROR -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/contractUnknownException.sol b/framework/src/test/resources/soliditycode_0.6.12/contractUnknownException.sol deleted file mode 100644 index 4fd9c64be72..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/contractUnknownException.sol +++ /dev/null @@ -1,64 +0,0 @@ - -contract testA { - constructor() public payable { - A a = (new A).value(10)(); - a.fun(); - } -} - -contract testB { - constructor() public payable { - B b = (new B).value(10)(); - b.fun(); - } -} - - -contract testC { - constructor() public payable{ - C c = (new C).value(10)(); - c.fun(); - } -} - -contract testD { - constructor() public payable{ - D d = (new D).value(10)(); - d.fun(); - } -} - - -contract A { - constructor() public payable{ - selfdestruct(msg.sender); - } - function fun() public { - } - -} - -contract B { - constructor() public payable { - revert(); - } - function fun() public { - } -} - - -contract C { - constructor() public payable { - assert(1==2); - } - function fun() public { - } -} - -contract D { - constructor() public payable { - require(1==2); - } - function fun() public { - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/create2CallContract.sol b/framework/src/test/resources/soliditycode_0.6.12/create2CallContract.sol deleted file mode 100644 index 046706ebd9e..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/create2CallContract.sol +++ /dev/null @@ -1,37 +0,0 @@ -contract callerContract { - constructor() payable public{} - fallback() payable external{} - function delegateCallCreate2(address called_address, bytes memory code, uint256 salt) public { - called_address.delegatecall(abi.encodeWithSignature("deploy(bytes,uint256)",code,salt)); - } - function callCreate2(address called_address,bytes memory code, uint256 salt) public returns(bool,bytes memory){ - return called_address.call(abi.encodeWithSignature("deploy(bytes,uint256)",code,salt)); - } -} - - -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - -contract TestConstract { - uint public i; - constructor () public { - } - function plusOne() public returns(uint){ - i++; - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/create2Istanbul.sol b/framework/src/test/resources/soliditycode_0.6.12/create2Istanbul.sol deleted file mode 100644 index c2ef8f3236b..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/create2Istanbul.sol +++ /dev/null @@ -1,28 +0,0 @@ - - -contract create2Istanbul { - function deploy(bytes memory code, uint256 salt) public returns(address) { - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - - } - return addr; - } - - // prefix in main net is 0x41, testnet config is 0xa0 - function get(bytes1 prefix, bytes calldata code, uint256 salt) external view returns(address) { - //bytes32 hash = keccak256(abi.encodePacked(bytes1(0x41),address(this), salt, keccak256(code))); - bytes32 hash = keccak256(abi.encodePacked(prefix,address(this), salt, keccak256(code))); - address addr = address(uint160(uint256(hash))); - return addr; - } - -} - -contract B { - constructor() public payable{} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/create2contract.sol b/framework/src/test/resources/soliditycode_0.6.12/create2contract.sol deleted file mode 100644 index 0171f4d5486..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/create2contract.sol +++ /dev/null @@ -1,52 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } - - event Deployed(address addr, bytes32 salt, address sender); - function deploy(bytes memory code, bytes32 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - -contract FactoryBytes { - event Deployed(address addr, bytes32 salt, address sender); - function deploy(bytes memory code, bytes32 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - -contract TestConstract { - uint public i; - constructor () public { - } - function plusOne() public returns(uint){ - i++; - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/create2contract22.sol b/framework/src/test/resources/soliditycode_0.6.12/create2contract22.sol deleted file mode 100644 index c33cb08edc3..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/create2contract22.sol +++ /dev/null @@ -1,109 +0,0 @@ -contract Factory { - event Deployed(address addr, trcToken salt, address sender); - event Deployed1(address addr, uint8 salt, address sender); - event Deployed2(address addr, address salt, address sender); - event Deployed3(address addr, string salt, address sender); - - - function deploy(bytes memory code, trcToken salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } - - function deploy1(bytes memory code, uint8 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed1(addr, salt, msg.sender); - return addr; - } - - function deploy2(bytes memory code, address salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed2(addr, salt, msg.sender); - return addr; - } - - function deploy3(bytes memory code, string memory salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed3(addr, salt, msg.sender); - return addr; - } - -} - - -contract TestConstract { - uint public i=1; - function testTransfer(uint256 i) payable public{ - msg.sender.transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} - -contract TestConstract1 { - uint public i=2; - function testTransfer(uint256 i) payable public{ - msg.sender.transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} - -contract TestConstract2 { - uint public i=3; - function testTransfer(uint256 i) payable public{ - msg.sender.transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} - -contract TestConstract3 { - uint public i=4; - function testTransfer(uint256 i) payable public{ - msg.sender.transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/create2contractn.sol b/framework/src/test/resources/soliditycode_0.6.12/create2contractn.sol deleted file mode 100644 index e0e3ae64c16..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/create2contractn.sol +++ /dev/null @@ -1,29 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract TestConstract { - uint public i=1; - function testTransfer(uint256 i) payable public{ - msg.sender.transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/create2contractn2.sol b/framework/src/test/resources/soliditycode_0.6.12/create2contractn2.sol deleted file mode 100644 index 626988c4e04..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/create2contractn2.sol +++ /dev/null @@ -1,26 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract TestConstract { - uint public i=1; - function set() payable public { - i=5; - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/demo.sol b/framework/src/test/resources/soliditycode_0.6.12/demo.sol deleted file mode 100644 index 06bf15387fc..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/demo.sol +++ /dev/null @@ -1,73 +0,0 @@ - - - contract tokenTest{ - uint256 codesize; - constructor() payable public{ - uint256 m; - address addr = address(this); - assembly { - m := extcodesize(addr) - } - codesize = m; - } - - // positive case - function pulsone() public payable{ - uint256 j = 0; - uint i = 100; - for (; i < i; i++) { - j++; - } - } - - - function getCodeSize() public returns (uint256){ - return codesize; - } - - } - - contract confirmTest{ - - uint256 codesize; - constructor() payable public{ - uint256 m; - address addr = address(this); - assembly { - m := extcodesize(addr) - - } - codesize = m; - } - - function getCodeSize() public returns (uint256){ - return codesize; - } - - function confirm(address addr) public returns (uint256){ - uint256 j; - assembly { - j := extcodesize(addr) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - return j; - } - - function at(address _addr) public returns (bytes memory o_code) { - assembly { - // retrieve the size of the code, this needs assembly - let size := extcodesize(_addr) - // allocate output byte array - this could also be done without assembly - // by using o_code = new bytes(size) - o_code := mload(0x40) - // new "memory end" including padding - mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) - // store length in memory - mstore(o_code, size) - // actually retrieve the code, this needs assembly - extcodecopy(_addr, add(o_code, 0x20), 0, size) - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/enumAndStruct.sol b/framework/src/test/resources/soliditycode_0.6.12/enumAndStruct.sol deleted file mode 100644 index 836a4ac850e..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/enumAndStruct.sol +++ /dev/null @@ -1,43 +0,0 @@ - - -struct S_out { -uint x; -} - -enum ErrorType { -Revert_Error, //0 -RevertWithMsg_Error, //1 -Require_Error, //2 -RequirewithMsg_Error, //3 -Assert_Error, //4 -Tansfer_Error, //5 -Send_Error, //6 -Math_Error, //7 -ArrayOverFlow_Error //8 -} - -contract enumAndStructTest { - -struct S_inner { -int x; -} - -enum ErrorType_inner { -Revert_Error, //0 -RevertWithMsg_Error, //1 -Require_Error, //2 -RequirewithMsg_Error, //3 -Assert_Error, //4 -Tansfer_Error, //5 -Send_Error, //6 -Math_Error, //7 -ArrayOverFlow_Error //8 -} - -function getvalue() public returns(uint) { - require(ErrorType.Require_Error == ErrorType(2)); - S_out memory s = S_out(1); - return s.x; -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/event001.sol b/framework/src/test/resources/soliditycode_0.6.12/event001.sol deleted file mode 100644 index 7662df3a5c6..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/event001.sol +++ /dev/null @@ -1,10 +0,0 @@ -contract Event { - event xixi(uint256 id) ; - event log2(uint256,uint256,uint256); - constructor() public payable{} - function messageI() payable public returns (uint ret) { - //emit log2(1,2,3); - emit xixi(1); - return 1; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/event002.sol b/framework/src/test/resources/soliditycode_0.6.12/event002.sol deleted file mode 100644 index a61f834e1b5..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/event002.sol +++ /dev/null @@ -1,52 +0,0 @@ - - -contract Event { - - event _0(); - event a_0() anonymous; - event a_4i(uint256 indexed x1, uint256 indexed x2 , uint256 indexed x3, uint256 indexed x4, uint256 x5)anonymous ; - event _3i(uint256 x1, uint256 indexed x2 , uint256 indexed x3, uint256 x4, uint256 x5) ; - event _1i(uint256 indexed x1, uint256, uint256 indexed, uint256 x4) ; - event a_1i(uint256) anonymous; - event _ai(uint8[2], uint8) ; - event a_ai(uint8[2], uint8) anonymous; - event _a1i(uint8[2] indexed, uint8) ; - event a_a1i(uint8[2] indexed, uint8) anonymous; - - constructor () public { - // emit a_0(); - // emit a_1i(123); - // emit a_4i(1,2,3,5,16); - // emit _0(); - emit _3i(1,2,3,5,16); - // emit _1i(1,2,3,5); - // emit _ai([1,2], 3); - // emit a_ai([3,4], 5); - // emit _a1i([1,2], 3); - // emit a_a1i([3,4], 5); - } - - function e() public { - emit _1i(1,2,3,4); - } - - function l() public { - emit a_1i(1); - } - - function k() public{ - emit a_4i(2,3,4,5,17); - emit _3i(2,3,4,5,16); - emit _1i(2,3,4,5); - emit a_1i(128); - emit _0(); - emit a_0(); - //selfdestruct(msg.sender); - //emit a_4i(1,2,3,5,16); - //emit _3i(1,2,3,5,16); - //emit _1i(1,2,3,5); - //emit a_1i(123); - //emit _0(); - //emit a_0(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/extCodeHash.sol b/framework/src/test/resources/soliditycode_0.6.12/extCodeHash.sol deleted file mode 100644 index d6209770682..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/extCodeHash.sol +++ /dev/null @@ -1,13 +0,0 @@ -contract TestExtCodeHash { - - function getCodeHashByAddr(address _addr) public returns (bytes32 _hash) { - assembly { - _hash := extcodehash(_addr) - } - } - function getCodeHashByUint(uint256 _addr) public returns (bytes32 _hash) { - assembly { - _hash := extcodehash(_addr) - } - } -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/extCodeHash11.sol b/framework/src/test/resources/soliditycode_0.6.12/extCodeHash11.sol deleted file mode 100644 index ad59f6cce1c..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/extCodeHash11.sol +++ /dev/null @@ -1,103 +0,0 @@ -contract Counter { -uint count = 0; -address payable owner; -event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); -constructor() public{ -owner = msg.sender; -} -function getCodeHashByAddr() public returns (bytes32 _hashBefore, bytes32 _hashAfter) { -address addr = address(this); -assembly { -_hashBefore := extcodehash(addr) -} -if (owner == msg.sender) { -selfdestruct(owner); -} -assembly { -_hashAfter := extcodehash(addr) -} -revert(); -emit LogResult(_hashBefore, _hashAfter); -} -} - -contract Counter1 { -uint count = 0; -address payable owner; -event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); -constructor() public{ -owner = msg.sender; -} -function getCodeHashByAddr() public returns (bytes32 _hashBefore, bytes32 _hashAfter) { -address addr = address(this); -assembly { -_hashBefore := extcodehash(addr) -} -if (owner == msg.sender) { -selfdestruct(owner); -} -assembly { -_hashAfter := extcodehash(addr) -} - -emit LogResult(_hashBefore, _hashAfter); -} -} - - -contract Counter2 { -uint count = 0; -address payable owner; -event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); -constructor() public{ -owner = msg.sender; -} -function getCodeHashByAddr(address c) public returns (bytes32 _hashBefore, bytes32 _hashAfter) { - TestConstract t=new TestConstract(); -address addr = address(t); -assembly { -_hashBefore := extcodehash(addr) -} - addr.call(abi.encodeWithSignature("testSuicideNonexistentTarget(address)",c)); - - -assembly { -_hashAfter := extcodehash(addr) -} - -emit LogResult(_hashBefore, _hashAfter); -} -} - - -contract Counter3 { -uint count = 0; -address payable owner; -event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); -constructor() public{ -owner = msg.sender; -} -function getCodeHashByAddr(address c) public returns (bytes32 _hashBefore, bytes32 _hashAfter) { - TestConstract t=new TestConstract(); -address addr = address(t); -assembly { -_hashBefore := extcodehash(addr) -} -if (owner == msg.sender) { -selfdestruct(owner); -} - -assembly { -_hashAfter := extcodehash(addr) -} - -emit LogResult(_hashBefore, _hashAfter); -} -} - -contract TestConstract { - uint public i=1; - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/extCodeHashConstruct.sol b/framework/src/test/resources/soliditycode_0.6.12/extCodeHashConstruct.sol deleted file mode 100644 index 6bb91b3d3b1..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/extCodeHashConstruct.sol +++ /dev/null @@ -1,14 +0,0 @@ -contract CounterConstruct { - uint count = 0; - address payable owner; - event LogResult(bytes32 _hashBefore); - constructor() public{ - owner = msg.sender; - address addr = address(this); - bytes32 _hashBefore; - assembly { - _hashBefore := extcodehash(addr) - } - emit LogResult(_hashBefore); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/extCodeHashStress.sol b/framework/src/test/resources/soliditycode_0.6.12/extCodeHashStress.sol deleted file mode 100644 index cf41f3c8106..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/extCodeHashStress.sol +++ /dev/null @@ -1,45 +0,0 @@ -contract Trigger { - function test(address addr) public returns(uint i) { - bytes32 hash; - while (gasleft() > 1000) { - assembly { - hash := extcodehash(addr) - } - i++; - } - } - - function test(address[] memory addrs) public returns(uint i) { - bytes32 hash; - uint i = 0; - for (; i < addrs.length; i++) { - address addr = addrs[i]; - assembly { - hash := extcodehash(addr) - } - } - return i; - } - } - - - - contract TriggerNormal { - function test(address addr) public returns(uint i) { - i = 0; - while (gasleft() > 100000) { - i++; - } - } - } - - contract TriggerNormal1 { - function test(address[] memory addrs) public returns(uint i) { - bytes32 hash; - uint i = 0; - for (; i < addrs.length; i++) { - address addr = addrs[i]; - addr.balance; - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/extCodeHashTestNoPayable.sol b/framework/src/test/resources/soliditycode_0.6.12/extCodeHashTestNoPayable.sol deleted file mode 100644 index c3a2ad8c6ae..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/extCodeHashTestNoPayable.sol +++ /dev/null @@ -1,8 +0,0 @@ -contract testConstantContract{ -uint256 public i; -function testNoPayable() public returns (uint256 z) { -i=1; -z=i; -return z; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/fallbackUpgrade.sol b/framework/src/test/resources/soliditycode_0.6.12/fallbackUpgrade.sol deleted file mode 100644 index f73140ad245..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/fallbackUpgrade.sol +++ /dev/null @@ -1,83 +0,0 @@ -contract Test0{ - event FuncCalled(bytes data,uint a); -} - -contract Test1 { - - event FuncCalled(string a); - fallback() external { - x = "fallback"; - emit FuncCalled(x); - } - string x; -} -//含有payable的fallback,无receice -contract Test2 { - - event FuncCalled(string data); - fallback() external payable{ - x = "fallback"; - emit FuncCalled(x); - } - string x; -} - -contract TestPayable { - event FuncCalled(string a); - - fallback() external payable { - x = "fallback"; - emit FuncCalled(x); - } - - receive() external payable { - x = "receive"; - emit FuncCalled(x); - } - string x; -} - -contract Caller { - function callTest0(Test0 test) public{ - (bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()")); - require(success); - } - function callTest1(address test) public returns (bool) { - (bool success,) = test.call(abi.encodeWithSignature("nonExistingFunction()")); - require(success); - (success,) = address(test).call(""); - require(success); - return true; - } - function callTest2(address test) public payable returns (bool) { - (bool success,) = test.call.value(1000)(abi.encodeWithSignature("nonExistingFunction()")); - require(success); - return true; - } - function callTestPayable1(TestPayable test) public payable returns (bool) { - (bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()")); - require(success); - (success,) = address(test).call(""); - require(success); - return true; - } -} - - -//contract Test0 { -// event FallbackCall(string data,bytes msg); -// //event FuncCalled(string a,bytes data); -// function() external payable{ -// x = "fallback"; -// emit FallbackCall(x,msg.data); -// } -// string x; -//} -//contract Caller{ -// function call(Test0 test) public payable returns(bool){ -// (bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()")); -// require(success); -// return true; -// } -//} - diff --git a/framework/src/test/resources/soliditycode_0.6.12/freezeContract001.sol b/framework/src/test/resources/soliditycode_0.6.12/freezeContract001.sol deleted file mode 100644 index 0ad8ed9f460..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/freezeContract001.sol +++ /dev/null @@ -1,63 +0,0 @@ - -contract TestFreeze { - constructor() public payable {} - - function freeze(address payable receiver, uint amount, uint res) external payable{ - receiver.freeze(amount, res); - } - - function unfreeze(address payable receiver, uint res) external { - receiver.unfreeze(res); - } - - function destroy(address payable inheritor) external { - selfdestruct(inheritor); - } - - function send(address payable A) external { - A.transfer(10); - } - - function send(address payable A, uint256 value) external { - A.transfer(value); - } - - function getExpireTime(address payable target, uint res) external view returns(uint) { - return target.freezeExpireTime(res); - } - - function deploy(uint256 salt) public returns(address){ - address addr; - bytes memory code = type(C).creationCode; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } - - function freezeAndSend(address payable receiver, uint amount, uint res) external { - receiver.transfer(amount); - receiver.freeze(amount, res); - } - - -} - - -contract C { - constructor() public payable {} - - function destroy(address payable inheritor) external { - selfdestruct(inheritor); - } -} - -contract D { - constructor() public payable { - msg.sender.freeze(msg.value, 1); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/getAddressChange.sol b/framework/src/test/resources/soliditycode_0.6.12/getAddressChange.sol deleted file mode 100644 index 2796da68770..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/getAddressChange.sol +++ /dev/null @@ -1,12 +0,0 @@ -contract getAddressChange { - constructor() public payable {} - // testaddress1函数新增了一个address属性。0.6.0之前 external函数可以通过address(x)来转化为地址,6.0将其禁止,可以通过函数address属性直接获取 - function testaddress1() public view returns(address) { - //return address(this.getamount); //0.6.0之前可以使用 - return this.getamount.address; //0.6.0 - - } - function getamount(address) external view returns(uint256) { - return address(this).balance; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/isSRCandidate.sol b/framework/src/test/resources/soliditycode_0.6.12/isSRCandidate.sol deleted file mode 100644 index e8e9b692dec..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/isSRCandidate.sol +++ /dev/null @@ -1,35 +0,0 @@ - - - -contract ContractB{ - address others; -} - -contract TestIsSRCandidate{ - - ContractB contractB = new ContractB(); - - function isSRCandidateTest(address addr) public view returns (bool) { - return address(addr).isSRCandidate; - } - - function zeroAddressTest() public view returns (bool) { - return address(0x0).isSRCandidate; - } - - function localContractAddrTest() public view returns (bool) { - return address(this).isSRCandidate; - } - - function otherContractAddrTest() public view returns (bool) { - return address(contractB).isSRCandidate; - } - - function nonpayableAddrTest(address addr) public view returns (bool) { - return addr.isSRCandidate; - } - - function payableAddrTest(address payable addr) public returns (bool) { - return addr.isSRCandidate; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/mappingGetter.sol b/framework/src/test/resources/soliditycode_0.6.12/mappingGetter.sol deleted file mode 100644 index dbd473717cb..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/mappingGetter.sol +++ /dev/null @@ -1,4 +0,0 @@ -contract mappingGetter { - mapping(bytes => uint256) public balances1; - mapping(string => uint256) public balances2; -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/multiValiSignPerformance01.sol b/framework/src/test/resources/soliditycode_0.6.12/multiValiSignPerformance01.sol deleted file mode 100644 index 74baa963366..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/multiValiSignPerformance01.sol +++ /dev/null @@ -1,37 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract ecrecoverValidateSign { - - using ECVerify for bytes32; - - function validateSign(bytes32 hash,bytes[] memory sig,address[] memory signer) public returns (bool) { - for(uint256 i=0;i=0.5.0 <0.7.0; - -contract A { - uint public x; - function setValue(uint _x) public { - x = _x; - } -} -contract B is A {} -contract C is A {} -// No explicit override required -contract D is B, C {} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/override003.sol b/framework/src/test/resources/soliditycode_0.6.12/override003.sol deleted file mode 100644 index 103133fc53c..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/override003.sol +++ /dev/null @@ -1,20 +0,0 @@ -pragma solidity ^0.6.0; -contract A { - uint public x; - function setValue(uint _x) public virtual { - x = _x; - } -} - -contract B { - uint public y; - function setValue(uint _y) public virtual { - y = _y; - } -} - -contract C is A, B { - function setValue(uint _x) public override(B,A) { - A.setValue(_x); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/override004.sol b/framework/src/test/resources/soliditycode_0.6.12/override004.sol deleted file mode 100644 index 1549d49b53f..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/override004.sol +++ /dev/null @@ -1,25 +0,0 @@ -pragma solidity >=0.5.0 <0.7.0; - -contract A { - uint public x = 4; - function setValue(uint _x) public notZero { - x = _x; - } - modifier notZero() virtual { - require(x >= 5,"x must >= 5"); - _; - } -} - -contract B is A { - function setValue2(uint _x) public { - x = _x; - } -} - -contract C is A,B { - modifier notZero override { - require(x >= 6,"x must >= 6"); - _; - } -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/override005.sol b/framework/src/test/resources/soliditycode_0.6.12/override005.sol deleted file mode 100644 index a8e44399ece..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/override005.sol +++ /dev/null @@ -1,39 +0,0 @@ -pragma solidity >= 0.6.0; - -contract Base { - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices public choice2 = ActionChoices.GoRight; - - function stopped() virtual external pure returns (bool) { - return true; - } - function i() virtual external pure returns (int) { - return 32482980; - } - function i2() virtual external pure returns (int) { - return -32482980; - } - function ui() virtual external pure returns (uint) { - return 23487820; - } - function origin() virtual external pure returns (address) { - return 0x3b0E4a6EdEE231CE0c3433F00F1bbc5FeD409c0B; - } - function b32() virtual external pure returns (bytes32) { - return 0xb55a21aaee0ce8f1c8ffaa0dbd23105cb55a21aaee0ce8f1c8ffaa0dbd231050; - } - function choice() virtual external returns (ActionChoices) { - return choice2; - } -} - -contract Test is Base { - - bool override public stopped = false; - int override public i = 32482989; - int override public i2 = -32482989; - uint override public ui = 23487823; - address override public origin = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF; - bytes32 override public b32 = 0xb55a21aaee0ce8f1c8ffaa0dbd23105cb55a21aaee0ce8f1c8ffaa0dbd23105c; - ActionChoices override public choice = ActionChoices.SitStill; -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/overridePrivateFunction.sol b/framework/src/test/resources/soliditycode_0.6.12/overridePrivateFunction.sol deleted file mode 100644 index b0b4d679620..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/overridePrivateFunction.sol +++ /dev/null @@ -1,22 +0,0 @@ -pragma solidity ^0.5.17; - -contract A { - - function test() private pure returns(uint) { - return 1; - } - -} - -contract B is A { - - function basic() private pure returns(uint) { - return 2; - } - function testOverridePrivate() external payable returns(uint) { - return basic(); - } - - constructor() public payable {} -} - diff --git a/framework/src/test/resources/soliditycode_0.6.12/payable001.sol b/framework/src/test/resources/soliditycode_0.6.12/payable001.sol deleted file mode 100644 index 4fe7b20921f..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/payable001.sol +++ /dev/null @@ -1,31 +0,0 @@ - - - -contract A { - constructor() public payable{ - } - - fallback() external payable { - } -} - -contract PayableTest { - -address payable a1; -function receiveMoneyTransfer(address a, uint256 _x) public { -a1 = payable(a); -a1.transfer(_x); -} - -function receiveMoneySend(address a, uint256 x) public { -address payable a2 = payable(a); -a2.send(x); -} - -function receiveMoneyTransferWithContract(A PayableTest, uint256 x) public { -payable(address(PayableTest)).transfer(x); -} - -constructor() public payable{ -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/pedersenHash001.sol b/framework/src/test/resources/soliditycode_0.6.12/pedersenHash001.sol deleted file mode 100644 index 6cad7cb9855..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/pedersenHash001.sol +++ /dev/null @@ -1,18 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract pedersenHashTest { - - function test1() public returns (bool, bytes memory){ - bytes memory empty = ""; - return address(0x1000004).delegatecall(empty); - } - - function test2(bytes memory data) public returns (bool, bytes memory){ - return address(0x1000004).delegatecall(data); - } - - function test3(uint32 hash, bytes32 left, bytes32 right) public returns (bytes32){ - return pedersenHash(hash, left, right); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/pedersenHash002.sol b/framework/src/test/resources/soliditycode_0.6.12/pedersenHash002.sol deleted file mode 100644 index b0a78973ef2..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/pedersenHash002.sol +++ /dev/null @@ -1,320 +0,0 @@ -pragma experimental ABIEncoderV2; - -import "./SafeMath.sol"; - -abstract contract TokenTRC20 { - function transfer(address _to, uint256 _value) public virtual returns (bool success); - - function transferFrom(address _from, address _to, uint256 _value) public virtual returns (bool success); -} - -contract ShieldedTRC20 { - using SafeMath for uint256; - - uint256 public scalingFactor; // used when decimals of TRC20 token is too large. - uint256 public leafCount; - uint256 constant INT64_MAX = 2 ** 63 - 1; - bytes32 public latestRoot; - mapping(bytes32 => bytes32) public nullifiers; // store nullifiers of spent commitments - mapping(bytes32 => bytes32) public roots; // store history root - mapping(uint256 => bytes32) public tree; - mapping(bytes32 => bytes32) public noteCommitment; - bytes32[33] frontier; - bytes32[32] zeroes = [bytes32(0x0100000000000000000000000000000000000000000000000000000000000000), bytes32(0x817de36ab2d57feb077634bca77819c8e0bd298c04f6fed0e6a83cc1356ca155), bytes32(0xffe9fc03f18b176c998806439ff0bb8ad193afdb27b2ccbc88856916dd804e34), bytes32(0xd8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c), bytes32(0xe110de65c907b9dea4ae0bd83a4b0a51bea175646a64c12b4c9f931b2cb31b49), bytes32(0x912d82b2c2bca231f71efcf61737fbf0a08befa0416215aeef53e8bb6d23390a), bytes32(0x8ac9cf9c391e3fd42891d27238a81a8a5c1d3a72b1bcbea8cf44a58ce7389613), bytes32(0xd6c639ac24b46bd19341c91b13fdcab31581ddaf7f1411336a271f3d0aa52813), bytes32(0x7b99abdc3730991cc9274727d7d82d28cb794edbc7034b4f0053ff7c4b680444), bytes32(0x43ff5457f13b926b61df552d4e402ee6dc1463f99a535f9a713439264d5b616b), bytes32(0xba49b659fbd0b7334211ea6a9d9df185c757e70aa81da562fb912b84f49bce72), bytes32(0x4777c8776a3b1e69b73a62fa701fa4f7a6282d9aee2c7a6b82e7937d7081c23c), bytes32(0xec677114c27206f5debc1c1ed66f95e2b1885da5b7be3d736b1de98579473048), bytes32(0x1b77dac4d24fb7258c3c528704c59430b630718bec486421837021cf75dab651), bytes32(0xbd74b25aacb92378a871bf27d225cfc26baca344a1ea35fdd94510f3d157082c), bytes32(0xd6acdedf95f608e09fa53fb43dcd0990475726c5131210c9e5caeab97f0e642f), bytes32(0x1ea6675f9551eeb9dfaaa9247bc9858270d3d3a4c5afa7177a984d5ed1be2451), bytes32(0x6edb16d01907b759977d7650dad7e3ec049af1a3d875380b697c862c9ec5d51c), bytes32(0xcd1c8dbf6e3acc7a80439bc4962cf25b9dce7c896f3a5bd70803fc5a0e33cf00), bytes32(0x6aca8448d8263e547d5ff2950e2ed3839e998d31cbc6ac9fd57bc6002b159216), bytes32(0x8d5fa43e5a10d11605ac7430ba1f5d81fb1b68d29a640405767749e841527673), bytes32(0x08eeab0c13abd6069e6310197bf80f9c1ea6de78fd19cbae24d4a520e6cf3023), bytes32(0x0769557bc682b1bf308646fd0b22e648e8b9e98f57e29f5af40f6edb833e2c49), bytes32(0x4c6937d78f42685f84b43ad3b7b00f81285662f85c6a68ef11d62ad1a3ee0850), bytes32(0xfee0e52802cb0c46b1eb4d376c62697f4759f6c8917fa352571202fd778fd712), bytes32(0x16d6252968971a83da8521d65382e61f0176646d771c91528e3276ee45383e4a), bytes32(0xd2e1642c9a462229289e5b0e3b7f9008e0301cbb93385ee0e21da2545073cb58), bytes32(0xa5122c08ff9c161d9ca6fc462073396c7d7d38e8ee48cdb3bea7e2230134ed6a), bytes32(0x28e7b841dcbc47cceb69d7cb8d94245fb7cb2ba3a7a6bc18f13f945f7dbd6e2a), bytes32(0xe1f34b034d4a3cd28557e2907ebf990c918f64ecb50a94f01d6fda5ca5c7ef72), bytes32(0x12935f14b676509b81eb49ef25f39269ed72309238b4c145803544b646dca62d), bytes32(0xb2eed031d4d6a4f02a097f80b54cc1541d4163c6b6f5971f88b6e41d35c53814)]; - address owner; - TokenTRC20 trc20Token; - - event MintNewLeaf(uint256 position, bytes32 cm, bytes32 cv, bytes32 epk, bytes32[21] c); - event TransferNewLeaf(uint256 position, bytes32 cm, bytes32 cv, bytes32 epk, bytes32[21] c); - event BurnNewLeaf(uint256 position, bytes32 cm, bytes32 cv, bytes32 epk, bytes32[21] c); - event TokenMint(address from, uint256 value); - event TokenBurn(address to, uint256 value, bytes32[3] ciphertext); - event NoteSpent(bytes32 nf); - - constructor (address trc20ContractAddress, uint256 scalingFactorExponent) public { - require(scalingFactorExponent < 77, "The scalingFactorExponent is out of range!"); - scalingFactor = 10 ** scalingFactorExponent; - owner = msg.sender; - trc20Token = TokenTRC20(trc20ContractAddress); - } - // output: cm, cv, epk, proof - function mint(uint256 rawValue, bytes32[9] calldata output, bytes32[2] calldata bindingSignature, bytes32[21] calldata c) external { - address sender = msg.sender; - // transfer the trc20Token from the sender to this contract - bool transferResult = trc20Token.transferFrom(sender, address(this), rawValue); - require(transferResult, "TransferFrom failed!"); - - require(noteCommitment[output[0]] == 0, "Duplicate noteCommitments!"); - uint64 value = rawValueToValue(rawValue); - bytes32 signHash = sha256(abi.encodePacked(address(this), value, output, c)); - (bytes32[] memory ret) = verifyMintProof(output, bindingSignature, value, signHash, frontier, leafCount); - uint256 result = uint256(ret[0]); - require(result == 1, "The proof and signature have not been verified by the contract!"); - - uint256 slot = uint256(ret[1]); - uint256 nodeIndex = leafCount + 2 ** 32 - 1; - tree[nodeIndex] = output[0]; - if (slot == 0) { - frontier[0] = output[0]; - } - for (uint256 i = 1; i < slot + 1; i++) { - nodeIndex = (nodeIndex - 1) / 2; - tree[nodeIndex] = ret[i + 1]; - if (i == slot) { - frontier[slot] = tree[nodeIndex]; - } - } - latestRoot = ret[slot + 2]; - roots[latestRoot] = latestRoot; - noteCommitment[output[0]] = output[0]; - leafCount ++; - - emit MintNewLeaf(leafCount - 1, output[0], output[1], output[2], c); - emit TokenMint(sender, rawValue); - } - //input: nf, anchor, cv, rk, proof - //output: cm, cv, epk, proof - function transfer(bytes32[10][] calldata input, bytes32[2][] calldata spendAuthoritySignature, bytes32[9][] calldata output, bytes32[2] calldata bindingSignature, bytes32[21][] calldata c) external { - require(input.length >= 1 && input.length <= 2, "Input number must be 1 or 2!"); - require(input.length == spendAuthoritySignature.length, "Input number must be equal to spendAuthoritySignature number!"); - require(output.length >= 1 && output.length <= 2, "Output number must be 1 or 2!"); - require(output.length == c.length, "Output number must be equal to c number!"); - - for (uint256 i = 0; i < input.length; i++) { - require(nullifiers[input[i][0]] == 0, "The note has already been spent!"); - require(roots[input[i][1]] != 0, "The anchor must exist!"); - } - for (uint256 i = 0; i < output.length; i++) { - require(noteCommitment[output[i][0]] == 0, "Duplicate noteCommitment!"); - } - - bytes32 signHash = sha256(abi.encodePacked(address(this), input, output, c)); - (bytes32[] memory ret) = verifyTransferProof(input, spendAuthoritySignature, output, bindingSignature, signHash, 0, frontier, leafCount); - uint256 result = uint256(ret[0]); - require(result == 1, "The proof and signature have not been verified by the contract!"); - - uint256 offset = 1; - //ret offset - for (uint256 i = 0; i < output.length; i++) { - uint256 slot = uint256(ret[offset++]); - uint256 nodeIndex = leafCount + 2 ** 32 - 1; - tree[nodeIndex] = output[i][0]; - if (slot == 0) { - frontier[0] = output[i][0]; - } - for (uint256 k = 1; k < slot + 1; k++) { - nodeIndex = (nodeIndex - 1) / 2; - tree[nodeIndex] = ret[offset++]; - if (k == slot) { - frontier[slot] = tree[nodeIndex]; - } - } - leafCount++; - } - latestRoot = ret[offset]; - roots[latestRoot] = latestRoot; - for (uint256 i = 0; i < input.length; i++) { - bytes32 nf = input[i][0]; - nullifiers[nf] = nf; - emit NoteSpent(nf); - } - for (uint256 i = 0; i < output.length; i++) { - noteCommitment[output[i][0]] = output[i][0]; - emit TransferNewLeaf(leafCount - (output.length - i), output[i][0], output[i][1], output[i][2], c[i]); - } - } - //input: nf, anchor, cv, rk, proof - //output: cm, cv, epk, proof - function burn(bytes32[10] calldata input, bytes32[2] calldata spendAuthoritySignature, uint256 rawValue, bytes32[2] calldata bindingSignature, address payTo, bytes32[3] calldata burnCipher, bytes32[9][] calldata output, bytes32[21][] calldata c) external { - uint64 value = rawValueToValue(rawValue); - bytes32 signHash = sha256(abi.encodePacked(address(this), input, output, c, payTo, value)); - - bytes32 nf = input[0]; - bytes32 anchor = input[1]; - require(nullifiers[nf] == 0, "The note has already been spent!"); - require(roots[anchor] != 0, "The anchor must exist!"); - - require(output.length <= 1, "Output number cannot exceed 1!"); - require(output.length == c.length, "Output number must be equal to length of c!"); - - // bytes32 signHash = sha256(abi.encodePacked(address(this), input, payTo, value, output, c)); - if (output.length == 0) { - (bool result) = verifyBurnProof(input, spendAuthoritySignature, value, bindingSignature, signHash); - require(result, "The proof and signature have not been verified by the contract!"); - } else { - transferInBurn(input, spendAuthoritySignature, value, bindingSignature, signHash, output, c); - } - - nullifiers[nf] = nf; - emit NoteSpent(nf); - //Finally, transfer trc20Token from this contract to the nominated address - bool transferResult = trc20Token.transfer(payTo, rawValue); - require(transferResult, "Transfer failed!"); - - emit TokenBurn(payTo, rawValue, burnCipher); - } - - function transferInBurn(bytes32[10] memory input, bytes32[2] memory spendAuthoritySignature, uint64 value, bytes32[2] memory bindingSignature, bytes32 signHash, bytes32[9][] memory output, bytes32[21][] memory c) private { - bytes32 cm = output[0][0]; - require(noteCommitment[cm] == 0, "Duplicate noteCommitment!"); - bytes32[10][] memory inputs = new bytes32[10][](1); - inputs[0] = input; - bytes32[2][] memory spendAuthoritySignatures = new bytes32[2][](1); - spendAuthoritySignatures[0] = spendAuthoritySignature; - (bytes32[] memory ret) = verifyTransferProof(inputs, spendAuthoritySignatures, output, bindingSignature, signHash, value, frontier, leafCount); - uint256 result = uint256(ret[0]); - require(result == 1, "The proof and signature have not been verified by the contract!"); - - uint256 slot = uint256(ret[1]); - uint256 nodeIndex = leafCount + 2 ** 32 - 1; - tree[nodeIndex] = cm; - if (slot == 0) { - frontier[0] = cm; - } - for (uint256 i = 1; i < slot + 1; i++) { - nodeIndex = (nodeIndex - 1) / 2; - tree[nodeIndex] = ret[i + 1]; - if (i == slot) { - frontier[slot] = tree[nodeIndex]; - } - } - latestRoot = ret[slot + 2]; - roots[latestRoot] = latestRoot; - noteCommitment[cm] = cm; - leafCount ++; - - emit BurnNewLeaf(leafCount - 1, cm, output[0][1], output[0][2], c[0]); - } - - //position: index of leafnode, start from 0 - function getPath(uint256 position) public view returns (bytes32, bytes32[32] memory) { - require(position >= 0, "Position should be non-negative!"); - require(position < leafCount, "Position should be smaller than leafCount!"); - uint256 index = position + 2 ** 32 - 1; - bytes32[32] memory path; - uint32 level = ancestorLevel(position); - bytes32 targetNodeValue = getTargetNodeValue(position, level); - for (uint32 i = 0; i < 32; i++) { - if (i == level) { - path[31 - i] = targetNodeValue; - } else { - if (index % 2 == 0) { - path[31 - i] = tree[index - 1]; - } else { - path[31 - i] = tree[index + 1] == 0 ? zeroes[i] : tree[index + 1]; - } - } - index = (index - 1) / 2; - } - return (latestRoot, path); - } - - //position: index of leafnode, start from 0 - function getPathByValueIsZero(uint256 position) public view returns (bytes32, bytes32[32] memory) { - require(position >= 0, "Position should be non-negative!"); - require(position < leafCount, "Position should be smaller than leafCount!"); - uint256 index = position + 2 ** 32 - 1; - bytes32[32] memory path; - uint32 level = ancestorLevel(position); - bytes32 targetNodeValue = getTargetNodeValueByValueIsZero(position, level); - for (uint32 i = 0; i < 32; i++) { - if (i == level) { - path[31 - i] = targetNodeValue; - } else { - if (index % 2 == 0) { - path[31 - i] = tree[index - 1]; - } else { - path[31 - i] = tree[index + 1] == 0 ? zeroes[i] : tree[index + 1]; - } - } - index = (index - 1) / 2; - } - return (latestRoot, path); - } - - function ancestorLevel(uint256 leafIndex) private view returns (uint32) { - uint256 nodeIndex1 = leafIndex + 2 ** 32 - 1; - uint256 nodeIndex2 = leafCount + 2 ** 32 - 2; - uint32 level = 0; - while (((nodeIndex1 - 1) / 2) != ((nodeIndex2 - 1) / 2)) { - nodeIndex1 = (nodeIndex1 - 1) / 2; - nodeIndex2 = (nodeIndex2 - 1) / 2; - level = level + 1; - } - return level; - } - - function getTargetNodeValue(uint256 leafIndex, uint32 level) private view returns (bytes32) { - bytes32 left; - bytes32 right; - uint256 index = leafIndex + 2 ** 32 - 1; - uint256 nodeIndex = leafCount + 2 ** 32 - 2; - bytes32 nodeValue = tree[nodeIndex]; - if (level == 0) { - if (index < nodeIndex) { - return nodeValue; - } - if (index == nodeIndex) { - if (index % 2 == 0) { - return tree[index - 1]; - } else { - return zeroes[0]; - } - } - } - for (uint32 i = 0; i < level; i++) { - if (nodeIndex % 2 == 0) { - left = tree[nodeIndex - 1]; - right = nodeValue; - } else { - left = nodeValue; - right = zeroes[i]; - } - nodeValue = pedersenHash(i, left, right); - nodeIndex = (nodeIndex - 1) / 2; - } - return nodeValue; - } - - function getTargetNodeValueByValueIsZero(uint256 leafIndex, uint32 level) private view returns (bytes32) { - bytes32 left; - bytes32 right; - uint256 index = leafIndex + 2 ** 32 - 1; - uint256 nodeIndex = leafCount + 2 ** 32 - 2; - bytes32 nodeValue = tree[nodeIndex]; - if (level == 0) { - if (index < nodeIndex) { - return nodeValue; - } - if (index == nodeIndex) { - if (index % 2 == 0) { - return tree[index - 1]; - } else { - return zeroes[0]; - } - } - } - for (uint32 i = 0; i < level; i++) { - if (nodeIndex % 2 == 0) { - left = tree[nodeIndex - 1]; - right = nodeValue; - } else { - left = nodeValue; - right = zeroes[i]; - } - left = bytes32(0x0); - right = bytes32(0x0); - nodeValue = pedersenHash(i, left, right); - nodeIndex = (nodeIndex - 1) / 2; - } - return nodeValue; - } - - function rawValueToValue(uint256 rawValue) private view returns (uint64) { - require(rawValue > 0, "Value must be positive!"); - require(rawValue.mod(scalingFactor) == 0, "Value must be integer multiples of scalingFactor!"); - uint256 value = rawValue.div(scalingFactor); - require(value < INT64_MAX); - return uint64(value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest1TestRequireContract.sol b/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest1TestRequireContract.sol deleted file mode 100644 index 16d01911d35..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest1TestRequireContract.sol +++ /dev/null @@ -1,15 +0,0 @@ - -contract TestThrowsContract{ - function testAssert() public { - assert(1==2); - } - function testRequire() public { - require(2==1); - } - function testRevert() public { - revert(); - } - //function testThrow(){ - // throw; - //} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest2TestThrowsContract.sol b/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest2TestThrowsContract.sol deleted file mode 100644 index 1ff73ad6460..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest2TestThrowsContract.sol +++ /dev/null @@ -1,15 +0,0 @@ - -contract TestThrowsContract{ - function testAssert() public { - assert(1==2); - } - function testRequire() public { - require(2==1); - } - function testRevert() public { - revert(); - } - // function testThrow() public { - // throw; - //} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest3TestRevertContract.sol b/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest3TestRevertContract.sol deleted file mode 100644 index b42a8c3fb23..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest3TestRevertContract.sol +++ /dev/null @@ -1,15 +0,0 @@ - -contract TestThrowsContract{ - function testAssert() public { - assert(1==2); - } - function testRequire() public { - require(2==1); - } - function testRevert() public { - revert(); - } - // function testThrow(){ - // throw; - // } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest4noPayableContract.sol b/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest4noPayableContract.sol deleted file mode 100644 index 35f89631e7d..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest4noPayableContract.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract noPayableContract { - -function noPayable() public payable returns (uint){ -return msg.value; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest4noPayableContract_1.sol b/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest4noPayableContract_1.sol deleted file mode 100644 index 5b6dd509f6f..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest4noPayableContract_1.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract noPayableContract { - -function noPayable() public returns (uint){ -return msg.value; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest5noPayableConstructor.sol b/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest5noPayableConstructor.sol deleted file mode 100644 index 097594ab7c9..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest5noPayableConstructor.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract MyContract { - uint money; - - //function MyContract(uint _money) { - constructor(uint _money) public payable{ - require(msg.value >= _money); - money = _money; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest5noPayableConstructor_1.sol b/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest5noPayableConstructor_1.sol deleted file mode 100644 index 5008ec5c9bf..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest5noPayableConstructor_1.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract MyContract { - uint money; - - //function MyContract(uint _money) { - constructor(uint _money) public { - require(msg.value >= _money); - money = _money; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest6transferTestContract.sol b/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest6transferTestContract.sol deleted file mode 100644 index 4f171aebb9a..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest6transferTestContract.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract transferTestContract { - function tranferTest(address payable addr) public payable{ - addr.transfer(10); - - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest7payableFallbakContract.sol b/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest7payableFallbakContract.sol deleted file mode 100644 index 534726cb1b4..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest7payableFallbakContract.sol +++ /dev/null @@ -1,14 +0,0 @@ - - -contract Test { - fallback() external { x = 1; } - uint x; -} - - -contract Caller { - function callTest(Test test) public { - //test.call(0xabcdef01); // hash does not exist - address(test).call(abi.encode(0xabcdef01)); // hash does not exist - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest8newContractGasNoenough.sol b/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest8newContractGasNoenough.sol deleted file mode 100644 index b8743e8231a..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest8newContractGasNoenough.sol +++ /dev/null @@ -1,19 +0,0 @@ - - -contract Account{ - uint256 public accId; - - // function Account(uint accountId) payable{ - constructor(uint accountId) payable public { - accId = accountId; - } -} - -contract Initialize{ - // Account public account = new Account(10); - - function newAccount() public { - Account account = new Account(1); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest9MessageUsedErrorFeed.sol b/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest9MessageUsedErrorFeed.sol deleted file mode 100644 index 18142d20ee8..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontest9MessageUsedErrorFeed.sol +++ /dev/null @@ -1,18 +0,0 @@ - - -contract MathedFeed { - - function divideMathed() public returns (uint ret) { - uint x=1; - uint y=0; - return x/y; - } -} - - -contract MathedUseContract { - - function MathedUse(address addr) public returns (uint) { - return MathedFeed(addr).divideMathed(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontestFunctionUsedErrorFeed.sol b/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontestFunctionUsedErrorFeed.sol deleted file mode 100644 index ad90faa6dab..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/requireExceptiontestFunctionUsedErrorFeed.sol +++ /dev/null @@ -1,17 +0,0 @@ - - -contract MessageFeed { - - function mValue() payable public returns (uint ret) { - return msg.value; - } -} - -contract MessageUseContract { - function inputValue() payable public returns (uint){ - return msg.value; - } - function messageUse(address addr) payable public returns (uint) { - return MessageFeed(addr).mValue.value(1)(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/selector.sol b/framework/src/test/resources/soliditycode_0.6.12/selector.sol deleted file mode 100644 index 5805a6e8d22..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/selector.sol +++ /dev/null @@ -1,21 +0,0 @@ - - -library A { - function getBalance(address) public view returns (uint256) { - return address(this).balance; - } - - function getamount(address) external view returns (uint256) { - return address(this).balance; - } -} - -contract testSelector { - using A for address; - - - function getselector2() public view returns (bytes4, bytes4) { - return (A.getBalance.selector, A.getamount.selector); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/stackContract001.sol b/framework/src/test/resources/soliditycode_0.6.12/stackContract001.sol deleted file mode 100644 index c2e8f2f7611..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/stackContract001.sol +++ /dev/null @@ -1,61 +0,0 @@ - - -contract A{ - event log(uint256); - constructor() payable public{ - emit log(withdrawreward()); - emit log(address(this).rewardbalance); - } - function withdrawRewardTest() public returns (uint256){ - return withdrawreward(); - } - - function test() public{ - emit log(123); - } -} - -contract B{ - event log(uint256); - constructor() payable public{ - emit log(withdrawreward()); - emit log(address(this).rewardbalance); - } - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } - function rewardBalance(address addr) public view returns (uint256){ - return addr.rewardbalance; - } - - function nullAddressTest() public view returns (uint256) { - return address(0x0).rewardbalance; - } - - function localContractAddrTest() public view returns (uint256) { - address payable localContract = address(uint160(address(this))); - return localContract.rewardbalance; - } - - function withdrawRewardTest() public returns (uint256){ - return withdrawreward(); - } - - function contractBWithdrawRewardTest(address contractB) public returns (uint) { - return B(contractB).withdrawRewardTest(); - } - - function createA() public returns (address){ - return address(new A()); - } - - function callA(address Addr) public{ - A(Addr).test(); - } -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/stackSuicide001.sol b/framework/src/test/resources/soliditycode_0.6.12/stackSuicide001.sol deleted file mode 100644 index d1fc520ddb2..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/stackSuicide001.sol +++ /dev/null @@ -1,84 +0,0 @@ - -contract testStakeSuicide{ - B b; - constructor() payable public{} - function deployB() payable public returns (B addrB){ - b = (new B).value(1000000000)(); - return b; - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } - function SelfdestructTest2(address sr, uint256 amount, address payable target) public{ - stake(sr, amount); - selfdestruct(target); - } - function Stake(address sr, uint256 amount) public payable returns (bool result){ - return stake(sr, amount); - } - function Stake2(address sr, uint256 amount) public returns (bool result){ - stake(sr, amount); - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function UnStake2() public returns (bool result){ - unstake(); - return unstake(); - } - function WithdrawReward() public { - withdrawreward(); - } - function RewardBalance(address addr) view public returns (uint256 balance) { - return addr.rewardbalance; - } - function revertTest1(address sr, uint256 amount, address payable transferAddr) public{ - transferAddr.transfer(1000000); - stake(sr, amount); - transferAddr.transfer(2000000); - stake(sr, 1000000000000000);//stake more than balance to fail - transferAddr.transfer(4000000); - } - function revertTest2(address payable transferAddr) public{ - transferAddr.transfer(1000000); - unstake(); - transferAddr.transfer(2000000); - unstake();//unstake twice to fail - transferAddr.transfer(4000000); - } - - function BStake(address sr, uint256 amount) public returns (bool result){ - return b.Stake(sr, amount); - } - function BUnStake() public returns (bool result){ - return b.UnStake(); - } - function transfer(address payable add,uint256 num) public { - return add.transfer(num); - } -} - -contract B{ - constructor() payable public{} - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } - - function deploy(bytes memory code, uint256 salt) public returns(address) { - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - return addr; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/stateVariableShadowing.sol b/framework/src/test/resources/soliditycode_0.6.12/stateVariableShadowing.sol deleted file mode 100644 index a9109ee296c..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/stateVariableShadowing.sol +++ /dev/null @@ -1,21 +0,0 @@ -contract test { -// uint public x; -// function setValue1(uint _x) public returns (uint){ -// x = _x; -// return x; -// } - uint public y; - function setValue3(uint _x) public returns (uint){ - y = _x; - return y; - } -} - -contract stateVariableShadowing is test { - uint public x; - function setValue2(uint _x) public returns (uint){ - x = _x; - return x; - } -} - diff --git a/framework/src/test/resources/soliditycode_0.6.12/stringSplit.sol b/framework/src/test/resources/soliditycode_0.6.12/stringSplit.sol deleted file mode 100644 index 84231f2d1fe..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/stringSplit.sol +++ /dev/null @@ -1,45 +0,0 @@ - - -contract testStringSplit { -string s1 = "s""1""2"",./"; -string s2 = "s123?\\'."; -string s3 = hex"41"hex"42"; -string s4 = hex"4142"; - -function getS1() public view returns (string memory) { -return s1; -} - -function getS1N1() public pure returns (string memory) { -string memory n1 = "s""1""2"",./"; -return n1; -} - -function getS2() public view returns (string memory) { -return s2; -} - -function getS2N2() public pure returns (string memory) { -string memory n2 = "s123?\'."; -return n2; -} - -function getS3() public view returns (string memory) { -return s3; -} - -function getS3N3() public pure returns (string memory) { -string memory n3 = hex"41"hex"42"; -return n3; -} - -function getS4() public view returns (string memory) { -return s4; -} - -function getS4N4() public pure returns (string memory) { -string memory n4 = hex"4142"; -return n4; -} - -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/suicide001.sol b/framework/src/test/resources/soliditycode_0.6.12/suicide001.sol deleted file mode 100644 index 3544f8bf84a..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/suicide001.sol +++ /dev/null @@ -1,32 +0,0 @@ -contract factory { - constructor() payable public { - } - - function create1() payable public returns (address){ - Caller add = (new Caller).value(0)(); - return address(add); - } - - function kill() payable public{ - selfdestruct(msg.sender); - } - - function create2(bytes memory code, uint256 salt) public returns(address){ - Caller addr; - Caller addr1; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - return address(addr); - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/suicide002.sol b/framework/src/test/resources/soliditycode_0.6.12/suicide002.sol deleted file mode 100644 index 160ab64f320..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/suicide002.sol +++ /dev/null @@ -1,43 +0,0 @@ -contract Factory { - uint256 public num; - event Deployed(address addr, uint256 salt, address sender); - constructor() public { - } - function deploy(bytes memory code, uint256 salt) public returns(address){ - TestConstract addr; - TestConstract addr1; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - - addr.testSuicideNonexistentTarget(msg.sender); - addr.set(); - - assembly { - addr1 := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(address(addr), salt, msg.sender); - return address(addr); - } -} - - - -contract TestConstract { - uint public i=1; - constructor () public { - } - - function set() public{ - i=9; - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/testOutOfMem.sol b/framework/src/test/resources/soliditycode_0.6.12/testOutOfMem.sol deleted file mode 100644 index 8d285b28b7d..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/testOutOfMem.sol +++ /dev/null @@ -1,7 +0,0 @@ -contract Test { - function testOutOfMem(uint256 x) public returns(bytes32 r) { - uint[] memory memVar; - memVar = new uint[](x); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/testStakeSuicide.sol b/framework/src/test/resources/soliditycode_0.6.12/testStakeSuicide.sol deleted file mode 100644 index 3342a5607f7..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/testStakeSuicide.sol +++ /dev/null @@ -1,71 +0,0 @@ - -contract testStakeSuicide{ - B b; - constructor() payable public{} - function deployB() payable public returns (B addrB){ - b = (new B).value(1000000000)(); - return b; - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } - function SelfdestructTest2(address sr, uint256 amount, address payable target) public{ - stake(sr, amount); - selfdestruct(target); - } - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - function Stake2(address sr, uint256 amount) public returns (bool result){ - stake(sr, amount); - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function UnStake2() public returns (bool result){ - unstake(); - return unstake(); - } - function WithdrawReward() public { - withdrawreward(); - } - function RewardBalance(address addr) view public returns (uint256 balance) { - return addr.rewardbalance; - } - function revertTest1(address sr, uint256 amount, address payable transferAddr) public{ - transferAddr.transfer(1000000); - stake(sr, amount); - transferAddr.transfer(2000000); - stake(sr, 1000000000000000);//stake more than balance to fail - transferAddr.transfer(4000000); - } - function revertTest2(address payable transferAddr) public{ - transferAddr.transfer(1000000); - unstake(); - transferAddr.transfer(2000000); - unstake();//unstake twice to fail - transferAddr.transfer(4000000); - } - function BStake(address sr, uint256 amount) public returns (bool result){ - return b.Stake(sr, amount); - } - function BUnStake() public returns (bool result){ - return b.UnStake(); - } - function BSelfdestructTest(address payable target) public{ - b.SelfdestructTest(target); - } -} -contract B{ - constructor() payable public{} - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/tryCatch001.sol b/framework/src/test/resources/soliditycode_0.6.12/tryCatch001.sol deleted file mode 100644 index 283db92e159..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/tryCatch001.sol +++ /dev/null @@ -1,105 +0,0 @@ - - -enum ErrorType { - Revert_Error, //0 - RevertWithMsg_Error, //1 - Require_Error, //2 - RequirewithMsg_Error, //3 - Assert_Error, //4 - Tansfer_Error, //5 - Send_Error, //6 - Math_Error, //7 - ArrayOverFlow_Error //8 -} -contract errorContract { - uint256[] arraryUint ; - - function errorSwitch(uint256 errorType) public returns(string memory) { - if (ErrorType(errorType) == ErrorType.Revert_Error){ - revert(); - } else if (ErrorType(errorType) == ErrorType.RevertWithMsg_Error){ - revert("Revert Msg."); - } else if (ErrorType(errorType) == ErrorType.Require_Error) { - require(0>1); - } else if (ErrorType(errorType) == ErrorType.RequirewithMsg_Error) { - require(0>1,"Require Msg."); - } else if (ErrorType(errorType) == ErrorType.Assert_Error) { - assert(1<0); - } else if (ErrorType(errorType) == ErrorType.Tansfer_Error) { - payable(msg.sender).transfer(1); - } else if (ErrorType(errorType) == ErrorType.Send_Error) { - payable(msg.sender).send(1); - } else if (ErrorType(errorType) == ErrorType.Math_Error) { - uint256 a = 1; - uint256 b = 0; - uint256 n = a / b; - } else if (ErrorType(errorType) == ErrorType.ArrayOverFlow_Error) { - arraryUint.pop(); - } - return "success"; - - } - - function callFun(string memory functionStr, string memory argsStr) public{ - address(this).call(abi.encodeWithSignature(functionStr, argsStr)); - } - -} - -contract NewContract { - uint256[] arraryUint ; - - constructor(uint256 errorType) public payable{ - if (ErrorType(errorType) == ErrorType.Revert_Error){ - revert(); - } else if (ErrorType(errorType) == ErrorType.RevertWithMsg_Error){ - revert("Revert Msg."); - } else if (ErrorType(errorType) == ErrorType.Require_Error) { - require(0>1); - } else if (ErrorType(errorType) == ErrorType.RequirewithMsg_Error) { - require(0>1,"Require Msg."); - } else if (ErrorType(errorType) == ErrorType.Assert_Error) { - assert(1<0); - } else if (ErrorType(errorType) == ErrorType.Tansfer_Error) { - payable(msg.sender).transfer(1); - } else if (ErrorType(errorType) == ErrorType.Send_Error) { - payable(msg.sender).send(1); - } else if (ErrorType(errorType) == ErrorType.Math_Error) { - uint256 a = 1; - uint256 b = 0; - uint256 n = a / b; - } else if (ErrorType(errorType) == ErrorType.ArrayOverFlow_Error) { - arraryUint.pop(); - } - } -} - -contract tryTest { - function getData(errorContract inter, string memory functionStr, string memory argsStr) public payable returns(string memory) { - try inter.callFun(functionStr,argsStr) { - return "123"; - } catch Error(string memory errorMsg/* 出错原因 */) { - return errorMsg; - } catch (bytes memory) { - return "3"; - } - } - - function getErrorSwitch(errorContract add, uint256 errorType ) public payable returns(string memory) { - try add.errorSwitch(errorType) returns (string memory Msg) { - return Msg; - } catch Error(string memory errorMsg/* 出错原因 */) { - return errorMsg; - } catch (bytes memory) { - return "NoErrorMsg"; - } - } - - function catchNewErrorSwitch(uint256 errorType) public returns (address nc){ - try new NewContract(errorType) returns (NewContract nc){ - return address(nc); - }catch { - return address(0x00); - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue001.sol b/framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue001.sol deleted file mode 100644 index 5388ed68473..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue001.sol +++ /dev/null @@ -1,25 +0,0 @@ - -contract tvmAssetIssue001 { - constructor() payable public{} - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - return assetissue(name, abbr, totalSupply, precision); - } - - function updateAsset(trcToken tokenId, string memory url, string memory desc) public returns (bool) { - return updateasset(tokenId, bytes(url), bytes(desc)); - } - - function updateOtherAccountAsset(string memory url, string memory desc) public returns (bool) { - trcToken tokenId = trcToken(1000004); - return updateasset(tokenId, bytes(url), bytes(desc)); - } - - function updateAssetOnBytes(trcToken tokenId, bytes memory url, bytes memory desc) public returns (bool) { - return updateasset(tokenId, url, desc); - } - - function transferToken(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue002.sol b/framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue002.sol deleted file mode 100644 index 87c1206b778..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue002.sol +++ /dev/null @@ -1,15 +0,0 @@ - - -contract tvmAssetIssue002 { - constructor() payable public{} - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - assetissue(name, abbr, totalSupply, precision); - return assetissue(name, abbr, totalSupply, precision); - } - - function updateAsset(trcToken tokenId, string memory url1, string memory desc1, string memory url2, string memory desc2) public returns (bool) { - updateasset(tokenId, bytes(url1), bytes(desc1)); - return updateasset(tokenId, bytes(url2), bytes(desc2)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue003.sol b/framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue003.sol deleted file mode 100644 index f5ce5e0dc3e..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue003.sol +++ /dev/null @@ -1,23 +0,0 @@ - - -contract tvmAssetIssue003 { - constructor() payable public{} - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - return assetissue(name, abbr, totalSupply, precision); - } - - function tokenIssueAndTransfer(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision, address addr) public { - address payable newaddress = address(uint160(addr)); - newaddress.transfer(100000000); - assetissue(name, abbr, totalSupply, precision); - newaddress.transfer(100000000); - } - - function updateAssetAndTransfer(trcToken tokenId, string memory url, string memory desc, address addr) public { - address payable newaddress = address(uint160(addr)); - newaddress.transfer(100000000); - updateasset(tokenId, bytes(url), bytes(desc)); - newaddress.transfer(100000000); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue004.sol b/framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue004.sol deleted file mode 100644 index c8332de8f45..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue004.sol +++ /dev/null @@ -1,39 +0,0 @@ - - -contract A { - - constructor() payable public{} - fallback() payable external {} - - function tokenIssueA(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint){ - return assetissue(name, abbr, totalSupply, precision); - } - - function updateAssetA(trcToken tokenId, string memory url, string memory desc) public returns (bool) { - return updateasset(tokenId, bytes(url), bytes(desc)); - } - - function transferToken(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } -} - -contract tvmAssetIssue004 { - - A a; - - constructor() payable public{} - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - return a.tokenIssueA(name, abbr, totalSupply, precision); - } - - function updateAsset(trcToken tokenId, string memory url, string memory desc) public returns (bool) { - return a.updateAssetA(tokenId, url, desc); - } - - function getContractAddress() public payable returns (address) { - a = (new A).value(1024000000)(); - return address(a); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue005.sol b/framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue005.sol deleted file mode 100644 index 8c36d050ff8..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/tvmAssetIssue005.sol +++ /dev/null @@ -1,45 +0,0 @@ - - -contract tvmAssetIssue005 { - constructor() payable public{} - - fallback() external payable { - } - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - return assetissue(name, abbr, totalSupply, precision); - } - - function updateAsset(trcToken tokenId, string memory url, string memory desc) public returns (bool) { - return updateasset(tokenId, bytes(url), bytes(desc)); - } - - function updateAssetOnBytes(trcToken tokenId, bytes memory url, bytes memory desc) public returns (bool) { - return updateasset(tokenId, url, desc); - } - - function transferToken(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - - function SelfdestructTest(address payable target) public { - selfdestruct(target); - } -} - -contract B { - event Deployed(address addr, uint256 salt); - - function deploy(uint256 salt) public returns (address) { - address addr; - bytes memory code = type(tvmAssetIssue005).creationCode; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt); - return addr; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/typeName.sol b/framework/src/test/resources/soliditycode_0.6.12/typeName.sol deleted file mode 100644 index 5b44abd1bbb..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/typeName.sol +++ /dev/null @@ -1,5 +0,0 @@ -contract TypeName { - function testTypeName() public returns (string memory){ - return type(TypeName).name; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/unStake001.sol b/framework/src/test/resources/soliditycode_0.6.12/unStake001.sol deleted file mode 100644 index 03734fecfa5..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/unStake001.sol +++ /dev/null @@ -1,90 +0,0 @@ - - -contract unStakeTest { - B b; - constructor() payable public{} - function deployB() payable public returns (B addrB){ - b = (new B).value(1000000000)(); - return b; - } - - function selfdestructTest(address payable target) public { - selfdestruct(target); - } - - function selfdestructTest2(address sr, uint256 amount, address payable target) public { - stake(sr, amount); - selfdestruct(target); - } - - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - - function stake2(address sr, uint256 amount) public returns (bool result){ - stake(sr, amount); - return stake(sr, amount); - } - - function unStake() public returns (bool result){ - return unstake(); - } - - function unStake2() public returns (bool result){ - unstake(); - return unstake(); - } - - function withdrawReward() public returns (uint256 amount) { - return withdrawreward(); - } - - function rewardBalance(address addr) view public returns (uint256 balance) { - return addr.rewardbalance; - } - - function revertTest1(address sr, uint256 amount, address payable transferAddr) public { - transferAddr.transfer(1000000); - stake(sr, amount); - transferAddr.transfer(2000000); - stake(sr, 1000000000000000); - //stake more than balance to fail - transferAddr.transfer(4000000); - } - - function revertTest2(address payable transferAddr) public { - transferAddr.transfer(1000000); - unstake(); - transferAddr.transfer(2000000); - unstake(); - //unstake twice to fail - transferAddr.transfer(4000000); - } - - function BStake(address sr, uint256 amount) public returns (bool result){ - return b.Stake(sr, amount); - } - - function BUnStake() public returns (bool result){ - return b.UnStake(); - } - - function BSelfdestructTest(address payable target) public { - b.SelfdestructTest(target); - } -} - -contract B { - constructor() payable public{} - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - - function UnStake() public returns (bool result){ - return unstake(); - } - - function SelfdestructTest(address payable target) public { - selfdestruct(target); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/validatemultisign001.sol b/framework/src/test/resources/soliditycode_0.6.12/validatemultisign001.sol deleted file mode 100644 index cc0a742d0c5..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/validatemultisign001.sol +++ /dev/null @@ -1,15 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract validatemultisignTest { - function testmulti(address a, uint256 perid, bytes32 hash, bytes[] memory signatures) public returns (bool){ - return validatemultisign(a, perid, hash, signatures); - } - - function testbatch(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public returns (bytes32){ - return batchvalidatesign(hash, signatures, addresses); - } - - function testMultiPrecompileContract(bytes memory data) public returns(bool, bytes memory){ - return address(0xa).delegatecall(data); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/verifyTransferProof001.sol b/framework/src/test/resources/soliditycode_0.6.12/verifyTransferProof001.sol deleted file mode 100644 index 587b4defd10..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/verifyTransferProof001.sol +++ /dev/null @@ -1,15 +0,0 @@ -contract verifyTransferProofTest { - - function test1() public returns (bool, bytes memory){ - bytes memory empty = ""; - return address(0x1000002).delegatecall(empty); - } - - function test2(bytes memory data) public returns (bool, bytes memory){ - return address(0x1000002).delegatecall(data); - } - - function test3(bytes32[10][] memory input, bytes32[2][] memory spendAuthoritySignature, bytes32[9][] memory output, bytes32[2] memory bindingSignature, bytes32 signHash, uint64 valueBalance, bytes32[33] memory frontier, uint256 leafCount) public returns (bytes32[] memory){ - return verifyTransferProof(input, spendAuthoritySignature, output, bindingSignature, signHash, valueBalance, frontier, leafCount); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.6.12/virtual001.sol b/framework/src/test/resources/soliditycode_0.6.12/virtual001.sol deleted file mode 100644 index 6dddac07ef4..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/virtual001.sol +++ /dev/null @@ -1,19 +0,0 @@ -pragma solidity ^0.6.0; -interface X { - function setValue(uint _x) external; -} -abstract contract Y { - function setBool(bool _y) external virtual ; -} -contract Y2 { - string public z; - function setString(string calldata _z) external virtual { z = "123"; } -} - -contract Z is X,Y,Y2 { - uint public x; - bool public y; - function setValue(uint _x) external override { x = _x; } - function setBool(bool _y) external override { y = _y; } - function setString(string calldata _z) external override { z = _z; } -} diff --git a/framework/src/test/resources/soliditycode_0.6.12/walletTestMutiSign004.sol b/framework/src/test/resources/soliditycode_0.6.12/walletTestMutiSign004.sol deleted file mode 100644 index 7b943aee5c1..00000000000 --- a/framework/src/test/resources/soliditycode_0.6.12/walletTestMutiSign004.sol +++ /dev/null @@ -1,51 +0,0 @@ -contract timeoutTest { - string public iarray1; - // cpu - function oneCpu() public { - require(1==1); - } - - function storage8Char() public { - iarray1 = "12345678"; - } - - function testUseCpu(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - } - return count; - } - - - uint256[] public iarray; - uint public calculatedFibNumber; - mapping(address=>mapping(address=>uint256)) public m; - - function testUseStorage(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - iarray.push(i); - } - return count; - } - - // stack - //uint n = 0; - uint yy = 0; - function test() public { - //n += 1; - yy += 1; - test(); - } - - function setFibonacci(uint n) public returns (uint256){ - calculatedFibNumber = fibonacci(n); - return calculatedFibNumber; - } - - function fibonacci(uint n) internal returns (uint) { - return fibonacci(n - 1) + fibonacci(n - 2); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/AssertException002.sol b/framework/src/test/resources/soliditycode_0.7.6/AssertException002.sol deleted file mode 100644 index 15cc07ff984..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/AssertException002.sol +++ /dev/null @@ -1,17 +0,0 @@ - - -contract AssertException{ - function divideIHaveArgsReturn(int x,int y) public returns (int z) { - return x / y; - } - function testAssert() public { - require(2==1); - } -} -contract C { - constructor() public payable { - assert(1==2); - } - function fun() public { - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/AssignToExternal.sol b/framework/src/test/resources/soliditycode_0.7.6/AssignToExternal.sol deleted file mode 100644 index d4f09590a36..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/AssignToExternal.sol +++ /dev/null @@ -1,30 +0,0 @@ -contract AssignToExternal { - // Not allow: - // function f(uint256[] calldata x, uint256[] calldata y) external pure { - // x = y; - // } - - // allow: - - function f(uint256 a) external returns (uint){ - a = a + 1; - return a; - } - - function StringSet(string calldata a) external returns (string memory){ - return a; - } - - function ByteSet(bytes32 a) external returns (bytes32){ - return a; - } - - function UintArraySet(uint256[2] calldata a) external returns (uint256[2] memory){ - return a; - } - - function AddSet(address a) external returns (address){ - return a; - } - -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/BlockHash.sol b/framework/src/test/resources/soliditycode_0.7.6/BlockHash.sol deleted file mode 100644 index 6603da65e44..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/BlockHash.sol +++ /dev/null @@ -1,38 +0,0 @@ -contract TestBlockHash { - - function testOR1(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = blockhash(block.number - 1) | bytes32(value); - return (b1, c, blockhash(block.number - 1)); - } - - function testOR2(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = bytes32(value) | blockhash(block.number - 1); - return (b1, c, blockhash(block.number - 1)); - } - - function testAND1(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = blockhash(block.number - 1) & bytes32(value); - return (b1, c, blockhash(block.number - 1)); - } - - function testAND2(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = bytes32(value) & blockhash(block.number - 1); - return (b1, c, blockhash(block.number - 1)); - } - - function testXOR1(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = blockhash(block.number - 1) ^ bytes32(value); - return (b1, c, blockhash(block.number - 1)); - } - - function testXOR2(bytes32 value) public returns(bytes32, bytes32, bytes32) { - bytes32 b1 = blockhash(block.number - 1); - bytes32 c = bytes32(value) ^ blockhash(block.number - 1); - return (b1, c, blockhash(block.number - 1)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/ClearAbi001.sol b/framework/src/test/resources/soliditycode_0.7.6/ClearAbi001.sol deleted file mode 100644 index 39a8e8cf005..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/ClearAbi001.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract testConstantContract{ -function testPayable() public view returns (int z) { -return 1; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/ClearAbi005.sol b/framework/src/test/resources/soliditycode_0.7.6/ClearAbi005.sol deleted file mode 100644 index a3115398386..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/ClearAbi005.sol +++ /dev/null @@ -1,26 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract TestConstract { - uint public i=0; - constructor () public { - } - function plusOne() public returns(uint){ - i++; - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/ConstructorDefaults.sol b/framework/src/test/resources/soliditycode_0.7.6/ConstructorDefaults.sol deleted file mode 100644 index 4b6186ccb95..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/ConstructorDefaults.sol +++ /dev/null @@ -1,9 +0,0 @@ -contract testIsContract{ - bool result; - constructor (bool a) public { - result = a; - } -function test( address a) public returns (bool) { -return result; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/Create2Test023.sol b/framework/src/test/resources/soliditycode_0.7.6/Create2Test023.sol deleted file mode 100644 index ba48645ae3f..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/Create2Test023.sol +++ /dev/null @@ -1,31 +0,0 @@ -contract factory { - constructor() payable public { - } - - function deploy(bytes memory code, uint256 salt) public returns(address){ - Caller addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - return address(addr); - } - - function testCreate() payable public returns (address){ - Caller add = (new Caller){value:0}(); - return address(add); - } - - function kill( ) payable public{ - selfdestruct(msg.sender); - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/Create2Test024.sol b/framework/src/test/resources/soliditycode_0.7.6/Create2Test024.sol deleted file mode 100644 index f5a9d032cff..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/Create2Test024.sol +++ /dev/null @@ -1,56 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - TestConstract addr; - TestConstract addr1; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - - addr.testSuicideNonexistentTarget(msg.sender); - addr.set(); - emit Deployed(address(addr), salt, msg.sender); - return address(addr); - } - - function deploy2(bytes memory code, uint256 salt) public returns(address){ - TestConstract addr; - TestConstract addr1; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - - //addr.testSuicideNonexistentTarget(msg.sender); - //addr.set(); - - assembly { - addr1 := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(address(addr), salt, msg.sender); - return address(addr); - } -} - - - -contract TestConstract { - uint public i=1; - constructor () public { - } - - function set() public{ - i=9; - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/Create2Test025.sol b/framework/src/test/resources/soliditycode_0.7.6/Create2Test025.sol deleted file mode 100644 index 895dc43e56f..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/Create2Test025.sol +++ /dev/null @@ -1,34 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - constructor() public { - } - - function create2(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } - - function get(bytes1 prefix, bytes calldata code, uint256 salt) external view returns(address) { - //bytes32 hash = keccak256(abi.encodePacked(bytes1(0x41),address(this), salt, keccak256(code))); - bytes32 hash = keccak256(abi.encodePacked(prefix,address(this), salt, keccak256(code))); - address addr = address(uint160(uint256(hash))); - return addr; - } -} - -contract TestContract{ - uint256 public num; - constructor(uint256 j) public{ - num = j; - } - function getNum() public returns (uint256){ - return num; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/ExtCodeHashTest010.sol b/framework/src/test/resources/soliditycode_0.7.6/ExtCodeHashTest010.sol deleted file mode 100644 index 6feaa923f4b..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/ExtCodeHashTest010.sol +++ /dev/null @@ -1,46 +0,0 @@ -contract Counter { - uint count = 0; - address payable owner; - event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); - constructor() public{ - owner = msg.sender; - } - function getCodeHashSuicide(address addr) public returns (bytes32 _hashBefore){ - assembly{ - _hashBefore := extcodehash(addr) - } - selfdestruct(owner); - return _hashBefore; - } - - function getCodeHashRevert() public returns (bytes32 _hashBefore, bytes32 _hashAfter) { - address addr = address(this); - assembly { - _hashBefore := extcodehash(addr) - } - if (owner == msg.sender) { - selfdestruct(owner); - } - assembly { - _hashAfter := extcodehash(addr) - } - revert(); - emit LogResult(_hashBefore, _hashAfter); - } - - function getCodeHashCreate() public returns (bytes32 _hashBefore){ - TestContract A = (new TestContract){value:0}(); - address addr = address(A); - assembly{ - _hashBefore := extcodehash(addr) - } - revert(); - return _hashBefore; - } -} - -contract TestContract{ - uint256 count = 1; - constructor() public payable{ - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/ExternalSelector.sol b/framework/src/test/resources/soliditycode_0.7.6/ExternalSelector.sol deleted file mode 100644 index 01fddac9e2e..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/ExternalSelector.sol +++ /dev/null @@ -1,92 +0,0 @@ -//pragma solidity ^0.6.0; - -contract selectorContract { - function testSelectorNoParam() external pure returns(uint) { - return 11; - } - - function testSelectorWithParam(uint x) external pure returns(uint) { - return 22; - } -} - -interface interfaceSelector { - function getSelector() external pure returns(uint); -} - -interface B is interfaceSelector { - // interface现在可以继承自其他interface - function testImplemention() external pure returns(uint); -} - -contract implementContract is B{ - function getSelector() external override pure returns(uint) { - return 66; - } - - function testImplemention() external override pure returns(uint) { - return 77; - } - - constructor() public payable {} -} - -contract basicContract{ - function testNewUse() external payable returns(uint) { - return 345; - } - - constructor() public payable {} -} - -contract TestGasValue{ - constructor() public payable {} - - function testNewUse() external payable returns(uint) { - return 123; - } - basicContract bc = new basicContract(); - // external方法在调用时可以采用c.f{gas: 10000, value: 4 trx}()的形式 - function callWithGasAndValue(uint x,uint y) external returns(uint) { - return bc.testNewUse{gas:x, value:y}(); - } - - function callThisNoGasAnd1Value() external returns(uint) { - return this.testNewUse{gas:0, value:1}(); - } - - // inline assembly中允许true和false字面量 - function testAssemblyTrue() public pure returns(uint x) { - assembly { - x := true - } - } - - // inline assembly中允许true和false字面量 - function testAssemblyFalse() public pure returns(uint x) { - assembly { - x := false - } - } - - // create2的high-level用法new C{salt: 0x1234, value: 1 ether}(arg1, arg2) - function testCreate2() public returns(address) { - basicContract c = new basicContract{salt: bytes32(bytes1(0x01)), value: 1 trx}(); - return address(c); - } - - - function getContractSelectorNoParam() public pure returns(bytes4) { - return selectorContract.testSelectorNoParam.selector; - } - - function getContractSelectorWithParam() public pure returns(bytes4) { - return selectorContract.testSelectorWithParam.selector; - } - - function getInterfaceSelectorNoParam() public pure returns(bytes4) { - return interfaceSelector.getSelector.selector; - } - -} - diff --git a/framework/src/test/resources/soliditycode_0.7.6/NewFeature068.sol b/framework/src/test/resources/soliditycode_0.7.6/NewFeature068.sol deleted file mode 100644 index be4ee209e15..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/NewFeature068.sol +++ /dev/null @@ -1,126 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -//pragma solidity ^0.6.8; - -abstract contract testModifier { - modifier isOwner() virtual; -} - -abstract contract testInterfaceId { - function getValue() external view virtual returns(uint); - function getOwner() external view virtual returns(uint); - -} - -interface a { - function getValue() external view returns(uint); - function getOwner() external view returns(uint); -} - -contract testMapKey is testModifier{ - - enum size{ - SMALL, - LARGE - } - - mapping(size => uint) public enums; - - mapping(testMapKey => uint) public contracts; - - function setEnumValue(uint value) public { - enums[size.SMALL] = value; - } - - function getEnumValue() public view returns(uint) { - return enums[size.SMALL]; - } - - function setContractValue() public { - contracts[this] = 2; - } - - function getContractValue() public view returns(uint) { - return contracts[this]; - } - - bytes4 constant functionSelector = this.getEnumValue.selector; - - function getfunctionSelector() public pure returns(bytes4) { - return functionSelector; - } - - uint immutable x; - address immutable owner = msg.sender; - - constructor() public { - x = 5; - } - - string b = "test"; - - function testStorage() public view returns(string memory) { - string storage aa; - aa = b; - return aa; - - } - - function getImmutableVal() public view returns(uint) { - return x; - } - - function getOwner() public view returns(address) { - return owner; - } - - function getInterfaceId() public pure returns(bytes4,bytes4) { - return (type(a).interfaceId, type(testInterfaceId).interfaceId); - } - - modifier isOwner() override { - require(msg.sender == owner); - _; - } - - function requireOwner() public view isOwner returns(uint) { - return 6; - } - - - function getUint256MinAndMax() public pure returns(uint, uint) { - return (type(uint).min, type(uint).max); - } - - - function getUint8MinAndMax() public pure returns(uint8, uint8) { - return (type(uint8).min, type(uint8).max); - } - -} - - -abstract contract base { - function abstractfun() virtual public returns(uint); -} - -abstract contract callEmptyFunction is base { - function callfun() public returns(uint) { - return abstractfun(); - } -} - - - - - - - - - - - - - - - - diff --git a/framework/src/test/resources/soliditycode_0.7.6/NewFeature076.sol b/framework/src/test/resources/soliditycode_0.7.6/NewFeature076.sol deleted file mode 100644 index 3191acb8f1d..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/NewFeature076.sol +++ /dev/null @@ -1,21 +0,0 @@ -function a() returns (uint) { - return 1; -} -abstract contract abvd { - -} -interface qwer { - function getValue() external view returns(uint); - function getOwner() external view returns(uint); -} -contract C { - function getOutsideMethod() external returns (uint) { - return a(); - } - function getAbstractName() public returns(string memory) { - return type(abvd).name; - } - function getInterfaceName() public returns(string memory) { - return type(qwer).name; - } -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/ParentTypeBug.sol b/framework/src/test/resources/soliditycode_0.7.6/ParentTypeBug.sol deleted file mode 100644 index 897c843ae24..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/ParentTypeBug.sol +++ /dev/null @@ -1,13 +0,0 @@ -contract Parent { - uint256 public m_aMember; - address public m_bMember; -} -contract Child is Parent { - function foo() public view returns (uint256) { return Parent.m_aMember; } - function bar() public view returns (address) { return Parent.m_bMember; } - - // complie failed - // function foo() public pure returns (uint256) { return Parent.m_aMember; } - // function bar() public pure returns (address) { return Parent.m_bMember; } - -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/SafeMath.sol b/framework/src/test/resources/soliditycode_0.7.6/SafeMath.sol deleted file mode 100644 index 1a7f1be2b8e..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/SafeMath.sol +++ /dev/null @@ -1,149 +0,0 @@ - - -/** - * @dev Wrappers over Solidity's arithmetic operations with added overflow - * checks. - * - * Arithmetic operations in Solidity wrap on overflow. This can easily result - * in bugs, because programmers usually assume that an overflow raises an - * error, which is the standard behavior in high level programming languages. - * `SafeMath` restores this intuition by reverting the transaction when an - * operation overflows. - * - * Using this library instead of the unchecked operations eliminates an entire - * class of bugs, so it's recommended to use it always. - */ -library SafeMath { - /** - * @dev Returns the addition of two unsigned integers, reverting on - * overflow. - * - * Counterpart to Solidity's `+` operator. - * - * Requirements: - * - Addition cannot overflow. - */ - function add(uint256 a, uint256 b) internal pure returns (uint256) { - uint256 c = a + b; - require(c >= a, "SafeMath: addition overflow"); - - return c; - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting on - * overflow (when the result is negative). - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - Subtraction cannot overflow. - */ - function sub(uint256 a, uint256 b) internal pure returns (uint256) { - return sub(a, b, "SafeMath: subtraction overflow"); - } - - /** - * @dev Returns the subtraction of two unsigned integers, reverting with custom message on - * overflow (when the result is negative). - * - * Counterpart to Solidity's `-` operator. - * - * Requirements: - * - Subtraction cannot overflow. - */ - function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b <= a, errorMessage); - uint256 c = a - b; - - return c; - } - - /** - * @dev Returns the multiplication of two unsigned integers, reverting on - * overflow. - * - * Counterpart to Solidity's `*` operator. - * - * Requirements: - * - Multiplication cannot overflow. - */ - function mul(uint256 a, uint256 b) internal pure returns (uint256) { - // Gas optimization: this is cheaper than requiring 'a' not being zero, but the - // benefit is lost if 'b' is also tested. - // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 - if (a == 0) { - return 0; - } - - uint256 c = a * b; - require(c / a == b, "SafeMath: multiplication overflow"); - - return c; - } - - /** - * @dev Returns the integer division of two unsigned integers. Reverts on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. Note: this function uses a - * `revert` opcode (which leaves remaining gas untouched) while Solidity - * uses an invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - return div(a, b, "SafeMath: division by zero"); - } - - /** - * @dev Returns the integer division of two unsigned integers. Reverts with custom message on - * division by zero. The result is rounded towards zero. - * - * Counterpart to Solidity's `/` operator. Note: this function uses a - * `revert` opcode (which leaves remaining gas untouched) while Solidity - * uses an invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b > 0, errorMessage); - uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - - return c; - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * Reverts when dividing by zero. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function mod(uint256 a, uint256 b) internal pure returns (uint256) { - return mod(a, b, "SafeMath: modulo by zero"); - } - - /** - * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), - * Reverts with custom message when dividing by zero. - * - * Counterpart to Solidity's `%` operator. This function uses a `revert` - * opcode (which leaves remaining gas untouched) while Solidity uses an - * invalid opcode to revert (consuming all remaining gas). - * - * Requirements: - * - The divisor cannot be zero. - */ - function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { - require(b != 0, errorMessage); - return a % b; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/ShiftCommand001.sol b/framework/src/test/resources/soliditycode_0.7.6/ShiftCommand001.sol deleted file mode 100644 index 574ee2b571b..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/ShiftCommand001.sol +++ /dev/null @@ -1,18 +0,0 @@ -contract TestBitwiseShift { - - function shlTest(uint256 num, uint256 input) public returns (bytes32 out) { - assembly { - out := shl(num, input) - } - } - function shrTest(uint256 num, uint256 input) public returns (bytes32 out) { - assembly { - out := shr(num, input) - } - } - function sarTest(uint256 num, uint256 input) public returns (bytes32 out) { - assembly { - out := sar(num, input) - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/SolidityMappingFix.sol b/framework/src/test/resources/soliditycode_0.7.6/SolidityMappingFix.sol deleted file mode 100644 index 67692d3b4ae..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/SolidityMappingFix.sol +++ /dev/null @@ -1,9 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Tests { - mapping(address => uint) public balances; - function update(uint256 amount) public returns (address addr) - { - balances[msg.sender] = amount; - return msg.sender; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/TestMappings_array_pop.sol b/framework/src/test/resources/soliditycode_0.7.6/TestMappings_array_pop.sol deleted file mode 100644 index 0d5c4bb7013..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TestMappings_array_pop.sol +++ /dev/null @@ -1,19 +0,0 @@ -contract C { - mapping (uint256 => uint256)[] a; - - function n1(uint256 key, uint256 value) public { - a.push(); - a[a.length - 1][key] = value; - } - - - - function map(uint256 key) public view returns (uint) { - return a[a.length - 1][key]; - } - - function p() public { - a.pop(); - } -} - diff --git a/framework/src/test/resources/soliditycode_0.7.6/TransferFailed001.sol b/framework/src/test/resources/soliditycode_0.7.6/TransferFailed001.sol deleted file mode 100644 index e35cd04f590..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TransferFailed001.sol +++ /dev/null @@ -1,147 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - - function testTransferTokenCompiledLongMax() payable public{ - address(0x1).transferToken(1,9223372036855775827); - } - - function testTransferTokenCompiled() payable public{ - address(0x1).transferToken(1,1); - } - - function testTransferTokenCompiledLongMin() payable public{ - //address(0x1).transferToken(1,-9223372036855775828); - } - - function testTransferTokenCompiledLongMin1() payable public returns(uint256){ - return address(0x2).tokenBalance(trcToken(-9223372036855775828)); - } - - function testTransferTokenCompiled1() payable public returns(uint256){ - return address(0x1).tokenBalance(trcToken(1)); - } - - function testTransferTokenCompiledLongMax1() payable public returns(uint256){ - return address(0x2).tokenBalance(trcToken(9223372036855775827)); - } - - function testTransferTokenCompiledTokenId(uint256 tokenid) payable public returns(uint256){ - return address(0x1).tokenBalance(trcToken(tokenid)); - } - - function testTransferTokenTest(address addr ,uint256 tokenid) payable public returns(uint256){ - return addr.tokenBalance(trcToken(tokenid)); - } - - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address payable caller) public { - caller.call{value:i}(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller){value:i}(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - nonexistentTarget.send(i); - } - - function testSendTrxRevert(uint256 i,address payable nonexistentTarget) payable public { - nonexistentTarget.send(i); - revert(); - } - - function testTransferTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - nonexistentTarget.transfer(i); - } - - function testTransferTrxrevert(uint256 i,address payable nonexistentTarget) payable public{ - nonexistentTarget.transfer(i); - revert(); - } - - function testTransferTokenNonexistentTarget(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - nonexistentTarget.transferToken(i, tokenId); - } - - function testTransferTokenRevert(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - nonexistentTarget.transferToken(i, tokenId); - revert(); - } - - function testCallTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - nonexistentTarget.call{value:i}(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - function testSuicideRevert(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - revert(); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - address payable self = address(uint160(address(this))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - address payable self = address(uint160(address(this))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - address payable self = address(uint160(address(this))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } - function deploy2(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(300, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/TransferFailed005.sol b/framework/src/test/resources/soliditycode_0.7.6/TransferFailed005.sol deleted file mode 100644 index 0a1a9d1849e..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TransferFailed005.sol +++ /dev/null @@ -1,90 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address payable caller) public returns (bool,bytes memory){ - return caller.call{value:i}(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller){value:i}(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.send(i); - } - - function testTransferTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.transfer(i); - } - - function testTransferTokenNonexistentTarget(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - require(address(this).balance >= i); - nonexistentTarget.transferToken(i, tokenId); - } - - function testCallTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.call{value:i}(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256 ){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/TransferFailed006.sol b/framework/src/test/resources/soliditycode_0.7.6/TransferFailed006.sol deleted file mode 100644 index 0a1a9d1849e..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TransferFailed006.sol +++ /dev/null @@ -1,90 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address payable caller) public returns (bool,bytes memory){ - return caller.call{value:i}(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller){value:i}(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.send(i); - } - - function testTransferTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.transfer(i); - } - - function testTransferTokenNonexistentTarget(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - require(address(this).balance >= i); - nonexistentTarget.transferToken(i, tokenId); - } - - function testCallTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.call{value:i}(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256 ){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/TransferFailed007.sol b/framework/src/test/resources/soliditycode_0.7.6/TransferFailed007.sol deleted file mode 100644 index 0a1a9d1849e..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TransferFailed007.sol +++ /dev/null @@ -1,90 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address payable caller) public returns (bool,bytes memory){ - return caller.call{value:i}(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller){value:i}(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.send(i); - } - - function testTransferTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.transfer(i); - } - - function testTransferTokenNonexistentTarget(uint256 i,address payable nonexistentTarget, trcToken tokenId) payable public { - require(address(this).balance >= i); - nonexistentTarget.transferToken(i, tokenId); - } - - function testCallTrxNonexistentTarget(uint256 i,address payable nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.call{value:i}(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - require(address(this).balance >= i); - address payable self = address(uint160(address(this))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256 ){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant001.sol b/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant001.sol deleted file mode 100644 index b385850577d..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant001.sol +++ /dev/null @@ -1,28 +0,0 @@ - - -contract testConstantContract{ - uint256 public i; - function testPayable() public payable returns (uint256 z) { - i=1; - z=i; - return z; - } - function testNoPayable() public returns (uint256 z) { - i=1; - z=i; - return z; - } - function testView() public view returns (uint256 z) { - uint256 i=1; - return i; - } - function testPure() public pure returns (uint256 z) { - uint256 i=1; - return i; - } - function testView2() public view returns (uint256 z) { - uint256 i=1; - revert(); - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant002.sol b/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant002.sol deleted file mode 100644 index 7708d81792a..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant002.sol +++ /dev/null @@ -1,10 +0,0 @@ - - -contract testConstantContract{ - uint256 public i; - function testNoPayable() public returns (uint256 z) { - i=1; - z=i; - return z; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant003.sol b/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant003.sol deleted file mode 100644 index 947b3f610e6..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant003.sol +++ /dev/null @@ -1,18 +0,0 @@ - - -contract testConstantContract{ - function testView() public view returns (uint256 z) { - uint256 i=1; - return i; - } - - function testPure() public pure returns (uint256 z) { - uint256 i=1; - return i; - } - - function testPayable() public payable returns (uint256 z) { - uint256 i=1; - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant004.sol b/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant004.sol deleted file mode 100644 index 7fcb44950e7..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant004.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract testConstantContract{ -function testPure() public pure returns (uint256 z) { -uint256 i=1; -return i; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant015.sol b/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant015.sol deleted file mode 100644 index d926c43c824..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant015.sol +++ /dev/null @@ -1,24 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract TestConstract { - constructor () public { - } - function plusOne() public returns(uint){ - return 1; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant024.sol b/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant024.sol deleted file mode 100644 index 69ad3a2d5b5..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TriggerConstant024.sol +++ /dev/null @@ -1,9 +0,0 @@ - - -contract testConstantContract{ -function testView() public view returns (uint256 z) { -uint256 i=1; -revert(); -return i; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/TvmIsContract.sol b/framework/src/test/resources/soliditycode_0.7.6/TvmIsContract.sol deleted file mode 100644 index 4266b9e92ca..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TvmIsContract.sol +++ /dev/null @@ -1,15 +0,0 @@ -contract testIsContract{ -bool public isContrct; -constructor () public { - isContrct = address(this).isContract; -} -function testIsContractCommand(address a) public returns (bool) { -return (a.isContract); -} -function selfdestructContract(address payable a) public { - selfdestruct(a); -} -function testConstructor() public returns(bool){ - return isContrct; -} -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/TvmIsContract001.sol b/framework/src/test/resources/soliditycode_0.7.6/TvmIsContract001.sol deleted file mode 100644 index 77aae930b59..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TvmIsContract001.sol +++ /dev/null @@ -1,24 +0,0 @@ -contract testIsContract{ -bool public isContrct; -constructor () public { - isContrct = address(this).isContract; -} -function testIsContractCommand(address a) public returns (bool) { -return (a.isContract); -} - -function testIsContractView(address a) view public returns (bool) { -return (a.isContract); -} - -function selfdestructContract(address payable a) public { - selfdestruct(a); -} -function testConstructor() public returns(bool){ - return isContrct; -} - -function testConstructorView() public view returns(bool){ - return isContrct; -} -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/TvmIsContract002.sol b/framework/src/test/resources/soliditycode_0.7.6/TvmIsContract002.sol deleted file mode 100644 index 2fe474fd98c..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TvmIsContract002.sol +++ /dev/null @@ -1,5 +0,0 @@ -contract testIsContract{ -function testIsContractCommand(address a) public returns (bool) { -return (a.isContract); -} -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand043.sol b/framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand043.sol deleted file mode 100644 index 04d9f7dde28..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand043.sol +++ /dev/null @@ -1,18 +0,0 @@ -contract TestBitwiseShift { - - function shlTest(int256 num, int256 input) public returns (bytes32 out) { - assembly { - out := shl(num, input) - } - } - function shrTest(int256 num, int256 input) public returns (bytes32 out) { - assembly { - out := shr(num, input) - } - } - function sarTest(int256 num, int256 input) public returns (bytes32 out) { - assembly { - out := sar(num, input) - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand103.sol b/framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand103.sol deleted file mode 100644 index dbc7fd0f0f4..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand103.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract testConstantContract{ -function testView() public constant returns (uint256 z) { -uint256 i=1; -return i; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand107.sol b/framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand107.sol deleted file mode 100644 index 5b51cd1842c..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand107.sol +++ /dev/null @@ -1,9 +0,0 @@ - - - contract testConstantContract{ - int256 public i; - function testPayable() public returns (int z) { - z=1+1; - return z; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand108.sol b/framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand108.sol deleted file mode 100644 index 0088054faf9..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand108.sol +++ /dev/null @@ -1,7 +0,0 @@ - - - contract testConstantContract{ - function test() pure public returns (int z) { - return 1; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand109.sol b/framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand109.sol deleted file mode 100644 index dc8dd1e8399..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TvmNewCommand109.sol +++ /dev/null @@ -1,7 +0,0 @@ - - - contract testConstantContract{ - function test() view public returns (int z) { - return 1; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/TvmOldCommand001.sol b/framework/src/test/resources/soliditycode_0.7.6/TvmOldCommand001.sol deleted file mode 100644 index f2927bd8e45..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/TvmOldCommand001.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract binaryRightContract{ - function binaryMoveR(uint i)public returns (uint z) { - return z = 5 >> i; - } - function binaryLiftR(uint i)public returns (uint z) { - return z = 5 << i; - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/VerifyBurnProof001.sol b/framework/src/test/resources/soliditycode_0.7.6/VerifyBurnProof001.sol deleted file mode 100644 index 4173e84de23..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/VerifyBurnProof001.sol +++ /dev/null @@ -1,20 +0,0 @@ - -contract VerifyBurnProof001Test { - // verifyBurnProof(bytes32[10],bytes32[2],uint64,bytes32[2],bytes32) - // size = 512 - // - - function VerifyBurnProofSize001(bytes32[10] memory output, bytes32[2] memory spendAuthoritySignature, uint64 value, bytes32[2] memory bindingSignature,bytes32 signHash) public returns (bool){ - return verifyBurnProof(output, spendAuthoritySignature, value, bindingSignature, signHash); - } - - function VerifyBurnProofSize002(bytes memory data) public returns (bool, bytes memory){ - // bytes memory empty = ""; - return address(0x1000003).delegatecall(data); - } - - function VerifyBurnProofSize003() public returns (bool, bytes memory){ - bytes memory empty = ""; - return address(0x1000003).delegatecall(empty); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/VerifyMintProof001.sol b/framework/src/test/resources/soliditycode_0.7.6/VerifyMintProof001.sol deleted file mode 100644 index cb0812c2ef5..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/VerifyMintProof001.sol +++ /dev/null @@ -1,33 +0,0 @@ - -contract VerifyMintProof001Test { - // verifyMintProof(bytes32[9],bytes32[2],uint64,bytes32,bytes32[33],uint256) - - function VerifyMintProofSize001(bytes32[9] memory output, bytes32[2] memory bindingSignature, uint64 value, bytes32 signHash, bytes32[33] memory frontier,uint256 leafCount) public returns (bytes32[] memory){ - return verifyMintProof(output, bindingSignature, value, signHash, frontier, leafCount); - } - - function VerifyMintProofSize002(bytes memory data) public returns (bool, bytes memory){ -// address verifyMint = address (0x1000001); -// -// assembly { -// let succeeded := delegatecall(sub(gas, 5000), verifyMint, add(data, 0x20), mload(data), 0, 0) -// let size := returndatasize -// let response := mload(0x40) -// mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f)))) -// mstore(response, size) -// returndatacopy(add(response, 0x20), 0, size) -// switch iszero(succeeded) -// case 1 { -// // throw if delegatecall failed -// revert(add(response, 0x20), size) -// } -// } - - return address(0x1000001).delegatecall(data); - } - - function VerifyMintProofSize003() public returns (bool, bytes memory){ - bytes memory empty = ""; - return address(0x1000001).call(empty); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/abiencode.sol b/framework/src/test/resources/soliditycode_0.7.6/abiencode.sol deleted file mode 100644 index 38fad3454d6..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/abiencode.sol +++ /dev/null @@ -1,16 +0,0 @@ -pragma experimental ABIEncoderV2; - -// tests encoding from storage arrays - -contract AbiEncode { - int256[2][] tmp_h; - function h(int256[2][] calldata s) external returns (bytes memory) { - tmp_h = s; - return abi.encode(tmp_h); - } - int256[2][2] tmp_i; - function i(int256[2][2] calldata s) external returns (bytes memory) { - tmp_i = s; - return abi.encode(tmp_i); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/abstract001.sol b/framework/src/test/resources/soliditycode_0.7.6/abstract001.sol deleted file mode 100644 index 741f236925d..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/abstract001.sol +++ /dev/null @@ -1,11 +0,0 @@ -//pragma solidity ^0.6.0; - -interface X { - function setValue(uint _x) external; - function setBalance(uint _x) external; -} - -abstract contract abstract001 is X { - uint x; - function setX(uint _x) public { x = _x; } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/abstract002.sol b/framework/src/test/resources/soliditycode_0.7.6/abstract002.sol deleted file mode 100644 index 7358fc8e163..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/abstract002.sol +++ /dev/null @@ -1,13 +0,0 @@ -//pragma solidity ^0.6.0; - -interface X { - function setValue(uint _x) external; - function setBalance(uint _x) external; -} - -abstract contract abstract002 is X { - uint x; - function setX(uint _x) public { x = _x; } - function setValue(uint _x) external override{ x = _x; } - function setBalance(uint _x) external override{ x = _x; } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/accountAssert.sol b/framework/src/test/resources/soliditycode_0.7.6/accountAssert.sol deleted file mode 100644 index 9ddeea64d91..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/accountAssert.sol +++ /dev/null @@ -1,94 +0,0 @@ -//pragma solidity ^0.6.0; - -contract transferTokenTestA { - - // transfer trc10 to a new address or exist address in constructor - constructor(address payable toAddress, uint256 tokenValue, trcToken id) payable public{ - toAddress.transferToken(tokenValue, id); - require(toAddress.tokenBalance(id) > 0, "tokenBalance should not be 0"); - } - - fallback() payable external{} - - function transferTest(address payable toAddress, uint256 tokenValue) payable public { - toAddress.transfer(tokenValue); - } - - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - - // suicide to a new address - function selfdestructTest(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - - // transfer to a new contract - function createContractTest(uint256 tokenValue, trcToken id) payable public returns(address){ - Simple s = new Simple(); - require(address(s).tokenBalance(id)==0, "tokenBalance should be 0"); - address(s).transferToken(tokenValue, id); - require(address(s).tokenBalance(id)==tokenValue, "tokenBalance should not be 0"); - return address(s); - } - - // revert transfer to a new contract - function revertCreateContractTest(uint256 tokenValue, trcToken id) payable public { - Simple s = new Simple(); - address(s).transferToken(tokenValue, id); - revert(); - } -} - -contract transferTokenTestB { - - constructor() payable public{ - } - - fallback() payable external{} - - function transferTest(address payable toAddress, uint256 tokenValue) payable public { - toAddress.transfer(tokenValue); - } - - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - - // suicide to a new address - function selfdestructTest(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - - // transfer to a new contract - function createContractTest(uint256 tokenValue, trcToken id) payable public returns(address){ - Simple s = new Simple(); - require(address(s).tokenBalance(id)==0, "tokenBalance should be 0"); - address(s).transferToken(tokenValue, id); - require(address(s).tokenBalance(id)==tokenValue, "tokenBalance should not be 0"); - return address(s); - } - - // revert transfer to a new contract - function revertCreateContractTest(uint256 tokenValue, trcToken id) payable public { - Simple s = new Simple(); - address(s).transferToken(tokenValue, id); - revert(); - } -} - -contract transferTokenTestC { - Simple public s; - - // transfer to a new address in constructor - constructor(trcToken id) payable public{ - s = new Simple(); - require(address(s).tokenBalance(id)==0, "new contract tokenBalance should be 0"); - require(address(this).tokenBalance(id)==0, "this.tokenBalance should be 0"); - } -} - -contract Simple { - constructor() payable public{} - fallback() payable external{} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/addMsg001Nonpayable.sol b/framework/src/test/resources/soliditycode_0.7.6/addMsg001Nonpayable.sol deleted file mode 100644 index fcd40cdb521..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/addMsg001Nonpayable.sol +++ /dev/null @@ -1,20 +0,0 @@ - - -contract IllegalDecorate { - -event log(uint256); -constructor() payable public{} - -fallback() payable external{} - -function transferTokenWithOutPayable(address payable toAddress, uint256 tokenValue)public { -// function transferTokenWithValue(address toAddress, uint256 tokenValue) payable public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); - -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/addMsg002View.sol b/framework/src/test/resources/soliditycode_0.7.6/addMsg002View.sol deleted file mode 100644 index 0c04b5c0b8a..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/addMsg002View.sol +++ /dev/null @@ -1,20 +0,0 @@ - - -contract IllegalDecorate { - -constructor() payable public{} - -fallback() payable external{} - -event log(uint256); - -function transferTokenWithView(address payable toAddress, uint256 tokenValue) public view{ -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} - diff --git a/framework/src/test/resources/soliditycode_0.7.6/addMsg003Constant.sol b/framework/src/test/resources/soliditycode_0.7.6/addMsg003Constant.sol deleted file mode 100644 index 2065802bed1..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/addMsg003Constant.sol +++ /dev/null @@ -1,19 +0,0 @@ - - -contract IllegalDecorate { - -constructor() payable public{} - -fallback() payable external{} - -event log(uint256); - -function transferTokenWithConstant(address payable toAddress, uint256 tokenValue) public constant{ -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/addMsg004Pure.sol b/framework/src/test/resources/soliditycode_0.7.6/addMsg004Pure.sol deleted file mode 100644 index 25f1a36d8b7..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/addMsg004Pure.sol +++ /dev/null @@ -1,19 +0,0 @@ - - -contract IllegalDecorate { - -constructor() payable public{} - -fallback() payable external{} - -event log(uint256); - -function transferTokenWithPure(address payable toAddress, uint256 tokenValue) public pure{ -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/addTransferToken001Nonpayable.sol b/framework/src/test/resources/soliditycode_0.7.6/addTransferToken001Nonpayable.sol deleted file mode 100644 index 039b341b6ac..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/addTransferToken001Nonpayable.sol +++ /dev/null @@ -1,13 +0,0 @@ - - - contract IllegalDecorate { - - constructor() payable public{} - - fallback() payable external{} - - function transferTokenWithOutPayable(address payable toAddress,trcToken id, uint256 tokenValue)public { - - toAddress.transferToken(tokenValue, id); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/addTransferToken001payable.sol b/framework/src/test/resources/soliditycode_0.7.6/addTransferToken001payable.sol deleted file mode 100644 index 17078e30189..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/addTransferToken001payable.sol +++ /dev/null @@ -1,13 +0,0 @@ - - - contract IllegalDecorate { - - constructor() payable public{} - - fallback() payable external{} - - function transferTokenWithOutPayable(address payable toAddress,trcToken id, uint256 tokenValue) public payable{ - - toAddress.transferToken(tokenValue, id); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/addTransferToken002View.sol b/framework/src/test/resources/soliditycode_0.7.6/addTransferToken002View.sol deleted file mode 100644 index c50a16390f5..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/addTransferToken002View.sol +++ /dev/null @@ -1,15 +0,0 @@ - - -contract IllegalDecorate { - - constructor() payable public{} - - fallback() payable external{} - - function transferTokenWithView(address payable toAddress,trcToken id, uint256 tokenValue) public view{ - - toAddress.transferToken(tokenValue, id); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/addTransferToken003Constant.sol b/framework/src/test/resources/soliditycode_0.7.6/addTransferToken003Constant.sol deleted file mode 100644 index 18721d9b94c..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/addTransferToken003Constant.sol +++ /dev/null @@ -1,14 +0,0 @@ - -contract IllegalDecorate { - - constructor() payable public{} - - fallback() payable external{} - - function transferTokenWithConstant(address payable toAddress, uint256 tokenValue) public constant{ - - toAddress.transferToken(tokenValue, 0x6e6d62); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/addTransferToken004Pure.sol b/framework/src/test/resources/soliditycode_0.7.6/addTransferToken004Pure.sol deleted file mode 100644 index f7716ee3874..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/addTransferToken004Pure.sol +++ /dev/null @@ -1,15 +0,0 @@ - - -contract IllegalDecorate { - - constructor() payable public{} - - fallback() payable external{} - - function transferTokenWithPure(address payable toAddress, uint256 tokenValue) public pure{ - - toAddress.transferToken(tokenValue, 0x6e6d62); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/addTrcToken001Assemble.sol b/framework/src/test/resources/soliditycode_0.7.6/addTrcToken001Assemble.sol deleted file mode 100644 index fe7a7f4cef8..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/addTrcToken001Assemble.sol +++ /dev/null @@ -1,62 +0,0 @@ - - -contract InAssemble { - -mapping(trcToken => uint256) tokenCnt; -mapping(uint256 => mapping(trcToken => trcToken)) cntTokenToken; -constructor () payable public {} -function getBalance (address addr) view public returns(uint256 r) { -assembly{ -r := balance(addr) -} -} - -function getTokenBalanceConstant (address addr, trcToken tokenId) view public returns(uint256 r) { -assembly{ -r := tokenbalance(tokenId, addr) -} -} - -function getTokenBalance (address addr, trcToken tokenId) public returns(uint256 r) { -assembly{ -r := tokenbalance(tokenId, addr) -} -} - -function transferTokenInAssembly(address addr, trcToken tokenId, uint256 tokenValue) public payable { -bytes4 sig = bytes4(keccak256("()")); // function signature - -assembly { -let x := mload(0x40) // get empty storage location -mstore(x,sig) // 4 bytes - place signature in empty storage - -let ret := calltoken(gas, addr, tokenValue, tokenId, -x, // input -0x04, // input size = 4 bytes -x, // output stored at input location, save space -0x0 // output size = 0 bytes -) - -// let ret := calltoken(gas, addr, tokenValue, -// x, // input -// 0x04, // input size = 4 bytes -// x, // output stored at input location, save space -// 0x0 // output size = 0 bytes -// ) // ERROR - - -mstore(0x40, add(x,0x20)) // update free memory pointer -} - -} - -function trcTokenInMap(trcToken tokenId, uint256 tokenValue) public returns(uint256 r) { -tokenCnt[tokenId] += tokenValue; -r = tokenCnt[tokenId]; -} - -function cntTokenTokenInMap(trcToken tokenId1, trcToken tokenId2, uint256 tokenValue) public returns(trcToken r) { -cntTokenToken[tokenValue][tokenId1] = tokenId2; -r = cntTokenToken[tokenValue][tokenId1]; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/addTrcToken002Cat.sol b/framework/src/test/resources/soliditycode_0.7.6/addTrcToken002Cat.sol deleted file mode 100644 index 0cd407079ba..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/addTrcToken002Cat.sol +++ /dev/null @@ -1,2051 +0,0 @@ - - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) public onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address payable public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address payable _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() public onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - emit Transfer(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(now), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - uint256 newKittenId = kitties.push(_kitty) - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - emit Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(address(0), _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -contract ERC721 { - // Required methods - function totalSupply() public view returns (uint256 total); - function balanceOf(address _owner) public view returns (uint256 balance); - function ownerOf(uint256 _tokenId) external view returns (address owner); - function approve(address _to, uint256 _tokenId) external; - function transfer(address _to, uint256 _tokenId) external; - function transferFrom(address _from, address _to, uint256 _tokenId) external; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) external view returns (bool); -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is ERC721, KittyBase { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public view returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - emit Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() public view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - external - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] memory _rawBytes, uint256 _stringLength) private view returns (string memory) { - string memory outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string calldata _preferredTransport) external view returns (string memory infoUrl) { - require( address(erc721Metadata) != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2 sun; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty memory _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty memory _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - emit Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.transfer(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, address(saleAuction)); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, address(siringAuction)); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid.value(msg.value - autoBirthFee)(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10 sun; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, address(saleAuction)); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(uint160(address(this))) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - constructor() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - emit ContractUpgrade(_v2Address); - } - - /// @notice No tipping! - /// @dev Reject all Ether from being sent here, unless it's from one of the - /// two auction contracts. (Hopefully, we can prevent user accidents.) - fallback() external payable { - require( - msg.sender == address(saleAuction) || - msg.sender == address(siringAuction) - ); - } - - /// @notice Returns all the relevant information about a specific kitty. - /// @param _id The ID of the kitty of interest. - function getKitty(uint256 _id) - external - view - returns ( - bool isGestating, - bool isReady, - uint256 cooldownIndex, - uint256 nextActionAt, - uint256 siringWithId, - uint256 birthTime, - uint256 matronId, - uint256 sireId, - uint256 generation, - uint256 genes - ) { - Kitty storage kit = kitties[_id]; - - // if this variable is 0 then it's not gestating - isGestating = (kit.siringWithId != 0); - isReady = (kit.cooldownEndBlock <= block.number); - cooldownIndex = uint256(kit.cooldownIndex); - nextActionAt = uint256(kit.cooldownEndBlock); - siringWithId = uint256(kit.siringWithId); - birthTime = uint256(kit.birthTime); - matronId = uint256(kit.matronId); - sireId = uint256(kit.sireId); - generation = uint256(kit.generation); - genes = kit.genes; - } - - /// @dev Override unpause so it requires all external contract addresses - /// to be set before contract can be unpaused. Also, we can't have - /// newContractAddress set either, because then the contract was upgraded. - /// @notice This is public rather than external so we can call super.unpause - /// without using an expensive CALL. - - function unpause(address payable toAddress, uint256 tokenValue, trcToken tokenId) public onlyCEO whenPaused returns (uint256 r) { - require(address(saleAuction) != address(0)); - require(address(siringAuction) != address(0)); - require(address(geneScience) != address(0)); - require(address(newContractAddress) == address(0)); - toAddress.transferToken(tokenValue, tokenId); - r = address(this).tokenBalance(tokenId); - // Actually unpause the contract. - super.unpause(); - } - - // @dev Allows the CFO to capture the balance available to the contract. - function withdrawBalance() external onlyCFO { - uint256 balance = address(this).balance; - // Subtract all the currently pregnant kittens we have, plus 1 of margin. - uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - - if (balance > subtractFees) { - cfoAddress.transfer(balance - subtractFees); - } - } -} - - - - - - - - - - - - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - - function isGeneScience() public pure returns (bool){ - return true; - } - - /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor - /// @param genes1 genes of mom - /// @param genes2 genes of sire - /// @return the genes that are supposed to be passed down the child - function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - - return (genes1+genes2+targetBlock)/2; - - -} -} - - - - - - - - - - - - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { - /// @dev Given a token Id, returns a byte array that is supposed to be converted into string. - function getMetadata(uint256 _tokenId, string memory) public view returns (bytes32[4] memory buffer, uint256 count) { - if (_tokenId == 1) { - buffer[0] = "Hello World! :D"; - count = 15; - } else if (_tokenId == 2) { - buffer[0] = "I would definitely choose a medi"; - buffer[1] = "um length string."; - count = 49; - } else if (_tokenId == 3) { - buffer[0] = "Lorem ipsum dolor sit amet, mi e"; - buffer[1] = "st accumsan dapibus augue lorem,"; - buffer[2] = " tristique vestibulum id, libero"; - buffer[3] = " suscipit varius sapien aliquam."; - count = 128; - } - } -} - - - - - - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - - // Represents an auction on an NFT - struct Auction { - // Current owner of NFT - address payable seller; - // Price (in wei) at beginning of auction - uint128 startingPrice; - // Price (in wei) at end of auction - uint128 endingPrice; - // Duration (in seconds) of auction - uint64 duration; - // Time when auction started - // NOTE: 0 if this auction has been concluded - uint64 startedAt; - } - - // Reference to contract tracking NFT ownership - ERC721 public nonFungibleContract; - - // Cut owner takes on each auction, measured in basis points (1/100 of a percent). - // Values 0-10,000 map to 0%-100% - uint256 public ownerCut; - - // Map from token ID to their corresponding auction. - mapping (uint256 => Auction) tokenIdToAuction; - - event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); - event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); - event AuctionCancelled(uint256 tokenId); - - /// @dev Returns true if the claimant owns the token. - /// @param _claimant - Address claiming to own the token. - /// @param _tokenId - ID of token whose ownership to verify. - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return (nonFungibleContract.ownerOf(_tokenId) == _claimant); - } - - /// @dev Escrows the NFT, assigning ownership to this contract. - /// Throws if the escrow fails. - /// @param _owner - Current owner address of token to escrow. - /// @param _tokenId - ID of token whose approval to verify. - function _escrow(address _owner, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transferFrom(_owner, address(this), _tokenId); - } - - /// @dev Transfers an NFT owned by this contract to another address. - /// Returns true if the transfer succeeds. - /// @param _receiver - Address to transfer NFT to. - /// @param _tokenId - ID of token to transfer. - function _transfer(address _receiver, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transfer(_receiver, _tokenId); - } - - /// @dev Adds an auction to the list of open auctions. Also fires the - /// AuctionCreated event. - /// @param _tokenId The ID of the token to be put on auction. - /// @param _auction Auction to add. - function _addAuction(uint256 _tokenId, Auction memory _auction) internal { - // Require that all auctions have a duration of - // at least one minute. (Keeps our math from getting hairy!) - require(_auction.duration >= 1 minutes); - - tokenIdToAuction[_tokenId] = _auction; - - emit AuctionCreated( - uint256(_tokenId), - uint256(_auction.startingPrice), - uint256(_auction.endingPrice), - uint256(_auction.duration) - ); - } - - /// @dev Cancels an auction unconditionally. - function _cancelAuction(uint256 _tokenId, address _seller) internal { - _removeAuction(_tokenId); - _transfer(_seller, _tokenId); - emit AuctionCancelled(_tokenId); - } - - /// @dev Computes the price and transfers winnings. - /// Does NOT transfer ownership of token. - function _bid(uint256 _tokenId, uint256 _bidAmount) - internal - returns (uint256) - { - // Get a reference to the auction struct - Auction storage auction = tokenIdToAuction[_tokenId]; - - // Explicitly check that this auction is currently live. - // (Because of how Ethereum mappings work, we can't just count - // on the lookup above failing. An invalid _tokenId will just - // return an auction object that is all zeros.) - require(_isOnAuction(auction)); - - // Check that the bid is greater than or equal to the current price - uint256 price = _currentPrice(auction); - require(_bidAmount >= price); - - // Grab a reference to the seller before the auction struct - // gets deleted. - address payable seller = auction.seller; - - // The bid is good! Remove the auction before sending the fees - // to the sender so we can't have a reentrancy attack. - _removeAuction(_tokenId); - - // Transfer proceeds to seller (if there are any!) - if (price > 0) { - // Calculate the auctioneer's cut. - // (NOTE: _computeCut() is guaranteed to return a - // value <= price, so this subtraction can't go negative.) - uint256 auctioneerCut = _computeCut(price); - uint256 sellerProceeds = price - auctioneerCut; - - // NOTE: Doing a transfer() in the middle of a complex - // method like this is generally discouraged because of - // reentrancy attacks and DoS attacks if the seller is - // a contract with an invalid fallback function. We explicitly - // guard against reentrancy attacks by removing the auction - // before calling transfer(), and the only thing the seller - // can DoS is the sale of their own asset! (And if it's an - // accident, they can call cancelAuction(). ) - seller.transfer(sellerProceeds); - } - - // Calculate any excess funds included with the bid. If the excess - // is anything worth worrying about, transfer it back to bidder. - // NOTE: We checked above that the bid amount is greater than or - // equal to the price so this cannot underflow. - uint256 bidExcess = _bidAmount - price; - - // Return the funds. Similar to the previous transfer, this is - // not susceptible to a re-entry attack because the auction is - // removed before any transfers occur. - msg.sender.transfer(bidExcess); - - // Tell the world! - emit AuctionSuccessful(_tokenId, price, msg.sender); - - return price; - } - - /// @dev Removes an auction from the list of open auctions. - /// @param _tokenId - ID of NFT on auction. - function _removeAuction(uint256 _tokenId) internal { - delete tokenIdToAuction[_tokenId]; - } - - /// @dev Returns true if the NFT is on auction. - /// @param _auction - Auction to check. - function _isOnAuction(Auction storage _auction) internal view returns (bool) { - return (_auction.startedAt > 0); - } - - /// @dev Returns current price of an NFT on auction. Broken into two - /// functions (this one, that computes the duration from the auction - /// structure, and the other that does the price computation) so we - /// can easily test that the price computation works correctly. - function _currentPrice(Auction storage _auction) - internal - view - returns (uint256) - { - uint256 secondsPassed = 0; - - // A bit of insurance against negative values (or wraparound). - // Probably not necessary (since Ethereum guarnatees that the - // now variable doesn't ever go backwards). - if (now > _auction.startedAt) { - secondsPassed = now - _auction.startedAt; - } - - return _computeCurrentPrice( - _auction.startingPrice, - _auction.endingPrice, - _auction.duration, - secondsPassed - ); - } - - /// @dev Computes the current price of an auction. Factored out - /// from _currentPrice so we can run extensive unit tests. - /// When testing, make this function public and turn on - /// `Current price computation` test suite. - function _computeCurrentPrice( - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - uint256 _secondsPassed - ) - internal - pure - returns (uint256) - { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our public functions carefully cap the maximum values for - // time (at 64-bits) and currency (at 128-bits). _duration is - // also known to be non-zero (see the require() statement in - // _addAuction()) - if (_secondsPassed >= _duration) { - // We've reached the end of the dynamic pricing portion - // of the auction, just return the end price. - return _endingPrice; - } else { - // Starting price can be higher than ending price (and often is!), so - // this delta can be negative. - int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - - // This multiplication can't overflow, _secondsPassed will easily fit within - // 64-bits, and totalPriceChange will easily fit within 128-bits, their product - // will always fit within 256-bits. - int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - - // currentPriceChange can be negative, but if so, will have a magnitude - // less that _startingPrice. Thus, this result will always end up positive. - int256 currentPrice = int256(_startingPrice) + currentPriceChange; - - return uint256(currentPrice); - } - } - - /// @dev Computes owner's cut of a sale. - /// @param _price - Sale price of NFT. - function _computeCut(uint256 _price) internal view returns (uint256) { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our entry functions carefully cap the maximum values for - // currency (at 128-bits), and ownerCut <= 10000 (see the require() - // statement in the ClockAuction constructor). The result of this - // function is always guaranteed to be <= _price. - return _price * ownerCut / 10000; - } - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { - event Pause(); - event Unpause(); - - bool public paused = false; - - - /** - * @dev modifier to allow actions only when the contract IS paused - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev modifier to allow actions only when the contract IS NOT paused - */ - modifier whenPaused { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyOwner whenNotPaused public returns (bool) { - paused = true; - emit Pause(); - return true; - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyOwner whenPaused public returns (bool) { - paused = false; - emit Unpause(); - return true; - } -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - - /// @dev The ERC-165 interface signature for ERC-721. - /// Ref: https://github.com/ethereum/EIPs/issues/165 - /// Ref: https://github.com/ethereum/EIPs/issues/721 - bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - - /// @dev Constructor creates a reference to the NFT ownership contract - /// and verifies the owner cut is in the valid range. - /// @param _nftAddress - address of a deployed contract implementing - /// the Nonfungible Interface. - /// @param _cut - percent cut the owner takes on each auction, must be - /// between 0-10,000. - constructor(address _nftAddress, uint256 _cut) public { - require(_cut <= 10000); - ownerCut = _cut; - - ERC721 candidateContract = ERC721(_nftAddress); - require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); - nonFungibleContract = candidateContract; - } - - /// @dev Remove all Ether from the contract, which is the owner's cuts - /// as well as any Ether sent directly to the contract address. - /// Always transfers to the NFT contract, but can be called either by - /// the owner or the NFT contract. - function withdrawBalance() external { - address payable nftAddress = address(uint160(address(nonFungibleContract))); - - require( - msg.sender == owner || - msg.sender == nftAddress - ); - // We are using this boolean method to make sure that even if one fails it will still work - bool res = nftAddress.send(address(this).balance); - } - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of time to move between starting - /// price and ending price (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - whenNotPaused - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(_owns(msg.sender, _tokenId)); - _escrow(msg.sender, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Bids on an open auction, completing the auction and transferring - /// ownership of the NFT if enough Ether is supplied. - /// @param _tokenId - ID of token to bid on. - function bid(uint256 _tokenId) - external - payable - whenNotPaused - { - // _bid will throw if the bid or funds transfer fails - _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - } - - /// @dev Cancels an auction that hasn't been won yet. - /// Returns the NFT to original owner. - /// @notice This is a state-modifying function that can - /// be called while the contract is paused. - /// @param _tokenId - ID of token on auction - function cancelAuction(uint256 _tokenId) - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - address seller = auction.seller; - require(msg.sender == seller); - _cancelAuction(_tokenId, seller); - } - - /// @dev Cancels an auction when the contract is paused. - /// Only the owner may do this, and NFTs are returned to - /// the seller. This should only be used in emergencies. - /// @param _tokenId - ID of the NFT on auction to cancel. - function cancelAuctionWhenPaused(uint256 _tokenId) - whenPaused - onlyOwner - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - _cancelAuction(_tokenId, auction.seller); - } - - /// @dev Returns auction info for an NFT on auction. - /// @param _tokenId - ID of NFT on auction. - function getAuction(uint256 _tokenId) - external - view - returns - ( - address seller, - uint256 startingPrice, - uint256 endingPrice, - uint256 duration, - uint256 startedAt - ) { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return ( - auction.seller, - auction.startingPrice, - auction.endingPrice, - auction.duration, - auction.startedAt - ); - } - - /// @dev Returns the current price of an auction. - /// @param _tokenId - ID of the token price we are checking. - function getCurrentPrice(uint256 _tokenId) - external - view - returns (uint256) - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return _currentPrice(auction); - } - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSiringAuctionAddress() call. - bool public isSiringClockAuction = true; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. Since this function is wrapped, - /// require sender to be KittyCore contract. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Places a bid for siring. Requires the sender - /// is the KittyCore contract because all bid methods - /// should be wrapped. Also returns the kitty to the - /// seller rather than the winner. - function bid(uint256 _tokenId) - external - payable - { - require(msg.sender == address(nonFungibleContract)); - address seller = tokenIdToAuction[_tokenId].seller; - // _bid checks that token ID is valid and will throw if bid fails - _bid(_tokenId, msg.value); - // We transfer the kitty back to the seller, the winner will get - // the offspring - _transfer(seller, _tokenId); - } - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSaleAuctionAddress() call. - bool public isSaleClockAuction = true; - - // Tracks last 5 sale price of gen0 kitty sales - uint256 public gen0SaleCount; - uint256[5] public lastGen0SalePrices; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Updates lastSalePrice if seller is the nft contract - /// Otherwise, works the same as default bid method. - function bid(uint256 _tokenId) - external - payable - { - // _bid verifies token ID size - address seller = tokenIdToAuction[_tokenId].seller; - uint256 price = _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - - // If not a gen0 auction, exit - if (seller == address(nonFungibleContract)) { - // Track gen0 sale prices - lastGen0SalePrices[gen0SaleCount % 5] = price; - gen0SaleCount++; - } - } - - function averageGen0SalePrice() external view returns (uint256) { - uint256 sum = 0; - for (uint256 i = 0; i < 5; i++) { - sum += lastGen0SalePrices[i]; - } - return sum / 5; - } - -} - - - - - - - diff --git a/framework/src/test/resources/soliditycode_0.7.6/addTrcToken002Cat_withFinny.sol b/framework/src/test/resources/soliditycode_0.7.6/addTrcToken002Cat_withFinny.sol deleted file mode 100644 index 24117bc5e6b..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/addTrcToken002Cat_withFinny.sol +++ /dev/null @@ -1,2051 +0,0 @@ - - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) public onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address payable public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address payable _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() public onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - emit Transfer(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(now), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - uint256 newKittenId = kitties.push(_kitty) - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - emit Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(address(0), _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -contract ERC721 { - // Required methods - function totalSupply() public view returns (uint256 total); - function balanceOf(address _owner) public view returns (uint256 balance); - function ownerOf(uint256 _tokenId) external view returns (address owner); - function approve(address _to, uint256 _tokenId) external; - function transfer(address _to, uint256 _tokenId) external; - function transferFrom(address _from, address _to, uint256 _tokenId) external; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) external view returns (bool); -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is ERC721, KittyBase { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public view returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - emit Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() public view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - external - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] memory _rawBytes, uint256 _stringLength) private view returns (string memory) { - string memory outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string calldata _preferredTransport) external view returns (string memory infoUrl) { - require( address(erc721Metadata) != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2 finney; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty memory _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty memory _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - emit Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.transfer(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, address(saleAuction)); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, address(siringAuction)); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid.value(msg.value - autoBirthFee)(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10 finney; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, address(saleAuction)); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(uint160(address(this))) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - constructor() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - emit ContractUpgrade(_v2Address); - } - - /// @notice No tipping! - /// @dev Reject all Ether from being sent here, unless it's from one of the - /// two auction contracts. (Hopefully, we can prevent user accidents.) - fallback() external payable { - require( - msg.sender == address(saleAuction) || - msg.sender == address(siringAuction) - ); - } - - /// @notice Returns all the relevant information about a specific kitty. - /// @param _id The ID of the kitty of interest. - function getKitty(uint256 _id) - external - view - returns ( - bool isGestating, - bool isReady, - uint256 cooldownIndex, - uint256 nextActionAt, - uint256 siringWithId, - uint256 birthTime, - uint256 matronId, - uint256 sireId, - uint256 generation, - uint256 genes - ) { - Kitty storage kit = kitties[_id]; - - // if this variable is 0 then it's not gestating - isGestating = (kit.siringWithId != 0); - isReady = (kit.cooldownEndBlock <= block.number); - cooldownIndex = uint256(kit.cooldownIndex); - nextActionAt = uint256(kit.cooldownEndBlock); - siringWithId = uint256(kit.siringWithId); - birthTime = uint256(kit.birthTime); - matronId = uint256(kit.matronId); - sireId = uint256(kit.sireId); - generation = uint256(kit.generation); - genes = kit.genes; - } - - /// @dev Override unpause so it requires all external contract addresses - /// to be set before contract can be unpaused. Also, we can't have - /// newContractAddress set either, because then the contract was upgraded. - /// @notice This is public rather than external so we can call super.unpause - /// without using an expensive CALL. - - function unpause(address payable toAddress, uint256 tokenValue, trcToken tokenId) public onlyCEO whenPaused returns (uint256 r) { - require(address(saleAuction) != address(0)); - require(address(siringAuction) != address(0)); - require(address(geneScience) != address(0)); - require(address(newContractAddress) == address(0)); - toAddress.transferToken(tokenValue, tokenId); - r = address(this).tokenBalance(tokenId); - // Actually unpause the contract. - super.unpause(); - } - - // @dev Allows the CFO to capture the balance available to the contract. - function withdrawBalance() external onlyCFO { - uint256 balance = address(this).balance; - // Subtract all the currently pregnant kittens we have, plus 1 of margin. - uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - - if (balance > subtractFees) { - cfoAddress.transfer(balance - subtractFees); - } - } -} - - - - - - - - - - - - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - - function isGeneScience() public pure returns (bool){ - return true; - } - - /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor - /// @param genes1 genes of mom - /// @param genes2 genes of sire - /// @return the genes that are supposed to be passed down the child - function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - - return (genes1+genes2+targetBlock)/2; - - -} -} - - - - - - - - - - - - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { - /// @dev Given a token Id, returns a byte array that is supposed to be converted into string. - function getMetadata(uint256 _tokenId, string memory) public view returns (bytes32[4] memory buffer, uint256 count) { - if (_tokenId == 1) { - buffer[0] = "Hello World! :D"; - count = 15; - } else if (_tokenId == 2) { - buffer[0] = "I would definitely choose a medi"; - buffer[1] = "um length string."; - count = 49; - } else if (_tokenId == 3) { - buffer[0] = "Lorem ipsum dolor sit amet, mi e"; - buffer[1] = "st accumsan dapibus augue lorem,"; - buffer[2] = " tristique vestibulum id, libero"; - buffer[3] = " suscipit varius sapien aliquam."; - count = 128; - } - } -} - - - - - - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - - // Represents an auction on an NFT - struct Auction { - // Current owner of NFT - address payable seller; - // Price (in wei) at beginning of auction - uint128 startingPrice; - // Price (in wei) at end of auction - uint128 endingPrice; - // Duration (in seconds) of auction - uint64 duration; - // Time when auction started - // NOTE: 0 if this auction has been concluded - uint64 startedAt; - } - - // Reference to contract tracking NFT ownership - ERC721 public nonFungibleContract; - - // Cut owner takes on each auction, measured in basis points (1/100 of a percent). - // Values 0-10,000 map to 0%-100% - uint256 public ownerCut; - - // Map from token ID to their corresponding auction. - mapping (uint256 => Auction) tokenIdToAuction; - - event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); - event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); - event AuctionCancelled(uint256 tokenId); - - /// @dev Returns true if the claimant owns the token. - /// @param _claimant - Address claiming to own the token. - /// @param _tokenId - ID of token whose ownership to verify. - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return (nonFungibleContract.ownerOf(_tokenId) == _claimant); - } - - /// @dev Escrows the NFT, assigning ownership to this contract. - /// Throws if the escrow fails. - /// @param _owner - Current owner address of token to escrow. - /// @param _tokenId - ID of token whose approval to verify. - function _escrow(address _owner, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transferFrom(_owner, address(this), _tokenId); - } - - /// @dev Transfers an NFT owned by this contract to another address. - /// Returns true if the transfer succeeds. - /// @param _receiver - Address to transfer NFT to. - /// @param _tokenId - ID of token to transfer. - function _transfer(address _receiver, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transfer(_receiver, _tokenId); - } - - /// @dev Adds an auction to the list of open auctions. Also fires the - /// AuctionCreated event. - /// @param _tokenId The ID of the token to be put on auction. - /// @param _auction Auction to add. - function _addAuction(uint256 _tokenId, Auction memory _auction) internal { - // Require that all auctions have a duration of - // at least one minute. (Keeps our math from getting hairy!) - require(_auction.duration >= 1 minutes); - - tokenIdToAuction[_tokenId] = _auction; - - emit AuctionCreated( - uint256(_tokenId), - uint256(_auction.startingPrice), - uint256(_auction.endingPrice), - uint256(_auction.duration) - ); - } - - /// @dev Cancels an auction unconditionally. - function _cancelAuction(uint256 _tokenId, address _seller) internal { - _removeAuction(_tokenId); - _transfer(_seller, _tokenId); - emit AuctionCancelled(_tokenId); - } - - /// @dev Computes the price and transfers winnings. - /// Does NOT transfer ownership of token. - function _bid(uint256 _tokenId, uint256 _bidAmount) - internal - returns (uint256) - { - // Get a reference to the auction struct - Auction storage auction = tokenIdToAuction[_tokenId]; - - // Explicitly check that this auction is currently live. - // (Because of how Ethereum mappings work, we can't just count - // on the lookup above failing. An invalid _tokenId will just - // return an auction object that is all zeros.) - require(_isOnAuction(auction)); - - // Check that the bid is greater than or equal to the current price - uint256 price = _currentPrice(auction); - require(_bidAmount >= price); - - // Grab a reference to the seller before the auction struct - // gets deleted. - address payable seller = auction.seller; - - // The bid is good! Remove the auction before sending the fees - // to the sender so we can't have a reentrancy attack. - _removeAuction(_tokenId); - - // Transfer proceeds to seller (if there are any!) - if (price > 0) { - // Calculate the auctioneer's cut. - // (NOTE: _computeCut() is guaranteed to return a - // value <= price, so this subtraction can't go negative.) - uint256 auctioneerCut = _computeCut(price); - uint256 sellerProceeds = price - auctioneerCut; - - // NOTE: Doing a transfer() in the middle of a complex - // method like this is generally discouraged because of - // reentrancy attacks and DoS attacks if the seller is - // a contract with an invalid fallback function. We explicitly - // guard against reentrancy attacks by removing the auction - // before calling transfer(), and the only thing the seller - // can DoS is the sale of their own asset! (And if it's an - // accident, they can call cancelAuction(). ) - seller.transfer(sellerProceeds); - } - - // Calculate any excess funds included with the bid. If the excess - // is anything worth worrying about, transfer it back to bidder. - // NOTE: We checked above that the bid amount is greater than or - // equal to the price so this cannot underflow. - uint256 bidExcess = _bidAmount - price; - - // Return the funds. Similar to the previous transfer, this is - // not susceptible to a re-entry attack because the auction is - // removed before any transfers occur. - msg.sender.transfer(bidExcess); - - // Tell the world! - emit AuctionSuccessful(_tokenId, price, msg.sender); - - return price; - } - - /// @dev Removes an auction from the list of open auctions. - /// @param _tokenId - ID of NFT on auction. - function _removeAuction(uint256 _tokenId) internal { - delete tokenIdToAuction[_tokenId]; - } - - /// @dev Returns true if the NFT is on auction. - /// @param _auction - Auction to check. - function _isOnAuction(Auction storage _auction) internal view returns (bool) { - return (_auction.startedAt > 0); - } - - /// @dev Returns current price of an NFT on auction. Broken into two - /// functions (this one, that computes the duration from the auction - /// structure, and the other that does the price computation) so we - /// can easily test that the price computation works correctly. - function _currentPrice(Auction storage _auction) - internal - view - returns (uint256) - { - uint256 secondsPassed = 0; - - // A bit of insurance against negative values (or wraparound). - // Probably not necessary (since Ethereum guarnatees that the - // now variable doesn't ever go backwards). - if (now > _auction.startedAt) { - secondsPassed = now - _auction.startedAt; - } - - return _computeCurrentPrice( - _auction.startingPrice, - _auction.endingPrice, - _auction.duration, - secondsPassed - ); - } - - /// @dev Computes the current price of an auction. Factored out - /// from _currentPrice so we can run extensive unit tests. - /// When testing, make this function public and turn on - /// `Current price computation` test suite. - function _computeCurrentPrice( - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - uint256 _secondsPassed - ) - internal - pure - returns (uint256) - { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our public functions carefully cap the maximum values for - // time (at 64-bits) and currency (at 128-bits). _duration is - // also known to be non-zero (see the require() statement in - // _addAuction()) - if (_secondsPassed >= _duration) { - // We've reached the end of the dynamic pricing portion - // of the auction, just return the end price. - return _endingPrice; - } else { - // Starting price can be higher than ending price (and often is!), so - // this delta can be negative. - int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - - // This multiplication can't overflow, _secondsPassed will easily fit within - // 64-bits, and totalPriceChange will easily fit within 128-bits, their product - // will always fit within 256-bits. - int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - - // currentPriceChange can be negative, but if so, will have a magnitude - // less that _startingPrice. Thus, this result will always end up positive. - int256 currentPrice = int256(_startingPrice) + currentPriceChange; - - return uint256(currentPrice); - } - } - - /// @dev Computes owner's cut of a sale. - /// @param _price - Sale price of NFT. - function _computeCut(uint256 _price) internal view returns (uint256) { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our entry functions carefully cap the maximum values for - // currency (at 128-bits), and ownerCut <= 10000 (see the require() - // statement in the ClockAuction constructor). The result of this - // function is always guaranteed to be <= _price. - return _price * ownerCut / 10000; - } - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { - event Pause(); - event Unpause(); - - bool public paused = false; - - - /** - * @dev modifier to allow actions only when the contract IS paused - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev modifier to allow actions only when the contract IS NOT paused - */ - modifier whenPaused { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyOwner whenNotPaused public returns (bool) { - paused = true; - emit Pause(); - return true; - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyOwner whenPaused public returns (bool) { - paused = false; - emit Unpause(); - return true; - } -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - - /// @dev The ERC-165 interface signature for ERC-721. - /// Ref: https://github.com/ethereum/EIPs/issues/165 - /// Ref: https://github.com/ethereum/EIPs/issues/721 - bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - - /// @dev Constructor creates a reference to the NFT ownership contract - /// and verifies the owner cut is in the valid range. - /// @param _nftAddress - address of a deployed contract implementing - /// the Nonfungible Interface. - /// @param _cut - percent cut the owner takes on each auction, must be - /// between 0-10,000. - constructor(address _nftAddress, uint256 _cut) public { - require(_cut <= 10000); - ownerCut = _cut; - - ERC721 candidateContract = ERC721(_nftAddress); - require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); - nonFungibleContract = candidateContract; - } - - /// @dev Remove all Ether from the contract, which is the owner's cuts - /// as well as any Ether sent directly to the contract address. - /// Always transfers to the NFT contract, but can be called either by - /// the owner or the NFT contract. - function withdrawBalance() external { - address payable nftAddress = address(uint160(address(nonFungibleContract))); - - require( - msg.sender == owner || - msg.sender == nftAddress - ); - // We are using this boolean method to make sure that even if one fails it will still work - bool res = nftAddress.send(address(this).balance); - } - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of time to move between starting - /// price and ending price (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - whenNotPaused - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(_owns(msg.sender, _tokenId)); - _escrow(msg.sender, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Bids on an open auction, completing the auction and transferring - /// ownership of the NFT if enough Ether is supplied. - /// @param _tokenId - ID of token to bid on. - function bid(uint256 _tokenId) - external - payable - whenNotPaused - { - // _bid will throw if the bid or funds transfer fails - _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - } - - /// @dev Cancels an auction that hasn't been won yet. - /// Returns the NFT to original owner. - /// @notice This is a state-modifying function that can - /// be called while the contract is paused. - /// @param _tokenId - ID of token on auction - function cancelAuction(uint256 _tokenId) - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - address seller = auction.seller; - require(msg.sender == seller); - _cancelAuction(_tokenId, seller); - } - - /// @dev Cancels an auction when the contract is paused. - /// Only the owner may do this, and NFTs are returned to - /// the seller. This should only be used in emergencies. - /// @param _tokenId - ID of the NFT on auction to cancel. - function cancelAuctionWhenPaused(uint256 _tokenId) - whenPaused - onlyOwner - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - _cancelAuction(_tokenId, auction.seller); - } - - /// @dev Returns auction info for an NFT on auction. - /// @param _tokenId - ID of NFT on auction. - function getAuction(uint256 _tokenId) - external - view - returns - ( - address seller, - uint256 startingPrice, - uint256 endingPrice, - uint256 duration, - uint256 startedAt - ) { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return ( - auction.seller, - auction.startingPrice, - auction.endingPrice, - auction.duration, - auction.startedAt - ); - } - - /// @dev Returns the current price of an auction. - /// @param _tokenId - ID of the token price we are checking. - function getCurrentPrice(uint256 _tokenId) - external - view - returns (uint256) - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return _currentPrice(auction); - } - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSiringAuctionAddress() call. - bool public isSiringClockAuction = true; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. Since this function is wrapped, - /// require sender to be KittyCore contract. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Places a bid for siring. Requires the sender - /// is the KittyCore contract because all bid methods - /// should be wrapped. Also returns the kitty to the - /// seller rather than the winner. - function bid(uint256 _tokenId) - external - payable - { - require(msg.sender == address(nonFungibleContract)); - address seller = tokenIdToAuction[_tokenId].seller; - // _bid checks that token ID is valid and will throw if bid fails - _bid(_tokenId, msg.value); - // We transfer the kitty back to the seller, the winner will get - // the offspring - _transfer(seller, _tokenId); - } - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSaleAuctionAddress() call. - bool public isSaleClockAuction = true; - - // Tracks last 5 sale price of gen0 kitty sales - uint256 public gen0SaleCount; - uint256[5] public lastGen0SalePrices; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Updates lastSalePrice if seller is the nft contract - /// Otherwise, works the same as default bid method. - function bid(uint256 _tokenId) - external - payable - { - // _bid verifies token ID size - address seller = tokenIdToAuction[_tokenId].seller; - uint256 price = _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - - // If not a gen0 auction, exit - if (seller == address(nonFungibleContract)) { - // Track gen0 sale prices - lastGen0SalePrices[gen0SaleCount % 5] = price; - gen0SaleCount++; - } - } - - function averageGen0SalePrice() external view returns (uint256) { - uint256 sum = 0; - for (uint256 i = 0; i < 5; i++) { - sum += lastGen0SalePrices[i]; - } - return sum / 5; - } - -} - - - - - - - diff --git a/framework/src/test/resources/soliditycode_0.7.6/addressCheckNew.sol b/framework/src/test/resources/soliditycode_0.7.6/addressCheckNew.sol deleted file mode 100644 index 3c10b8c680d..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/addressCheckNew.sol +++ /dev/null @@ -1,9 +0,0 @@ -pragma experimental ABIEncoderV2; -contract testIsContract{ - function checkAddress(address addr) public returns (address){ - return addr; - } - function checkAddress2(address addr) pure public returns(address){ - return addr; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/addressCheckOld.sol b/framework/src/test/resources/soliditycode_0.7.6/addressCheckOld.sol deleted file mode 100644 index 6c6b15d1736..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/addressCheckOld.sol +++ /dev/null @@ -1,8 +0,0 @@ -contract testIsContract{ - function checkAddress(address addr) public returns (address){ - return addr; - } - function checkAddress2(address addr) pure public returns (address){ - return addr; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/altbn.sol b/framework/src/test/resources/soliditycode_0.7.6/altbn.sol deleted file mode 100644 index c3cfcdbe2b9..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/altbn.sol +++ /dev/null @@ -1,61 +0,0 @@ -contract AltBn128 { - constructor() public payable {} - function callBn256Add(bytes32 ax, bytes32 ay, bytes32 bx, bytes32 by) public returns (bytes32[2] memory result) { - bytes32[4] memory input; - input[0] = ax; - input[1] = ay; - input[2] = bx; - input[3] = by; - assembly { - let success := call(gas(), 0x06, 0, input, 0x80, result, 0x40) - } - - } - - function callBn256AddNoValue(bytes32 ax, bytes32 ay, bytes32 bx, bytes32 by) public returns - (bytes32[2] memory result) { - bytes32[4] memory input; - input[0] = ax; - input[1] = ay; - input[2] = bx; - input[3] = by; - assembly { - let success := call(gas(), 0xac, 0, input, 0x80, result, 0x40) - } - } - - function callBn256ScalarMul(bytes32 x, bytes32 y, bytes32 scalar) public returns (bytes32[2] memory result) { - bytes32[3] memory input; - input[0] = x; - input[1] = y; - input[2] = scalar; - assembly { - let success := call(gas(), 0x07, 0, input, 0x60, result, 0x40) - switch success - case 0 { - revert(0,0) - } - } - } - - function callBn256Pairing(bytes memory input) public returns (bytes32 result) { - // input is a serialized bytes stream of (a1, b1, a2, b2, ..., ak, bk) from (G_1 x G_2)^k - uint256 len = input.length; - require(len % 192 == 0); - assembly { - let memPtr := mload(0x40) - let success := call(gas(), 0x08, 0, add(input, 0x20), len, memPtr, 0x20) - switch success - case 0 { - revert(0,0) - } default { - result := mload(memPtr) - } - } - } - - function convert(uint256 num) public view returns(bytes32) { - return bytes32(num); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/arrayLength001.sol b/framework/src/test/resources/soliditycode_0.7.6/arrayLength001.sol deleted file mode 100644 index 46b2405a97e..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/arrayLength001.sol +++ /dev/null @@ -1,64 +0,0 @@ - - -contract arrayLength { - byte[] a; - uint256[] IntergerArray; - bytes bs; - - // arrary length - function arrayPushValue() public returns (byte[] memory){ - a = new byte[](1); - a.push(0x01); - return a; - } - - function arrayPush() public returns(byte[] memory){ - a = new byte[](1); - a.push(); - return a; - } - - function arrayPop() public returns(byte[] memory){ - a = new byte[](1); - a.pop(); - return a; - } - - // arrary push/pop return Value - function arrayPushValueReturn() public { - a = new byte[](1); - return a.push(0x01); - } - - function arrayPushReturn() public returns (bytes1){ - a = new byte[](1); - return a.push(); - } - - function arrayPopReturn() public{ - a = new byte[](1); - return a.pop(); - } - - function uint256ArrayPushValue() public returns (byte[] memory){ - IntergerArray = [1,2,3]; - IntergerArray.push(); - return a; - } - - - // bytes - function bytesPushValue() public { - - return bs.push(0x01); - } - - function bytesPush() public returns (bytes1){ - return bs.push(); - } - - function bytesPop() public { - return bs.pop(); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/assemblyTest.sol b/framework/src/test/resources/soliditycode_0.7.6/assemblyTest.sol deleted file mode 100644 index 519a5a85fa3..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/assemblyTest.sol +++ /dev/null @@ -1,61 +0,0 @@ - -contract assemblyTest { - - uint constant x = 1; - uint constant y = x; - function getZuint() public view returns (uint) { - uint z = y + 1; - assembly { - z := y - } - return z; - } - - function getZuint2() public returns (uint) { - uint z = y + 1; - assembly { - z := y - } - return z; - } - - bool constant bool1 = true; - bool constant bool2 = bool1; - function getZbool() public view returns (bool) { - bool z; - assembly { - z := bool2 - } - return z; - } - - function getZbool2() public returns (bool) { - bool z; - assembly { - z := bool2 - } - return z; - } - - -// string constant string1 = "abc"; -// string constant string2 = string1; -// function getZstring() public view returns (string memory) { -// string memory z; -// assembly { -// z := string2 -// } -// return z; -// } - - -// address origin1 = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF; -// address origin2 = origin1; -// function getZaddress() public view returns (address) { -// address z; -// assembly { -// z := origin2 -// } -// return z; -// } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest1DivideInt.sol b/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest1DivideInt.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest1DivideInt.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest2FindArgsContractMinTest.sol b/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest2FindArgsContractMinTest.sol deleted file mode 100644 index 75436287805..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest2FindArgsContractMinTest.sol +++ /dev/null @@ -1,10 +0,0 @@ - -contract findArgsIContract{ -function findArgsByIndex1(uint i) public returns (uint z) { -uint[] memory a = new uint[](3); -a[0]=1; -a[1]=2; -a[2]=3; -return a[i]; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest3ByteMinContract.sol b/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest3ByteMinContract.sol deleted file mode 100644 index c8a2e5e363b..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest3ByteMinContract.sol +++ /dev/null @@ -1,11 +0,0 @@ - -contract byteContract{ -bytes b; -function testBytesGet(uint i) public returns (bytes1){ -b = new bytes(3); -b[0]=0x0b; -b[1]=0x0c; -b[2]=0x0d; -return b[i]; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest4Enum.sol b/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest4Enum.sol deleted file mode 100644 index 6bd2ade2eea..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest4Enum.sol +++ /dev/null @@ -1,13 +0,0 @@ - - -contract enumContract { - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices _choice; - function setGoStraight(ActionChoices choice) public { - _choice = choice; - } - - function getChoice() public returns (ActionChoices) { - return _choice; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest5MoveRight.sol b/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest5MoveRight.sol deleted file mode 100644 index ad8f6f0f173..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest5MoveRight.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract binaryRightContract{ - function binaryMoveR(uint i)public returns (uint z) { - return z = 5 >> i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest6UninitializedContract.sol b/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest6UninitializedContract.sol deleted file mode 100644 index c82e0f5806c..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest6UninitializedContract.sol +++ /dev/null @@ -1,27 +0,0 @@ - -contract uni { -function b(int x, int y) internal returns (int) -{ - return x * y; -} - -function test1() external returns (int) -{ - // Variable containing a function pointer - function (int, int) internal returns (int) funcPtr; - - funcPtr = b; - - // This call to funcPtr will succeed - return funcPtr(4, 5); -} - -function test2() external returns (int) -{ - // Variable containing a function pointer - function (int, int) internal returns (int) funcPtr; - - // This call will fail because funcPtr is still a zero-initialized function pointer - return funcPtr(4, 5); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest7TestAssertContract.sol b/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest7TestAssertContract.sol deleted file mode 100644 index 05b592e0682..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/assertExceptiontest7TestAssertContract.sol +++ /dev/null @@ -1,14 +0,0 @@ -contract TestThrowsContract{ - function testAssert() public{ - assert(1==2); - } - function testRequire() public{ - require(2==1); - } - function testRevert() public{ - revert(); - } - function testThrow() public{ - revert(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign.sol b/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign.sol deleted file mode 100644 index 9e1c1b289b5..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign.sol +++ /dev/null @@ -1,14 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - - function testArray2(bytes memory data) public returns(bool, bytes memory){ - return address(0x9).delegatecall(data); - } - - function testArray4(bytes memory data) public { - //address(0x1).delegatecall(data); - } - //function testArray3(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public { - //address(0x9).delegatecall(hash,signatures,addresses); - //} -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign001.sol b/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign001.sol deleted file mode 100644 index 57e051ce415..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign001.sol +++ /dev/null @@ -1,10 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - function testPure(bytes32 hash, bytes[] memory signatures, address[] memory addresses) pure public returns(bytes32){ - return batchvalidatesign(hash, signatures, addresses); - } - - function testArray(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public returns(bytes32){ - return batchvalidatesign(hash, signatures, addresses); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign002.sol b/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign002.sol deleted file mode 100644 index 375cec3a2a2..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign002.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - function testArray(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public returns(bytes32){ - - return batchvalidatesign(hash, signatures, addresses); - - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign003.sol b/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign003.sol deleted file mode 100644 index c43536af499..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign003.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract Demo { -bytes32 public result; -constructor (bytes32 hash, bytes[] memory signatures, address[] memory addresses) public { - result = batchvalidatesign(hash, signatures, addresses); -} -function testConstructor() public returns(bytes32){ - return result; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign005.sol b/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign005.sol deleted file mode 100644 index 3a6ca362973..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign005.sol +++ /dev/null @@ -1,14 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - - function testArray2(bytes memory data) public returns(bool, bytes memory){ - return address(0x9).delegatecall(data); - } - - function testArray4(bytes memory data) public { - //address(0x1).delegatecall(data); - } - function testArray3(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public { - //address(0x9).delegatecall(hash,signatures,addresses); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign007.sol b/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign007.sol deleted file mode 100644 index 974ffb34efe..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign007.sol +++ /dev/null @@ -1,17 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract Demo { - bytes32 public result; - - constructor (bytes32 hash, bytes[] memory signatures, address[] memory addresses) public { - result = batchvalidatesign(hash, signatures, addresses); - } - - function testConstructor() public returns(bytes32){ - return result; - } - - function testConstructorPure() public view returns(bytes32){ - return result; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign02.sol b/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign02.sol deleted file mode 100644 index 375cec3a2a2..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/batchvalidatesign02.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma experimental ABIEncoderV2; -contract Demo { - function testArray(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public returns(bytes32){ - - return batchvalidatesign(hash, signatures, addresses); - - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/callValueGasPure.sol b/framework/src/test/resources/soliditycode_0.7.6/callValueGasPure.sol deleted file mode 100644 index 6aab49bab84..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/callValueGasPure.sol +++ /dev/null @@ -1,8 +0,0 @@ - -contract C { -function check(address a) external pure returns (bool success) { - a.call{value:42,gas:42}; - a.call{gas:42}; - //a.call.value(1).gas(42)("fwefewf"); -} -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/calldata.sol b/framework/src/test/resources/soliditycode_0.7.6/calldata.sol deleted file mode 100644 index 6e877ac1b2f..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/calldata.sol +++ /dev/null @@ -1,33 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract C { - struct S { uint256 a; } - - function f(S calldata s) external returns (bytes memory) { - return abi.encode(s); - } - - function g(S calldata s) external returns (bytes memory) { - return this.f(s); - } - - function m(uint256[] calldata) external pure returns (bytes memory) { - return msg.data; - } - function h(uint8[] calldata s) external pure returns (bytes memory) { - return abi.encode(s); - } - function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) { - return this.h(s[which]); - } - function j(bytes calldata s) external pure returns (bytes memory) { - return abi.encode(s); - } - function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) { - return this.j(s[which]); - } - function l(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) { - assert(s.length == 3); - return (s[0](), s[1](), s[2]()); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/callvalue.sol b/framework/src/test/resources/soliditycode_0.7.6/callvalue.sol deleted file mode 100644 index f01dcf2b52f..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/callvalue.sol +++ /dev/null @@ -1,9 +0,0 @@ -contract Callvalue { -function check() public payable returns(uint) { - uint256 wad; - assembly { - wad := callvalue() - } - return wad; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/chainid001.sol b/framework/src/test/resources/soliditycode_0.7.6/chainid001.sol deleted file mode 100644 index 9cf24077dfb..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/chainid001.sol +++ /dev/null @@ -1,19 +0,0 @@ - -contract IstanbulTest { - constructor() public payable {} - function getId() public view returns(uint256){ - uint256 id; - assembly { - id := chainid() - } - return id; - } - - function getBalance(address src) public view returns(uint256){ - return address(src).balance; - } - - function getBalance() public view returns(uint256){ - return address(this).balance; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/codeSaftySupport.sol b/framework/src/test/resources/soliditycode_0.7.6/codeSaftySupport.sol deleted file mode 100644 index 1cee8e4646c..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/codeSaftySupport.sol +++ /dev/null @@ -1,19 +0,0 @@ - - -contract IllegalDecorate { - -constructor() payable public{} - -fallback() payable external{} - -event log(uint256); - -function transferToken(address payable toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/codeSaftyUnsupport.sol b/framework/src/test/resources/soliditycode_0.7.6/codeSaftyUnsupport.sol deleted file mode 100644 index fa65a134001..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/codeSaftyUnsupport.sol +++ /dev/null @@ -1,56 +0,0 @@ - - -contract SubC { - -event log(string); - -fallback() payable external{} - -function receiveToken() payable public{} - -function getBalance() view public returns (uint256 r) { -r = address(this).balance; -} -} - -contract UseDot { -constructor() payable public{} -fallback() payable external{} -mapping(address => mapping(trcToken => uint256)) sender_tokens; - -function trigger1(address payable addr, trcToken tokenInputId) payable public { - //address(SubC(addr)).call.value(1000).tokenId(tokenInputId)(abi.encodeWithSignature("receiveToken()")); // ERROR -} - -function trigger2(address payable addr) payable public { -// addr.transferToken.value(10)(10, 0x6e6d62); // ERROR -} - -function trigger3(address payable addr) payable public { - // address(SubC(addr)).receiveToken.tokenvalue(10)(); // ERROR -} - -function trigger4(address payable addr) payable public { - //SubC(addr).receiveToken.tokenId(0x6e6d62)(); // ERROR -} - -function trigger5(address payable addr) payable public { - SubC(addr).receiveToken{value:10}(); -} - -function trigger6(address payable addr, trcToken tokenId) payable public { -address(SubC(addr)).call{value:1000}(abi.encodeWithSignature("transferToken(uint256, trcToken)", 10, tokenId)); -} - -function trigger7(address addr) payable public { - //sender_tokens[msg.sender][msg.tokenid] += msg.tokenvalue; // compile success, no necessary to trigger -} - -function trigger8(address addr) public payable returns(bytes memory r){ -// r = msg.data; // compile success, no necessary to trigger -} - -function getBalance() public returns (uint256 r){ -r = address(this).balance; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/constantCallStorage001.sol b/framework/src/test/resources/soliditycode_0.7.6/constantCallStorage001.sol deleted file mode 100644 index 1f584923a55..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/constantCallStorage001.sol +++ /dev/null @@ -1,159 +0,0 @@ -contract NotView { - uint256 public num = 123; - function setnum() public returns(uint256){ - num = num + 15; - return num; - } -} -contract NotViewInterface{ - function setnum() public returns(uint256); -} -contract UseNotView { - function setnumuseproxy(address contractAddress) public returns(uint256){ - NotViewInterface inter = NotViewInterface(contractAddress); - return inter.setnum(); - } -} -contract viewCall { - bool stopped = false; - int i = 32482989; - int i2 = -32482989; - uint ui = 23487823; - address origin = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF; - bytes32 b32 = bytes32(uint256(0xdCad3a6d3569DF655070DEd0)); - bytes bs = new bytes(3); - string s = "123qwe"; - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices choice = ActionChoices.GoRight; - int64[] b = [-1, 2, -3]; - int32[2][] tmp_h = [[1,2],[3,4],[5,6]]; - int256[2][2] tmp_i = [[11,22],[33,44]]; - mapping (address => uint256) public mapa; - constructor() payable public{ - mapa[address(0x00)] = 34; - } - event log(int); - event log(uint); - event log(bool); - event log(address); - event log(bytes32); - event log(bytes); - event log(string); - event log(ActionChoices); - event log(int64[]); - event log(int32[2][]); - event log(int256[2][2]); - function changeBool(bool param) public returns (bool){ - stopped = param; - emit log(stopped); - return stopped; - } - function getBool() public returns (bool){ - emit log(stopped); - return stopped; - } - function changeInt(int param) public returns (int){ - i = param; - emit log(i); - return i; - } - function getInt() public returns (int){ - emit log(i); - return i; - } - function changeNegativeInt(int param) public returns (int){ - i2 = param; - emit log(i2); - return i2; - } - function getNegativeInt() public returns (int){ - emit log(i2); - return i2; - } - function changeUint(uint param) public returns (uint){ - ui = param; - emit log(ui); - return ui; - } - function getUint() public returns (uint){ - emit log(ui); - return ui; - } - function changeAddress(address param) public returns (address){ - origin = param; - emit log(origin); - return origin; - } - function getAddress() public returns (address){ - emit log(origin); - return origin; - } - function changeBytes32(bytes32 param) public returns (bytes32){ - b32 = param; - emit log(b32); - return b32; - } - function getBytes32() public returns (bytes32){ - emit log(b32); - return b32; - } - function changeBytes(bytes memory param) public returns (bytes memory){ - bs = param; - emit log(bs); - return bs; - } - function getBytes() public returns (bytes memory){ - emit log(bs); - return bs; - } - function changeString(string memory param) public returns (string memory){ - s = param; - emit log(s); - return s; - } - function getString() public returns (string memory){ - emit log(s); - return s; - } - function changeActionChoices(ActionChoices param) public returns (ActionChoices){ - choice = param; - emit log(choice); - return choice; - } - function getActionChoices() public returns (ActionChoices){ - emit log(choice); - return choice; - } - function changeInt64NegativeArray(int64[] memory param) public returns (int64[] memory){ - b = param; - emit log(b); - return b; - } - function getInt64NegativeArray() public returns (int64[] memory){ - emit log(b); - return b; - } - function changeInt32Array(int32[2][] memory param) public returns (int32[2][] memory){ - tmp_h = param; - emit log(tmp_h); - return tmp_h; - } - function getInt32Array() public returns (int32[2][] memory){ - emit log(tmp_h); - return tmp_h; - } - function changeInt256Array(int256[2][2] memory param) public returns (int256[2][2] memory){ - tmp_i = param; - emit log(tmp_i); - return tmp_i; - } - function getInt256Array() public returns (int256[2][2] memory){ - emit log(tmp_i); - return tmp_i; - } - function setMapping(uint256 param) public returns (uint256){ - mapa[msg.sender] = param; - return mapa[msg.sender]; - - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/constantCallStorage002.sol b/framework/src/test/resources/soliditycode_0.7.6/constantCallStorage002.sol deleted file mode 100644 index 1ceba5e87d2..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/constantCallStorage002.sol +++ /dev/null @@ -1,16 +0,0 @@ -contract NotView { - uint256 public num = 123; - function setnum() public returns(uint256){ - num = num + 15; - return num; - } -} -contract NotViewInterface{ - function setnum() public view returns(uint256); -} -contract UseNotView { - function setnumuseproxy(address contractAddress) public view returns(uint256){ - NotViewInterface inter = NotViewInterface(contractAddress); - return inter.setnum(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/constantCallStorage0425.sol b/framework/src/test/resources/soliditycode_0.7.6/constantCallStorage0425.sol deleted file mode 100644 index 8ecf771626d..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/constantCallStorage0425.sol +++ /dev/null @@ -1,156 +0,0 @@ -contract constantCall { - bool stopped = false; - int i = 32482989; - int i2 = -32482989; - uint ui = 23487823; - address origin = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF; - bytes32 b32 = 0xb55a21aaee0ce8f1c8ffaa0dbd23105cb55a21aaee0ce8f1c8ffaa0dbd23105c; - bytes bs = new bytes(9); - string s = "123qwe"; - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices choice = ActionChoices.SitStill; - int64[] b = [91, 2, 333]; - int32[2][] tmp_h = [[1,2],[3,4],[5,6]]; - int256[2][2] tmp_i = [[11,22],[33,44]]; - mapping (address => uint256) public mapa; - - constructor() payable public{ - mapa[address(0x00)] = 88; - } - event log(int); - event log(uint); - event log(bool); - event log(address); - event log(bytes32); - event log(bytes); - event log(string); - event log(ActionChoices); - event log(int64[]); - event log(int32[2][]); - event log(int256[2][2]); - - function changeBool(bool param) public constant returns (bool){ - stopped = param; - log(stopped); - return stopped; - } - function getBool() public constant returns (bool){ - log(stopped); - return stopped; - } - - function changeInt(int param) public returns (int){ - i = param; - log(i); - return i; - } - function getInt() public returns (int){ - log(i); - return i; - } - - function changeNegativeInt(int param) public constant returns (int){ - i2 = param; - log(i2); - return i2; - } - function getNegativeInt() public constant returns (int){ - log(i2); - return i2; - } - - function changeUint(uint param) public returns (uint){ - ui = param; - log(ui); - return ui; - } - function getUint() public returns (uint){ - log(ui); - return ui; - } - - function changeAddress(address param) public constant returns (address){ - origin = param; - log(origin); - return origin; - } - function getAddress() public constant returns (address){ - log(origin); - return origin; - } - - function changeBytes32(bytes32 param) public constant returns (bytes32){ - b32 = param; - log(b32); - return b32; - } - function getBytes32() public returns (bytes32){ - log(b32); - return b32; - } - - function changeBytes(bytes param) public constant returns (bytes){ - bs = param; - log(bs); - return bs; - } - function getBytes() public constant returns (bytes){ - log(bs); - return bs; - } - - function changeString(string param) public constant returns (string){ - s = param; - log(s); - return s; - } - function getString() public returns (string){ - log(s); - return s; - } - - function changeActionChoices(ActionChoices param) public constant returns (ActionChoices){ - choice = param; - log(choice); - return choice; - } - function getActionChoices() public constant returns (ActionChoices){ - log(choice); - return choice; - } - - function changeInt64NegativeArray(int64[] param) public constant returns (int64[]){ - b = param; - log(b); - return b; - } - function getInt64NegativeArray() public constant returns (int64[]){ - log(b); - return b; - } - - function changeInt32Array(int32[2][] param) public returns (int32[2][]){ - tmp_h = param; - log(tmp_h); - return tmp_h; - } - function getInt32Array() public constant returns (int32[2][]){ - log(tmp_h); - return tmp_h; - } - - function changeInt256Array(int256[2][2] param) public returns (int256[2][2]){ - tmp_i = param; - log(tmp_i); - return tmp_i; - } - function getInt256Array() public constant returns (int256[2][2]){ - log(tmp_i); - return tmp_i; - } - function setMapping(uint256 param) public returns (uint256){ - mapa[msg.sender] = param; - return mapa[msg.sender]; - - } -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/constantContract001.sol b/framework/src/test/resources/soliditycode_0.7.6/constantContract001.sol deleted file mode 100644 index 7d574c5a008..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/constantContract001.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract testConstantContract{ -function testPure(uint256 x,uint256 y) public pure returns (uint256 z) { -uint256 i=1; -return i + x + y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGetterContract.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGetterContract.sol deleted file mode 100644 index 365b53ebf1a..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGetterContract.sol +++ /dev/null @@ -1,17 +0,0 @@ - - - -contract getterContract { - -constructor() public payable{} -fallback() external payable{} - -uint public c = msg.value; - -function getDataUsingAccessor() public payable returns (uint){ - -return c; - -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test1Grammar001.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test1Grammar001.sol deleted file mode 100644 index 659e56c9150..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test1Grammar001.sol +++ /dev/null @@ -1,18 +0,0 @@ - -contract FunctionSelector { - function select(bool useB, uint x) public returns (uint z) { - //var f = a; - //if (useB) f = b; - //return f(x); - if (useB) - return b(x); - else - return a(x); - } -function a(uint x) public returns (uint z) { - return x * x; - } -function b(uint x) public returns (uint z) { - return 2 * x; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test2Grammar002.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test2Grammar002.sol deleted file mode 100644 index 744b17e9585..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test2Grammar002.sol +++ /dev/null @@ -1,44 +0,0 @@ - -library Set { - // We define a new struct datatype that will be used to - // hold its data in the calling contract. - struct Data { mapping(uint => bool) flags; } - - // Note that the first parameter is of type "storage - // reference" and thus only its storage address and not - // its contents is passed as part of the call. This is a - // special feature of library functions. It is idiomatic - // to call the first parameter 'self', if the function can - // be seen as a method of that object. - function insert(Data storage self, uint value) public returns (bool) { - if (self.flags[value]) - return false; // already there - self.flags[value] = true; - return true; - } - - function remove(Data storage self, uint value) public returns (bool) { - if (!self.flags[value]) - return false; // not there - self.flags[value] = false; - return true; - } - - function contains(Data storage self, uint value) public returns (bool) { - return self.flags[value]; - } -} - - -contract C { - Set.Data knownValues; - - function register (uint value) public{ - // The library functions can be called without a - // specific instance of the library, since the - // "instance" will be the current contract. - if (!Set.insert(knownValues, value)) - revert(); - } - // In this contract, we can also directly access knownValues.flags, if we want. -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test3Grammar003.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test3Grammar003.sol deleted file mode 100644 index 140ba2a8f56..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test3Grammar003.sol +++ /dev/null @@ -1,44 +0,0 @@ - - -library Set { - struct Data { mapping(uint => bool) flags; } - - function insert(Data storage self, uint value) public - returns (bool) - { - if (self.flags[value]) - return false; // already there - self.flags[value] = true; - return true; - } - - function remove(Data storage self, uint value) public - returns (bool) - { - if (!self.flags[value]) - return false; // not there - self.flags[value] = false; - return true; - } - - function contains(Data storage self, uint value) public - returns (bool) - { - return self.flags[value]; - } -} - - -contract C { - using Set for Set.Data; // this is the crucial change - Set.Data knownValues; - - function register(uint value) public{ - // Here, all variables of type Set.Data have - // corresponding member functions. - // The following function call is identical to - // Set.insert(knownValues, value) - if (!knownValues.insert(value)) - revert(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test4Grammar004.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test4Grammar004.sol deleted file mode 100644 index 772691cebc5..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test4Grammar004.sol +++ /dev/null @@ -1,31 +0,0 @@ - - -library Search { - function indexOf(uint[] storage self, uint value) public returns (uint) { - for (uint i = 0; i < self.length; i++) - if (self[i] == value) return i; - return uint(-1); - } -} - - -contract C { - using Search for uint[]; - uint[] public data; - - function append(uint value) public{ - data.push(value); - } - - function replace(uint _old, uint _new) public{ - // This performs the library function call - uint index = data.indexOf(_old); - if (index == uint(-1)) - data.push(_new); - else - data[index] = _new; - } - function getData(uint256 index) public returns(uint256){ - return data[index]; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test5Grammar006.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test5Grammar006.sol deleted file mode 100644 index 275d42d1e71..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar001test5Grammar006.sol +++ /dev/null @@ -1,45 +0,0 @@ -contract InfoFeed { -function d1(uint x1) public{ - - assembly{ - function f(x) -> y { switch x case 0 { y := 1 } default { y := mul(x, f(sub(x, 1))) } } - } - } - function d2(uint x1) public{ - assembly { - let x:=1 - x := mul(1, add(2, 3))} - } - function f(uint x) public{ - assembly { x := sub(x, 1) } - - } - // 0.6.0 Variable declarations cannot shadow declarations outside the assembly block. - function d(uint x1) public returns(uint256){ - uint256 x; - assembly{ - x := add(2, 3) - let y := mload(0x40) - x := add(x, y) - } - return x; - } - function d4(uint x) public{ - // Error: The labels 'repeat' is disallowed. Please use "if", "switch", "for" or function calls instead - //assembly{let x := 10 repeat: x := sub(x, 1) jumpi(repeat, eq(x, 0)) - x = x; - //} - } - function d5(uint x1) public{ - assembly{ - function f(x) -> y { switch x case 0 { y := mul(x, 2) } default { y := 0 } } - - } - } - - function d6(uint x1) public{ - assembly{ - function f(x) -> y { for { let i := 0 } lt(i, x) { i := add(i, 1) } { y := mul(2, y) } } - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test1Grammar007_1.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test1Grammar007_1.sol deleted file mode 100644 index 020c2a38ca4..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test1Grammar007_1.sol +++ /dev/null @@ -1,60 +0,0 @@ -contract Doug{ - mapping (bytes32 => uint) public contracts; - constructor() public{ - contracts['hww'] = 1; - contracts['brian'] = 2; - contracts['zzy'] = 7; - } - - function getDougName(string memory _name) public view returns(string memory) { - return _name; - } - - function getDougAge(uint _age) public pure returns(uint) { - return 3 ** _age; - } -} - -// -abstract contract DogInterface { - function getDougAge(uint _age) public virtual returns (uint); - function contracts(bytes32 name) public virtual returns (uint); -} -contract main{ - - event FetchContract(address dogInterfaceAddress, address sender, bytes32 name); - - address public DOUG; - - address dogInterfaceAddress; - DogInterface dogContract ; - - function setDOUG(address _doug) public { - DOUG = _doug; - } - - constructor(address addr) public{ - dogInterfaceAddress = addr; - dogContract = DogInterface(dogInterfaceAddress); - } - - function dougOfage(uint _age) public returns(uint) { - - uint num = dogContract.getDougAge(_age); - return _age+num; - // return num; - } - - function uintOfName(bytes32 _name) public returns (uint) { - - dogContract.contracts(_name); - emit FetchContract(dogInterfaceAddress, msg.sender, _name); - - } - - // function getTest(string _name) public view returns(string) { - // string memory newName = _name ; - // DogInterface(DOUG).getDougName(newName); - // return newName; - // } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test1Grammar007_2.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test1Grammar007_2.sol deleted file mode 100644 index 8945b566543..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test1Grammar007_2.sol +++ /dev/null @@ -1,60 +0,0 @@ - -contract Doug{ - mapping (bytes32 => uint) public contracts; - constructor() public{ - contracts['hww'] = 1; - contracts['brian'] = 2; - contracts['zzy'] = 7; - } - - function getDougName(string memory _name) public view returns(string memory) { - return _name; - } - - function getDougAge(uint _age) public pure returns(uint) { - return 3 ** _age; - } -} - -abstract contract DogInterface { - function getDougAge(uint _age) public virtual returns (uint); - function contracts(bytes32 name) public virtual returns (uint); -} -contract main{ - - event FetchContract(address dogInterfaceAddress, address sender, bytes32 name); - - address public DOUG; - - address dogInterfaceAddress; - DogInterface dogContract ; - - function setDOUG(address _doug) public { - DOUG = _doug; - } - - constructor(address addr) public{ - dogInterfaceAddress = addr; - dogContract = DogInterface(dogInterfaceAddress); - } - - function dougOfage(uint _age) public returns(uint) { - - uint num = dogContract.getDougAge(_age); - return _age+num; - // return num; - } - - function uintOfName(bytes32 _name) public returns (uint) { - - dogContract.contracts(_name); - emit FetchContract(dogInterfaceAddress, msg.sender, _name); - - } - - // function getTest(string _name) public view returns(string) { - // string memory newName = _name ; - // DogInterface(DOUG).getDougName(newName); - // return newName; - // } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test2Grammar008.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test2Grammar008.sol deleted file mode 100644 index 956623c3103..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test2Grammar008.sol +++ /dev/null @@ -1,18 +0,0 @@ - - -// version 0.6.0 change -// add abstract and override -abstract contract Feline { - - function utterance() public virtual returns (bytes32); - - function getContractName() public returns (string memory){ - return "Feline"; - } -} - - -contract Cat is Feline { - function utterance() public override returns (bytes32) { return "miaow"; } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test3Grammar010.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test3Grammar010.sol deleted file mode 100644 index 617f96cb4e5..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test3Grammar010.sol +++ /dev/null @@ -1,10 +0,0 @@ - -contract InfoFeed { -function info() public payable returns (uint ret) { return 42; } -} -contract Consumer { -constructor() payable public{} -InfoFeed feed; -function setFeed(address addr) public { feed = InfoFeed(addr); } -function callFeed() public payable { feed.info{value:10,gas:800}(); } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test4Grammar011.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test4Grammar011.sol deleted file mode 100644 index fcd18f438ef..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test4Grammar011.sol +++ /dev/null @@ -1,11 +0,0 @@ - -contract C { -function f(uint key, uint value) public returns(uint) { -return key; -// do something -} -function g() public { -// named arguments -f({value: 2, key: 3}); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test4Grammar012.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test4Grammar012.sol deleted file mode 100644 index 293b5e2ba9d..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test4Grammar012.sol +++ /dev/null @@ -1,24 +0,0 @@ - -contract rTest { -function info() public payable returns (uint,address,bytes4,uint,uint,uint,address,uint) { -//function info() public payable returns (address ,uint,uint,uint,bytes32,uint,bytes,uint,address,bytes4,uint,uint,uint,address,uint) { -//var a = block.coinbase ; -//var b = block.difficulty; -//var c = block.gaslimit; -//var d = block.number; -//var e = block.blockhash(0); -//var e = d; -//var f = block.timestamp; -//bytes memory g = msg.data; -uint256 h = gasleft(); -address payable i = msg.sender; -bytes4 j = msg.sig; -uint256 k = msg.value; -uint256 l = block.timestamp; -uint256 m = tx.gasprice; -address payable n = tx.origin; -uint256 o = address(this).balance; -return (h,i,j,k,l,m,n,o); -//return (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test6Grammar013.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test6Grammar013.sol deleted file mode 100644 index 53de5def6bc..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar002test6Grammar013.sol +++ /dev/null @@ -1,24 +0,0 @@ - -contract Counter { -uint count = 0; -address payable owner; -//function Counter() public{ -constructor() public{ -owner = msg.sender; -} -function increment() public { -uint step = 10; -if (owner == msg.sender) { -count = count + step; -} -} -function getCount() public returns (uint){ -return count; -} -function kill() public{ -if (owner == msg.sender) { -selfdestruct(owner); -//selfdestruct(address(owner)); -} -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test1Grammar014.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test1Grammar014.sol deleted file mode 100644 index b2d70b3741c..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test1Grammar014.sol +++ /dev/null @@ -1,67 +0,0 @@ -contract A { -uint256 public numberForB; -address public senderForB; -function callTest(address bAddress, uint256 _number) public{ - -//bAddress.call(bytes4(sha3("setValue(uint256)")), _number); // B's storage is set, A is not modified -bAddress.call(abi.encodeWithSignature("setValue(uint256)",_number)); // B's storage is set, A is not modified -} -function callcodeTest(address bAddress, uint256 _number) public{ -//bAddress.callcode(bytes4(sha3("setValue(uint256)")), _number); // A's storage is set, B is not modified -bAddress.delegatecall(abi.encodeWithSignature("setValue(uint256)", _number)); // A's storage is set, B is not modified -} -function delegatecallTest(address bAddress, uint256 _number) public{ -//bAddress.delegatecall(bytes4(sha3("setValue(uint256)")), _number); // A's storage is set, B is not modified -bAddress.delegatecall(abi.encodeWithSignature("setValue(uint256)", _number)); // A's storage is set, B is not modified -} - -function callAddTest(address bAddress) public{ -//bAddress.call(bytes4(sha3("add()"))); // B's storage is set, A is not modified -bAddress.call(abi.encodeWithSignature("add()")); // B's storage is set, A is not modified -//bAddress.call(bytes4(sha3("add()"))); // B's storage is set, A is not modified -bAddress.call(abi.encodeWithSignature("add()")); // B's storage is set, A is not modified -} -function getnumberForB() public returns(uint256){ - return numberForB; - } - function getsenderForB() public returns(address){ - return senderForB; - } -} -contract B { -uint256 public numberForB; -address public senderForB; -address public addr11; -mapping(uint256=>address) public addr1; -mapping(uint256=>address) public addr2; -event ssss(uint256); -function setValue(uint256 _number) public{ - -emit ssss(_number); -numberForB = _number; -senderForB = msg.sender; -// senderForB is A if invoked by A's callTest. B's storage will be updated -// senderForB is A if invoked by A's callcodeTest. None of B's storage is updated -// senderForB is OWNER if invoked by A's delegatecallTest. None of B's storage is updated -} - -function add() public{ -numberForB=numberForB+1; -C c1 = new C(); -addr1[numberForB]=c1.getAddress(); -addr11 = c1.getAddress(); -C c2 = new C(); -addr2[numberForB] = c2.getAddress(); -} -function getnumberForB() public returns(uint256){ - return numberForB; - } - function getsenderForB() public returns(address){ - return senderForB; - } -} -contract C { -function getAddress() public view returns(address){ -return address(this); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test2Grammar015.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test2Grammar015.sol deleted file mode 100644 index 0aa93e5e94f..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test2Grammar015.sol +++ /dev/null @@ -1,40 +0,0 @@ - - -contract ExecuteFallback{ - - //回退事件,会把调用的数据打印出来 - event FallbackCalled(bytes data); - //fallback函数,注意是没有名字的,没有参数,没有返回值的 - // 0.6.0 Split unnamed fallback functions into two cases defined using fallback() and receive() - fallback() external{ - emit FallbackCalled(msg.data); - } - - //调用已存在函数的事件,会把调用的原始数据,请求参数打印出来 - event ExistFuncCalled(bytes data, uint256 para); - //一个存在的函数 - function existFunc(uint256 para) public{ - emit ExistFuncCalled(msg.data, para); - } - - // 模拟从外部对一个存在的函数发起一个调用,将直接调用函数 - function callExistFunc() public{ - bytes4 funcIdentifier = bytes4(keccak256("existFunc(uint256)")); - //this.call(funcIdentifier, uint256(1)); - address(this).call(abi.encode(funcIdentifier, uint256(1))); - } - - //模拟从外部对一个不存在的函数发起一个调用,由于匹配不到函数,将调用回退函数 - function callNonExistFunc() public{ - bytes4 funcIdentifier = bytes4(keccak256("functionNotExist()")); - //this.call(funcIdentifier); - address(this).call(abi.encode(funcIdentifier)); - } - - function ExistFuncCalledTopic() view public returns(bytes32){ - return keccak256("ExistFuncCalled(bytes,uint256)"); - } - function FallbackCalledTopic() view public returns(bytes32){ - return keccak256("FallbackCalled(bytes)"); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test3Grammar016.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test3Grammar016.sol deleted file mode 100644 index 6a73d7a8d7e..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test3Grammar016.sol +++ /dev/null @@ -1,23 +0,0 @@ - -contract C { -uint private data; -function f(uint a) private returns(uint b) { return a + 1; } -function setData(uint a) public { data = a; } -function getData() public returns(uint) { return data; } -function compute(uint a, uint b) internal returns (uint) { return a+b; } -} -contract D { -function readData() public{ -C c = new C(); -//uint local = c.f(7); // error: member "f" is not visible -c.setData(3); -uint local = c.getData(); -// local = c.compute(3, 5); // error: member "compute" is not visible -} -} -contract E is C { -function g() public { -C c = new C(); -uint val = compute(3, 5); // access to internal member (from derived to parent contract) -} -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test4Grammar017.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test4Grammar017.sol deleted file mode 100644 index 38746d90734..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test4Grammar017.sol +++ /dev/null @@ -1,51 +0,0 @@ -contract CrowdFunding{ - struct Funder{ - address addr; - uint amount; - } - - struct Campaign{ - address payable beneficiary; - uint goal; - uint amount; - uint funderNum; - mapping(uint => Funder) funders; - } - - uint compaingnID; - mapping (uint => Campaign) campaigns; - - function candidate(address payable beneficiary, uint goal) public payable returns (uint compaingnID){ - // initialize - Campaign storage c = campaigns[compaingnID++]; - c.beneficiary = beneficiary; - c.goal = goal; - } - - function vote(uint compaingnID) payable public { - Campaign storage c = campaigns[compaingnID]; - - //another way to initialize - c.funders[c.funderNum++] = Funder({addr: msg.sender, amount: msg.value}); - c.amount += msg.value; - } - - function check(uint comapingnId) public payable returns (bool){ - Campaign storage c = campaigns[comapingnId]; - - if(c.amount < c.goal){ - return false; - } - - uint amount = c.amount; - // incase send much more - c.amount = 0; - // address payable addr = address(uint160(c.beneficiary)); - //if(! addr.send(amount)){ - - if (! c.beneficiary.send(amount)){ - revert(); - } - return true; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test5Grammar018.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test5Grammar018.sol deleted file mode 100644 index ec241f3eae9..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test5Grammar018.sol +++ /dev/null @@ -1,37 +0,0 @@ - - - -contract Grammar18{ - function testAddmod() public returns (uint z) { - //计算(x + y)%k,其中以任意精度执行加法,并且不在2 ** 256处围绕 - z=addmod(2, 2, 3); - return z; - } - function testMulmod() public returns (uint z) { -//计算(x * y)%k,其中乘法以任意精度执行,并且不会在2 ** 256处循环。 - z=mulmod(2, 3, 4); - return z; - } - - function testKeccak256() public returns(bytes32){ - //计算的(紧凑)参数的Ethereum-SHA-3(Keccak-256)的散列 - return keccak256("11"); - } - - function testSha256() public returns(bytes32){ - //计算(紧密包装)参数的SHA-256散列 - return sha256("11"); - } - function testSha3() public returns(bytes32){ - //计算(紧密包装)参数的SHA-256散列 - //return sha3("11"); - return keccak256("11"); - } - - function testRipemd160() public returns(bytes32){ - //计算(紧密包装)参数的RIPEMD-160哈希值 - return ripemd160("11"); - } - - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test6Grammar019.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test6Grammar019.sol deleted file mode 100644 index 727ef7091e7..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test6Grammar019.sol +++ /dev/null @@ -1,12 +0,0 @@ - -contract timetest { - -constructor() public { -require( 1 == 1 seconds); -require(1 minutes == 60 seconds); -require(1 hours == 60 minutes); -require(1 days == 24 hours); -require(1 weeks == 7 days); -//require(1 years == 365 days); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test7Grammar020.sol b/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test7Grammar020.sol deleted file mode 100644 index 39a7fddcb7e..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractGrammar003test7Grammar020.sol +++ /dev/null @@ -1,8 +0,0 @@ - -contract trxtest { - -function test() public { -require(1 trx == 1000000 sun); - -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInnerContract.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInnerContract.sol deleted file mode 100644 index 5e6addef105..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInnerContract.sol +++ /dev/null @@ -1,32 +0,0 @@ - - - - -contract InnerContract { - - constructor() public payable{} - fallback() external payable{} - - function messageI() payable public returns (uint ret) { - - - - } - -} - - - -contract OuterContract { - - - constructor() public payable{} - fallback() external payable{} - - function callInner(address payable addr) payable public returns (uint) { - - return InnerContract(addr).messageI{value:1}(); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction001.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction001.sol deleted file mode 100644 index 52dcfb16fc3..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction001.sol +++ /dev/null @@ -1,41 +0,0 @@ - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address payable cAddr) public payable{ - B b1 = (new B){value:10}();//1.1 - B b2 = new B();//1.2 - payable(address(b2)).transfer(5);//1.3 - b2.callCGetZero(cAddr, 1);//1.4 - b2.callCGetZero(cAddr,2);//1.6 - } - function test2(address payable cAddress,uint256 amount) public payable{ - cAddress.call{value:amount}(abi.encodeWithSignature("newBAndTransfer()"));//2.1 - cAddress.call{value:amount + 1}(abi.encodeWithSignature("newBAndTransfer()"));//2.6 - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero(address payable cAddress,uint256 amount) public{ - cAddress.call{value:amount}(abi.encodeWithSignature("getZero()"));//1.5,1.7 - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - B b1 = (new B){value:7}();//2.2,2.7 - b1.getOne();//2.3,2.8 - B b2 = (new B){value:3}();//2.4,2.9 - b2.getOne();//2.5,2.10 - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction002.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction002.sol deleted file mode 100644 index 502e42d0c7b..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction002.sol +++ /dev/null @@ -1,20 +0,0 @@ - -contract A{ - constructor() payable public{} - fallback() payable external{} - - function test2(address cAddress,uint256 amount) public payable{ - //cAddress.call.value(amount)();//2.1 - cAddress.call{value:amount}("");//2.1 - } -} - - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction003.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction003.sol deleted file mode 100644 index 9d3e38affbd..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction003.sol +++ /dev/null @@ -1,30 +0,0 @@ - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer() payable public{ - B b = (new B){value:10}();//1 - - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable public returns(bool) { - return true; - } - constructor() public payable {} - function payC(address payable c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - fallback() payable external{} - } - diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction004.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction004.sol deleted file mode 100644 index e8f32d7bfd9..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction004.sol +++ /dev/null @@ -1,24 +0,0 @@ - -contract A{ - constructor () payable public{} - function test(address payable toAddress) public payable{ - selfdestruct(toAddress); - } - fallback() payable external{} - function getBalance() public view returns(uint256){ - return address(this).balance; - } -} -contract B{ - fallback() external payable{} - function kill(address contractAddres, address toAddress) payable public { - contractAddres.call(abi.encodeWithSignature("test(address)",address(this))); - } - function kill2() public{ - A a = new A(); - a.test(payable(address(this))); - } - function getBalance() public view returns(uint256){ - return address(this).balance; - } -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction005.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction005.sol deleted file mode 100644 index f6bdf294a99..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction005.sol +++ /dev/null @@ -1,53 +0,0 @@ - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1() public payable{ - B b1 = (new B){value:10}();//1.1 - b1.callCGetZero(false); - b1.callCGetZero(true);//1.4 - } - function test2() public payable{ - C c1 = (new C){value:10}();//1.1 - c1.newBAndTransfer(false); - c1.newBAndTransfer(true);//1.4 - - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero(bool success) public payable{ - if(!success){ - assert(1==2); - } - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract C{ - uint256 public flag=0; - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer(bool success) payable public returns(uint256){ - flag = 1; - if(!success){ - require(2==1); - } - } - function getFlag() public returns(uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction006.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction006.sol deleted file mode 100644 index ec574998b29..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction001testInternalTransaction006.sol +++ /dev/null @@ -1,54 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1() public payable{ - B b1 = (new B){value:10}();//1.1 - b1.callCGetZero(true);//1.4 - b1.callCGetZero(false); - } - function test2() public payable{ - C c1 = (new C){value:10}();//1.1 - c1.newBAndTransfer(true);//1.4 - c1.newBAndTransfer(false); - - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero(bool success) public payable{ - if(!success){ - assert(1==2); - } - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract C{ - uint256 public flag=0; - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer(bool success) payable public returns(uint256){ - flag = 1; - if(!success){ - require(2==1); - } - } - function getFlag() public returns(uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test1InternalTransaction007.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test1InternalTransaction007.sol deleted file mode 100644 index d14c3d8aa16..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test1InternalTransaction007.sol +++ /dev/null @@ -1,38 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address cAddr) public payable{ - B b1 = (new B){value:10}();//1.1 - B b2 = new B();//1.2 - payable(address(b2)).transfer(5);//1.3 - b2.callCGetZero();//1.4 - } - function test2(address cAddress,uint256 amount) public payable{ - cAddress.call{value:amount}(abi.encodeWithSignature("newBAndTransfer()"));//2.1 - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero() public{ - assert(1==2); - - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test2InternalTransaction008.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test2InternalTransaction008.sol deleted file mode 100644 index 2e57a0e635c..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test2InternalTransaction008.sol +++ /dev/null @@ -1,60 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - - function testAssert(address bAddress,uint256 amount) public payable{ - bAddress.call{value:amount,gas:1000000}(abi.encodeWithSignature("callCGetZero(bool)",false));//2.1 - bAddress.call{value:amount,gas:1000000}(abi.encodeWithSignature("callCGetZero(bool)",true)); - } - function testRequire(address cAddress,uint256 amount) public payable{ - cAddress.call{value:amount,gas:1000000}(abi.encodeWithSignature("newBAndTransfer(bool)",false));//2.1 - cAddress.call{value:amount,gas:1000000}(abi.encodeWithSignature("newBAndTransfer(bool)",true)); - } - function testAssert1(address bAddress,uint256 amount) public payable{ - bAddress.call{value:amount,gas:1000000}(abi.encodeWithSignature("callCGetZero(bool)",true)); - bAddress.call{value:amount,gas:1000000}(abi.encodeWithSignature("callCGetZero(bool)",false));//2.1 - } - function testtRequire2(address cAddress,uint256 amount) public payable{ - cAddress.call{value:amount,gas:1000000}(abi.encodeWithSignature("newBAndTransfer(bool)",true)); - cAddress.call{value:amount,gas:1000000}(abi.encodeWithSignature("newBAndTransfer(bool)",false));//2.1 - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function callCGetZero(bool success) payable public{ - if(!success){ - assert(1==2); - } - } - function getBalance() view public returns(uint256){ - return address(this).balance; - } -} - -contract C{ - uint256 public flag=0; - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer(bool success) payable public returns(uint256){ - flag = 1; - if(!success){ - require(2==1); - } - } - function getFlag() public returns(uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test3InternalTransaction009.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test3InternalTransaction009.sol deleted file mode 100644 index d750df65ea4..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test3InternalTransaction009.sol +++ /dev/null @@ -1,47 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address cAddr,address dcontract,address baddress) public payable{ - B b1 = (new B){value:10}();//1.1 - payable(address(b1)).transfer(5);//1.3 - b1.callCGetZero(cAddr, 1);//1.4 - b1.getOne(dcontract,baddress); - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne(address contractAddres, address toAddress) payable public{ - contractAddres.call(abi.encodeWithSignature("suicide1(address)",address(this))); - - } - function callCGetZero(address cAddress,uint256 amount) public{ - cAddress.call{value:amount}(abi.encodeWithSignature("getZero()"));//1.5,1.7 - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public{ - B b1 = (new B){value:7}();//2.2,2.7 - B b2 = (new B){value:3}();//2.4,2.9 - } -} - -contract D{ - constructor () payable public{} - function suicide1(address payable toAddress) public payable{ - selfdestruct(toAddress); - } - fallback() payable external{} - function getBalance() public view returns(uint256){ - return address(this).balance; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test4InternalTransaction010.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test4InternalTransaction010.sol deleted file mode 100644 index ff5817ea173..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test4InternalTransaction010.sol +++ /dev/null @@ -1,186 +0,0 @@ - - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer() payable public{ - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - - } - function transfer2() payable public{ - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - - } - function getBalance() public returns(uint256) { - return address(this).balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable public returns(bool) { - return true; - } - constructor() public payable {} - function payC(address payable c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - fallback() payable external{} - } - diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test4InternalTransaction010_1.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test4InternalTransaction010_1.sol deleted file mode 100644 index d0c80d14ffb..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test4InternalTransaction010_1.sol +++ /dev/null @@ -1,210 +0,0 @@ - - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - } - function transfer2() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - - } - function getBalance() returns(uint256){ - return this.balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable returns(bool) { - return true; - } - constructor() public payable {} - function payC(address c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() returns(uint256){ - return this.balance; - } - fallback() payable{} - } - - \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test5InternalTransaction012.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test5InternalTransaction012.sol deleted file mode 100644 index 59ffe9f0fe9..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction002test5InternalTransaction012.sol +++ /dev/null @@ -1,51 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address bAddr,address eAddr) public payable{ - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - } - -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function testNN(address eAddress) public payable{ - D d1=(new D){value:1000}(); - d1.getOne(eAddress); - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract D{ - constructor() payable public{} - fallback() payable external{} - function getOne(address eAddress) payable public returns(uint256){ - eAddress.call{value:1}(abi.encodeWithSignature("getZero()"));//2.1 - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction013.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction013.sol deleted file mode 100644 index 1dae0beb03c..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction013.sol +++ /dev/null @@ -1,56 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address dAddr) public payable{ - B b1 = (new B){value:10}();//1.1 - b1.testNN(dAddr,2);//1.6 - // C c1 = (new C).value(1000000000000)();//1.2 - // E e1 = (new E).value(1)();//1.2 - } - function test2(address cAddress,uint256 amount) public payable{ - cAddress.call{value:amount}(abi.encodeWithSignature("newBAndTransfer()"));//2.1 - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function testNN(address dAddress,uint256 amount) public payable{ - // D d1=(new D)(); - dAddress.call{value:amount}(abi.encodeWithSignature("getOne()"));//2.1 - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract D{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - E e = (new E){value:5}(); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction014.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction014.sol deleted file mode 100644 index 0346cec669b..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction014.sol +++ /dev/null @@ -1,38 +0,0 @@ -contract callerContract { - constructor() payable public{} - fallback() payable external{} - function sendToB(address called_address,address c) public payable{ - called_address.delegatecall(abi.encodeWithSignature("transferTo(address)",c)); - } - function sendToB2(address called_address,address c) public payable{ - called_address.call(abi.encodeWithSignature("transferTo(address)",c)); - } - function sendToB3(address called_address,address c) public payable{ - called_address.delegatecall(abi.encodeWithSignature("transferTo(address)",c)); - } -} - - contract calledContract { - fallback() payable external {} - constructor() payable public{} - function transferTo(address payable toAddress)public payable{ - toAddress.transfer(5); - } - - function setIinC(address c) public payable{ - c.call{value:5}(abi.encodeWithSignature("setI()")); - } - - } - - contract c{ - uint256 public i=0; - constructor() public payable{} - function getBalance() public view returns(uint256){ - return address(this).balance; - } - function setI() payable public{ - i=5; - } - fallback() payable external{} - } diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction015.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction015.sol deleted file mode 100644 index edeb9488454..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction015.sol +++ /dev/null @@ -1,60 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address dAddr,address eAddr) public payable{ - B b1 = (new B){value:10}();//1.1 - b1.testNN(dAddr,2,eAddr);//1.6 - // C c1 = (new C).value(1000000000000)();//1.2 - // E e1 = (new E).value(1)();//1.2 - } - function test2(address cAddress,uint256 amount) public payable{ - cAddress.call{value:amount}(abi.encodeWithSignature("newBAndTransfer()"));//2.1 - } -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function testNN(address dAddress,uint256 amount,address eAddress) public payable{ - // D d1=(new D)(); - dAddress.call{value:amount}(abi.encodeWithSignature("getOne(address)",address(this)));//2.1 - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } - function suicide(address payable toAddress) public payable{ - selfdestruct(toAddress); - } -} -contract D{ - constructor() payable public{} - fallback() payable external{} - function getOne(address payable eAddress) payable public{ - E e = (new E){value:5}(); - e.suicide(eAddress); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction016.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction016.sol deleted file mode 100644 index 418d4d09ac0..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction016.sol +++ /dev/null @@ -1,174 +0,0 @@ - - - contract A{ - uint256 public num = 0; - constructor() public payable{} - fallback() payable external{} - function transfer() payable public{ - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - B b1=(new B){value:1}();//1 - address payable aaa=address(this); - b1.suicide1(aaa); - } - function transfer2() payable public{ - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - B b1=(new B){value:1}();//1 - address payable aaa=address(this); - b1.suicide1(aaa); - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable public returns(bool) { - return true; - } - constructor() public payable {} - function payC(address payable c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - fallback() payable external{} - function suicide1(address payable toAddress) public payable{ - selfdestruct(toAddress); - } - } - diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction017.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction017.sol deleted file mode 100644 index 32cf9f2a04d..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction017.sol +++ /dev/null @@ -1,199 +0,0 @@ - - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer(address payable Address) payable public{ - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - - B b=(new B){value:1}();//1 - selfdestruct(Address); - } - function transfer2() payable public{ - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - (new B){value:1}();//1 - - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable public returns(bool) { - return true; - } - constructor() public payable {} - function payC(address payable c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() public returns(uint256){ - return address(this).balance; - } - fallback() payable external{} - } - diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction018.sol b/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction018.sol deleted file mode 100644 index fadb5f84b51..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractInternalTransaction003testInternalTransaction018.sol +++ /dev/null @@ -1,97 +0,0 @@ - - -contract A{ - constructor() payable public{} - fallback() payable external{} - function test1(address payable bAddr,address eAddr) public payable{ - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - bAddr.call{value:1}(abi.encodeWithSignature("testNN(address)",eAddr));//2.1 - - } - -} - -contract B{ - constructor() payable public{} - fallback() payable external{} - function getOne() payable public returns(uint256){ - return 1; - } - function testNN(address eAddress) public payable { - D d1=(new D){value:100}(); - d1.getOne(eAddress); - } -} - -contract C{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - fallback() payable external{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract D{ - constructor() payable public{} - fallback() payable external{} - function getOne(address eAddress) payable public returns(uint256){ - eAddress.call{value:1}(abi.encodeWithSignature("getZero()"));//2.1 - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractLinkage001.sol b/framework/src/test/resources/soliditycode_0.7.6/contractLinkage001.sol deleted file mode 100644 index 8d441fba2da..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractLinkage001.sol +++ /dev/null @@ -1,9 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -constructor() payable public{} -fallback() payable external{} -function divideIHaveArgsReturn(int x,int y) public payable returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractLinkage002.sol b/framework/src/test/resources/soliditycode_0.7.6/contractLinkage002.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractLinkage002.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractLinkage003.sol b/framework/src/test/resources/soliditycode_0.7.6/contractLinkage003.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractLinkage003.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractLinkage004.sol b/framework/src/test/resources/soliditycode_0.7.6/contractLinkage004.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractLinkage004.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractLinkage005.sol b/framework/src/test/resources/soliditycode_0.7.6/contractLinkage005.sol deleted file mode 100644 index 7b943aee5c1..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractLinkage005.sol +++ /dev/null @@ -1,51 +0,0 @@ -contract timeoutTest { - string public iarray1; - // cpu - function oneCpu() public { - require(1==1); - } - - function storage8Char() public { - iarray1 = "12345678"; - } - - function testUseCpu(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - } - return count; - } - - - uint256[] public iarray; - uint public calculatedFibNumber; - mapping(address=>mapping(address=>uint256)) public m; - - function testUseStorage(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - iarray.push(i); - } - return count; - } - - // stack - //uint n = 0; - uint yy = 0; - function test() public { - //n += 1; - yy += 1; - test(); - } - - function setFibonacci(uint n) public returns (uint256){ - calculatedFibNumber = fibonacci(n); - return calculatedFibNumber; - } - - function fibonacci(uint n) internal returns (uint) { - return fibonacci(n - 1) + fibonacci(n - 2); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractLinkage006.sol b/framework/src/test/resources/soliditycode_0.7.6/contractLinkage006.sol deleted file mode 100644 index 53449f61ce2..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractLinkage006.sol +++ /dev/null @@ -1,18 +0,0 @@ - -contract AA{ - uint256 public count=0; - constructor () payable public{} - function init(address payable addr, uint256 max) payable public { - count =0; - this.hack(addr,max); - } - function hack(address payable addr, uint256 max) payable public { - while (count < max) { - count = count +1; - this.hack(addr,max); - } - if (count == max) { - addr.send(20); - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractOriginEnergyLimit001.sol b/framework/src/test/resources/soliditycode_0.7.6/contractOriginEnergyLimit001.sol deleted file mode 100644 index 6feb7fff3b8..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractOriginEnergyLimit001.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract findArgsContractTest{ - function findArgsByIndexTest(uint i) public returns (uint z) { - uint[] memory a = new uint[](3); - a[0]=1; - a[1]=2; - a[2]=3; - return a[i]; - } -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractOriginEnergyLimit004.sol b/framework/src/test/resources/soliditycode_0.7.6/contractOriginEnergyLimit004.sol deleted file mode 100644 index 6feb7fff3b8..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractOriginEnergyLimit004.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract findArgsContractTest{ - function findArgsByIndexTest(uint i) public returns (uint z) { - uint[] memory a = new uint[](3); - a[0]=1; - a[1]=2; - a[2]=3; - return a[i]; - } -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractOtherToTrcToken.sol b/framework/src/test/resources/soliditycode_0.7.6/contractOtherToTrcToken.sol deleted file mode 100644 index 933358e128b..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractOtherToTrcToken.sol +++ /dev/null @@ -1,41 +0,0 @@ - - -contract ConvertType { - -constructor() payable public{} - -fallback() payable external{} - -//function stringToTrctoken(address payable toAddress, string memory tokenStr, uint256 tokenValue) public { -// trcToken t = trcToken(tokenStr); // ERROR -// toAddress.transferToken(tokenValue, tokenStr); // ERROR -//} - -function uint256ToTrctoken(address payable toAddress, uint256 tokenValue, uint256 tokenInt) public { - trcToken t = trcToken(tokenInt); // OK - toAddress.transferToken(tokenValue, t); // OK - toAddress.transferToken(tokenValue, tokenInt); // OK -} - -function addressToTrctoken(address payable toAddress, uint256 tokenValue, address adr) public { - trcToken t = trcToken(adr); // OK - toAddress.transferToken(tokenValue, t); // OK -//toAddress.transferToken(tokenValue, adr); // ERROR -} - -//function bytesToTrctoken(address payable toAddress, bytes memory b, uint256 tokenValue) public { - // trcToken t = trcToken(b); // ERROR - // toAddress.transferToken(tokenValue, b); // ERROR -//} - -function bytes32ToTrctoken(address payable toAddress, uint256 tokenValue, bytes32 b32) public { - trcToken t = trcToken(b32); // OK - toAddress.transferToken(tokenValue, t); // OK -// toAddress.transferToken(tokenValue, b32); // ERROR -} - -//function arrayToTrctoken(address payable toAddress, uint256[] memory arr, uint256 tokenValue) public { -//trcToken t = trcToken(arr); // ERROR -// toAddress.transferToken(tokenValue, arr); // ERROR -//} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractScenario001.sol b/framework/src/test/resources/soliditycode_0.7.6/contractScenario001.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractScenario001.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractScenario002.sol b/framework/src/test/resources/soliditycode_0.7.6/contractScenario002.sol deleted file mode 100644 index 5b990fe36e8..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractScenario002.sol +++ /dev/null @@ -1,53 +0,0 @@ - -contract TronNative{ - - address public voteContractAddress= address(0x10001); - address public freezeBalanceAddress = address(0x10002); - address public unFreezeBalanceAddress = address(0x10003); - address public withdrawBalanceAddress = address(0x10004); - address public approveProposalAddress = address(0x10005); - address public createProposalAddress = address(0x10006); - address public deleteProposalAddress = address(0x10007); - constructor () payable public {} - - function voteForSingleWitness (address payable witnessAddr, uint256 voteValue) public{ - // method 1: - voteContractAddress.delegatecall(abi.encode(witnessAddr,voteValue)); - } - - function voteUsingAssembly (address witnessAddr, uint256 voteValue) public{ - // method 2: - assembly{ - mstore(0x80,witnessAddr) - mstore(0xa0,voteValue) - // gas, address, in, size, out, size - if iszero(delegatecall(0, 0x10001, 0x80, 0x40, 0x80, 0x0)) { - revert(0, 0) - } - } - } - - function freezeBalance(uint256 frozen_Balance,uint256 frozen_Duration) public { - freezeBalanceAddress.delegatecall(abi.encode(frozen_Balance,frozen_Duration)); - } - - function unFreezeBalance() public { - unFreezeBalanceAddress.delegatecall(""); - } - - function withdrawBalance() public { - withdrawBalanceAddress.delegatecall(""); - } - - function approveProposal(uint256 id, bool isApprove) public { - approveProposalAddress.delegatecall(abi.encode(id,isApprove)); - } - - function createProposal(bytes32 [] memory data) public { - createProposalAddress.delegatecall(abi.encode(data)); - } - - function deleteProposal(uint256 id) public{ - deleteProposalAddress.delegatecall(abi.encode(id)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractScenario003.sol b/framework/src/test/resources/soliditycode_0.7.6/contractScenario003.sol deleted file mode 100644 index 92778e42bc9..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractScenario003.sol +++ /dev/null @@ -1,7 +0,0 @@ - - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractScenario004.sol b/framework/src/test/resources/soliditycode_0.7.6/contractScenario004.sol deleted file mode 100644 index f6919502914..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractScenario004.sol +++ /dev/null @@ -1,88 +0,0 @@ - - -contract TronToken { - - string public name = "Tronix"; // token name - string public symbol = "TRX"; // token symbol - uint256 public decimals = 6; // token digit - - mapping (address => uint256) public balanceOf; - mapping (address => mapping (address => uint256)) public allowance; - - uint256 public totalSupply = 0; - bool public stopped = false; - - uint256 constant valueFounder = 100000000000000000; - address owner = address(0x0); - - modifier isOwner { - assert(owner == msg.sender); - _; - } - - modifier isRunning { - assert (!stopped); - _; - } - - modifier validAddress { - assert(address(0x0) != msg.sender); - _; - } - - constructor(address _addressFounder) public { - owner = msg.sender; - totalSupply = valueFounder; - balanceOf[_addressFounder] = valueFounder; - emit Transfer(address(0x0), _addressFounder, valueFounder); - } - - function transfer(address _to, uint256 _value) isRunning validAddress public returns (bool success) { - require(balanceOf[msg.sender] >= _value); - require(balanceOf[_to] + _value >= balanceOf[_to]); - balanceOf[msg.sender] -= _value; - balanceOf[_to] += _value; - emit Transfer(msg.sender, _to, _value); - return true; - } - - function transferFrom(address _from, address _to, uint256 _value) isRunning validAddress public returns (bool success) { - require(balanceOf[_from] >= _value); - require(balanceOf[_to] + _value >= balanceOf[_to]); - require(allowance[_from][msg.sender] >= _value); - balanceOf[_to] += _value; - balanceOf[_from] -= _value; - allowance[_from][msg.sender] -= _value; - emit Transfer(_from, _to, _value); - return true; - } - - function approve(address _spender, uint256 _value) isRunning validAddress public returns (bool success) { - require(_value == 0 || allowance[msg.sender][_spender] == 0); - allowance[msg.sender][_spender] = _value; - emit Approval(msg.sender, _spender, _value); - return true; - } - - function stop() isOwner public { - stopped = true; - } - - function start() isOwner public { - stopped = false; - } - - function setName(string memory _name) isOwner public { - name = _name; - } - - function burn(uint256 _value) public { - require(balanceOf[msg.sender] >= _value); - balanceOf[msg.sender] -= _value; - balanceOf[address(0x0)] += _value; - emit Transfer(msg.sender, address(0x0), _value); - } - - event Transfer(address indexed _from, address indexed _to, uint256 _value); - event Approval(address indexed _owner, address indexed _spender, uint256 _value); -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractScenario005.sol b/framework/src/test/resources/soliditycode_0.7.6/contractScenario005.sol deleted file mode 100644 index 39fe4665559..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractScenario005.sol +++ /dev/null @@ -1,103 +0,0 @@ - - -interface token { - function transfer(address receiver, uint amount) external; -} - -contract Crowdsale { - address payable public beneficiary = 0x1b228F5D9f934c7bb18Aaa86F90418932888E7b4; // 募资成功后的收款方 - uint public fundingGoal = 10000000; // 募资额度 - uint public amountRaised = 1000000; // 参与数量 - uint public deadline; // 募资截止期 - - uint public price; // token 与以太坊的汇率 , token卖多少钱 - token public tokenReward; // 要卖的token - - mapping(address => uint256) public balanceOf; - - bool fundingGoalReached = false; // 众筹是否达到目标 - bool crowdsaleClosed = false; // 众筹是否结束 - - /** - * 事件可以用来跟踪信息 - **/ - event GoalReached(address recipient, uint totalAmountRaised); - event FundTransfer(address backer, uint amount, bool isContribution); - - /** - * 构造函数, 设置相关属性 - */ - constructor( - address payable ifSuccessfulSendTo, - uint fundingGoalInEthers, - uint durationInMinutes, - uint finneyCostOfEachToken, - address addressOfTokenUsedAsReward) public{ - beneficiary = ifSuccessfulSendTo; - fundingGoal = fundingGoalInEthers * 1 sun; - deadline = block.timestamp + durationInMinutes * 1 minutes; - price = finneyCostOfEachToken * 1 trx; - tokenReward = token(addressOfTokenUsedAsReward); // 传入已发布的 token 合约的地址来创建实例 - } - - /** - * 无函数名的Fallback函数, - * 在向合约转账时,这个函数会被调用 - */ - fallback() payable external{ - require(!crowdsaleClosed); - uint amount = msg.value; - balanceOf[msg.sender] += amount; - amountRaised += amount; - tokenReward.transfer(msg.sender, amount / price); - emit FundTransfer(msg.sender, amount, true); - } - - /** - * 定义函数修改器modifier(作用和Python的装饰器很相似) - * 用于在函数执行前检查某种前置条件(判断通过之后才会继续执行该方法) - * _ 表示继续执行之后的代码 - **/ - modifier afterDeadline() { if (block.timestamp >= deadline) _; } - - /** - * 判断众筹是否完成融资目标, 这个方法使用了afterDeadline函数修改器 - * - */ - function checkGoalReached() afterDeadline public{ - if (amountRaised >= fundingGoal) { - fundingGoalReached = true; - emit GoalReached(beneficiary, amountRaised); - } - crowdsaleClosed = true; - } - - - /** - * 完成融资目标时,融资款发送到收款方 - * 未完成融资目标时,执行退款 - * - */ - function safeWithdrawal() afterDeadline public{ - if (!fundingGoalReached) { - uint amount = balanceOf[msg.sender]; - balanceOf[msg.sender] = 0; - if (amount > 0) { - if (msg.sender.send(amount)) { - emit FundTransfer(msg.sender, amount, false); - } else { - balanceOf[msg.sender] = amount; - } - } - } - - if (fundingGoalReached && beneficiary == msg.sender) { - if (payable(beneficiary).send(amountRaised)) { - emit FundTransfer(beneficiary, amountRaised, false); - } else { - //If we fail to send the funds to beneficiary, unlock funders balance - fundingGoalReached = false; - } - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractScenario006.sol b/framework/src/test/resources/soliditycode_0.7.6/contractScenario006.sol deleted file mode 100644 index 7b8e2270e23..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractScenario006.sol +++ /dev/null @@ -1,1963 +0,0 @@ - - -interface PlayerBookInterface { - function getPlayerID(address _addr) external returns (uint256); - function getPlayerName(uint256 _pID) external view returns (bytes32); - function getPlayerLAff(uint256 _pID) external view returns (uint256); - function getPlayerAddr(uint256 _pID) external view returns (address); - function getNameFee() external view returns (uint256); - function registerNameXIDFromDapp(address _addr, bytes32 _name, uint256 _affCode, bool _all) external payable returns(bool, uint256); - function registerNameXaddrFromDapp(address _addr, bytes32 _name, address _affCode, bool _all) external payable returns(bool, uint256); - function registerNameXnameFromDapp(address _addr, bytes32 _name, bytes32 _affCode, bool _all) external payable returns(bool, uint256); - function isDev(address _who) external view returns(bool); -} - - -/** -* @title -Name Filter- v0.1.9 -* ┌┬┐┌─┐┌─┐┌┬┐ ╦╦ ╦╔═╗╔╦╗ ┌─┐┬─┐┌─┐┌─┐┌─┐┌┐┌┌┬┐┌─┐ -* │ ├┤ ├─┤│││ ║║ ║╚═╗ ║ ├─┘├┬┘├┤ └─┐├┤ │││ │ └─┐ -* ┴ └─┘┴ ┴┴ ┴ ╚╝╚═╝╚═╝ ╩ ┴ ┴└─└─┘└─┘└─┘┘└┘ ┴ └─┘ -* _____ _____ -* (, / /) /) /) (, / /) /) -* ┌─┐ / _ (/_ // // / _ // _ __ _(/ -* ├─┤ ___/___(/_/(__(_/_(/_(/_ ___/__/_)_(/_(_(_/ (_(_(_ -* ┴ ┴ / / .-/ _____ (__ / -* (__ / (_/ (, / /)™ -* / __ __ __ __ _ __ __ _ _/_ _ _(/ -* ┌─┐┬─┐┌─┐┌┬┐┬ ┬┌─┐┌┬┐ /__/ (_(__(_)/ (_/_)_(_)/ (_(_(_(__(/_(_(_ -* ├─┘├┬┘│ │ │││ ││ │ (__ / .-/ © Jekyll Island Inc. 2018 -* ┴ ┴└─└─┘─┴┘└─┘└─┘ ┴ (_/ -* _ __ _ ____ ____ _ _ _____ ____ ___ -*=============| |\ | / /\ | |\/| | |_ =====| |_ | | | | | | | |_ | |_)==============* -*=============|_| \| /_/--\ |_| | |_|__=====|_| |_| |_|__ |_| |_|__ |_| \==============* -* -* ╔═╗┌─┐┌┐┌┌┬┐┬─┐┌─┐┌─┐┌┬┐ ╔═╗┌─┐┌┬┐┌─┐ ┌──────────┐ -* ║ │ ││││ │ ├┬┘├─┤│ │ ║ │ │ ││├┤ │ Inventor │ -* ╚═╝└─┘┘└┘ ┴ ┴└─┴ ┴└─┘ ┴ ╚═╝└─┘─┴┘└─┘ └──────────┘ -*/ - -library NameFilter { - /** - * @dev filters name strings - * -converts uppercase to lower case. - * -makes sure it does not start/end with a space - * -makes sure it does not contain multiple spaces in a row - * -cannot be only numbers - * -cannot start with 0x - * -restricts characters to A-Z, a-z, 0-9, and space. - * @return reprocessed string in bytes32 format - */ - function nameFilter(string memory _input) - internal - pure - returns(bytes32) - { - bytes memory _temp = bytes(_input); - uint256 _length = _temp.length; - - //sorry limited to 32 characters - require (_length <= 32 && _length > 0, "string must be between 1 and 32 characters"); - // make sure it doesnt start with or end with space - require(_temp[0] != 0x20 && _temp[_length-1] != 0x20, "string cannot start or end with space"); - // make sure first two characters are not 0x - if (_temp[0] == 0x30) - { - require(_temp[1] != 0x78, "string cannot start with 0x"); - require(_temp[1] != 0x58, "string cannot start with 0X"); - } - - // create a bool to track if we have a non number character - bool _hasNonNumber; - - // convert & check - for (uint256 i = 0; i < _length; i++) - { - // if its uppercase A-Z - if (_temp[i] > 0x40 && _temp[i] < 0x5b) - { - // convert to lower case a-z - _temp[i] = byte(uint8(_temp[i]) + 32); - - // we have a non number - if (_hasNonNumber == false) - _hasNonNumber = true; - } else { - require - ( - // require character is a space - _temp[i] == 0x20 || - // OR lowercase a-z - (_temp[i] > 0x60 && _temp[i] < 0x7b) || - // or 0-9 - (_temp[i] > 0x2f && _temp[i] < 0x3a), - "string contains invalid characters" - ); - // make sure theres not 2x spaces in a row - if (_temp[i] == 0x20) - require( _temp[i+1] != 0x20, "string cannot contain consecutive spaces"); - - // see if we have a character other than a number - if (_hasNonNumber == false && (_temp[i] < 0x30 || _temp[i] > 0x39)) - _hasNonNumber = true; - } - } - - require(_hasNonNumber == true, "string cannot be only numbers"); - - bytes32 _ret; - assembly { - _ret := mload(add(_temp, 32)) - } - return (_ret); - } -} - - -library SafeMath { - - /** - * @dev Multiplies two numbers, throws on overflow. - */ - function mul(uint256 a, uint256 b) - internal - pure - returns (uint256 c) - { - if (a == 0) { - return 0; - } - c = a * b; - require(c / a == b, "SafeMath mul failed"); - return c; - } - - /** - * @dev Integer division of two numbers, truncating the quotient. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - // assert(b > 0); // Solidity automatically throws when dividing by 0 - uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - return c; - } - - /** - * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). - */ - function sub(uint256 a, uint256 b) - internal - pure - returns (uint256) - { - require(b <= a, "SafeMath sub failed"); - return a - b; - } - - /** - * @dev Adds two numbers, throws on overflow. - */ - function add(uint256 a, uint256 b) - internal - pure - returns (uint256 c) - { - c = a + b; - require(c >= a, "SafeMath add failed"); - return c; - } - - /** - * @dev gives square root of given x. - */ - function sqrt(uint256 x) - internal - pure - returns (uint256 y) - { - uint256 z = ((add(x,1)) / 2); - y = x; - while (z < y) - { - y = z; - z = ((add((x / z),z)) / 2); - } - } - - /** - * @dev gives square. multiplies x by x - */ - function sq(uint256 x) - internal - pure - returns (uint256) - { - return (mul(x,x)); - } - - /** - * @dev x to the power of y - */ - function pwr(uint256 x, uint256 y) - internal - pure - returns (uint256) - { - if (x==0) - return (0); - else if (y==0) - return (1); - else - { - uint256 z = x; - for (uint256 i=1; i < y; i++) - z = mul(z,x); - return (z); - } - } -} - -//============================================================================== -// | _ _ _ | _ . -// |<(/_\/ (_(_||(_ . -//=======/====================================================================== -library F3DKeysCalcLong { - using SafeMath for *; - /** - * @dev calculates number of keys received given X eth - * @param _curEth current amount of eth in contract - * @param _newEth eth being spent - * @return amount of ticket purchased - */ - function keysRec(uint256 _curEth, uint256 _newEth) - internal - pure - returns (uint256) - { - return(keys((_curEth).add(_newEth)).sub(keys(_curEth))); - } - - /** - * @dev calculates amount of eth received if you sold X keys - * @param _curKeys current amount of keys that exist - * @param _sellKeys amount of keys you wish to sell - * @return amount of eth received - */ - function ethRec(uint256 _curKeys, uint256 _sellKeys) - internal - pure - returns (uint256) - { - return((eth(_curKeys)).sub(eth(_curKeys.sub(_sellKeys)))); - } - - /** - * @dev calculates how many keys would exist with given an amount of eth - * @param _eth eth "in contract" - * @return number of keys that would exist - */ - function keys(uint256 _eth) - internal - pure - returns(uint256) - { - return ((((((_eth).mul(1000000000000000000)).mul(312500000000000000000000000)).add(5624988281256103515625000000000000000000000000000000000000000000)).sqrt()).sub(74999921875000000000000000000000)) / (156250000); - } - - /** - * @dev calculates how much eth would be in contract given a number of keys - * @param _keys number of keys "in contract" - * @return eth that would exists - */ - function eth(uint256 _keys) - internal - pure - returns(uint256) - { - return ((78125000).mul(_keys.sq()).add(((149999843750000).mul(_keys.mul(1000000000000000000))) / (2))) / ((1000000000000000000).sq()); - } -} - -library F3Ddatasets { - //compressedData key - // [76-33][32][31][30][29][28-18][17][16-6][5-3][2][1][0] - // 0 - new player (bool) - // 1 - joined round (bool) - // 2 - new leader (bool) - // 3-5 - air drop tracker (uint 0-999) - // 6-16 - round end time - // 17 - winnerTeam - // 18 - 28 timestamp - // 29 - team - // 30 - 0 = reinvest (round), 1 = buy (round), 2 = buy (ico), 3 = reinvest (ico) - // 31 - airdrop happened bool - // 32 - airdrop tier - // 33 - airdrop amount won - //compressedIDs key - // [77-52][51-26][25-0] - // 0-25 - pID - // 26-51 - winPID - // 52-77 - rID - struct EventReturns { - uint256 compressedData; - uint256 compressedIDs; - address winnerAddr; // winner address - bytes32 winnerName; // winner name - uint256 amountWon; // amount won - uint256 newPot; // amount in new pot - uint256 P3DAmount; // amount distributed to p3d - uint256 genAmount; // amount distributed to gen - uint256 potAmount; // amount added to pot - } - struct Player { - address payable addr; // player address - bytes32 name; // player name - uint256 win; // winnings vault - uint256 gen; // general vault - uint256 aff; // affiliate vault - uint256 lrnd; // last round played - uint256 laff; // last affiliate id used - } - struct PlayerRounds { - uint256 eth; // eth player has added to round (used for eth limiter) - uint256 keys; // keys - uint256 mask; // player mask - uint256 ico; // ICO phase investment - } - struct Round { - uint256 plyr; // pID of player in lead - uint256 team; // tID of team in lead - uint256 end; // time ends/ended - bool ended; // has round end function been ran - uint256 strt; // time round started - uint256 keys; // keys - uint256 eth; // total eth in - uint256 pot; // eth to pot (during round) / final amount paid to winner (after round ends) - uint256 mask; // global mask - uint256 ico; // total eth sent in during ICO phase - uint256 icoGen; // total eth for gen during ICO phase - uint256 icoAvg; // average key price for ICO phase - } - struct TeamFee { - uint256 gen; // % of buy in thats paid to key holders of current round - uint256 p3d; // % of buy in thats paid to p3d holders - } - struct PotSplit { - uint256 gen; // % of pot thats paid to key holders of current round - uint256 p3d; // % of pot thats paid to p3d holders - } -} - -contract F3Devents { - // fired whenever a player registers a name - event onNewName - ( - uint256 indexed playerID, - address indexed playerAddress, - bytes32 indexed playerName, - bool isNewPlayer, - uint256 affiliateID, - address affiliateAddress, - bytes32 affiliateName, - uint256 amountPaid, - uint256 timeStamp - ); - - // fired at end of buy or reload - event onEndTx - ( - uint256 compressedData, - uint256 compressedIDs, - bytes32 playerName, - address playerAddress, - uint256 ethIn, - uint256 keysBought, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount, - uint256 potAmount, - uint256 airDropPot - ); - - // fired whenever theres a withdraw - event onWithdraw - ( - uint256 indexed playerID, - address playerAddress, - bytes32 playerName, - uint256 ethOut, - uint256 timeStamp - ); - - // fired whenever a withdraw forces end round to be ran - event onWithdrawAndDistribute - ( - address playerAddress, - bytes32 playerName, - uint256 ethOut, - uint256 compressedData, - uint256 compressedIDs, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount - ); - - // (fomo3d long only) fired whenever a player tries a buy after round timer - // hit zero, and causes end round to be ran. - event onBuyAndDistribute - ( - address playerAddress, - bytes32 playerName, - uint256 ethIn, - uint256 compressedData, - uint256 compressedIDs, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount - ); - - // (fomo3d long only) fired whenever a player tries a reload after round timer - // hit zero, and causes end round to be ran. - event onReLoadAndDistribute - ( - address playerAddress, - bytes32 playerName, - uint256 compressedData, - uint256 compressedIDs, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount - ); - - // fired whenever an affiliate is paid - event onAffiliatePayout - ( - uint256 indexed affiliateID, - address affiliateAddress, - bytes32 affiliateName, - uint256 indexed roundID, - uint256 indexed buyerID, - uint256 amount, - uint256 timeStamp - ); - - // received pot swap deposit - event onPotSwapDeposit - ( - uint256 roundID, - uint256 amountAddedToPot - ); -} - - - -contract FoMo3Dlong is F3Devents { - using SafeMath for *; - using NameFilter for string; - using F3DKeysCalcLong for uint256; - - address public otherF3D_; - address public Divies; - address public Jekyll_Island_Inc; - PlayerBookInterface public playerBook;// =PlayerBookInterface(0x0dcd2f752394c41875e259e00bb44fd505297caf);//new PlayerBook();// - // TeamJustInterface constant private teamJust = TeamJustInterface(0x3a5f8140b9213a0f733a6a639857c9df43ee3f5a);// new TeamJust();// - - //============================================================================== - // _ _ _ |`. _ _ _ |_ | _ _ . - // (_(_)| |~|~|(_||_|| (_||_)|(/__\ . (game settings) - //=================_|=========================================================== - string constant public name = "FoMo3D Long Official"; - string constant public symbol = "F3D"; - uint256 private rndExtra_ = 30;//extSettings.getLongExtra(); // length of the very first ICO - uint256 private rndGap_ = 30; //extSettings.getLongGap(); // length of ICO phase, set to 1 year for EOS. - uint256 constant private rndInit_ = 1 hours; // round timer starts at this - uint256 constant private rndInc_ = 30 seconds; // every full key purchased adds this much to the timer - uint256 constant private rndMax_ = 24 hours; // max length a round timer can be - //============================================================================== - // _| _ _|_ _ _ _ _|_ _ . - // (_|(_| | (_| _\(/_ | |_||_) . (data used to store game info that changes) - //=============================|================================================ - uint256 public airDropPot_; // person who gets the airdrop wins part of this pot - uint256 public airDropTracker_ = 0; // incremented each time a "qualified" tx occurs. used to determine winning air drop - uint256 public rID_; // round id number / total rounds that have happened - //**************** - // PLAYER DATA - //**************** - mapping(address => uint256) public pIDxAddr_; // (addr => pID) returns player id by address - mapping(bytes32 => uint256) public pIDxName_; // (name => pID) returns player id by name - mapping(uint256 => F3Ddatasets.Player) public plyr_; // (pID => data) player data - mapping(uint256 => mapping(uint256 => F3Ddatasets.PlayerRounds)) public plyrRnds_; // (pID => rID => data) player round data by player id & round id - mapping(uint256 => mapping(bytes32 => bool)) public plyrNames_; // (pID => name => bool) list of names a player owns. (used so you can change your display name amongst any name you own) - //**************** - // ROUND DATA - //**************** - mapping(uint256 => F3Ddatasets.Round) public round_; // (rID => data) round data - mapping(uint256 => mapping(uint256 => uint256)) public rndTmEth_; // (rID => tID => data) eth in per team, by round id and team id - //**************** - // TEAM FEE DATA - //**************** - mapping(uint256 => F3Ddatasets.TeamFee) public fees_; // (team => fees) fee distribution by team - mapping(uint256 => F3Ddatasets.PotSplit) public potSplit_; // (team => fees) pot split distribution by team - - function setPlayerBook(address _playerBook) external { - require(msg.sender == owner, 'only dev!'); - require(address(playerBook) == address(0), 'already set!'); - playerBook = PlayerBookInterface(_playerBook); - } - - address public owner; - - //============================================================================== - // _ _ _ __|_ _ __|_ _ _ . - // (_(_)| |_\ | | |_|(_ | (_)| . (initial data setup upon contract deploy) - //============================================================================== - constructor() - public - { - owner = msg.sender; - // Team allocation structures - // 0 = whales - // 1 = bears - // 2 = sneks - // 3 = bulls - - // Team allocation percentages - // (F3D, P3D) + (Pot , Referrals, Community) - // Referrals / Community rewards are mathematically designed to come from the winner's share of the pot. - fees_[0] = F3Ddatasets.TeamFee(30, 6); - //50% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - fees_[1] = F3Ddatasets.TeamFee(43, 0); - //43% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - fees_[2] = F3Ddatasets.TeamFee(56, 10); - //20% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - fees_[3] = F3Ddatasets.TeamFee(43, 8); - //35% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - - // how to split up the final pot based on which team was picked - // (F3D, P3D) - potSplit_[0] = F3Ddatasets.PotSplit(15, 10); - //48% to winner, 25% to next round, 2% to com - potSplit_[1] = F3Ddatasets.PotSplit(25, 0); - //48% to winner, 25% to next round, 2% to com - potSplit_[2] = F3Ddatasets.PotSplit(20, 20); - //48% to winner, 10% to next round, 2% to com - potSplit_[3] = F3Ddatasets.PotSplit(30, 10); - //48% to winner, 10% to next round, 2% to com - } - //============================================================================== - // _ _ _ _|. |`. _ _ _ . - // | | |(_)(_||~|~|(/_| _\ . (these are safety checks) - //============================================================================== - /** - * @dev used to make sure no one can interact with contract until it has - * been activated. - */ - modifier isActivated() { - require(activated_ == true, "its not ready yet. check ?eta in discord"); - _; - } - - /** - * @dev prevents contracts from interacting with fomo3d - */ - modifier isHuman() { - address _addr = msg.sender; - uint256 _codeLength; - - assembly {_codeLength := extcodesize(_addr)} - require(_codeLength == 0, "sorry humans only"); - _; - } - - modifier onlyDevs() - { - require(playerBook.isDev(msg.sender) == true, "msg sender is not a dev"); - _; - } - - /** - * @dev sets boundaries for incoming tx - */ - modifier isWithinLimits(uint256 _eth) { - require(_eth >= 1000000000, "pocket lint: not a valid currency"); - require(_eth <= 100000000000000000000000, "no vitalik, no"); - _; - } - - //============================================================================== - // _ |_ |. _ |` _ __|_. _ _ _ . - // |_)|_||_)||(_ ~|~|_|| |(_ | |(_)| |_\ . (use these to interact with contract) - //====|========================================================================= - /** - * @dev emergency buy uses last stored affiliate ID and team snek - */ - fallback() - isActivated() - isHuman() - isWithinLimits(msg.value) - external - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_ ; - _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // buy core - buyCore(_pID, plyr_[_pID].laff, 2, _eventData_); - } - - /** - * @dev converts all incoming ethereum to keys. - * -functionhash- 0x8f38f309 (using ID for affiliate) - * -functionhash- 0x98a0871d (using address for affiliate) - * -functionhash- 0xa65b37a1 (using name for affiliate) - * @param _affCode the ID/address/name of the player who gets the affiliate fee - * @param _team what team is the player playing for? - */ - function buyXid(uint256 _affCode, uint256 _team) - isActivated() - isHuman() - isWithinLimits(msg.value) - public - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_; - _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == 0 || _affCode == _pID) - { - // use last stored affiliate code - _affCode = plyr_[_pID].laff; - - // if affiliate code was given & its not the same as previously stored - } else if (_affCode != plyr_[_pID].laff) { - // update last affiliate - plyr_[_pID].laff = _affCode; - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // buy core - buyCore(_pID, _affCode, _team, _eventData_); - } - - function buyXaddr(address _affCode, uint256 _team) - isActivated() - isHuman() - isWithinLimits(msg.value) - public - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_; - _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == address(0) || _affCode == msg.sender) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxAddr_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // buy core - buyCore(_pID, _affID, _team, _eventData_); - } - - function buyXname(bytes32 _affCode, uint256 _team) - isActivated() - isHuman() - isWithinLimits(msg.value) - public - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_ ; - _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == '' || _affCode == plyr_[_pID].name) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxName_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // buy core - buyCore(_pID, _affID, _team, _eventData_); - } - - /** - * @dev essentially the same as buy, but instead of you sending ether - * from your wallet, it uses your unwithdrawn earnings. - * -functionhash- 0x349cdcac (using ID for affiliate) - * -functionhash- 0x82bfc739 (using address for affiliate) - * -functionhash- 0x079ce327 (using name for affiliate) - * @param _affCode the ID/address/name of the player who gets the affiliate fee - * @param _team what team is the player playing for? - * @param _eth amount of earnings to use (remainder returned to gen vault) - */ - function reLoadXid(uint256 _affCode, uint256 _team, uint256 _eth) - isActivated() - isHuman() - isWithinLimits(_eth) - public - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == 0 || _affCode == _pID) - { - // use last stored affiliate code - _affCode = plyr_[_pID].laff; - - // if affiliate code was given & its not the same as previously stored - } else if (_affCode != plyr_[_pID].laff) { - // update last affiliate - plyr_[_pID].laff = _affCode; - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // reload core - reLoadCore(_pID, _affCode, _team, _eth, _eventData_); - } - - function reLoadXaddr(address _affCode, uint256 _team, uint256 _eth) - isActivated() - isHuman() - isWithinLimits(_eth) - public - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == address(0) || _affCode == msg.sender) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxAddr_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // reload core - reLoadCore(_pID, _affID, _team, _eth, _eventData_); - } - - function reLoadXname(bytes32 _affCode, uint256 _team, uint256 _eth) - isActivated() - isHuman() - isWithinLimits(_eth) - public - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == '' || _affCode == plyr_[_pID].name) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxName_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // reload core - reLoadCore(_pID, _affID, _team, _eth, _eventData_); - } - - /** - * @dev withdraws all of your earnings. - * -functionhash- 0x3ccfd60b - */ - function withdraw() - isActivated() - isHuman() - public - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = block.timestamp; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // setup temp var for player eth - uint256 _eth; - - // check to see if round has ended and no one has run round end yet - if (_now > round_[_rID].end && round_[_rID].ended == false && round_[_rID].plyr != 0) - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // end the round (distributes pot) - round_[_rID].ended = true; - _eventData_ = endRound(_eventData_); - - // get their earnings - _eth = withdrawEarnings(_pID); - - // gib moni - if (_eth > 0) - plyr_[_pID].addr.transfer(_eth); - - // build event data - _eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID; - - // fire withdraw and distribute event - emit F3Devents.onWithdrawAndDistribute - ( - msg.sender, - plyr_[_pID].name, - _eth, - _eventData_.compressedData, - _eventData_.compressedIDs, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount - ); - - // in any other situation - } else { - // get their earnings - _eth = withdrawEarnings(_pID); - - // gib moni - if (_eth > 0) - plyr_[_pID].addr.transfer(_eth); - - // fire withdraw event - emit F3Devents.onWithdraw(_pID, msg.sender, plyr_[_pID].name, _eth, _now); - } - } - - /** - * @dev use these to register names. they are just wrappers that will send the - * registration requests to the PlayerBook contract. So registering here is the - * same as registering there. UI will always display the last name you registered. - * but you will still own all previously registered names to use as affiliate - * links. - * - must pay a registration fee. - * - name must be unique - * - names will be converted to lowercase - * - name cannot start or end with a space - * - cannot have more than 1 space in a row - * - cannot be only numbers - * - cannot start with 0x - * - name must be at least 1 char - * - max length of 32 characters long - * - allowed characters: a-z, 0-9, and space - * -functionhash- 0x921dec21 (using ID for affiliate) - * -functionhash- 0x3ddd4698 (using address for affiliate) - * -functionhash- 0x685ffd83 (using name for affiliate) - * @param _nameString players desired name - * @param _affCode affiliate ID, address, or name of who referred you - * @param _all set to true if you want this to push your info to all games - * (this might cost a lot of gas) - */ - function registerNameXID(string memory _nameString, uint256 _affCode, bool _all) - isHuman() - public - payable - { - bytes32 _name = _nameString.nameFilter(); - address _addr = msg.sender; - uint256 _paid = msg.value; - (bool _isNewPlayer, uint256 _affID) = playerBook.registerNameXIDFromDapp{value:_paid}(_addr, _name, _affCode, _all); - - uint256 _pID = pIDxAddr_[_addr]; - - // fire event - emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, block.timestamp); - } - - function registerNameXaddr(string memory _nameString, address _affCode, bool _all) - isHuman() - public - payable - { - bytes32 _name = _nameString.nameFilter(); - address _addr = msg.sender; - uint256 _paid = msg.value; - (bool _isNewPlayer, uint256 _affID) = playerBook.registerNameXaddrFromDapp{value:msg.value}(msg.sender, _name, _affCode, _all); - - uint256 _pID = pIDxAddr_[_addr]; - - // fire event - emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, block.timestamp); - } - - function registerNameXname(string memory _nameString, bytes32 _affCode, bool _all) - isHuman() - public - payable - { - bytes32 _name = _nameString.nameFilter(); - address _addr = msg.sender; - uint256 _paid = msg.value; - (bool _isNewPlayer, uint256 _affID) = playerBook.registerNameXnameFromDapp{value:msg.value}(msg.sender, _name, _affCode, _all); - - uint256 _pID = pIDxAddr_[_addr]; - - // fire event - emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, block.timestamp); - } - //============================================================================== - // _ _ _|__|_ _ _ _ . - // (_|(/_ | | (/_| _\ . (for UI & viewing things on etherscan) - //=====_|======================================================================= - /** - * @dev return the price buyer will pay for next 1 individual key. - * -functionhash- 0x018a25e8 - * @return price for next key bought (in wei format) - */ - function getBuyPrice() - public - view - returns (uint256) - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = block.timestamp; - - // are we in a round? - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - return ((round_[_rID].keys.add(1000000000000000000)).ethRec(1000000000000000000)); - else // rounds over. need price for new round - return (75000000000000); - // init - } - - /** - * @dev returns time left. dont spam this, you'll ddos yourself from your node - * provider - * -functionhash- 0xc7e284b8 - * @return time left in seconds - */ - function getTimeLeft() - public - view - returns (uint256) - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = block.timestamp; - - if (_now < round_[_rID].end) - if (_now > round_[_rID].strt + rndGap_) - return ((round_[_rID].end).sub(_now)); - else - return ((round_[_rID].strt + rndGap_).sub(_now)); - else - return (0); - } - - /** - * @dev returns player earnings per vaults - * -functionhash- 0x63066434 - * @return winnings vault - * @return general vault - * @return affiliate vault - */ - function getPlayerVaults(uint256 _pID) - public - view - returns (uint256, uint256, uint256) - { - // setup local rID - uint256 _rID = rID_; - - // if round has ended. but round end has not been run (so contract has not distributed winnings) - if (block.timestamp > round_[_rID].end && round_[_rID].ended == false && round_[_rID].plyr != 0) - { - // if player is winner - if (round_[_rID].plyr == _pID) - { - return - ( - (plyr_[_pID].win).add(((round_[_rID].pot).mul(48)) / 100), - (plyr_[_pID].gen).add(getPlayerVaultsHelper(_pID, _rID).sub(plyrRnds_[_pID][_rID].mask)), - plyr_[_pID].aff - ); - // if player is not the winner - } else { - return - ( - plyr_[_pID].win, - (plyr_[_pID].gen).add(getPlayerVaultsHelper(_pID, _rID).sub(plyrRnds_[_pID][_rID].mask)), - plyr_[_pID].aff - ); - } - - // if round is still going on, or round has ended and round end has been ran - } else { - return - ( - plyr_[_pID].win, - (plyr_[_pID].gen).add(calcUnMaskedEarnings(_pID, plyr_[_pID].lrnd)), - plyr_[_pID].aff - ); - } - } - - /** - * solidity hates stack limits. this lets us avoid that hate - */ - function getPlayerVaultsHelper(uint256 _pID, uint256 _rID) - private - view - returns (uint256) - { - return (((((round_[_rID].mask).add(((((round_[_rID].pot).mul(potSplit_[round_[_rID].team].gen)) / 100).mul(1000000000000000000)) / (round_[_rID].keys))).mul(plyrRnds_[_pID][_rID].keys)) / 1000000000000000000)); - } - - /** - * @dev returns all current round info needed for front end - * -functionhash- 0x747dff42 - * @return eth invested during ICO phase - * @return round id - * @return total keys for round - * @return time round ends - * @return time round started - * @return current pot - * @return current team ID & player ID in lead - * @return current player in leads address - * @return current player in leads name - * @return whales eth in for round - * @return bears eth in for round - * @return sneks eth in for round - * @return bulls eth in for round - * @return airdrop tracker # & airdrop pot - */ - function getCurrentRoundInfo() - public - view - returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256, address, bytes32, uint256, uint256, uint256, uint256, uint256) - { - // setup local rID - uint256 _rID = rID_; - - return - ( - round_[_rID].ico, //0 - _rID, //1 - round_[_rID].keys, //2 - round_[_rID].end, //3 - round_[_rID].strt, //4 - round_[_rID].pot, //5 - (round_[_rID].team + (round_[_rID].plyr * 10)), //6 - plyr_[round_[_rID].plyr].addr, //7 - plyr_[round_[_rID].plyr].name, //8 - rndTmEth_[_rID][0], //9 - rndTmEth_[_rID][1], //10 - rndTmEth_[_rID][2], //11 - rndTmEth_[_rID][3], //12 - airDropTracker_ + (airDropPot_ * 1000) //13 - ); - } - - /** - * @dev returns player info based on address. if no address is given, it will - * use msg.sender - * -functionhash- 0xee0b5d8b - * @param _addr address of the player you want to lookup - * @return player ID - * @return player name - * @return keys owned (current round) - * @return winnings vault - * @return general vault - * @return affiliate vault - * @return player round eth - */ - function getPlayerInfoByAddress(address _addr) - public - view - returns (uint256, bytes32, uint256, uint256, uint256, uint256, uint256) - { - // setup local rID - uint256 _rID = rID_; - - if (_addr == address(0)) - { - _addr == msg.sender; - } - uint256 _pID = pIDxAddr_[_addr]; - - return - ( - _pID, //0 - plyr_[_pID].name, //1 - plyrRnds_[_pID][_rID].keys, //2 - plyr_[_pID].win, //3 - (plyr_[_pID].gen).add(calcUnMaskedEarnings(_pID, plyr_[_pID].lrnd)), //4 - plyr_[_pID].aff, //5 - plyrRnds_[_pID][_rID].eth //6 - ); - } - - //============================================================================== - // _ _ _ _ | _ _ . _ . - // (_(_)| (/_ |(_)(_||(_ . (this + tools + calcs + modules = our softwares engine) - //=====================_|======================================================= - /** - * @dev logic runs whenever a buy order is executed. determines how to handle - * incoming eth depending on if we are in an active round or not - */ - function buyCore(uint256 _pID, uint256 _affID, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) - private - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = block.timestamp; - - // if round is active - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - { - // call core - core(_rID, _pID, msg.value, _affID, _team, _eventData_); - - // if round is not active - } else { - // check to see if end round needs to be ran - if (_now > round_[_rID].end && round_[_rID].ended == false) - { - // end the round (distributes pot) & start new round - round_[_rID].ended = true; - _eventData_ = endRound(_eventData_); - - // build event data - _eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID; - - // fire buy and distribute event - emit F3Devents.onBuyAndDistribute - ( - msg.sender, - plyr_[_pID].name, - msg.value, - _eventData_.compressedData, - _eventData_.compressedIDs, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount - ); - } - - // put eth in players vault - plyr_[_pID].gen = plyr_[_pID].gen.add(msg.value); - } - } - - /** - * @dev logic runs whenever a reload order is executed. determines how to handle - * incoming eth depending on if we are in an active round or not - */ - function reLoadCore(uint256 _pID, uint256 _affID, uint256 _team, uint256 _eth, F3Ddatasets.EventReturns memory _eventData_) - private - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = block.timestamp; - - // if round is active - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - { - // get earnings from all vaults and return unused to gen vault - // because we use a custom safemath library. this will throw if player - // tried to spend more eth than they have. - plyr_[_pID].gen = withdrawEarnings(_pID).sub(_eth); - - // call core - core(_rID, _pID, _eth, _affID, _team, _eventData_); - - // if round is not active and end round needs to be ran - } else if (_now > round_[_rID].end && round_[_rID].ended == false) { - // end the round (distributes pot) & start new round - round_[_rID].ended = true; - _eventData_ = endRound(_eventData_); - - // build event data - _eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID; - - // fire buy and distribute event - emit F3Devents.onReLoadAndDistribute - ( - msg.sender, - plyr_[_pID].name, - _eventData_.compressedData, - _eventData_.compressedIDs, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount - ); - } - } - - /** - * @dev this is the core logic for any buy/reload that happens while a round - * is live. - */ - function core(uint256 _rID, uint256 _pID, uint256 _eth, uint256 _affID, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) - private - { - // if player is new to round - if (plyrRnds_[_pID][_rID].keys == 0) - _eventData_ = managePlayer(_pID, _eventData_); - - // early round eth limiter - if (round_[_rID].eth < 100000000000000000000 && plyrRnds_[_pID][_rID].eth.add(_eth) > 1000000000000000000) - { - uint256 _availableLimit = (1000000000000000000).sub(plyrRnds_[_pID][_rID].eth); - uint256 _refund = _eth.sub(_availableLimit); - plyr_[_pID].gen = plyr_[_pID].gen.add(_refund); - _eth = _availableLimit; - } - - // if eth left is greater than min eth allowed (sorry no pocket lint) - if (_eth > 1000000000) - { - - // mint the new keys - uint256 _keys = (round_[_rID].eth).keysRec(_eth); - - // if they bought at least 1 whole key - if (_keys >= 1000000000000000000) - { - updateTimer(_keys, _rID); - - // set new leaders - if (round_[_rID].plyr != _pID) - round_[_rID].plyr = _pID; - if (round_[_rID].team != _team) - round_[_rID].team = _team; - - // set the new leader bool to true - _eventData_.compressedData = _eventData_.compressedData + 100; - } - - // manage airdrops - if (_eth >= 100000000000000000) - { - airDropTracker_++; - if (airdrop() == true) - { - // gib muni - uint256 _prize; - if (_eth >= 10000000000000000000) - { - // calculate prize and give it to winner - _prize = ((airDropPot_).mul(75)) / 100; - plyr_[_pID].win = (plyr_[_pID].win).add(_prize); - - // adjust airDropPot - airDropPot_ = (airDropPot_).sub(_prize); - - // let event know a tier 3 prize was won - _eventData_.compressedData += 300000000000000000000000000000000; - } else if (_eth >= 1000000000000000000 && _eth < 10000000000000000000) { - // calculate prize and give it to winner - _prize = ((airDropPot_).mul(50)) / 100; - plyr_[_pID].win = (plyr_[_pID].win).add(_prize); - - // adjust airDropPot - airDropPot_ = (airDropPot_).sub(_prize); - - // let event know a tier 2 prize was won - _eventData_.compressedData += 200000000000000000000000000000000; - } else if (_eth >= 100000000000000000 && _eth < 1000000000000000000) { - // calculate prize and give it to winner - _prize = ((airDropPot_).mul(25)) / 100; - plyr_[_pID].win = (plyr_[_pID].win).add(_prize); - - // adjust airDropPot - airDropPot_ = (airDropPot_).sub(_prize); - - // let event know a tier 3 prize was won - _eventData_.compressedData += 300000000000000000000000000000000; - } - // set airdrop happened bool to true - _eventData_.compressedData += 10000000000000000000000000000000; - // let event know how much was won - _eventData_.compressedData += _prize * 1000000000000000000000000000000000; - - // reset air drop tracker - airDropTracker_ = 0; - } - } - - // store the air drop tracker number (number of buys since last airdrop) - _eventData_.compressedData = _eventData_.compressedData + (airDropTracker_ * 1000); - - // update player - plyrRnds_[_pID][_rID].keys = _keys.add(plyrRnds_[_pID][_rID].keys); - plyrRnds_[_pID][_rID].eth = _eth.add(plyrRnds_[_pID][_rID].eth); - - // update round - round_[_rID].keys = _keys.add(round_[_rID].keys); - round_[_rID].eth = _eth.add(round_[_rID].eth); - rndTmEth_[_rID][_team] = _eth.add(rndTmEth_[_rID][_team]); - - // distribute eth - _eventData_ = distributeExternal(_rID, _pID, _eth, _affID, _team, _eventData_); - _eventData_ = distributeInternal(_rID, _pID, _eth, _team, _keys, _eventData_); - - // call end tx function to fire end tx event. - endTx(_pID, _team, _eth, _keys, _eventData_); - } - } - //============================================================================== - // _ _ | _ | _ _|_ _ _ _ . - // (_(_||(_|_||(_| | (_)| _\ . - //============================================================================== - /** - * @dev calculates unmasked earnings (just calculates, does not update mask) - * @return earnings in wei format - */ - function calcUnMaskedEarnings(uint256 _pID, uint256 _rIDlast) - private - view - returns (uint256) - { - return ((((round_[_rIDlast].mask).mul(plyrRnds_[_pID][_rIDlast].keys)) / (1000000000000000000)).sub(plyrRnds_[_pID][_rIDlast].mask)); - } - - /** - * @dev returns the amount of keys you would get given an amount of eth. - * -functionhash- 0xce89c80c - * @param _rID round ID you want price for - * @param _eth amount of eth sent in - * @return keys received - */ - function calcKeysReceived(uint256 _rID, uint256 _eth) - public - view - returns (uint256) - { - // grab time - uint256 _now = block.timestamp; - - // are we in a round? - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - return ((round_[_rID].eth).keysRec(_eth)); - else // rounds over. need keys for new round - return ((_eth).keys()); - } - - /** - * @dev returns current eth price for X keys. - * -functionhash- 0xcf808000 - * @param _keys number of keys desired (in 18 decimal format) - * @return amount of eth needed to send - */ - function iWantXKeys(uint256 _keys) - public - view - returns (uint256) - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = block.timestamp; - - // are we in a round? - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - return ((round_[_rID].keys.add(_keys)).ethRec(_keys)); - else // rounds over. need price for new round - return ((_keys).eth()); - } - //============================================================================== - // _|_ _ _ | _ . - // | (_)(_)|_\ . - //============================================================================== - /** - * @dev receives name/player info from names contract - */ - function receivePlayerInfo(uint256 _pID, address payable _addr, bytes32 _name, uint256 _laff) - external - { - require(msg.sender == address(playerBook), "your not playerNames contract... hmmm.."); - if (pIDxAddr_[_addr] != _pID) - pIDxAddr_[_addr] = _pID; - if (pIDxName_[_name] != _pID) - pIDxName_[_name] = _pID; - if (plyr_[_pID].addr != _addr) - plyr_[_pID].addr = _addr; - if (plyr_[_pID].name != _name) - plyr_[_pID].name = _name; - if (plyr_[_pID].laff != _laff) - plyr_[_pID].laff = _laff; - if (plyrNames_[_pID][_name] == false) - plyrNames_[_pID][_name] = true; - } - - /** - * @dev receives entire player name list - */ - function receivePlayerNameList(uint256 _pID, bytes32 _name) - external - { - require(msg.sender == address(playerBook), "your not playerNames contract... hmmm.."); - if (plyrNames_[_pID][_name] == false) - plyrNames_[_pID][_name] = true; - } - - /** - * @dev gets existing or registers new pID. use this when a player may be new - * @return pID - */ - function determinePID(F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - uint256 _pID = pIDxAddr_[msg.sender]; - // if player is new to this version of fomo3d - if (_pID == 0) - { - // grab their player ID, name and last aff ID, from player names contract - _pID = playerBook.getPlayerID(msg.sender); - bytes32 _name = playerBook.getPlayerName(_pID); - uint256 _laff = playerBook.getPlayerLAff(_pID); - - // set up player account - pIDxAddr_[msg.sender] = _pID; - plyr_[_pID].addr = msg.sender; - - if (_name != "") - { - pIDxName_[_name] = _pID; - plyr_[_pID].name = _name; - plyrNames_[_pID][_name] = true; - } - - if (_laff != 0 && _laff != _pID) - plyr_[_pID].laff = _laff; - - // set the new player bool to true - _eventData_.compressedData = _eventData_.compressedData + 1; - } - return (_eventData_); - } - - /** - * @dev checks to make sure user picked a valid team. if not sets team - * to default (sneks) - */ - function verifyTeam(uint256 _team) - private - pure - returns (uint256) - { - if (_team < 0 || _team > 3) - return (2); - else - return (_team); - } - - /** - * @dev decides if round end needs to be run & new round started. and if - * player unmasked earnings from previously played rounds need to be moved. - */ - function managePlayer(uint256 _pID, F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - // if player has played a previous round, move their unmasked earnings - // from that round to gen vault. - if (plyr_[_pID].lrnd != 0) - updateGenVault(_pID, plyr_[_pID].lrnd); - - // update player's last round played - plyr_[_pID].lrnd = rID_; - - // set the joined round bool to true - _eventData_.compressedData = _eventData_.compressedData + 10; - - return (_eventData_); - } - - /** - * @dev ends the round. manages paying out winner/splitting up pot - */ - function endRound(F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - // setup local rID - uint256 _rID = rID_; - - // grab our winning player and team id's - uint256 _winPID = round_[_rID].plyr; - uint256 _winTID = round_[_rID].team; - - // grab our pot amount - uint256 _pot = round_[_rID].pot; - - // calculate our winner share, community rewards, gen share, - // p3d share, and amount reserved for next pot - uint256 _win = (_pot.mul(48)) / 100; - uint256 _com = (_pot / 50); - uint256 _gen = (_pot.mul(potSplit_[_winTID].gen)) / 100; - uint256 _p3d = (_pot.mul(potSplit_[_winTID].p3d)) / 100; - uint256 _res = (((_pot.sub(_win)).sub(_com)).sub(_gen)).sub(_p3d); - - // calculate ppt for round mask - uint256 _ppt = (_gen.mul(1000000000000000000)) / (round_[_rID].keys); - uint256 _dust = _gen.sub((_ppt.mul(round_[_rID].keys)) / 1000000000000000000); - if (_dust > 0) - { - _gen = _gen.sub(_dust); - _res = _res.add(_dust); - } - - // pay our winner - plyr_[_winPID].win = _win.add(plyr_[_winPID].win); - - // community rewards - address payable add = address(uint160(Jekyll_Island_Inc)); - if (!add.send(_com)) - { - // This ensures Team Just cannot influence the outcome of FoMo3D with - // bank migrations by breaking outgoing transactions. - // Something we would never do. But that's not the point. - // We spent 2000$ in eth re-deploying just to patch this, we hold the - // highest belief that everything we create should be trustless. - // Team JUST, The name you shouldn't have to trust. - _p3d = _p3d.add(_com); - _com = 0; - } - - // distribute gen portion to key holders - round_[_rID].mask = _ppt.add(round_[_rID].mask); - - // send share for p3d to divies - if (_p3d > 0){ - address payable addr = address(uint160(Divies)); - addr.transfer(_p3d); - } - // prepare event data - _eventData_.compressedData = _eventData_.compressedData + (round_[_rID].end * 1000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + (_winPID * 100000000000000000000000000) + (_winTID * 100000000000000000); - _eventData_.winnerAddr = plyr_[_winPID].addr; - _eventData_.winnerName = plyr_[_winPID].name; - _eventData_.amountWon = _win; - _eventData_.genAmount = _gen; - _eventData_.P3DAmount = _p3d; - _eventData_.newPot = _res; - - // start next round - rID_++; - _rID++; - round_[_rID].strt = block.timestamp; - round_[_rID].end = block.timestamp.add(rndInit_).add(rndGap_); - round_[_rID].pot = _res; - - return (_eventData_); - } - - /** - * @dev moves any unmasked earnings to gen vault. updates earnings mask - */ - function updateGenVault(uint256 _pID, uint256 _rIDlast) - private - { - uint256 _earnings = calcUnMaskedEarnings(_pID, _rIDlast); - if (_earnings > 0) - { - // put in gen vault - plyr_[_pID].gen = _earnings.add(plyr_[_pID].gen); - // zero out their earnings by updating mask - plyrRnds_[_pID][_rIDlast].mask = _earnings.add(plyrRnds_[_pID][_rIDlast].mask); - } - } - - /** - * @dev updates round timer based on number of whole keys bought. - */ - function updateTimer(uint256 _keys, uint256 _rID) - private - { - // grab time - uint256 _now = block.timestamp; - - // calculate time based on number of keys bought - uint256 _newTime; - if (_now > round_[_rID].end && round_[_rID].plyr == 0) - _newTime = (((_keys) / (1000000000000000000)).mul(rndInc_)).add(_now); - else - _newTime = (((_keys) / (1000000000000000000)).mul(rndInc_)).add(round_[_rID].end); - - // compare to max and set new end time - if (_newTime < (rndMax_).add(_now)) - round_[_rID].end = _newTime; - else - round_[_rID].end = rndMax_.add(_now); - } - - /** - * @dev generates a random number between 0-99 and checks to see if thats - * resulted in an airdrop win - * @return do we have a winner? - */ - function airdrop() - private - view - returns (bool) - { - uint256 seed = uint256(keccak256(abi.encodePacked( - - (block.timestamp).add - (block.difficulty).add - ((uint256(keccak256(abi.encodePacked(block.coinbase)))) / (block.timestamp)).add - (block.gaslimit).add - ((uint256(keccak256(abi.encodePacked(msg.sender)))) / (block.timestamp)).add - (block.number) - - ))); - if ((seed - ((seed / 1000) * 1000)) < airDropTracker_) - return (true); - else - return (false); - } - - /** - * @dev distributes eth based on fees to com, aff, and p3d - */ - function distributeExternal(uint256 _rID, uint256 _pID, uint256 _eth, uint256 _affID, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - // pay 2% out to community rewards - uint256 _com = _eth / 50; - uint256 _p3d; - address payable addr = address(uint160(Jekyll_Island_Inc)); - if (!addr.send(_com)) - { - // This ensures Team Just cannot influence the outcome of FoMo3D with - // bank migrations by breaking outgoing transactions. - // Something we would never do. But that's not the point. - // We spent 2000$ in eth re-deploying just to patch this, we hold the - // highest belief that everything we create should be trustless. - // Team JUST, The name you shouldn't have to trust. - _p3d = _com; - _com = 0; - } - - // pay 1% out to FoMo3D short - _com = _eth / 100; - address payable add = address(uint160(otherF3D_)); - add.transfer(_com); - - // distribute share to affiliate - _com = _eth / 10; - - // decide what to do with affiliate share of fees - // affiliate must not be self, and must have a name registered - if (_affID != _pID && plyr_[_affID].name != '') { - plyr_[_affID].aff = _com.add(plyr_[_affID].aff); - emit F3Devents.onAffiliatePayout(_affID, plyr_[_affID].addr, plyr_[_affID].name, _rID, _pID, _com, block.timestamp); - } else { - _p3d = _com; - } - - // pay out p3d - _p3d = _p3d.add((_eth.mul(fees_[_team].p3d)) / (100)); - if (_p3d > 0) - { - // deposit to divies contract - address payable add = address(uint160(Divies)); - add.transfer(_p3d); - - // set up event data - _eventData_.P3DAmount = _p3d.add(_eventData_.P3DAmount); - } - - return (_eventData_); - } - - function potSwap() - external - payable - { - // setup local rID - uint256 _rID = rID_ + 1; - - round_[_rID].pot = round_[_rID].pot.add(msg.value); - emit F3Devents.onPotSwapDeposit(_rID, msg.value); - } - - /** - * @dev distributes eth based on fees to gen and pot - */ - function distributeInternal(uint256 _rID, uint256 _pID, uint256 _eth, uint256 _team, uint256 _keys, F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns memory) - { - // calculate gen share - uint256 _gen = (_eth.mul(fees_[_team].gen)) / 100; - - // toss 1% into airdrop pot - uint256 _air = (_eth / 100); - airDropPot_ = airDropPot_.add(_air); - - // update eth balance (eth = eth - (com share + pot swap share + aff share + p3d share + airdrop pot share)) - _eth = _eth.sub(((_eth.mul(14)) / 100).add((_eth.mul(fees_[_team].p3d)) / 100)); - - // calculate pot - uint256 _pot = _eth.sub(_gen); - - // distribute gen share (thats what updateMasks() does) and adjust - // balances for dust. - uint256 _dust = updateMasks(_rID, _pID, _gen, _keys); - if (_dust > 0) - _gen = _gen.sub(_dust); - - // add eth to pot - round_[_rID].pot = _pot.add(_dust).add(round_[_rID].pot); - - // set up event data - _eventData_.genAmount = _gen.add(_eventData_.genAmount); - _eventData_.potAmount = _pot; - - return (_eventData_); - } - - /** - * @dev updates masks for round and player when keys are bought - * @return dust left over - */ - function updateMasks(uint256 _rID, uint256 _pID, uint256 _gen, uint256 _keys) - private - returns (uint256) - { - /* MASKING NOTES - earnings masks are a tricky thing for people to wrap their minds around. - the basic thing to understand here. is were going to have a global - tracker based on profit per share for each round, that increases in - relevant proportion to the increase in share supply. - - the player will have an additional mask that basically says "based - on the rounds mask, my shares, and how much i've already withdrawn, - how much is still owed to me?" - */ - - // calc profit per key & round mask based on this buy: (dust goes to pot) - uint256 _ppt = (_gen.mul(1000000000000000000)) / (round_[_rID].keys); - round_[_rID].mask = _ppt.add(round_[_rID].mask); - - // calculate player earning from their own buy (only based on the keys - // they just bought). & update player earnings mask - uint256 _pearn = (_ppt.mul(_keys)) / (1000000000000000000); - plyrRnds_[_pID][_rID].mask = (((round_[_rID].mask.mul(_keys)) / (1000000000000000000)).sub(_pearn)).add(plyrRnds_[_pID][_rID].mask); - - // calculate & return dust - return (_gen.sub((_ppt.mul(round_[_rID].keys)) / (1000000000000000000))); - } - - /** - * @dev adds up unmasked earnings, & vault earnings, sets them all to 0 - * @return earnings in wei format - */ - function withdrawEarnings(uint256 _pID) - private - returns (uint256) - { - // update gen vault - updateGenVault(_pID, plyr_[_pID].lrnd); - - // from vaults - uint256 _earnings = (plyr_[_pID].win).add(plyr_[_pID].gen).add(plyr_[_pID].aff); - if (_earnings > 0) - { - plyr_[_pID].win = 0; - plyr_[_pID].gen = 0; - plyr_[_pID].aff = 0; - } - - return (_earnings); - } - - /** - * @dev prepares compression data and fires event for buy or reload tx's - */ - function endTx(uint256 _pID, uint256 _team, uint256 _eth, uint256 _keys, F3Ddatasets.EventReturns memory _eventData_) - private - { - _eventData_.compressedData = _eventData_.compressedData + (block.timestamp * 1000000000000000000) + (_team * 100000000000000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID + (rID_ * 10000000000000000000000000000000000000000000000000000); - - emit F3Devents.onEndTx - ( - _eventData_.compressedData, - _eventData_.compressedIDs, - plyr_[_pID].name, - msg.sender, - _eth, - _keys, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount, - _eventData_.potAmount, - airDropPot_ - ); - } - //============================================================================== - // (~ _ _ _._|_ . - // _)(/_(_|_|| | | \/ . - //====================/========================================================= - /** upon contract deploy, it will be deactivated. this is a one time - * use function that will activate the contract. we do this so devs - * have time to set things up on the web end **/ - bool public activated_ = false; - - function activate() - public - onlyDevs - { - - // can only be ran once - require(activated_ == false, "fomo3d already activated"); - - // activate the contract - activated_ = true; - - otherF3D_ = msg.sender; - Divies = msg.sender; - Jekyll_Island_Inc = msg.sender; - - // lets start first round - rID_ = 1; - round_[1].strt = block.timestamp + rndExtra_ - rndGap_; - round_[1].end = block.timestamp + rndInit_ + rndExtra_; - } - - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractScenario007.sol b/framework/src/test/resources/soliditycode_0.7.6/contractScenario007.sol deleted file mode 100644 index a6fa095860f..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractScenario007.sol +++ /dev/null @@ -1,1432 +0,0 @@ - -/** - * @title ERC165 - * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md - */ -interface ERC165 { - - /** - * @notice Query if a contract implements an interface - * @param _interfaceId The interface identifier, as specified in ERC-165 - * @dev Interface identification is specified in ERC-165. This function - * uses less than 30,000 gas. - */ - function supportsInterface(bytes4 _interfaceId) external view returns (bool); - -} - -contract ERC721Basic is ERC165 { - - event Transfer( - address indexed _from, - address indexed _to, - uint256 indexed _tokenId - ); - event Approval( - address indexed _owner, - address indexed _approved, - uint256 indexed _tokenId - ); - event ApprovalForAll( - address indexed _owner, - address indexed _operator, - bool _approved - ); - - function balanceOf(address _owner) public view returns (uint256 _balance); - function ownerOf(uint256 _tokenId) public view returns (address _owner); - function exists(uint256 _tokenId) public view returns (bool _exists); - - function approve(address _to, uint256 _tokenId) public; - function getApproved(uint256 _tokenId) - public view returns (address _operator); - - function setApprovalForAll(address _operator, bool _approved) public; - function isApprovedForAll(address _owner, address _operator) - public view returns (bool); - - function transferFrom(address _from, address _to, uint256 _tokenId) public; - function safeTransferFrom(address _from, address _to, uint256 _tokenId) - public; - - function safeTransferFrom( - address _from, - address _to, - uint256 _tokenId, - bytes memory _data - ) - public; -} - - -/** - * @title SupportsInterfaceWithLookup - * @author Matt Condon (@shrugs) - * @dev Implements ERC165 using a lookup table. - */ -contract SupportsInterfaceWithLookup is ERC165 { - bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7; - /** - * 0x01ffc9a7 === - * bytes4(keccak256('supportsInterface(bytes4)')) - */ - - /** - * @dev a mapping of interface id to whether or not it's supported - */ - mapping(bytes4 => bool) internal supportedInterfaces; - - /** - * @dev A contract implementing SupportsInterfaceWithLookup - * implement ERC165 itself - */ - constructor() public { - _registerInterface(InterfaceId_ERC165); - } - - /** - * @dev implement supportsInterface(bytes4) using a lookup table - */ - function supportsInterface(bytes4 _interfaceId) external view returns (bool) { - return supportedInterfaces[_interfaceId]; - } - - /** - * @dev private method for registering an interface - */ - function _registerInterface(bytes4 _interfaceId) internal { - require(_interfaceId != 0xffffffff); - supportedInterfaces[_interfaceId] = true; - } -} - -contract Governable { - - event Pause(); - event Unpause(); - - address public governor; - bool public paused = false; - - constructor() public { - governor = msg.sender; - } - - function setGovernor(address _gov) public onlyGovernor { - governor = _gov; - } - - modifier onlyGovernor { - require(msg.sender == governor); - _; - } - - /** - * @dev Modifier to make a function callable only when the contract is not paused. - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev Modifier to make a function callable only when the contract is paused. - */ - modifier whenPaused() { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyGovernor whenNotPaused public { - paused = true; - emit Pause(); - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyGovernor whenPaused public { - paused = false; - emit Unpause(); - } - -} - -contract CardBase is Governable { - - struct Card { - uint16 proto; - uint16 purity; - } - - function getCard(uint id) public view returns (uint16 proto, uint16 purity) { - Card memory card = cards[id]; - return (card.proto, card.purity); - } - - function getShine(uint16 purity) public pure returns (uint8) { - return uint8(purity / 1000); - } - - Card[] public cards; - -} - -contract CardProto is CardBase { - - event NewProtoCard( - uint16 id, uint8 season, uint8 god, - Rarity rarity, uint8 mana, uint8 attack, - uint8 health, uint8 cardType, uint8 tribe, bool packable - ); - - struct Limit { - uint64 limit; - bool exists; - } - - // limits for mythic cards - mapping(uint16 => Limit) public limits; - - // can only set limits once - function setLimit(uint16 id, uint64 limit) public onlyGovernor { - Limit memory l = limits[id]; - require(!l.exists); - limits[id] = Limit({ - limit: limit, - exists: true - }); - } - - function getLimit(uint16 id) public view returns (uint64 limit, bool set) { - Limit memory l = limits[id]; - return (l.limit, l.exists); - } - - // could make these arrays to save gas - // not really necessary - will be update a very limited no of times - mapping(uint8 => bool) public seasonTradable; - mapping(uint8 => bool) public seasonTradabilityLocked; - uint8 public currentSeason; - - function makeTradable(uint8 season) public onlyGovernor { - seasonTradable[season] = true; - } - - function makeUntradable(uint8 season) public onlyGovernor { - require(!seasonTradabilityLocked[season]); - seasonTradable[season] = false; - } - - function makePermanantlyTradable(uint8 season) public onlyGovernor { - require(seasonTradable[season]); - seasonTradabilityLocked[season] = true; - } - - function isTradable(uint16 proto) public view returns (bool) { - return seasonTradable[protos[proto].season]; - } - - function nextSeason() public onlyGovernor { - //Seasons shouldn't go to 0 if there is more than the uint8 should hold, the governor should know this ¯\_(ツ)_/¯ -M - require(currentSeason <= 255); - - currentSeason++; - mythic.length = 0; - legendary.length = 0; - epic.length = 0; - rare.length = 0; - common.length = 0; - } - - enum Rarity { - Common, - Rare, - Epic, - Legendary, - Mythic - } - - uint8 constant SPELL = 1; - uint8 constant MINION = 2; - uint8 constant WEAPON = 3; - uint8 constant HERO = 4; - - struct ProtoCard { - bool exists; - uint8 god; - uint8 season; - uint8 cardType; - Rarity rarity; - uint8 mana; - uint8 attack; - uint8 health; - uint8 tribe; - } - - // there is a particular design decision driving this: - // need to be able to iterate over mythics only for card generation - // don't store 5 different arrays: have to use 2 ids - // better to bear this cost (2 bytes per proto card) - // rather than 1 byte per instance - - uint16 public protoCount; - - mapping(uint16 => ProtoCard) protos; - - uint16[] public mythic; - uint16[] public legendary; - uint16[] public epic; - uint16[] public rare; - uint16[] public common; - - function addProtos( - uint16[] memory externalIDs, uint8[] memory gods, Rarity[] memory rarities, uint8[] memory manas, uint8[] memory attacks, - uint8[] memory healths, uint8[] memory cardTypes, uint8[] memory tribes, bool[] memory packable - ) public onlyGovernor returns(uint16) { - - for (uint i = 0; i < externalIDs.length; i++) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: gods[i], - season: currentSeason, - cardType: cardTypes[i], - rarity: rarities[i], - mana: manas[i], - attack: attacks[i], - health: healths[i], - tribe: tribes[i] - }); - - _addProto(externalIDs[i], card, packable[i]); - } - - } - - function addProto( - uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 cardType, uint8 tribe, bool packable - ) public onlyGovernor returns(uint16) { - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: cardType, - rarity: rarity, - mana: mana, - attack: attack, - health: health, - tribe: tribe - }); - - _addProto(externalID, card, packable); - } - - function addWeapon( - uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 durability, bool packable - ) public onlyGovernor returns(uint16) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: WEAPON, - rarity: rarity, - mana: mana, - attack: attack, - health: durability, - tribe: 0 - }); - - _addProto(externalID, card, packable); - } - - function addSpell(uint16 externalID, uint8 god, Rarity rarity, uint8 mana, bool packable) public onlyGovernor returns(uint16) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: SPELL, - rarity: rarity, - mana: mana, - attack: 0, - health: 0, - tribe: 0 - }); - - _addProto(externalID, card, packable); - } - - function addMinion( - uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 tribe, bool packable - ) public onlyGovernor returns(uint16) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: MINION, - rarity: rarity, - mana: mana, - attack: attack, - health: health, - tribe: tribe - }); - - _addProto(externalID, card, packable); - } - - function _addProto(uint16 externalID, ProtoCard memory card, bool packable) internal { - - require(!protos[externalID].exists); - - card.exists = true; - - protos[externalID] = card; - - protoCount++; - - emit NewProtoCard( - externalID, currentSeason, card.god, - card.rarity, card.mana, card.attack, - card.health, card.cardType, card.tribe, packable - ); - - if (packable) { - Rarity rarity = card.rarity; - if (rarity == Rarity.Common) { - common.push(externalID); - } else if (rarity == Rarity.Rare) { - rare.push(externalID); - } else if (rarity == Rarity.Epic) { - epic.push(externalID); - } else if (rarity == Rarity.Legendary) { - legendary.push(externalID); - } else if (rarity == Rarity.Mythic) { - mythic.push(externalID); - } else { - require(false); - } - } - } - - function getProto(uint16 id) public view returns( - bool exists, uint8 god, uint8 season, uint8 cardType, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 tribe - ) { - ProtoCard memory proto = protos[id]; - return ( - proto.exists, - proto.god, - proto.season, - proto.cardType, - proto.rarity, - proto.mana, - proto.attack, - proto.health, - proto.tribe - ); - } - - function getRandomCard(Rarity rarity, uint16 random) public view returns (uint16) { - // modulo bias is fine - creates rarity tiers etc - // will obviously revert is there are no cards of that type: this is expected - should never happen - if (rarity == Rarity.Common) { - return common[random % common.length]; - } else if (rarity == Rarity.Rare) { - return rare[random % rare.length]; - } else if (rarity == Rarity.Epic) { - return epic[random % epic.length]; - } else if (rarity == Rarity.Legendary) { - return legendary[random % legendary.length]; - } else if (rarity == Rarity.Mythic) { - // make sure a mythic is available - uint16 id; - uint64 limit; - bool set; - for (uint i = 0; i < mythic.length; i++) { - id = mythic[(random + i) % mythic.length]; - (limit, set) = getLimit(id); - if (set && limit > 0){ - return id; - } - } - // if not, they get a legendary :( - return legendary[random % legendary.length]; - } - require(false); - return 0; - } - - // can never adjust tradable cards - // each season gets a 'balancing beta' - // totally immutable: season, rarity - function replaceProto( - uint16 index, uint8 god, uint8 cardType, uint8 mana, uint8 attack, uint8 health, uint8 tribe - ) public onlyGovernor { - ProtoCard memory pc = protos[index]; - require(!seasonTradable[pc.season]); - protos[index] = ProtoCard({ - exists: true, - god: god, - season: pc.season, - cardType: cardType, - rarity: pc.rarity, - mana: mana, - attack: attack, - health: health, - tribe: tribe - }); - } - -} - -contract ERC721Receiver { - /** - * @dev Magic value to be returned upon successful reception of an NFT - * Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`, - * which can be also obtained as `ERC721Receiver(0).onERC721Received.selector` - */ - bytes4 internal constant ERC721_RECEIVED = 0x150b7a02; - - /** - * @notice Handle the receipt of an NFT - * @dev The ERC721 smart contract calls this function on the recipient - * after a `safetransfer`. This function MAY throw to revert and reject the - * transfer. Return of other than the magic value MUST result in the - * transaction being reverted. - * Note: the contract address is always the message sender. - * @param _operator The address which called `safeTransferFrom` function - * @param _from The address which previously owned the token - * @param _tokenId The NFT identifier which is being transfered - * @param _data Additional data with no specified format - * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` - */ - function onERC721Received( - address _operator, - address _from, - uint256 _tokenId, - bytes memory _data - ) - public - returns(bytes4); -} - -library AddressUtils { - - /** - * Returns whether the target address is a contract - * @dev This function will return false if invoked during the constructor of a contract, - * as the code is not actually created until after the constructor finishes. - * @param addr address to check - * @return whether the target address is a contract - */ - function isContract1(address addr) internal view returns (bool) { - uint256 size; - // XXX Currently there is no better way to check if there is a contract in an address - // than to check the size of the code at that address. - // See https://ethereum.stackexchange.com/a/14016/36603 - // for more details about how this works. - // TODO Check this again before the Serenity release, because all addresses will be - // contracts then. - // solium-disable-next-line security/no-inline-assembly - assembly { size := extcodesize(addr) } - return size > 0; - } - -} - -library SafeMath { - - /** - * @dev Multiplies two numbers, throws on overflow. - */ - function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { - // Gas optimization: this is cheaper than asserting 'a' not being zero, but the - // benefit is lost if 'b' is also tested. - // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 - if (a == 0) { - return 0; - } - - c = a * b; - assert(c / a == b); - return c; - } - - /** - * @dev Integer division of two numbers, truncating the quotient. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - // assert(b > 0); // Solidity automatically throws when dividing by 0 - // uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - return a / b; - } - - /** - * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). - */ - function sub(uint256 a, uint256 b) internal pure returns (uint256) { - assert(b <= a); - return a - b; - } - - /** - * @dev Adds two numbers, throws on overflow. - */ - function add(uint256 a, uint256 b) internal pure returns (uint256 c) { - c = a + b; - assert(c >= a); - return c; - } -} - -contract ERC721BasicToken is CardProto, SupportsInterfaceWithLookup, ERC721Basic { - - bytes4 private constant InterfaceId_ERC721 = 0x80ac58cd; - /* - * 0x80ac58cd === - * bytes4(keccak256('balanceOf(address)')) ^ - * bytes4(keccak256('ownerOf(uint256)')) ^ - * bytes4(keccak256('approve(address,uint256)')) ^ - * bytes4(keccak256('getApproved(uint256)')) ^ - * bytes4(keccak256('setApprovalForAll(address,bool)')) ^ - * bytes4(keccak256('isApprovedForAll(address,address)')) ^ - * bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^ - * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) - */ - - bytes4 private constant InterfaceId_ERC721Exists = 0x4f558e79; - /* - * 0x4f558e79 === - * bytes4(keccak256('exists(uint256)')) - */ - - using SafeMath for uint256; - using AddressUtils for address; - - // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` - // which can be also obtained as `ERC721Receiver(0).onERC721Received.selector` - bytes4 private constant ERC721_RECEIVED = 0x150b7a02; - - // Mapping from token ID to owner - mapping (uint256 => address) internal tokenOwner; - - // Mapping from token ID to approved address - mapping (uint256 => address) internal tokenApprovals; - - // Mapping from owner to number of owned token - // mapping (address => uint256) internal ownedTokensCount; - - // Mapping from owner to operator approvals - mapping (address => mapping (address => bool)) internal operatorApprovals; - - /** - * @dev Guarantees msg.sender is owner of the given token - * @param _tokenId uint256 ID of the token to validate its ownership belongs to msg.sender - */ - modifier onlyOwnerOf(uint256 _tokenId) { - require(ownerOf(_tokenId) == msg.sender); - _; - } - - /** - * @dev Checks msg.sender can transfer a token, by being owner, approved, or operator - * @param _tokenId uint256 ID of the token to validate - */ - modifier canTransfer(uint256 _tokenId) { - require(isApprovedOrOwner(msg.sender, _tokenId)); - _; - } - - constructor() - public - { - // register the supported interfaces to conform to ERC721 via ERC165 - _registerInterface(InterfaceId_ERC721); - _registerInterface(InterfaceId_ERC721Exists); - } - - /** - * @dev Gets the balance of the specified address - * @param _owner address to query the balance of - * @return uint256 representing the amount owned by the passed address - */ - function balanceOf(address _owner) public view returns (uint256); - - /** - * @dev Gets the owner of the specified token ID - * @param _tokenId uint256 ID of the token to query the owner of - * @return owner address currently marked as the owner of the given token ID - */ - function ownerOf(uint256 _tokenId) public view returns (address) { - address owner = tokenOwner[_tokenId]; - require(owner != address(0)); - return owner; - } - - /** - * @dev Returns whether the specified token exists - * @param _tokenId uint256 ID of the token to query the existence of - * @return whether the token exists - */ - function exists(uint256 _tokenId) public view returns (bool) { - address owner = tokenOwner[_tokenId]; - return owner != address(0); - } - - /** - * @dev Approves another address to transfer the given token ID - * The zero address indicates there is no approved address. - * There can only be one approved address per token at a given time. - * Can only be called by the token owner or an approved operator. - * @param _to address to be approved for the given token ID - * @param _tokenId uint256 ID of the token to be approved - */ - function approve(address _to, uint256 _tokenId) public { - address owner = ownerOf(_tokenId); - require(_to != owner); - require(msg.sender == owner || isApprovedForAll(owner, msg.sender)); - - tokenApprovals[_tokenId] = _to; - emit Approval(owner, _to, _tokenId); - } - - /** - * @dev Gets the approved address for a token ID, or zero if no address set - * @param _tokenId uint256 ID of the token to query the approval of - * @return address currently approved for the given token ID - */ - function getApproved(uint256 _tokenId) public view returns (address) { - return tokenApprovals[_tokenId]; - } - - /** - * @dev Sets or unsets the approval of a given operator - * An operator is allowed to transfer all tokens of the sender on their behalf - * @param _to operator address to set the approval - * @param _approved representing the status of the approval to be set - */ - function setApprovalForAll(address _to, bool _approved) public { - require(_to != msg.sender); - operatorApprovals[msg.sender][_to] = _approved; - emit ApprovalForAll(msg.sender, _to, _approved); - } - - /** - * @dev Tells whether an operator is approved by a given owner - * @param _owner owner address which you want to query the approval of - * @param _operator operator address which you want to query the approval of - * @return bool whether the given operator is approved by the given owner - */ - function isApprovedForAll( - address _owner, - address _operator - ) - public - view - returns (bool) - { - return operatorApprovals[_owner][_operator]; - } - - /** - * @dev Transfers the ownership of a given token ID to another address - * Usage of this method is discouraged, use `safeTransferFrom` whenever possible - * Requires the msg sender to be the owner, approved, or operator - * @param _from current owner of the token - * @param _to address to receive the ownership of the given token ID - * @param _tokenId uint256 ID of the token to be transferred - */ - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - public - canTransfer(_tokenId) - { - require(_from != address(0)); - require(_to != address(0)); - - clearApproval(_from, _tokenId); - removeTokenFrom(_from, _tokenId); - addTokenTo(_to, _tokenId); - - emit Transfer(_from, _to, _tokenId); - } - - /** - * @dev Safely transfers the ownership of a given token ID to another address - * If the target address is a contract, it must implement `onERC721Received`, - * which is called upon a safe transfer, and return the magic value - * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, - * the transfer is reverted. - * - * Requires the msg sender to be the owner, approved, or operator - * @param _from current owner of the token - * @param _to address to receive the ownership of the given token ID - * @param _tokenId uint256 ID of the token to be transferred - */ - function safeTransferFrom( - address _from, - address _to, - uint256 _tokenId - ) - public - canTransfer(_tokenId) - { - // solium-disable-next-line arg-overflow - safeTransferFrom(_from, _to, _tokenId, ""); - } - - /** - * @dev Safely transfers the ownership of a given token ID to another address - * If the target address is a contract, it must implement `onERC721Received`, - * which is called upon a safe transfer, and return the magic value - * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, - * the transfer is reverted. - * Requires the msg sender to be the owner, approved, or operator - * @param _from current owner of the token - * @param _to address to receive the ownership of the given token ID - * @param _tokenId uint256 ID of the token to be transferred - * @param _data bytes data to send along with a safe transfer check - */ - function safeTransferFrom( - address _from, - address _to, - uint256 _tokenId, - bytes memory _data - ) - public - canTransfer(_tokenId) - { - transferFrom(_from, _to, _tokenId); - // solium-disable-next-line arg-overflow - require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data)); - } - - /** - * @dev Returns whether the given spender can transfer a given token ID - * @param _spender address of the spender to query - * @param _tokenId uint256 ID of the token to be transferred - * @return bool whether the msg.sender is approved for the given token ID, - * is an operator of the owner, or is the owner of the token - */ - function isApprovedOrOwner( - address _spender, - uint256 _tokenId - ) - internal - view - returns (bool) - { - address owner = ownerOf(_tokenId); - // Disable solium check because of - // https://github.com/duaraghav8/Solium/issues/175 - // solium-disable-next-line operator-whitespace - return ( - _spender == owner || - getApproved(_tokenId) == _spender || - isApprovedForAll(owner, _spender) - ); - } - - /** - * @dev Internal function to clear current approval of a given token ID - * Reverts if the given address is not indeed the owner of the token - * @param _owner owner of the token - * @param _tokenId uint256 ID of the token to be transferred - */ - function clearApproval(address _owner, uint256 _tokenId) internal { - require(ownerOf(_tokenId) == _owner); - if (tokenApprovals[_tokenId] != address(0)) { - tokenApprovals[_tokenId] = address(0); - } - } - - /** - * @dev Internal function to mint a new token - * Reverts if the given token ID already exists - * @param _to The address that will own the minted token - * @param _tokenId uint256 ID of the token to be minted by the msg.sender - */ - function _mint(address _to, uint256 _tokenId) internal { - require(_to != address(0)); - addNewTokenTo(_to, _tokenId); - emit Transfer(address(0), _to, _tokenId); - } - - - /** - * @dev Internal function to burn a specific token - * Reverts if the token does not exist - * @param _tokenId uint256 ID of the token being burned by the msg.sender - */ - function _burn(address _owner, uint256 _tokenId) internal { - clearApproval(_owner, _tokenId); - removeTokenFrom(_owner, _tokenId); - emit Transfer(_owner, address(0), _tokenId); - } - - function addNewTokenTo(address _to, uint256 _tokenId) internal { - require(tokenOwner[_tokenId] == address(0)); - tokenOwner[_tokenId] = _to; - } - - /** - * @dev Internal function to add a token ID to the list of a given address - * @param _to address representing the new owner of the given token ID - * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address - */ - function addTokenTo(address _to, uint256 _tokenId) internal { - require(tokenOwner[_tokenId] == address(0)); - tokenOwner[_tokenId] = _to; - // ownedTokensCount[_to] = ownedTokensCount[_to].add(1); - } - - /** - * @dev Internal function to remove a token ID from the list of a given address - * @param _from address representing the previous owner of the given token ID - * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address - */ - function removeTokenFrom(address _from, uint256 _tokenId) internal { - require(ownerOf(_tokenId) == _from); - // ownedTokensCount[_from] = ownedTokensCount[_from].sub(1); - tokenOwner[_tokenId] = address(0); - } - - /** - * @dev Internal function to invoke `onERC721Received` on a target address - * The call is not executed if the target address is not a contract - * @param _from address representing the previous owner of the given token ID - * @param _to target address that will receive the tokens - * @param _tokenId uint256 ID of the token to be transferred - * @param _data bytes optional data to send along with the call - * @return whether the call correctly returned the expected magic value - */ - function checkAndCallSafeTransfer( - address _from, - address _to, - uint256 _tokenId, - bytes memory _data - ) - internal - returns (bool) - { - if (!_to.isContract1()) { - return true; - } - bytes4 retval = ERC721Receiver(_to).onERC721Received( - msg.sender, _from, _tokenId, _data); - return (retval == ERC721_RECEIVED); - } - -} - - - -contract ERC721Enumerable is ERC721Basic { - function totalSupply() public view returns (uint256); - function tokenOfOwnerByIndex( - address _owner, - uint256 _index - ) - public - view - returns (uint256 _tokenId); - - function tokenByIndex(uint256 _index) public view returns (uint256); -} - -contract ERC721Metadata is ERC721Basic { - function name() external view returns (string memory _name); - function symbol() external view returns (string memory _symbol); - function tokenURI(uint256 _tokenId) public view returns (string memory); -} - -contract ERC721 is ERC721Basic, ERC721Enumerable, ERC721Metadata { - -} - - - - -library Strings { - - // via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol - function strConcat(string memory _a, string memory _b, string memory _c, string memory _d, string memory _e) internal pure returns (string memory ) { - bytes memory _ba = bytes(_a); - bytes memory _bb = bytes(_b); - bytes memory _bc = bytes(_c); - bytes memory _bd = bytes(_d); - bytes memory _be = bytes(_e); - string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length); - bytes memory babcde = bytes(abcde); - uint k = 0; - for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i]; - for (uint i = 0; i < _bb.length; i++) babcde[k++] = _bb[i]; - for (uint i = 0; i < _bc.length; i++) babcde[k++] = _bc[i]; - for (uint i = 0; i < _bd.length; i++) babcde[k++] = _bd[i]; - for (uint i = 0; i < _be.length; i++) babcde[k++] = _be[i]; - return string(babcde); - } - - function strConcat(string memory _a, string memory _b, string memory _c, string memory _d) internal pure returns (string memory ) { - return strConcat(_a, _b, _c, _d, ""); - } - - function strConcat(string memory _a, string memory _b, string memory _c) internal pure returns (string memory ) { - return strConcat(_a, _b, _c, "", ""); - } - - function strConcat(string memory _a, string memory _b) internal pure returns (string memory ) { - return strConcat(_a, _b, "", "", ""); - } - - function uint2str(uint i) internal pure returns (string memory ) { - if (i == 0) return "0"; - uint j = i; - uint len; - while (j != 0){ - len++; - j /= 10; - } - bytes memory bstr = new bytes(len); - uint k = len - 1; - while (i != 0){ - bstr[k--] = byte(uint8(48 + i % 10)); - i /= 10; - } - return string(bstr); - } -} - -contract ERC721Token is SupportsInterfaceWithLookup, ERC721BasicToken, ERC721 { - - using Strings for string; - - bytes4 private constant InterfaceId_ERC721Enumerable = 0x780e9d63; - /** - * 0x780e9d63 === - * bytes4(keccak256('totalSupply()')) ^ - * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^ - * bytes4(keccak256('tokenByIndex(uint256)')) - */ - - bytes4 private constant InterfaceId_ERC721Metadata = 0x5b5e139f; - /** - * 0x5b5e139f === - * bytes4(keccak256('name()')) ^ - * bytes4(keccak256('symbol()')) ^ - * bytes4(keccak256('tokenURI(uint256)')) - */ - - /*** Constants ***/ - // Configure these for your own deployment - string public constant NAME = "Gods Unchained"; - string public constant SYMBOL = "GODS"; - string public tokenMetadataBaseURI = "https://api.godsunchained.com/card/"; - - // Mapping from owner to list of owned token IDs - // EDITED: limit to 2^40 (around 1T) - mapping(address => uint40[]) internal ownedTokens; - - uint32[] ownedTokensIndex; - - /** - * @dev Constructor function - */ - constructor() public { - - // register the supported interfaces to conform to ERC721 via ERC165 - _registerInterface(InterfaceId_ERC721Enumerable); - _registerInterface(InterfaceId_ERC721Metadata); - } - - /** - * @dev Gets the token name - * @return string representing the token name - */ - function name() external view returns (string memory) { - return NAME; - } - - /** - * @dev Gets the token symbol - * @return string representing the token symbol - */ - function symbol() external view returns (string memory) { - return SYMBOL; - } - - /** - * @dev Returns an URI for a given token ID - * Throws if the token ID does not exist. May return an empty string. - * @param _tokenId uint256 ID of the token to query - */ - function tokenURI(uint256 _tokenId) public view returns (string memory) { - return Strings.strConcat( - tokenMetadataBaseURI, - Strings.uint2str(_tokenId) - ); - } - - /** - * @dev Gets the token ID at a given index of the tokens list of the requested owner - * @param _owner address owning the tokens list to be accessed - * @param _index uint256 representing the index to be accessed of the requested tokens list - * @return uint256 token ID at the given index of the tokens list owned by the requested address - */ - function tokenOfOwnerByIndex( - address _owner, - uint256 _index - ) - public - view - returns (uint256) - { - require(_index < balanceOf(_owner)); - return ownedTokens[_owner][_index]; - } - - /** - * @dev Gets the total amount of tokens stored by the contract - * @return uint256 representing the total amount of tokens - */ - function totalSupply() public view returns (uint256) { - return cards.length; - } - - /** - * @dev Gets the token ID at a given index of all the tokens in this contract - * Reverts if the index is greater or equal to the total number of tokens - * @param _index uint256 representing the index to be accessed of the tokens list - * @return uint256 token ID at the given index of the tokens list - */ - function tokenByIndex(uint256 _index) public view returns (uint256) { - require(_index < totalSupply()); - return _index; - } - - /** - * @dev Internal function to add a token ID to the list of a given address - * @param _to address representing the new owner of the given token ID - * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address - */ - function addTokenTo(address _to, uint256 _tokenId) internal { - super.addTokenTo(_to, _tokenId); - uint256 length = ownedTokens[_to].length; - // EDITED: prevent overflow - require(length == uint32(length)); - ownedTokens[_to].push(uint40(_tokenId)); - - ownedTokensIndex[_tokenId] = uint32(length); - } - - // EDITED - // have to have in order to use array rather than mapping - function addNewTokenTo(address _to, uint256 _tokenId) internal { - super.addNewTokenTo(_to, _tokenId); - uint256 length = ownedTokens[_to].length; - // EDITED: prevent overflow - require(length == uint32(length)); - ownedTokens[_to].push(uint40(_tokenId)); - ownedTokensIndex.push(uint32(length)); - } - - /** - * @dev Internal function to remove a token ID from the list of a given address - * @param _from address representing the previous owner of the given token ID - * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address - */ - function removeTokenFrom(address _from, uint256 _tokenId) internal { - super.removeTokenFrom(_from, _tokenId); - - uint32 tokenIndex = ownedTokensIndex[_tokenId]; - uint256 lastTokenIndex = ownedTokens[_from].length.sub(1); - uint40 lastToken = ownedTokens[_from][lastTokenIndex]; - - ownedTokens[_from][tokenIndex] = lastToken; - ownedTokens[_from][lastTokenIndex] = 0; - // Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to - // be zero. Then we can make sure that we will remove _tokenId from the ownedTokens list since we are first swapping - // the lastToken to the first position, and then dropping the element placed in the last position of the list - - ownedTokens[_from].length--; - ownedTokensIndex[_tokenId] = 0; - ownedTokensIndex[lastToken] = tokenIndex; - } - - /** - * @dev Gets the balance of the specified address - overrriden from previous to save gas - * @param _owner address to query the balance of - * @return uint256 representing the amount owned by the passed address - */ - function balanceOf(address _owner) public view returns (uint256) { - return ownedTokens[_owner].length; - } - -} - -contract CardOwnershipTwo is ERC721Token { - - uint public burnCount; - - function getActiveCards() public view returns (uint) { - return totalSupply() - burnCount; - } - - /** - * @param to : the address to which the card will be transferred - * @param id : the id of the card to be transferred - */ - function transfer(address to, uint id) public payable onlyOwnerOf(id) { - require(isTradable(cards[id].proto)); - require(to != address(0)); - - _transfer(msg.sender, to, id); - } - - function _transfer(address from, address to, uint id) internal { - - clearApproval(from, id); - - removeTokenFrom(from, id); - - addTokenTo(to, id); - - emit Transfer(from, to, id); - } - - /** - * @param to : the address to which the cards will be transferred - * @param ids : the ids of the cards to be transferred - */ - function transferAll(address to, uint[] memory ids) public payable { - for (uint i = 0; i < ids.length; i++) { - transfer(to, ids[i]); - } - } - - /** - * @param proposed : the claimed owner of the cards - * @param ids : the ids of the cards to check - * @return whether proposed owns all of the cards - */ - function ownsAll(address proposed, uint[] memory ids) public view returns (bool) { - require(ids.length > 0); - for (uint i = 0; i < ids.length; i++) { - if (!owns(proposed, ids[i])) { - return false; - } - } - return true; - } - - /** - * @param proposed : the claimed owner of the card - * @param id : the id of the card to check - * @return whether proposed owns the card - */ - function owns(address proposed, uint id) public view returns (bool) { - return ownerOf(id) == proposed; - } - - function burn(uint id) public onlyOwnerOf(id) { - burnCount++; - _burn(msg.sender, id); - } - - /** - * @param ids : the indices of the tokens to burn - */ - function burnAll(uint[] memory ids) public { - for (uint i = 0; i < ids.length; i++){ - burn(ids[i]); - } - } - - /** - * @param to : the address to approve for transfer - * @param id : the index of the card to be approved - */ - function approve(address to, uint id) public { - require(isTradable(cards[id].proto)); - super.approve(to, id); - } - - /** - * @param to : the address to approve for transfer - * @param ids : the indices of the cards to be approved - */ - function approveAll(address to, uint[] memory ids) public { - for (uint i = 0; i < ids.length; i++) { - approve(to, ids[i]); - } - } - - /** - * @param to : the address to which the token should be transferred - * @param id : the index of the token to transfer - */ - function transferFrom(address from, address to, uint id) public { - require(isTradable(cards[id].proto)); - super.transferFrom(from, to, id); - } - - /** - * @param to : the address to which the tokens should be transferred - * @param ids : the indices of the tokens to transfer - */ - function transferAllFrom(address from, address to, uint[] memory ids) public { - for (uint i = 0; i < ids.length; i++) { - transferFrom(from, to, ids[i]); - } - } - - /** - * @return the number of cards which have been burned - */ - function getBurnCount() public view returns (uint) { - return burnCount; - } - -} - -contract CardIntegrationTwo is CardOwnershipTwo { - - address[] public packs; - - event CardCreated(uint indexed id, uint16 proto, uint16 purity, address owner); - - function addPack(address approved) public onlyGovernor { - packs.push(approved); - } - - modifier onlyApprovedPacks { - require(_isApprovedPack()); - _; - } - - function _isApprovedPack() private view returns (bool) { - for (uint i = 0; i < packs.length; i++) { - if (msg.sender == address(packs[i])) { - return true; - } - } - return false; - } - - function createCard(address owner, uint16 proto, uint16 purity) public whenNotPaused onlyApprovedPacks returns (uint) { - ProtoCard memory card = protos[proto]; - require(card.season == currentSeason); - if (card.rarity == Rarity.Mythic) { - uint64 limit; - bool exists; - (limit, exists) = getLimit(proto); - require(!exists || limit > 0); - limits[proto].limit--; - } - return _createCard(owner, proto, purity); - } - - function _createCard(address owner, uint16 proto, uint16 purity) internal returns (uint) { - Card memory card = Card({ - proto: proto, - purity: purity - }); - - uint id = cards.push(card) - 1; - - _mint(owner, id); - - emit CardCreated(id, proto, purity, owner); - - return id; - } - - /*function combineCards(uint[] ids) public whenNotPaused { - require(ids.length == 5); - require(ownsAll(msg.sender, ids)); - Card memory first = cards[ids[0]]; - uint16 proto = first.proto; - uint8 shine = _getShine(first.purity); - require(shine < shineLimit); - uint16 puritySum = first.purity - (shine * 1000); - burn(ids[0]); - for (uint i = 1; i < ids.length; i++) { - Card memory next = cards[ids[i]]; - require(next.proto == proto); - require(_getShine(next.purity) == shine); - puritySum += (next.purity - (shine * 1000)); - burn(ids[i]); - } - uint16 newPurity = uint16(((shine + 1) * 1000) + (puritySum / ids.length)); - _createCard(msg.sender, proto, newPurity); - }*/ - - - // PURITY NOTES - // currently, we only - // however, to protect rarity, you'll never be abl - // this is enforced by the restriction in the create-card function - // no cards above this point can be found in packs - - - -} - -contract PreviousInterface { - - function ownerOf(uint id) public view returns (address); - - function getCard(uint id) public view returns (uint16, uint16); - - function totalSupply() public view returns (uint); - - function burnCount() public view returns (uint); - -} - -contract CardMigration is CardIntegrationTwo { - - constructor(PreviousInterface previous) public { - old = previous; - } - - // use interface to lower deployment cost - PreviousInterface old; - - mapping(uint => bool) public migrated; - - function migrate(uint id) public { - - require(!migrated[id]); - - migrated[id] = true; - - address owner = old.ownerOf(id); - - uint16 proto; - uint16 purity; - - (proto, purity) = old.getCard(id); - - _createCard(owner, proto, purity); - } - - function migrateAll(uint[] memory ids) public { - - for (uint i = 0; i < ids.length; i++){ - migrate(ids[i]); - } - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractScenario008.sol b/framework/src/test/resources/soliditycode_0.7.6/contractScenario008.sol deleted file mode 100644 index 9881507fab7..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractScenario008.sol +++ /dev/null @@ -1,2061 +0,0 @@ - - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) public onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address payable public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address payable _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() virtual public onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer1(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - emit Transfer1(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(block.timestamp), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - kitties.push(_kitty); - uint256 newKittenId = kitties.length - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - emit Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(address(0), _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -abstract contract ERC721 { - // Required methods - function totalSupply() virtual public view returns (uint256 total); - function balanceOf(address _owner) virtual public view returns (uint256 balance); - function ownerOf(uint256 _tokenId) virtual external view returns (address owner); - function approve(address _to, uint256 _tokenId) virtual external; - function transfer(address _to, uint256 _tokenId) virtual external; - function transferFrom(address _from, address _to, uint256 _tokenId) virtual external; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) virtual external view returns (bool); -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is ERC721, KittyBase { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external override view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public override view returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - override - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - override - external - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - emit Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - override - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() override public view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - override - external - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] memory _rawBytes, uint256 _stringLength) private view returns (string memory) { - string memory outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string calldata _preferredTransport) external view returns (string memory infoUrl) { - require( address(erc721Metadata) != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty memory _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty memory _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - emit Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.transfer(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, address(saleAuction)); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, address(siringAuction)); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid{value:(msg.value - autoBirthFee)}(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, address(saleAuction)); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(uint160(address(this))) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - constructor() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - emit ContractUpgrade(_v2Address); - } - -/// @notice No tipping! -/// @dev Reject all Ether from being sent here, unless it's from one of the -/// two auction contracts. (Hopefully, we can prevent user accidents.) -fallback() external payable { -require( -msg.sender == address(saleAuction) || -msg.sender == address(siringAuction) -); -} - -/// @notice Returns all the relevant information about a specific kitty. -/// @param _id The ID of the kitty of interest. -function getKitty(uint256 _id) -external -view -returns ( -bool isGestating, -bool isReady, -uint256 cooldownIndex, -uint256 nextActionAt, -uint256 siringWithId, -uint256 birthTime, -uint256 matronId, -uint256 sireId, -uint256 generation, -uint256 genes -) { -Kitty storage kit = kitties[_id]; - -// if this variable is 0 then it's not gestating -isGestating = (kit.siringWithId != 0); -isReady = (kit.cooldownEndBlock <= block.number); -cooldownIndex = uint256(kit.cooldownIndex); -nextActionAt = uint256(kit.cooldownEndBlock); -siringWithId = uint256(kit.siringWithId); -birthTime = uint256(kit.birthTime); -matronId = uint256(kit.matronId); -sireId = uint256(kit.sireId); -generation = uint256(kit.generation); -genes = kit.genes; -} - -/// @dev Override unpause so it requires all external contract addresses -/// to be set before contract can be unpaused. Also, we can't have -/// newContractAddress set either, because then the contract was upgraded. -/// @notice This is public rather than external so we can call super.unpause -/// without using an expensive CALL. - -function unpause() override public onlyCEO whenPaused { -require(address(saleAuction) != address(0)); -require(address(siringAuction) != address(0)); -require(address(geneScience) != address(0)); -require(newContractAddress == address(0)); - -// Actually unpause the contract. -super.unpause(); -} - -// @dev Allows the CFO to capture the balance available to the contract. -function withdrawBalance() external onlyCFO { -uint256 balance = address(this).balance; -// Subtract all the currently pregnant kittens we have, plus 1 of margin. -uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - -if (balance > subtractFees) { -cfoAddress.transfer(balance - subtractFees); -} -} -} - - - - - - - - - - - - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - -function isGeneScience() public pure returns (bool){ -return true; -} - -/// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor -/// @param genes1 genes of mom -/// @param genes2 genes of sire -/// @return the genes that are supposed to be passed down the child -function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - -return (genes1+genes2+targetBlock)/2; - - -} -} - - - - - - - - - - - - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { -/// @dev Given a token Id, returns a byte array that is supposed to be converted into string. -function getMetadata(uint256 _tokenId, string memory) public view returns (bytes32[4] memory buffer, uint256 count) { -if (_tokenId == 1) { -buffer[0] = "Hello World! :D"; -count = 15; -} else if (_tokenId == 2) { -buffer[0] = "I would definitely choose a medi"; -buffer[1] = "um length string."; -count = 49; -} else if (_tokenId == 3) { -buffer[0] = "Lorem ipsum dolor sit amet, mi e"; -buffer[1] = "st accumsan dapibus augue lorem,"; -buffer[2] = " tristique vestibulum id, libero"; -buffer[3] = " suscipit varius sapien aliquam."; -count = 128; -} -} -} - - - - - - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - -// Represents an auction on an NFT -struct Auction { -// Current owner of NFT -address payable seller; -// Price (in wei) at beginning of auction -uint128 startingPrice; -// Price (in wei) at end of auction -uint128 endingPrice; -// Duration (in seconds) of auction -uint64 duration; -// Time when auction started -// NOTE: 0 if this auction has been concluded -uint64 startedAt; -} - -// Reference to contract tracking NFT ownership -ERC721 public nonFungibleContract; - -// Cut owner takes on each auction, measured in basis points (1/100 of a percent). -// Values 0-10,000 map to 0%-100% -uint256 public ownerCut; - -// Map from token ID to their corresponding auction. -mapping (uint256 => Auction) tokenIdToAuction; - -event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); -event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); -event AuctionCancelled(uint256 tokenId); - -/// @dev Returns true if the claimant owns the token. -/// @param _claimant - Address claiming to own the token. -/// @param _tokenId - ID of token whose ownership to verify. -function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { -return (nonFungibleContract.ownerOf(_tokenId) == _claimant); -} - -/// @dev Escrows the NFT, assigning ownership to this contract. -/// Throws if the escrow fails. -/// @param _owner - Current owner address of token to escrow. -/// @param _tokenId - ID of token whose approval to verify. -function _escrow(address _owner, uint256 _tokenId) internal { -// it will throw if transfer fails -nonFungibleContract.transferFrom(_owner, address(this), _tokenId); -} - -/// @dev Transfers an NFT owned by this contract to another address. -/// Returns true if the transfer succeeds. -/// @param _receiver - Address to transfer NFT to. -/// @param _tokenId - ID of token to transfer. -function _transfer(address _receiver, uint256 _tokenId) internal { -// it will throw if transfer fails -nonFungibleContract.transfer(_receiver, _tokenId); -} - -/// @dev Adds an auction to the list of open auctions. Also fires the -/// AuctionCreated event. -/// @param _tokenId The ID of the token to be put on auction. -/// @param _auction Auction to add. -function _addAuction(uint256 _tokenId, Auction memory _auction) internal { -// Require that all auctions have a duration of -// at least one minute. (Keeps our math from getting hairy!) -require(_auction.duration >= 1 minutes); - -tokenIdToAuction[_tokenId] = _auction; - -emit AuctionCreated( -uint256(_tokenId), -uint256(_auction.startingPrice), -uint256(_auction.endingPrice), -uint256(_auction.duration) -); -} - -/// @dev Cancels an auction unconditionally. -function _cancelAuction(uint256 _tokenId, address _seller) internal { -_removeAuction(_tokenId); -_transfer(_seller, _tokenId); -emit AuctionCancelled(_tokenId); -} - -/// @dev Computes the price and transfers winnings. -/// Does NOT transfer ownership of token. -function _bid(uint256 _tokenId, uint256 _bidAmount) -internal -returns (uint256) -{ -// Get a reference to the auction struct -Auction storage auction = tokenIdToAuction[_tokenId]; - -// Explicitly check that this auction is currently live. -// (Because of how Ethereum mappings work, we can't just count -// on the lookup above failing. An invalid _tokenId will just -// return an auction object that is all zeros.) -require(_isOnAuction(auction)); - -// Check that the bid is greater than or equal to the current price -uint256 price = _currentPrice(auction); -require(_bidAmount >= price); - -// Grab a reference to the seller before the auction struct -// gets deleted. -address payable seller = auction.seller; - -// The bid is good! Remove the auction before sending the fees -// to the sender so we can't have a reentrancy attack. -_removeAuction(_tokenId); - -// Transfer proceeds to seller (if there are any!) -if (price > 0) { -// Calculate the auctioneer's cut. -// (NOTE: _computeCut() is guaranteed to return a -// value <= price, so this subtraction can't go negative.) -uint256 auctioneerCut = _computeCut(price); -uint256 sellerProceeds = price - auctioneerCut; - -// NOTE: Doing a transfer() in the middle of a complex -// method like this is generally discouraged because of -// reentrancy attacks and DoS attacks if the seller is -// a contract with an invalid fallback function. We explicitly -// guard against reentrancy attacks by removing the auction -// before calling transfer(), and the only thing the seller -// can DoS is the sale of their own asset! (And if it's an -// accident, they can call cancelAuction(). ) -seller.transfer(sellerProceeds); -} - -// Calculate any excess funds included with the bid. If the excess -// is anything worth worrying about, transfer it back to bidder. -// NOTE: We checked above that the bid amount is greater than or -// equal to the price so this cannot underflow. -uint256 bidExcess = _bidAmount - price; - -// Return the funds. Similar to the previous transfer, this is -// not susceptible to a re-entry attack because the auction is -// removed before any transfers occur. -msg.sender.transfer(bidExcess); - -// Tell the world! -emit AuctionSuccessful(_tokenId, price, msg.sender); - -return price; -} - -/// @dev Removes an auction from the list of open auctions. -/// @param _tokenId - ID of NFT on auction. -function _removeAuction(uint256 _tokenId) internal { -delete tokenIdToAuction[_tokenId]; -} - -/// @dev Returns true if the NFT is on auction. -/// @param _auction - Auction to check. -function _isOnAuction(Auction storage _auction) internal view returns (bool) { -return (_auction.startedAt > 0); -} - -/// @dev Returns current price of an NFT on auction. Broken into two -/// functions (this one, that computes the duration from the auction -/// structure, and the other that does the price computation) so we -/// can easily test that the price computation works correctly. -function _currentPrice(Auction storage _auction) -internal -view -returns (uint256) -{ -uint256 secondsPassed = 0; - -// A bit of insurance against negative values (or wraparound). -// Probably not necessary (since Ethereum guarnatees that the -// now variable doesn't ever go backwards). -if (block.timestamp > _auction.startedAt) { -secondsPassed = block.timestamp - _auction.startedAt; -} - -return _computeCurrentPrice( -_auction.startingPrice, -_auction.endingPrice, -_auction.duration, -secondsPassed -); -} - -/// @dev Computes the current price of an auction. Factored out -/// from _currentPrice so we can run extensive unit tests. -/// When testing, make this function public and turn on -/// `Current price computation` test suite. -function _computeCurrentPrice( -uint256 _startingPrice, -uint256 _endingPrice, -uint256 _duration, -uint256 _secondsPassed -) -internal -pure -returns (uint256) -{ -// NOTE: We don't use SafeMath (or similar) in this function because -// all of our public functions carefully cap the maximum values for -// time (at 64-bits) and currency (at 128-bits). _duration is -// also known to be non-zero (see the require() statement in -// _addAuction()) -if (_secondsPassed >= _duration) { -// We've reached the end of the dynamic pricing portion -// of the auction, just return the end price. -return _endingPrice; -} else { -// Starting price can be higher than ending price (and often is!), so -// this delta can be negative. -int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - -// This multiplication can't overflow, _secondsPassed will easily fit within -// 64-bits, and totalPriceChange will easily fit within 128-bits, their product -// will always fit within 256-bits. -int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - -// currentPriceChange can be negative, but if so, will have a magnitude -// less that _startingPrice. Thus, this result will always end up positive. -int256 currentPrice = int256(_startingPrice) + currentPriceChange; - -return uint256(currentPrice); -} -} - -/// @dev Computes owner's cut of a sale. -/// @param _price - Sale price of NFT. -function _computeCut(uint256 _price) internal view returns (uint256) { -// NOTE: We don't use SafeMath (or similar) in this function because -// all of our entry functions carefully cap the maximum values for -// currency (at 128-bits), and ownerCut <= 10000 (see the require() -// statement in the ClockAuction constructor). The result of this -// function is always guaranteed to be <= _price. -return _price * ownerCut / 10000; -} - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { -event Pause(); -event Unpause(); - -bool public paused = false; - - -/** - * @dev modifier to allow actions only when the contract IS paused - */ -modifier whenNotPaused() { -require(!paused); -_; -} - -/** - * @dev modifier to allow actions only when the contract IS NOT paused - */ -modifier whenPaused { -require(paused); -_; -} - -/** - * @dev called by the owner to pause, triggers stopped state - */ -function pause() onlyOwner whenNotPaused public returns (bool) { -paused = true; -emit Pause(); -return true; -} - -/** - * @dev called by the owner to unpause, returns to normal state - */ -function unpause() onlyOwner whenPaused public returns (bool) { -paused = false; -emit Unpause(); -return true; -} -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - -/// @dev The ERC-165 interface signature for ERC-721. -/// Ref: https://github.com/ethereum/EIPs/issues/165 -/// Ref: https://github.com/ethereum/EIPs/issues/721 -bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - -/// @dev Constructor creates a reference to the NFT ownership contract -/// and verifies the owner cut is in the valid range. -/// @param _nftAddress - address of a deployed contract implementing -/// the Nonfungible Interface. -/// @param _cut - percent cut the owner takes on each auction, must be -/// between 0-10,000. -constructor(address _nftAddress, uint256 _cut) public { -require(_cut <= 10000); -ownerCut = _cut; - -ERC721 candidateContract = ERC721(_nftAddress); -require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); -nonFungibleContract = candidateContract; -} - -/// @dev Remove all Ether from the contract, which is the owner's cuts -/// as well as any Ether sent directly to the contract address. -/// Always transfers to the NFT contract, but can be called either by -/// the owner or the NFT contract. -function withdrawBalance() external { -address payable nftAddress = address(uint160(address(nonFungibleContract))); - -require( -msg.sender == owner || -msg.sender == nftAddress -); -// We are using this boolean method to make sure that even if one fails it will still work -bool res = nftAddress.send(address(this).balance); -} - -/// @dev Creates and begins a new auction. -/// @param _tokenId - ID of token to auction, sender must be owner. -/// @param _startingPrice - Price of item (in wei) at beginning of auction. -/// @param _endingPrice - Price of item (in wei) at end of auction. -/// @param _duration - Length of time to move between starting -/// price and ending price (in seconds). -/// @param _seller - Seller, if not the message sender -function createAuction( -uint256 _tokenId, -uint256 _startingPrice, -uint256 _endingPrice, -uint256 _duration, -address payable _seller -) -virtual -external -whenNotPaused -{ -// Sanity check that no inputs overflow how many bits we've allocated -// to store them in the auction struct. -require(_startingPrice == uint256(uint128(_startingPrice))); -require(_endingPrice == uint256(uint128(_endingPrice))); -require(_duration == uint256(uint64(_duration))); - -require(_owns(msg.sender, _tokenId)); -_escrow(msg.sender, _tokenId); -Auction memory auction = Auction( -_seller, -uint128(_startingPrice), -uint128(_endingPrice), -uint64(_duration), -uint64(block.timestamp) -); -_addAuction(_tokenId, auction); -} - -/// @dev Bids on an open auction, completing the auction and transferring -/// ownership of the NFT if enough Ether is supplied. -/// @param _tokenId - ID of token to bid on. -function bid(uint256 _tokenId) -external -payable -whenNotPaused -virtual -{ -// _bid will throw if the bid or funds transfer fails -_bid(_tokenId, msg.value); -_transfer(msg.sender, _tokenId); -} - -/// @dev Cancels an auction that hasn't been won yet. -/// Returns the NFT to original owner. -/// @notice This is a state-modifying function that can -/// be called while the contract is paused. -/// @param _tokenId - ID of token on auction -function cancelAuction(uint256 _tokenId) -external -{ -Auction storage auction = tokenIdToAuction[_tokenId]; -require(_isOnAuction(auction)); -address seller = auction.seller; -require(msg.sender == seller); -_cancelAuction(_tokenId, seller); -} - -/// @dev Cancels an auction when the contract is paused. -/// Only the owner may do this, and NFTs are returned to -/// the seller. This should only be used in emergencies. -/// @param _tokenId - ID of the NFT on auction to cancel. -function cancelAuctionWhenPaused(uint256 _tokenId) -whenPaused -onlyOwner -external -{ -Auction storage auction = tokenIdToAuction[_tokenId]; -require(_isOnAuction(auction)); -_cancelAuction(_tokenId, auction.seller); -} - -/// @dev Returns auction info for an NFT on auction. -/// @param _tokenId - ID of NFT on auction. -function getAuction(uint256 _tokenId) -external -view -returns -( -address seller, -uint256 startingPrice, -uint256 endingPrice, -uint256 duration, -uint256 startedAt -) { -Auction storage auction = tokenIdToAuction[_tokenId]; -require(_isOnAuction(auction)); -return ( -auction.seller, -auction.startingPrice, -auction.endingPrice, -auction.duration, -auction.startedAt -); -} - -/// @dev Returns the current price of an auction. -/// @param _tokenId - ID of the token price we are checking. -function getCurrentPrice(uint256 _tokenId) -external -view -returns (uint256) -{ -Auction storage auction = tokenIdToAuction[_tokenId]; -require(_isOnAuction(auction)); -return _currentPrice(auction); -} - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - -// @dev Sanity check that allows us to ensure that we are pointing to the -// right auction in our setSiringAuctionAddress() call. -bool public isSiringClockAuction = true; - -// Delegate constructor -constructor(address _nftAddr, uint256 _cut) public -ClockAuction(_nftAddr, _cut) {} - -/// @dev Creates and begins a new auction. Since this function is wrapped, -/// require sender to be KittyCore contract. -/// @param _tokenId - ID of token to auction, sender must be owner. -/// @param _startingPrice - Price of item (in wei) at beginning of auction. -/// @param _endingPrice - Price of item (in wei) at end of auction. -/// @param _duration - Length of auction (in seconds). -/// @param _seller - Seller, if not the message sender -function createAuction( -uint256 _tokenId, -uint256 _startingPrice, -uint256 _endingPrice, -uint256 _duration, -address payable _seller -) -override -external -{ -// Sanity check that no inputs overflow how many bits we've allocated -// to store them in the auction struct. -require(_startingPrice == uint256(uint128(_startingPrice))); -require(_endingPrice == uint256(uint128(_endingPrice))); -require(_duration == uint256(uint64(_duration))); - -require(msg.sender == address(nonFungibleContract)); -_escrow(_seller, _tokenId); -Auction memory auction = Auction( -_seller, -uint128(_startingPrice), -uint128(_endingPrice), -uint64(_duration), -uint64(block.timestamp) -); -_addAuction(_tokenId, auction); -} - -/// @dev Places a bid for siring. Requires the sender -/// is the KittyCore contract because all bid methods -/// should be wrapped. Also returns the kitty to the -/// seller rather than the winner. -function bid(uint256 _tokenId) -external -payable -override -{ -require(msg.sender == address(nonFungibleContract)); -address seller = tokenIdToAuction[_tokenId].seller; -// _bid checks that token ID is valid and will throw if bid fails -_bid(_tokenId, msg.value); -// We transfer the kitty back to the seller, the winner will get -// the offspring -_transfer(seller, _tokenId); -} - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - -// @dev Sanity check that allows us to ensure that we are pointing to the -// right auction in our setSaleAuctionAddress() call. -bool public isSaleClockAuction = true; - -// Tracks last 5 sale price of gen0 kitty sales -uint256 public gen0SaleCount; -uint256[5] public lastGen0SalePrices; - -// Delegate constructor -constructor(address _nftAddr, uint256 _cut) public -ClockAuction(_nftAddr, _cut) {} - -/// @dev Creates and begins a new auction. -/// @param _tokenId - ID of token to auction, sender must be owner. -/// @param _startingPrice - Price of item (in wei) at beginning of auction. -/// @param _endingPrice - Price of item (in wei) at end of auction. -/// @param _duration - Length of auction (in seconds). -/// @param _seller - Seller, if not the message sender -function createAuction( -uint256 _tokenId, -uint256 _startingPrice, -uint256 _endingPrice, -uint256 _duration, -address payable _seller -) -override -external -{ -// Sanity check that no inputs overflow how many bits we've allocated -// to store them in the auction struct. -require(_startingPrice == uint256(uint128(_startingPrice))); -require(_endingPrice == uint256(uint128(_endingPrice))); -require(_duration == uint256(uint64(_duration))); - -require(msg.sender == address(nonFungibleContract)); -_escrow(_seller, _tokenId); -Auction memory auction = Auction( -_seller, -uint128(_startingPrice), -uint128(_endingPrice), -uint64(_duration), -uint64(block.timestamp) -); -_addAuction(_tokenId, auction); -} - -/// @dev Updates lastSalePrice if seller is the nft contract -/// Otherwise, works the same as default bid method. -function bid(uint256 _tokenId) -external -override -payable -{ -// _bid verifies token ID size -address seller = tokenIdToAuction[_tokenId].seller; -uint256 price = _bid(_tokenId, msg.value); -_transfer(msg.sender, _tokenId); - -// If not a gen0 auction, exit -if (seller == address(nonFungibleContract)) { -// Track gen0 sale prices -lastGen0SalePrices[gen0SaleCount % 5] = price; -gen0SaleCount++; -} -} - -function averageGen0SalePrice() external view returns (uint256) { -uint256 sum = 0; -for (uint256 i = 0; i < 5; i++) { -sum += lastGen0SalePrices[i]; -} -return sum / 5; -} - -} - - - - - - - diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractScenario009.sol b/framework/src/test/resources/soliditycode_0.7.6/contractScenario009.sol deleted file mode 100644 index 52fa63e90ac..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractScenario009.sol +++ /dev/null @@ -1,51 +0,0 @@ - - -library Set { - // We define a new struct datatype that will be used to - // hold its data in the calling contract. - struct Data { mapping(uint => bool) flags; } - - // Note that the first parameter is of type "storage - // reference" and thus only its storage address and not - // its contents is passed as part of the call. This is a - // special feature of library functions. It is idiomatic - // to call the first parameter 'self', if the function can - // be seen as a method of that object. - function insert (Data storage self, uint value) public - returns (bool) - { - if (self.flags[value]) - return false; // already there - self.flags[value] = true; - return true; - } - - function remove(Data storage self, uint value) public - returns (bool) - { - if (!self.flags[value]) - return false; // not there - self.flags[value] = false; - return true; - } - - function contains(Data storage self, uint value) public - returns (bool) - { - return self.flags[value]; - } -} - - -contract C { - Set.Data knownValues; - - function register(uint value) public { - // The library functions can be called without a - // specific instance of the library, since the - // "instance" will be the current contract. - if (!Set.insert(knownValues, value)) - revert(); - } - // In this contract, we can also directly access knownValues.flags, if we want. -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractScenario010.sol b/framework/src/test/resources/soliditycode_0.7.6/contractScenario010.sol deleted file mode 100644 index 4e299efecad..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractScenario010.sol +++ /dev/null @@ -1,107 +0,0 @@ - - -contract TRON_ERC721 { - //name - function name() view public returns (string memory name){ - return "Tron ERC721 Token"; - } - //symbol - function symbol() view public returns (string memory symbol){ - return "T721T"; - } - - //totalSupply - - function totalSupply() view public returns (uint256 supply){ - uint256 totalSupply = 1000000000000; - return totalSupply; - } - - mapping(address => uint) private balances; - function balanceOf(address _owner) view public returns (uint balance) - { - return balances[_owner]; - } - - - mapping(uint256 => address) private tokenOwners; - mapping(uint256 => bool) private tokenExists; - function ownerOf(uint256 _tokenId) view public returns (address owner) { - require(tokenExists[_tokenId]); - return tokenOwners[_tokenId]; - } - - - mapping(address => mapping (address => uint256)) allowed; - function approve(address _to, uint256 _tokenId) public{ - require(msg.sender == ownerOf(_tokenId)); - require(msg.sender != _to); - allowed[msg.sender][_to] = _tokenId; - emit Approval(msg.sender, _to, _tokenId); - } - - - function takeOwnership(uint256 _tokenId) public { - require(tokenExists[_tokenId]); - address oldOwner = ownerOf(_tokenId); - address newOwner = msg.sender; - require(newOwner != oldOwner); - require(allowed[oldOwner][newOwner] == _tokenId); - balances[oldOwner] -= 1; - tokenOwners[_tokenId] = newOwner; - balances[newOwner] += 1; - emit Transfer(oldOwner, newOwner, _tokenId); - } - - - mapping(address => mapping(uint256 => uint256)) private ownerTokens; - function removeFromTokenList(address owner, uint256 _tokenId) private { - for(uint256 i = 0;ownerTokens[owner][i] != _tokenId;i++){ - ownerTokens[owner][i] = 0; - } - } - - function transfer(address _to, uint256 _tokenId) public{ - address currentOwner = msg.sender; - address newOwner = _to; - require(tokenExists[_tokenId]); - require(currentOwner == ownerOf(_tokenId)); - require(currentOwner != newOwner); - require(newOwner != address(0)); - address oldOwner =currentOwner; - removeFromTokenList(oldOwner,_tokenId); - balances[oldOwner] -= 1; - tokenOwners[_tokenId] = newOwner; - balances[newOwner] += 1; - emit Transfer(oldOwner, newOwner, _tokenId); - } - - function transferFrom(address _from,address _to, uint256 _tokenId) public{ - address currentOwner = _from; - address newOwner = _to; - require(tokenExists[_tokenId]); - require(currentOwner == ownerOf(_tokenId)); - require(currentOwner != newOwner); - require(newOwner != address(0)); - address oldOwner =currentOwner; - removeFromTokenList(oldOwner,_tokenId); - balances[oldOwner] -= 1; - tokenOwners[_tokenId] = newOwner; - balances[newOwner] += 1; - emit Transfer(oldOwner, newOwner, _tokenId); - } - - - function tokenOfOwnerByIndex(address _owner, uint256 _index) view public returns (uint tokenId){ - return ownerTokens[_owner][_index]; - } - - - mapping(uint256 => string) tokenLinks; - function tokenMetadata(uint256 _tokenId) view public returns (string memory infoUrl) { - return tokenLinks[_tokenId]; - } - // Events - event Transfer(address indexed _from, address indexed _to, uint256 _tokenId); - event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId); -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractScenario011.sol b/framework/src/test/resources/soliditycode_0.7.6/contractScenario011.sol deleted file mode 100644 index 6b213fa0f28..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractScenario011.sol +++ /dev/null @@ -1,2060 +0,0 @@ - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) public onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address payable public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address payable _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() public virtual onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer1(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - emit Transfer1(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(block.timestamp), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - kitties.push(_kitty); - uint256 newKittenId = kitties.length - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - emit Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(address(0), _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -abstract contract ERC721 { - // Required methods - function totalSupply() public virtual view returns (uint256 total); - function balanceOf(address _owner) public virtual view returns (uint256 balance); - function ownerOf(uint256 _tokenId) external virtual view returns (address owner); - function approve(address _to, uint256 _tokenId) external virtual; - function transfer(address _to, uint256 _tokenId) external virtual; - function transferFrom(address _from, address _to, uint256 _tokenId) external virtual; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) external virtual view returns (bool); -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is ERC721, KittyBase { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external override view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public view override returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - override - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - external - override - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - emit Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - external - override - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() public override view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - external - override - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] memory _rawBytes, uint256 _stringLength) private view returns (string memory) { - string memory outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string calldata _preferredTransport) external view returns (string memory infoUrl) { - require( address(erc721Metadata) != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2 ; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty memory _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty memory _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - emit Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.transfer(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, address(saleAuction)); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, address(siringAuction)); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid{value : (msg.value - autoBirthFee)}(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10 ; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, address(saleAuction)); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(uint160(address(this))) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - constructor() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - emit ContractUpgrade(_v2Address); - } - - /// @notice No tipping! - /// @dev Reject all Ether from being sent here, unless it's from one of the - /// two auction contracts. (Hopefully, we can prevent user accidents.) - fallback() external payable { - require( - msg.sender == address(saleAuction) || - msg.sender == address(siringAuction) - ); - } - - /// @notice Returns all the relevant information about a specific kitty. - /// @param _id The ID of the kitty of interest. - function getKitty(uint256 _id) - external - view - returns ( - bool isGestating, - bool isReady, - uint256 cooldownIndex, - uint256 nextActionAt, - uint256 siringWithId, - uint256 birthTime, - uint256 matronId, - uint256 sireId, - uint256 generation, - uint256 genes - ) { - Kitty storage kit = kitties[_id]; - - // if this variable is 0 then it's not gestating - isGestating = (kit.siringWithId != 0); - isReady = (kit.cooldownEndBlock <= block.number); - cooldownIndex = uint256(kit.cooldownIndex); - nextActionAt = uint256(kit.cooldownEndBlock); - siringWithId = uint256(kit.siringWithId); - birthTime = uint256(kit.birthTime); - matronId = uint256(kit.matronId); - sireId = uint256(kit.sireId); - generation = uint256(kit.generation); - genes = kit.genes; - } - - /// @dev Override unpause so it requires all external contract addresses - /// to be set before contract can be unpaused. Also, we can't have - /// newContractAddress set either, because then the contract was upgraded. - /// @notice This is public rather than external so we can call super.unpause - /// without using an expensive CALL. - - function unpause() public override onlyCEO whenPaused { - require(address(saleAuction) != address(0)); - require(address(siringAuction) != address(0)); - require(address(geneScience) != address(0)); - require(newContractAddress == address(0)); - - // Actually unpause the contract. - super.unpause(); - } - - // @dev Allows the CFO to capture the balance available to the contract. - function withdrawBalance() external onlyCFO { - uint256 balance = address(this).balance; - // Subtract all the currently pregnant kittens we have, plus 1 of margin. - uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - - if (balance > subtractFees) { - cfoAddress.transfer(balance - subtractFees); - } - } -} - - - - - - - - - - - - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - - function isGeneScience() public pure returns (bool){ - return true; - } - - /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor - /// @param genes1 genes of mom - /// @param genes2 genes of sire - /// @return the genes that are supposed to be passed down the child - function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - - return (genes1+genes2+targetBlock)/2; - - - } -} - - - - - - - - - - - - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { - /// @dev Given a token Id, returns a byte array that is supposed to be converted into string. - function getMetadata(uint256 _tokenId, string memory) public view returns (bytes32[4] memory buffer, uint256 count) { - if (_tokenId == 1) { - buffer[0] = "Hello World! :D"; - count = 15; - } else if (_tokenId == 2) { - buffer[0] = "I would definitely choose a medi"; - buffer[1] = "um length string."; - count = 49; - } else if (_tokenId == 3) { - buffer[0] = "Lorem ipsum dolor sit amet, mi e"; - buffer[1] = "st accumsan dapibus augue lorem,"; - buffer[2] = " tristique vestibulum id, libero"; - buffer[3] = " suscipit varius sapien aliquam."; - count = 128; - } - } -} - - - - - - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - - // Represents an auction on an NFT - struct Auction { - // Current owner of NFT - address payable seller; - // Price (in wei) at beginning of auction - uint128 startingPrice; - // Price (in wei) at end of auction - uint128 endingPrice; - // Duration (in seconds) of auction - uint64 duration; - // Time when auction started - // NOTE: 0 if this auction has been concluded - uint64 startedAt; - } - - // Reference to contract tracking NFT ownership - ERC721 public nonFungibleContract; - - // Cut owner takes on each auction, measured in basis points (1/100 of a percent). - // Values 0-10,000 map to 0%-100% - uint256 public ownerCut; - - // Map from token ID to their corresponding auction. - mapping (uint256 => Auction) tokenIdToAuction; - - event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); - event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); - event AuctionCancelled(uint256 tokenId); - - /// @dev Returns true if the claimant owns the token. - /// @param _claimant - Address claiming to own the token. - /// @param _tokenId - ID of token whose ownership to verify. - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return (nonFungibleContract.ownerOf(_tokenId) == _claimant); - } - - /// @dev Escrows the NFT, assigning ownership to this contract. - /// Throws if the escrow fails. - /// @param _owner - Current owner address of token to escrow. - /// @param _tokenId - ID of token whose approval to verify. - function _escrow(address _owner, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transferFrom(_owner, address(this), _tokenId); - } - - /// @dev Transfers an NFT owned by this contract to another address. - /// Returns true if the transfer succeeds. - /// @param _receiver - Address to transfer NFT to. - /// @param _tokenId - ID of token to transfer. - function _transfer(address _receiver, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transfer(_receiver, _tokenId); - } - - /// @dev Adds an auction to the list of open auctions. Also fires the - /// AuctionCreated event. - /// @param _tokenId The ID of the token to be put on auction. - /// @param _auction Auction to add. - function _addAuction(uint256 _tokenId, Auction memory _auction) internal { - // Require that all auctions have a duration of - // at least one minute. (Keeps our math from getting hairy!) - require(_auction.duration >= 1 minutes); - - tokenIdToAuction[_tokenId] = _auction; - - emit AuctionCreated( - uint256(_tokenId), - uint256(_auction.startingPrice), - uint256(_auction.endingPrice), - uint256(_auction.duration) - ); - } - - /// @dev Cancels an auction unconditionally. - function _cancelAuction(uint256 _tokenId, address _seller) internal { - _removeAuction(_tokenId); - _transfer(_seller, _tokenId); - emit AuctionCancelled(_tokenId); - } - - /// @dev Computes the price and transfers winnings. - /// Does NOT transfer ownership of token. - function _bid(uint256 _tokenId, uint256 _bidAmount) - internal - returns (uint256) - { - // Get a reference to the auction struct - Auction storage auction = tokenIdToAuction[_tokenId]; - - // Explicitly check that this auction is currently live. - // (Because of how Ethereum mappings work, we can't just count - // on the lookup above failing. An invalid _tokenId will just - // return an auction object that is all zeros.) - require(_isOnAuction(auction)); - - // Check that the bid is greater than or equal to the current price - uint256 price = _currentPrice(auction); - require(_bidAmount >= price); - - // Grab a reference to the seller before the auction struct - // gets deleted. - address payable seller = auction.seller; - - // The bid is good! Remove the auction before sending the fees - // to the sender so we can't have a reentrancy attack. - _removeAuction(_tokenId); - - // Transfer proceeds to seller (if there are any!) - if (price > 0) { - // Calculate the auctioneer's cut. - // (NOTE: _computeCut() is guaranteed to return a - // value <= price, so this subtraction can't go negative.) - uint256 auctioneerCut = _computeCut(price); - uint256 sellerProceeds = price - auctioneerCut; - - // NOTE: Doing a transfer() in the middle of a complex - // method like this is generally discouraged because of - // reentrancy attacks and DoS attacks if the seller is - // a contract with an invalid fallback function. We explicitly - // guard against reentrancy attacks by removing the auction - // before calling transfer(), and the only thing the seller - // can DoS is the sale of their own asset! (And if it's an - // accident, they can call cancelAuction(). ) - seller.transfer(sellerProceeds); - } - - // Calculate any excess funds included with the bid. If the excess - // is anything worth worrying about, transfer it back to bidder. - // NOTE: We checked above that the bid amount is greater than or - // equal to the price so this cannot underflow. - uint256 bidExcess = _bidAmount - price; - - // Return the funds. Similar to the previous transfer, this is - // not susceptible to a re-entry attack because the auction is - // removed before any transfers occur. - msg.sender.transfer(bidExcess); - - // Tell the world! - emit AuctionSuccessful(_tokenId, price, msg.sender); - - return price; - } - - /// @dev Removes an auction from the list of open auctions. - /// @param _tokenId - ID of NFT on auction. - function _removeAuction(uint256 _tokenId) internal { - delete tokenIdToAuction[_tokenId]; - } - - /// @dev Returns true if the NFT is on auction. - /// @param _auction - Auction to check. - function _isOnAuction(Auction storage _auction) internal view returns (bool) { - return (_auction.startedAt > 0); - } - - /// @dev Returns current price of an NFT on auction. Broken into two - /// functions (this one, that computes the duration from the auction - /// structure, and the other that does the price computation) so we - /// can easily test that the price computation works correctly. - function _currentPrice(Auction storage _auction) - internal - view - returns (uint256) - { - uint256 secondsPassed = 0; - - // A bit of insurance against negative values (or wraparound). - // Probably not necessary (since Ethereum guarnatees that the - // now variable doesn't ever go backwards). - if (block.timestamp > _auction.startedAt) { - secondsPassed = block.timestamp - _auction.startedAt; - } - - return _computeCurrentPrice( - _auction.startingPrice, - _auction.endingPrice, - _auction.duration, - secondsPassed - ); - } - - /// @dev Computes the current price of an auction. Factored out - /// from _currentPrice so we can run extensive unit tests. - /// When testing, make this function public and turn on - /// `Current price computation` test suite. - function _computeCurrentPrice( - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - uint256 _secondsPassed - ) - internal - pure - returns (uint256) - { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our public functions carefully cap the maximum values for - // time (at 64-bits) and currency (at 128-bits). _duration is - // also known to be non-zero (see the require() statement in - // _addAuction()) - if (_secondsPassed >= _duration) { - // We've reached the end of the dynamic pricing portion - // of the auction, just return the end price. - return _endingPrice; - } else { - // Starting price can be higher than ending price (and often is!), so - // this delta can be negative. - int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - - // This multiplication can't overflow, _secondsPassed will easily fit within - // 64-bits, and totalPriceChange will easily fit within 128-bits, their product - // will always fit within 256-bits. - int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - - // currentPriceChange can be negative, but if so, will have a magnitude - // less that _startingPrice. Thus, this result will always end up positive. - int256 currentPrice = int256(_startingPrice) + currentPriceChange; - - return uint256(currentPrice); - } - } - - /// @dev Computes owner's cut of a sale. - /// @param _price - Sale price of NFT. - function _computeCut(uint256 _price) internal view returns (uint256) { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our entry functions carefully cap the maximum values for - // currency (at 128-bits), and ownerCut <= 10000 (see the require() - // statement in the ClockAuction constructor). The result of this - // function is always guaranteed to be <= _price. - return _price * ownerCut / 10000; - } - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { - event Pause(); - event Unpause(); - - bool public paused = false; - - - /** - * @dev modifier to allow actions only when the contract IS paused - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev modifier to allow actions only when the contract IS NOT paused - */ - modifier whenPaused { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyOwner whenNotPaused public returns (bool) { - paused = true; - emit Pause(); - return true; - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyOwner whenPaused public returns (bool) { - paused = false; - emit Unpause(); - return true; - } -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - - /// @dev The ERC-165 interface signature for ERC-721. - /// Ref: https://github.com/ethereum/EIPs/issues/165 - /// Ref: https://github.com/ethereum/EIPs/issues/721 - bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - - /// @dev Constructor creates a reference to the NFT ownership contract - /// and verifies the owner cut is in the valid range. - /// @param _nftAddress - address of a deployed contract implementing - /// the Nonfungible Interface. - /// @param _cut - percent cut the owner takes on each auction, must be - /// between 0-10,000. - constructor(address _nftAddress, uint256 _cut) public { - require(_cut <= 10000); - ownerCut = _cut; - - ERC721 candidateContract = ERC721(_nftAddress); - require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); - nonFungibleContract = candidateContract; - } - - /// @dev Remove all Ether from the contract, which is the owner's cuts - /// as well as any Ether sent directly to the contract address. - /// Always transfers to the NFT contract, but can be called either by - /// the owner or the NFT contract. - function withdrawBalance() external { - address payable nftAddress = address(uint160(address(nonFungibleContract))); - - require( - msg.sender == owner || - msg.sender == nftAddress - ); - // We are using this boolean method to make sure that even if one fails it will still work - bool res = nftAddress.send(address(this).balance); - } - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of time to move between starting - /// price and ending price (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - virtual - whenNotPaused - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(_owns(msg.sender, _tokenId)); - _escrow(msg.sender, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(block.timestamp) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Bids on an open auction, completing the auction and transferring - /// ownership of the NFT if enough Ether is supplied. - /// @param _tokenId - ID of token to bid on. - function bid(uint256 _tokenId) - external - payable - virtual - whenNotPaused - { - // _bid will throw if the bid or funds transfer fails - _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - } - - /// @dev Cancels an auction that hasn't been won yet. - /// Returns the NFT to original owner. - /// @notice This is a state-modifying function that can - /// be called while the contract is paused. - /// @param _tokenId - ID of token on auction - function cancelAuction(uint256 _tokenId) - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - address seller = auction.seller; - require(msg.sender == seller); - _cancelAuction(_tokenId, seller); - } - - /// @dev Cancels an auction when the contract is paused. - /// Only the owner may do this, and NFTs are returned to - /// the seller. This should only be used in emergencies. - /// @param _tokenId - ID of the NFT on auction to cancel. - function cancelAuctionWhenPaused(uint256 _tokenId) - whenPaused - onlyOwner - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - _cancelAuction(_tokenId, auction.seller); - } - - /// @dev Returns auction info for an NFT on auction. - /// @param _tokenId - ID of NFT on auction. - function getAuction(uint256 _tokenId) - external - view - returns - ( - address seller, - uint256 startingPrice, - uint256 endingPrice, - uint256 duration, - uint256 startedAt - ) { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return ( - auction.seller, - auction.startingPrice, - auction.endingPrice, - auction.duration, - auction.startedAt - ); - } - - /// @dev Returns the current price of an auction. - /// @param _tokenId - ID of the token price we are checking. - function getCurrentPrice(uint256 _tokenId) - external - view - returns (uint256) - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return _currentPrice(auction); - } - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSiringAuctionAddress() call. - bool public isSiringClockAuction = true; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. Since this function is wrapped, - /// require sender to be KittyCore contract. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - override - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(block.timestamp) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Places a bid for siring. Requires the sender - /// is the KittyCore contract because all bid methods - /// should be wrapped. Also returns the kitty to the - /// seller rather than the winner. - function bid(uint256 _tokenId) - external - payable - override - { - require(msg.sender == address(nonFungibleContract)); - address seller = tokenIdToAuction[_tokenId].seller; - // _bid checks that token ID is valid and will throw if bid fails - _bid(_tokenId, msg.value); - // We transfer the kitty back to the seller, the winner will get - // the offspring - _transfer(seller, _tokenId); - } - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSaleAuctionAddress() call. - bool public isSaleClockAuction = true; - - // Tracks last 5 sale price of gen0 kitty sales - uint256 public gen0SaleCount; - uint256[5] public lastGen0SalePrices; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address payable _seller - ) - external - override - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(block.timestamp) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Updates lastSalePrice if seller is the nft contract - /// Otherwise, works the same as default bid method. - function bid(uint256 _tokenId) - external - payable - override - { - // _bid verifies token ID size - address seller = tokenIdToAuction[_tokenId].seller; - uint256 price = _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - - // If not a gen0 auction, exit - if (seller == address(nonFungibleContract)) { - // Track gen0 sale prices - lastGen0SalePrices[gen0SaleCount % 5] = price; - gen0SaleCount++; - } - } - - function averageGen0SalePrice() external view returns (uint256) { - uint256 sum = 0; - for (uint256 i = 0; i < 5; i++) { - sum += lastGen0SalePrices[i]; - } - return sum / 5; - } - -} - - - - - - - diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractScenario012.sol b/framework/src/test/resources/soliditycode_0.7.6/contractScenario012.sol deleted file mode 100644 index 7fea2b1ccf1..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractScenario012.sol +++ /dev/null @@ -1,57 +0,0 @@ - -contract PayTest { - -uint256 public n; -constructor() payable public{ -n = 0; -} - -function nPlusOne() public{ -n = n+1; -} - -//get current contract balance -function getBalance() payable public returns (uint) { -return address(this).balance; -} - -function getSenderBalance() public view returns(address, uint) { -return (msg.sender, msg.sender.balance); -} - -address public user; - -//deposit 1 coin to msg.sender -function depositOneCoin() payable public returns(bool success){ -return msg.sender.send(1); -} - -// function transferOneCoin() payable public returns(){ -// address(msg.sender).transfer(1); -// } - -// function depositOneCoin() payable public returns(address addr, uint amount, bool success){ -// return (msg.sender, msg.value, msg.sender.send(1)); -// } - -//deposit coin to msg.sender -function deposit(uint256 money) payable public returns(bool success){ -return msg.sender.send(money); -} -// function deposit(uint money) payable public returns(address addr, uint amount, bool success){ -// return (msg.sender, msg.value, msg.sender.send(money)); -// } - -// fallback() payable { -// msg.sender.send(1); -// } - -function sendToAddress(address payable _receiver) payable public{ -_receiver.transfer(msg.value); -} - -function sendToAddress2(address payable _receiver) payable public{ -_receiver.transfer(5); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractScenario013.sol b/framework/src/test/resources/soliditycode_0.7.6/contractScenario013.sol deleted file mode 100644 index 93b7905679b..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractScenario013.sol +++ /dev/null @@ -1,8 +0,0 @@ - -contract timetest { - -function time() public{ -require(1 trx == 1000000 sun); - -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractScenario014.sol b/framework/src/test/resources/soliditycode_0.7.6/contractScenario014.sol deleted file mode 100644 index 9f423d1b1ab..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractScenario014.sol +++ /dev/null @@ -1,34 +0,0 @@ - -contract Contract1 { - constructor() public payable{} - function send5SunToReceiver(address payable _receiver) payable public{ - _receiver.transfer(5); - } -} -contract contract2 { - address public payContract; - - constructor(address _add) payable public{ - payContract = _add; - } - - function triggerContract1(address _receiver) payable public{ - payContract.call(abi.encodeWithSignature("send5SunToReceiver(address)",_receiver)); - } - - function triggerContract1ButRevert(address _receiver) payable public{ - payContract.call(abi.encodeWithSignature("send5SunToReceiver(address)",_receiver)); - require(1 == 2); - } - -} -contract contract3 { - address public payContract; - constructor(address _add) payable public{ - payContract = _add; - } - - function triggerContract2(address _receiver) payable public{ - payContract.call(abi.encodeWithSignature("triggerContract1(address)",_receiver)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTest.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTest.sol deleted file mode 100644 index 9a72b4a53b4..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTest.sol +++ /dev/null @@ -1,19 +0,0 @@ - - -contract Test{ - -function a() public returns (uint){ - -uint256 count = 0; - -for (uint256 i = 1; i > 0; i++) { - -count++; - -} - -return count; - -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractToMathedFeed.sol b/framework/src/test/resources/soliditycode_0.7.6/contractToMathedFeed.sol deleted file mode 100644 index d9df9d9c10d..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractToMathedFeed.sol +++ /dev/null @@ -1,21 +0,0 @@ - - -contract ToMathedFeed { - uint public i=1; - function ToMathed (uint value) public { - i=value; - } -} - -contract ToMathedUseINContract { - function ToMathedIUseNR(address a,uint256 n) public returns(bool){ - address payContract=a; - (bool success, bytes memory data) = payContract.call(abi.encodeWithSignature("ToMathedNot(uint256)",n)); - return success; - } - function ToMathedIUseNRE(address a,uint256 value) public returns(bool){ - address payContract=a; - (bool success, bytes memory data) = payContract.call(abi.encodeWithSignature("ToMathed(uint256)",value)); - return success; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTransferToken001.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTransferToken001.sol deleted file mode 100644 index 0edbbfbb44a..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTransferToken001.sol +++ /dev/null @@ -1,22 +0,0 @@ -contract A { - address public a; - constructor() public payable{} - function kill(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - function newB() public payable returns(address){ - B bAddress=new B(); - a= address(bAddress); - return a; - - } - - } - -contract B{ - constructor() public payable {} - fallback() external payable {} - function kill(address payable toAddress) payable public{ - selfdestruct(toAddress); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken001.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken001.sol deleted file mode 100644 index ea28f4a62b6..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken001.sol +++ /dev/null @@ -1,30 +0,0 @@ - - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken002.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken002.sol deleted file mode 100644 index ea28f4a62b6..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken002.sol +++ /dev/null @@ -1,30 +0,0 @@ - - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken003.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken003.sol deleted file mode 100644 index 863429fc4f8..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken003.sol +++ /dev/null @@ -1,16 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken005.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken005.sol deleted file mode 100644 index 863429fc4f8..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken005.sol +++ /dev/null @@ -1,16 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken011.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken011.sol deleted file mode 100644 index 43e4010ec3f..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken011.sol +++ /dev/null @@ -1,35 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken012.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken012.sol deleted file mode 100644 index ab0c19767e7..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken012.sol +++ /dev/null @@ -1,26 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken014.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken014.sol deleted file mode 100644 index 589406c47c6..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken014.sol +++ /dev/null @@ -1,34 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken018.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken018.sol deleted file mode 100644 index ab0c19767e7..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken018.sol +++ /dev/null @@ -1,26 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken023.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken023.sol deleted file mode 100644 index 070acb201ff..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken023.sol +++ /dev/null @@ -1,26 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - toAddress.transferToken(amount,id); - } - } - -contract B{ - uint256 public flag = 0; - constructor() public payable {} - fallback() external { - flag = 1; -} - -} - -contract C{ - uint256 public flag = 0; - constructor() public payable {} - fallback() external payable { - //flag = 1; -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken026.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken026.sol deleted file mode 100644 index 5464265d81f..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken026.sol +++ /dev/null @@ -1,31 +0,0 @@ - - -contract token{ - constructor() payable public{} - fallback() payable external{} - function testInCall(address callBAddress,address callCAddress, address toAddress ,uint256 amount,trcToken id) payable public{ - //callBAddress.call(bytes4(keccak256("transC(address,address,uint256,trcToken)")),callCAddress,toAddress,amount,id); - callBAddress.call(abi.encodeWithSignature("transC(address,address,uint256,trcToken)",callCAddress,toAddress,amount,id)); - } - function testIndelegateCall(address callBddress,address callAddressC, address toAddress,uint256 amount, trcToken id) payable public{ - callBddress.delegatecall(abi.encodeWithSignature("transC(address,address,uint256,trcToken)",callAddressC,toAddress,amount,id)); - } - } - - - -contract B{ - constructor() public payable{} - fallback() external payable{} - function transC(address payable callCAddress,address payable toAddress,uint256 amount, trcToken id) payable public{ - callCAddress.call(abi.encodeWithSignature("trans(address,uint256,trcToken)",toAddress,amount,id)); - } -} -contract C{ - constructor() payable public{} - fallback() payable external{} - function trans(address payable toAddress,uint256 amount, trcToken id) payable public{ - toAddress.transferToken(amount,id); - } - -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken027.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken027.sol deleted file mode 100644 index e7d6ee768f3..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken027.sol +++ /dev/null @@ -1,30 +0,0 @@ - - -contract token{ - constructor() payable public{} - fallback() payable external{} - function testInCall(address callBAddress,address callCAddress, address toAddress ,uint256 amount,trcToken id) payable public{ - callBAddress.call(abi.encodeWithSignature("transC(address,address,uint256,trcToken)",callCAddress,toAddress,amount,id)); - } - function testIndelegateCall(address callBddress,address callAddressC, address toAddress,uint256 amount, trcToken id) payable public{ - callBddress.delegatecall(abi.encodeWithSignature("transC(address,address,uint256,trcToken)",callAddressC,toAddress,amount,id)); - } - } - - - -contract B{ - constructor() public payable{} - fallback() external payable{} - function transC(address callCAddress,address toAddress,uint256 amount, trcToken id) payable public{ - callCAddress.call(abi.encodeWithSignature("trans(address,uint256,trcToken)",toAddress,amount,id)); - } -} -contract C{ - constructor() payable public{} - fallback() payable external{} - function trans(address payable toAddress,uint256 amount, trcToken id) payable public{ - toAddress.transferToken(amount,id); - } - -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken028.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken028.sol deleted file mode 100644 index 0f27d89c819..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken028.sol +++ /dev/null @@ -1,25 +0,0 @@ - - -contract token{ - uint256 public a=1; - constructor() public payable{} - function tokenBalanceWithSameName(trcToken id) public payable{ - B b= new B(); - a= b.tokenBalance(id); - } - function getA() public returns(uint256){ - return a; - } -} - - -contract B{ - uint256 public flag =0; - constructor() public payable{} - fallback() external payable{} - function tokenBalance(trcToken id) payable public returns(uint256){ - flag =9; - return flag; - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken029.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken029.sol deleted file mode 100644 index 8480cf6f19d..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken029.sol +++ /dev/null @@ -1,24 +0,0 @@ - - -contract token{ - address public a; - constructor() public payable{} - function transferTokenWithSameName(trcToken id,uint256 amount) public payable{ - B b= new B(); - b.transferToken(amount,id); - a= address(b); - } -} - - -contract B{ - uint256 public flag =0; - constructor() public payable{} - fallback() external payable{} - function transferToken(uint256 amount, trcToken id) payable public returns(bool){ - flag =9; - } - function getFlag() public view returns (uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken030.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken030.sol deleted file mode 100644 index 06b8201979c..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken030.sol +++ /dev/null @@ -1,17 +0,0 @@ - - contract token{ - constructor() public payable{} - - // 4)suicide也会转移token - // 所有token,trx均被转移到toAddress, - // 若toAddress为合约地址本身,则所有token,trx均被烧掉进黑洞 - function kill(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - - } - -contract B{ - constructor() public payable {} - fallback() external payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken031.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken031.sol deleted file mode 100644 index 65ec394e8da..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken031.sol +++ /dev/null @@ -1,18 +0,0 @@ - - - contract token{ - constructor() public payable{} - - // 4)suicide也会转移token - // 所有token,trx均被转移到toAddress, - // 若toAddress为合约地址本身,则所有token,trx均被烧掉进黑洞 - function kill(address payable toAddress) payable public{ - selfdestruct(toAddress); - } - - } - -contract B{ - constructor() public payable {} - fallback() external payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken034.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken034.sol deleted file mode 100644 index 32c55f8c84b..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken034.sol +++ /dev/null @@ -1,25 +0,0 @@ - - - contract token{ - - constructor() public payable {} - - // 2. 异常测试 - // 1)revert, 金额回退 - function failTransferTokenRevert(address payable toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - require(1==2); - } - - // 2)Error, 金额回退, fee limit 扣光 - function failTransferTokenError(address payable toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - assert(1==2); - } - - } - contract B{ - uint256 public flag = 0; - constructor() public payable {} - fallback() external payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken035.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken035.sol deleted file mode 100644 index ca45dde790d..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken035.sol +++ /dev/null @@ -1,24 +0,0 @@ - - - contract token{ - constructor() public payable {} - - // 2. 异常测试 - // 1)revert, 金额回退 - function failTransferTokenRevert(address payable toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - require(1==2); - } - - // 2)Error, 金额回退, fee limit 扣光 - function failTransferTokenError(address payable toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - assert(1==2); - } - - } - contract B{ - uint256 public flag = 0; - constructor() public payable {} - fallback() external payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036.sol deleted file mode 100644 index c1da2f7555e..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036.sol +++ /dev/null @@ -1,52 +0,0 @@ - -contract IllegalDecorate { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithPure(address payable toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate1 { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithConstant(address payable toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate2 { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithView(address payable toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate3 { -event log(uint256); -constructor() payable public{} -fallback() payable external{} -function transferTokenWithOutPayable(address payable toAddress, uint256 tokenValue) public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_1.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_1.sol deleted file mode 100644 index 327ab5a756e..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_1.sol +++ /dev/null @@ -1,13 +0,0 @@ - -contract IllegalDecorate { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithPure(address payable toAddress, uint256 tokenValue) public pure { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_2.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_2.sol deleted file mode 100644 index 817a96e3c80..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_2.sol +++ /dev/null @@ -1,13 +0,0 @@ - -contract IllegalDecorate { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithConstant(address toAddress, uint256 tokenValue) public constant { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_3.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_3.sol deleted file mode 100644 index 67400c2e8ad..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_3.sol +++ /dev/null @@ -1,13 +0,0 @@ - -contract IllegalDecorate { -constructor() payable public{} -fallback() payable external{} -event log(uint256); -function transferTokenWithView(address payable toAddress, uint256 tokenValue) public view { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_4.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_4.sol deleted file mode 100644 index cbaca0d4b38..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_4.sol +++ /dev/null @@ -1,13 +0,0 @@ - -contract IllegalDecorate { -event log(uint256); -constructor() payable public{} -fallback() payable external{} -function transferTokenWithOutPayable(address payable toAddress, uint256 tokenValue) public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_old.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_old.sol deleted file mode 100644 index 1f03afb7636..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken036_old.sol +++ /dev/null @@ -1,41 +0,0 @@ - - - -contract IllegalDecorate1 { -constructor() payable public{} -fallback() payable public{} -event log(uint256); -function transferTokenWithConstant(address toAddress, uint256 tokenValue) public constant { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate2 { -constructor() payable public{} -fallback() payable public{} -event log(uint256); -function transferTokenWithView(address toAddress, uint256 tokenValue) public view { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate3 { -event log(uint256); -constructor() payable public{} -fallback() payable public{} -function transferTokenWithOutPayable(address toAddress, uint256 tokenValue) public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken037.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken037.sol deleted file mode 100644 index 7cdd91702e8..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken037.sol +++ /dev/null @@ -1,24 +0,0 @@ - - -contract transferTrc10 { - function receive(address payable rec) public payable { - uint256 aamount=address(this).tokenBalance(msg.tokenid); - uint256 bamount=rec.tokenBalance(msg.tokenid); - require(msg.tokenvalue==aamount); - require(aamount==msg.tokenvalue); - rec.transferToken(aamount,msg.tokenid); - require(0==address(this).tokenBalance(msg.tokenid)); - require(bamount+aamount==rec.tokenBalance(msg.tokenid)); - (bool success, bytes memory data) =rec.call(abi.encodeWithSignature("checkTrc10(uint256,trcToken,uint256)",bamount+aamount,msg.tokenid,0)); - require(success); - - } -} - -contract receiveTrc10 { - fallback() external payable {} - function checkTrc10(uint256 amount,trcToken tid,uint256 meamount) public{ - require(amount==address(this).tokenBalance(tid)); - require(meamount==msg.sender.tokenBalance(tid)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken038.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken038.sol deleted file mode 100644 index eeb5ae744cf..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken038.sol +++ /dev/null @@ -1,24 +0,0 @@ - - -contract transferTrc10 { - function receive(address payable rec) public payable { - uint256 aamount=address(this).tokenBalance(msg.tokenid); - uint256 bamount=rec.tokenBalance(msg.tokenid); - require(msg.tokenvalue==aamount); - require(aamount==msg.tokenvalue); - rec.transferToken(aamount,msg.tokenid); - //require(rec.call(abi.encode(bytes4(keccak256("AssertError()"))))); - (bool suc, bytes memory data) = rec.call(abi.encodeWithSignature("AssertError()")); - require(suc); - require(aamount==address(this).tokenBalance(msg.tokenid)); - require(bamount==rec.tokenBalance(msg.tokenid)); - } -} - -contract receiveTrc10 { - fallback() external payable { - } - function AssertError() public{ - assert(1==2); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken039.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken039.sol deleted file mode 100644 index ebf6fb932ed..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken039.sol +++ /dev/null @@ -1,44 +0,0 @@ - -/* - * 1. caller账户issue一个token - * 2. caller部署proxy, 传入1000 token,1000 trx - * 3. caller部署A - * 4. caller部署B - * 5. caller调用proxy中upgradetTo函数,传入A的地址 - * 6. caller调用proxy中不存在的trans(uint256,address,trcToken)函数,注意这时trcToken是无意义的,但也带上tokenid。address是任意另外某账户的地址 - * 7. 可以看到目标地址trx增长5,caller账户trx减少5 - * 8. caller调用proxy中upgradeTo函数,传入B的地址 - * 9. caller调用proxy中不存在的trans(uint256,address,trcToken)函数。 - * 10. 可以看到目标地址token增长5,caller账户token减少5 -*/ -contract Proxy { - constructor() payable public{} - address public implementation; - function upgradeTo(address _address) public { - implementation = _address; - } - fallback() payable external{ - address addr = implementation; - require(addr != address(0)); - assembly { - let freememstart := mload(0x40) - calldatacopy(freememstart, 0, calldatasize()) - let success := delegatecall(not(0), addr, freememstart, calldatasize(), freememstart, 0) - returndatacopy(freememstart, 0, returndatasize()) - switch success - case 0 { revert(freememstart, returndatasize()) } - default { return(freememstart, returndatasize()) } - } - } -} - -contract A { - function trans(uint256 amount, address payable toAddress, trcToken id) payable public { - toAddress.transfer(amount); - } -} -contract B{ - function trans(uint256 amount, address payable toAddress, trcToken id) payable public { - toAddress.transferToken(amount,id); - } -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken041.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken041.sol deleted file mode 100644 index 6284253d1d5..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken041.sol +++ /dev/null @@ -1,20 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } - -contract B{ - uint256 public flag = 0; - constructor() public payable {} - fallback() external payable {} - - function setFlag() public payable{ - flag = 1; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken043.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken043.sol deleted file mode 100644 index 43e4010ec3f..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken043.sol +++ /dev/null @@ -1,35 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken048.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken048.sol deleted file mode 100644 index e705f696c1d..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken048.sol +++ /dev/null @@ -1,14 +0,0 @@ - - - contract Test { - event log(uint256); - function testMsgTokenValue() payable public returns(uint256 value) { - emit log(msg.tokenvalue); - return msg.tokenvalue; - } - - function testMsgValue() payable public returns(uint256 value) { - emit log(msg.value); - return msg.value; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken049.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken049.sol deleted file mode 100644 index d40480720df..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken049.sol +++ /dev/null @@ -1,9 +0,0 @@ - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken050.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken050.sol deleted file mode 100644 index 6bc6d956898..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken050.sol +++ /dev/null @@ -1,10 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken051.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken051.sol deleted file mode 100644 index 493016b777f..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken051.sol +++ /dev/null @@ -1,11 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - fallback() external payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken052.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken052.sol deleted file mode 100644 index 6bc6d956898..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken052.sol +++ /dev/null @@ -1,10 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken054.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken054.sol deleted file mode 100644 index 863429fc4f8..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken054.sol +++ /dev/null @@ -1,16 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken055.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken055.sol deleted file mode 100644 index 863429fc4f8..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken055.sol +++ /dev/null @@ -1,16 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken060.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken060.sol deleted file mode 100644 index ea28f4a62b6..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken060.sol +++ /dev/null @@ -1,30 +0,0 @@ - - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken061.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken061.sol deleted file mode 100644 index ea28f4a62b6..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken061.sol +++ /dev/null @@ -1,30 +0,0 @@ - - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken064.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken064.sol deleted file mode 100644 index 43e0da8a510..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken064.sol +++ /dev/null @@ -1,49 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } - function transferTokenTestValueMaxBigInteger(address payable toAddress) payable public { - toAddress.transferToken(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0); - } - function transferTokenTestValueOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(9223372036854775808, 1000001); - } - function transferTokenTestValueMaxLong(address payable toAddress) payable public { - toAddress.transferToken(9223372036854775807, 1000001); - } - function transferTokenTestValue0IdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(0, 9223372036854775809); - } -} - - - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken066.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken066.sol deleted file mode 100644 index 43e4010ec3f..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken066.sol +++ /dev/null @@ -1,35 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken067.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken067.sol deleted file mode 100644 index 43e4010ec3f..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken067.sol +++ /dev/null @@ -1,35 +0,0 @@ - -contract transferTokenContract { - constructor() payable public{} - fallback() payable external{} - function transferTokenTest(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address payable toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - fallback() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken073.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken073.sol deleted file mode 100644 index a9ee8ea412b..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken073.sol +++ /dev/null @@ -1,16 +0,0 @@ - -contract Dest { - event logFallback(uint256 indexed, uint256 indexed, uint256 indexed); - event logGetToken(uint256 indexed, uint256 indexed, uint256 indexed, uint256); - - - constructor() payable public {} - - function getToken(trcToken tokenId) payable public{ - emit logGetToken(msg.sender.tokenBalance(tokenId), msg.tokenid, msg.tokenvalue, msg.value); - } - - fallback() payable external{ - emit logFallback(msg.tokenid, msg.tokenvalue, msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken075.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken075.sol deleted file mode 100644 index 9f201900295..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken075.sol +++ /dev/null @@ -1,26 +0,0 @@ - - -contract Dest { - event logFallback(uint256 indexed, uint256 indexed, uint256 indexed); - event logGetToken(uint256 indexed, uint256 indexed, uint256 indexed, uint256); - - constructor() payable public {} - - function getToken(trcToken tokenId) payable public{ - emit logGetToken(msg.sender.tokenBalance(tokenId), msg.tokenid, msg.tokenvalue, msg.value); - } - - function getTokenLongMin() payable public{ - // long.min - 1000020 - emit logGetToken(msg.sender.tokenBalance(trcToken(-9223372036855775828)), msg.tokenid, msg.tokenvalue, msg.value); - } - - function getTokenLongMax() payable public{ - // long.max + 1000020 - emit logGetToken(msg.sender.tokenBalance(trcToken(9223372036855775827)), msg.tokenid, msg.tokenvalue, msg.value); - } - - fallback() payable external{ - emit logFallback(msg.tokenid, msg.tokenvalue, msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken076.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken076.sol deleted file mode 100644 index a9decbee320..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken076.sol +++ /dev/null @@ -1,19 +0,0 @@ - -contract Test { - address public origin; - address public sender; - bool public result1; - bool public result2; - function test() external { - origin = tx.origin; - sender = msg.sender; - result1 = msg.sender == tx.origin; // true - result2 = origin == sender; // true - } -function getResult1() public returns(bool){ - return result1; -} -function getResult2() public returns(bool){ - return result2; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken077.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken077.sol deleted file mode 100644 index aeecf9cb9a5..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken077.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract trcToken077 { -function addressTest() public returns(bytes32 addressValue) { - assembly{ - let x := mload(0x40) //Find empty storage location using "free memory pointer" - mstore(x,address) //Place current contract address - addressValue := mload(x) - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken078.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken078.sol deleted file mode 100644 index 8d10d25312d..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken078.sol +++ /dev/null @@ -1,35 +0,0 @@ - -contract callerContract { - constructor() public payable{} - fallback() external payable{} - function sendToB(address called_address, address c) public payable{ - called_address.delegatecall(abi.encodeWithSignature("transferTo(address)",c)); - } - function sendToB2(address called_address,address c) public payable{ - called_address.call(abi.encodeWithSignature("transferTo(address)",c)); - } - function sendToB3(address called_address,address c) public payable{ - called_address.delegatecall(abi.encodeWithSignature("transferTo(address)",c)); - } -} - contract calledContract { - fallback() external payable{} - constructor() public payable {} - function transferTo(address payable toAddress)public payable{ - toAddress.transfer(5); - } - - function setIinC(address c) public payable{ - c.call{value:5}(abi.encode(bytes4(keccak256("setI()")))); - } - - } - contract c{ - address public origin; - address public sender; - constructor() public payable{} - event log(address,address); - fallback() payable external{ - emit log(tx.origin,msg.sender); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken079.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken079.sol deleted file mode 100644 index 863429fc4f8..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken079.sol +++ /dev/null @@ -1,16 +0,0 @@ - - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken080.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken080.sol deleted file mode 100644 index 2d2688b74a4..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcToken080.sol +++ /dev/null @@ -1,30 +0,0 @@ - - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - fallback() external payable{} - // positive case - function TransferTokenTo(address payable toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractTrcTokenToOther.sol b/framework/src/test/resources/soliditycode_0.7.6/contractTrcTokenToOther.sol deleted file mode 100644 index 8e926d3ba17..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractTrcTokenToOther.sol +++ /dev/null @@ -1,44 +0,0 @@ - - -contract ConvertType { - -constructor() payable public{} - -fallback() payable external{} - -//function trcTokenOnStorage(trcToken storage token) internal { // ERROR: Data location can only be specified for array, struct or mapping types, but "storage" was given. -//} - -function trcTokenToString(trcToken token) public pure returns(string memory s){ -// s = token; // ERROR -// s = string(token); // ERROR -} - -function trcTokenToUint256(trcToken token) public pure returns(uint256 r){ -uint256 u = token; // OK -uint256 u2 = uint256(token); // OK -r = u2; -} - -function trcTokenToAddress(trcToken token) public pure returns(address r){ -//r = token; // ERROR -token = 0x1234567812345678123456781234567812345678123456781234567812345678; -address a2 = address(token); // OK -r = a2; -} - -function trcTokenToBytes(trcToken token) public pure returns(bytes memory r){ -//r = token; // ERROR -// r = bytes(token); // ERROR -} - -function trcTokenToBytes32(trcToken token) public pure returns(bytes32 r){ -// r = token; // ERROR -bytes32 b2 = bytes32(token); // OK -r = b2; -} - -function trcTokenToArray(trcToken token) public pure returns(uint[] memory r){ -//r = token; // ERROR -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/contractUnknownException.sol b/framework/src/test/resources/soliditycode_0.7.6/contractUnknownException.sol deleted file mode 100644 index 0aca7badde8..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/contractUnknownException.sol +++ /dev/null @@ -1,64 +0,0 @@ - -contract testA { - constructor() public payable { - A a = (new A){value:10}(); - a.fun(); - } -} - -contract testB { - constructor() public payable { - B b = (new B){value:10}(); - b.fun(); - } -} - - -contract testC { - constructor() public payable{ - C c = (new C){value:10}(); - c.fun(); - } -} - -contract testD { - constructor() public payable{ - D d = (new D){value:10}(); - d.fun(); - } -} - - -contract A { - constructor() public payable{ - selfdestruct(msg.sender); - } - function fun() public { - } - -} - -contract B { - constructor() public payable { - revert(); - } - function fun() public { - } -} - - -contract C { - constructor() public payable { - assert(1==2); - } - function fun() public { - } -} - -contract D { - constructor() public payable { - require(1==2); - } - function fun() public { - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/create2CallContract.sol b/framework/src/test/resources/soliditycode_0.7.6/create2CallContract.sol deleted file mode 100644 index 046706ebd9e..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/create2CallContract.sol +++ /dev/null @@ -1,37 +0,0 @@ -contract callerContract { - constructor() payable public{} - fallback() payable external{} - function delegateCallCreate2(address called_address, bytes memory code, uint256 salt) public { - called_address.delegatecall(abi.encodeWithSignature("deploy(bytes,uint256)",code,salt)); - } - function callCreate2(address called_address,bytes memory code, uint256 salt) public returns(bool,bytes memory){ - return called_address.call(abi.encodeWithSignature("deploy(bytes,uint256)",code,salt)); - } -} - - -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - -contract TestConstract { - uint public i; - constructor () public { - } - function plusOne() public returns(uint){ - i++; - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/create2Istanbul.sol b/framework/src/test/resources/soliditycode_0.7.6/create2Istanbul.sol deleted file mode 100644 index c2ef8f3236b..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/create2Istanbul.sol +++ /dev/null @@ -1,28 +0,0 @@ - - -contract create2Istanbul { - function deploy(bytes memory code, uint256 salt) public returns(address) { - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - - } - return addr; - } - - // prefix in main net is 0x41, testnet config is 0xa0 - function get(bytes1 prefix, bytes calldata code, uint256 salt) external view returns(address) { - //bytes32 hash = keccak256(abi.encodePacked(bytes1(0x41),address(this), salt, keccak256(code))); - bytes32 hash = keccak256(abi.encodePacked(prefix,address(this), salt, keccak256(code))); - address addr = address(uint160(uint256(hash))); - return addr; - } - -} - -contract B { - constructor() public payable{} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/create2contract.sol b/framework/src/test/resources/soliditycode_0.7.6/create2contract.sol deleted file mode 100644 index 0171f4d5486..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/create2contract.sol +++ /dev/null @@ -1,52 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } - - event Deployed(address addr, bytes32 salt, address sender); - function deploy(bytes memory code, bytes32 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - -contract FactoryBytes { - event Deployed(address addr, bytes32 salt, address sender); - function deploy(bytes memory code, bytes32 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - -contract TestConstract { - uint public i; - constructor () public { - } - function plusOne() public returns(uint){ - i++; - return i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/create2contract22.sol b/framework/src/test/resources/soliditycode_0.7.6/create2contract22.sol deleted file mode 100644 index c33cb08edc3..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/create2contract22.sol +++ /dev/null @@ -1,109 +0,0 @@ -contract Factory { - event Deployed(address addr, trcToken salt, address sender); - event Deployed1(address addr, uint8 salt, address sender); - event Deployed2(address addr, address salt, address sender); - event Deployed3(address addr, string salt, address sender); - - - function deploy(bytes memory code, trcToken salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } - - function deploy1(bytes memory code, uint8 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed1(addr, salt, msg.sender); - return addr; - } - - function deploy2(bytes memory code, address salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed2(addr, salt, msg.sender); - return addr; - } - - function deploy3(bytes memory code, string memory salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed3(addr, salt, msg.sender); - return addr; - } - -} - - -contract TestConstract { - uint public i=1; - function testTransfer(uint256 i) payable public{ - msg.sender.transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} - -contract TestConstract1 { - uint public i=2; - function testTransfer(uint256 i) payable public{ - msg.sender.transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} - -contract TestConstract2 { - uint public i=3; - function testTransfer(uint256 i) payable public{ - msg.sender.transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} - -contract TestConstract3 { - uint public i=4; - function testTransfer(uint256 i) payable public{ - msg.sender.transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/create2contractn.sol b/framework/src/test/resources/soliditycode_0.7.6/create2contractn.sol deleted file mode 100644 index e0e3ae64c16..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/create2contractn.sol +++ /dev/null @@ -1,29 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract TestConstract { - uint public i=1; - function testTransfer(uint256 i) payable public{ - msg.sender.transfer(i); - } - function testTransferToken(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/create2contractn2.sol b/framework/src/test/resources/soliditycode_0.7.6/create2contractn2.sol deleted file mode 100644 index 626988c4e04..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/create2contractn2.sol +++ /dev/null @@ -1,26 +0,0 @@ -contract Factory { - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract TestConstract { - uint public i=1; - function set() payable public { - i=5; - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/demo.sol b/framework/src/test/resources/soliditycode_0.7.6/demo.sol deleted file mode 100644 index 06bf15387fc..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/demo.sol +++ /dev/null @@ -1,73 +0,0 @@ - - - contract tokenTest{ - uint256 codesize; - constructor() payable public{ - uint256 m; - address addr = address(this); - assembly { - m := extcodesize(addr) - } - codesize = m; - } - - // positive case - function pulsone() public payable{ - uint256 j = 0; - uint i = 100; - for (; i < i; i++) { - j++; - } - } - - - function getCodeSize() public returns (uint256){ - return codesize; - } - - } - - contract confirmTest{ - - uint256 codesize; - constructor() payable public{ - uint256 m; - address addr = address(this); - assembly { - m := extcodesize(addr) - - } - codesize = m; - } - - function getCodeSize() public returns (uint256){ - return codesize; - } - - function confirm(address addr) public returns (uint256){ - uint256 j; - assembly { - j := extcodesize(addr) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - return j; - } - - function at(address _addr) public returns (bytes memory o_code) { - assembly { - // retrieve the size of the code, this needs assembly - let size := extcodesize(_addr) - // allocate output byte array - this could also be done without assembly - // by using o_code = new bytes(size) - o_code := mload(0x40) - // new "memory end" including padding - mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) - // store length in memory - mstore(o_code, size) - // actually retrieve the code, this needs assembly - extcodecopy(_addr, add(o_code, 0x20), 0, size) - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/enumAndStruct.sol b/framework/src/test/resources/soliditycode_0.7.6/enumAndStruct.sol deleted file mode 100644 index 836a4ac850e..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/enumAndStruct.sol +++ /dev/null @@ -1,43 +0,0 @@ - - -struct S_out { -uint x; -} - -enum ErrorType { -Revert_Error, //0 -RevertWithMsg_Error, //1 -Require_Error, //2 -RequirewithMsg_Error, //3 -Assert_Error, //4 -Tansfer_Error, //5 -Send_Error, //6 -Math_Error, //7 -ArrayOverFlow_Error //8 -} - -contract enumAndStructTest { - -struct S_inner { -int x; -} - -enum ErrorType_inner { -Revert_Error, //0 -RevertWithMsg_Error, //1 -Require_Error, //2 -RequirewithMsg_Error, //3 -Assert_Error, //4 -Tansfer_Error, //5 -Send_Error, //6 -Math_Error, //7 -ArrayOverFlow_Error //8 -} - -function getvalue() public returns(uint) { - require(ErrorType.Require_Error == ErrorType(2)); - S_out memory s = S_out(1); - return s.x; -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/event001.sol b/framework/src/test/resources/soliditycode_0.7.6/event001.sol deleted file mode 100644 index 7662df3a5c6..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/event001.sol +++ /dev/null @@ -1,10 +0,0 @@ -contract Event { - event xixi(uint256 id) ; - event log2(uint256,uint256,uint256); - constructor() public payable{} - function messageI() payable public returns (uint ret) { - //emit log2(1,2,3); - emit xixi(1); - return 1; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/event002.sol b/framework/src/test/resources/soliditycode_0.7.6/event002.sol deleted file mode 100644 index a61f834e1b5..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/event002.sol +++ /dev/null @@ -1,52 +0,0 @@ - - -contract Event { - - event _0(); - event a_0() anonymous; - event a_4i(uint256 indexed x1, uint256 indexed x2 , uint256 indexed x3, uint256 indexed x4, uint256 x5)anonymous ; - event _3i(uint256 x1, uint256 indexed x2 , uint256 indexed x3, uint256 x4, uint256 x5) ; - event _1i(uint256 indexed x1, uint256, uint256 indexed, uint256 x4) ; - event a_1i(uint256) anonymous; - event _ai(uint8[2], uint8) ; - event a_ai(uint8[2], uint8) anonymous; - event _a1i(uint8[2] indexed, uint8) ; - event a_a1i(uint8[2] indexed, uint8) anonymous; - - constructor () public { - // emit a_0(); - // emit a_1i(123); - // emit a_4i(1,2,3,5,16); - // emit _0(); - emit _3i(1,2,3,5,16); - // emit _1i(1,2,3,5); - // emit _ai([1,2], 3); - // emit a_ai([3,4], 5); - // emit _a1i([1,2], 3); - // emit a_a1i([3,4], 5); - } - - function e() public { - emit _1i(1,2,3,4); - } - - function l() public { - emit a_1i(1); - } - - function k() public{ - emit a_4i(2,3,4,5,17); - emit _3i(2,3,4,5,16); - emit _1i(2,3,4,5); - emit a_1i(128); - emit _0(); - emit a_0(); - //selfdestruct(msg.sender); - //emit a_4i(1,2,3,5,16); - //emit _3i(1,2,3,5,16); - //emit _1i(1,2,3,5); - //emit a_1i(123); - //emit _0(); - //emit a_0(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/extCodeHash.sol b/framework/src/test/resources/soliditycode_0.7.6/extCodeHash.sol deleted file mode 100644 index d6209770682..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/extCodeHash.sol +++ /dev/null @@ -1,13 +0,0 @@ -contract TestExtCodeHash { - - function getCodeHashByAddr(address _addr) public returns (bytes32 _hash) { - assembly { - _hash := extcodehash(_addr) - } - } - function getCodeHashByUint(uint256 _addr) public returns (bytes32 _hash) { - assembly { - _hash := extcodehash(_addr) - } - } -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/extCodeHash11.sol b/framework/src/test/resources/soliditycode_0.7.6/extCodeHash11.sol deleted file mode 100644 index ad59f6cce1c..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/extCodeHash11.sol +++ /dev/null @@ -1,103 +0,0 @@ -contract Counter { -uint count = 0; -address payable owner; -event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); -constructor() public{ -owner = msg.sender; -} -function getCodeHashByAddr() public returns (bytes32 _hashBefore, bytes32 _hashAfter) { -address addr = address(this); -assembly { -_hashBefore := extcodehash(addr) -} -if (owner == msg.sender) { -selfdestruct(owner); -} -assembly { -_hashAfter := extcodehash(addr) -} -revert(); -emit LogResult(_hashBefore, _hashAfter); -} -} - -contract Counter1 { -uint count = 0; -address payable owner; -event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); -constructor() public{ -owner = msg.sender; -} -function getCodeHashByAddr() public returns (bytes32 _hashBefore, bytes32 _hashAfter) { -address addr = address(this); -assembly { -_hashBefore := extcodehash(addr) -} -if (owner == msg.sender) { -selfdestruct(owner); -} -assembly { -_hashAfter := extcodehash(addr) -} - -emit LogResult(_hashBefore, _hashAfter); -} -} - - -contract Counter2 { -uint count = 0; -address payable owner; -event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); -constructor() public{ -owner = msg.sender; -} -function getCodeHashByAddr(address c) public returns (bytes32 _hashBefore, bytes32 _hashAfter) { - TestConstract t=new TestConstract(); -address addr = address(t); -assembly { -_hashBefore := extcodehash(addr) -} - addr.call(abi.encodeWithSignature("testSuicideNonexistentTarget(address)",c)); - - -assembly { -_hashAfter := extcodehash(addr) -} - -emit LogResult(_hashBefore, _hashAfter); -} -} - - -contract Counter3 { -uint count = 0; -address payable owner; -event LogResult(bytes32 _hashBefore, bytes32 _hashAfter); -constructor() public{ -owner = msg.sender; -} -function getCodeHashByAddr(address c) public returns (bytes32 _hashBefore, bytes32 _hashAfter) { - TestConstract t=new TestConstract(); -address addr = address(t); -assembly { -_hashBefore := extcodehash(addr) -} -if (owner == msg.sender) { -selfdestruct(owner); -} - -assembly { -_hashAfter := extcodehash(addr) -} - -emit LogResult(_hashBefore, _hashAfter); -} -} - -contract TestConstract { - uint public i=1; - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/extCodeHashConstruct.sol b/framework/src/test/resources/soliditycode_0.7.6/extCodeHashConstruct.sol deleted file mode 100644 index 6bb91b3d3b1..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/extCodeHashConstruct.sol +++ /dev/null @@ -1,14 +0,0 @@ -contract CounterConstruct { - uint count = 0; - address payable owner; - event LogResult(bytes32 _hashBefore); - constructor() public{ - owner = msg.sender; - address addr = address(this); - bytes32 _hashBefore; - assembly { - _hashBefore := extcodehash(addr) - } - emit LogResult(_hashBefore); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/extCodeHashStress.sol b/framework/src/test/resources/soliditycode_0.7.6/extCodeHashStress.sol deleted file mode 100644 index cf41f3c8106..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/extCodeHashStress.sol +++ /dev/null @@ -1,45 +0,0 @@ -contract Trigger { - function test(address addr) public returns(uint i) { - bytes32 hash; - while (gasleft() > 1000) { - assembly { - hash := extcodehash(addr) - } - i++; - } - } - - function test(address[] memory addrs) public returns(uint i) { - bytes32 hash; - uint i = 0; - for (; i < addrs.length; i++) { - address addr = addrs[i]; - assembly { - hash := extcodehash(addr) - } - } - return i; - } - } - - - - contract TriggerNormal { - function test(address addr) public returns(uint i) { - i = 0; - while (gasleft() > 100000) { - i++; - } - } - } - - contract TriggerNormal1 { - function test(address[] memory addrs) public returns(uint i) { - bytes32 hash; - uint i = 0; - for (; i < addrs.length; i++) { - address addr = addrs[i]; - addr.balance; - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/extCodeHashTestNoPayable.sol b/framework/src/test/resources/soliditycode_0.7.6/extCodeHashTestNoPayable.sol deleted file mode 100644 index c3a2ad8c6ae..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/extCodeHashTestNoPayable.sol +++ /dev/null @@ -1,8 +0,0 @@ -contract testConstantContract{ -uint256 public i; -function testNoPayable() public returns (uint256 z) { -i=1; -z=i; -return z; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/fallbackUpgrade.sol b/framework/src/test/resources/soliditycode_0.7.6/fallbackUpgrade.sol deleted file mode 100644 index 6751858c65e..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/fallbackUpgrade.sol +++ /dev/null @@ -1,83 +0,0 @@ -contract Test0{ - event FuncCalled(bytes data,uint a); -} - -contract Test1 { - - event FuncCalled(string a); - fallback() external { - x = "fallback"; - emit FuncCalled(x); - } - string x; -} -//含有payable的fallback,无receice -contract Test2 { - - event FuncCalled(string data); - fallback() external payable{ - x = "fallback"; - emit FuncCalled(x); - } - string x; -} - -contract TestPayable { - event FuncCalled(string a); - - fallback() external payable { - x = "fallback"; - emit FuncCalled(x); - } - - receive() external payable { - x = "receive"; - emit FuncCalled(x); - } - string x; -} - -contract Caller { - function callTest0(Test0 test) public{ - (bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()")); - require(success); - } - function callTest1(address test) public returns (bool) { - (bool success,) = test.call(abi.encodeWithSignature("nonExistingFunction()")); - require(success); - (success,) = address(test).call(""); - require(success); - return true; - } - function callTest2(address test) public payable returns (bool) { - (bool success,) = test.call{value:1000}(abi.encodeWithSignature("nonExistingFunction()")); - require(success); - return true; - } - function callTestPayable1(TestPayable test) public payable returns (bool) { - (bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()")); - require(success); - (success,) = address(test).call(""); - require(success); - return true; - } -} - - -//contract Test0 { -// event FallbackCall(string data,bytes msg); -// //event FuncCalled(string a,bytes data); -// function() external payable{ -// x = "fallback"; -// emit FallbackCall(x,msg.data); -// } -// string x; -//} -//contract Caller{ -// function call(Test0 test) public payable returns(bool){ -// (bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()")); -// require(success); -// return true; -// } -//} - diff --git a/framework/src/test/resources/soliditycode_0.7.6/freezeContract001.sol b/framework/src/test/resources/soliditycode_0.7.6/freezeContract001.sol deleted file mode 100644 index 0ad8ed9f460..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/freezeContract001.sol +++ /dev/null @@ -1,63 +0,0 @@ - -contract TestFreeze { - constructor() public payable {} - - function freeze(address payable receiver, uint amount, uint res) external payable{ - receiver.freeze(amount, res); - } - - function unfreeze(address payable receiver, uint res) external { - receiver.unfreeze(res); - } - - function destroy(address payable inheritor) external { - selfdestruct(inheritor); - } - - function send(address payable A) external { - A.transfer(10); - } - - function send(address payable A, uint256 value) external { - A.transfer(value); - } - - function getExpireTime(address payable target, uint res) external view returns(uint) { - return target.freezeExpireTime(res); - } - - function deploy(uint256 salt) public returns(address){ - address addr; - bytes memory code = type(C).creationCode; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } - - function freezeAndSend(address payable receiver, uint amount, uint res) external { - receiver.transfer(amount); - receiver.freeze(amount, res); - } - - -} - - -contract C { - constructor() public payable {} - - function destroy(address payable inheritor) external { - selfdestruct(inheritor); - } -} - -contract D { - constructor() public payable { - msg.sender.freeze(msg.value, 1); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/getAddressChange.sol b/framework/src/test/resources/soliditycode_0.7.6/getAddressChange.sol deleted file mode 100644 index 2796da68770..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/getAddressChange.sol +++ /dev/null @@ -1,12 +0,0 @@ -contract getAddressChange { - constructor() public payable {} - // testaddress1函数新增了一个address属性。0.6.0之前 external函数可以通过address(x)来转化为地址,6.0将其禁止,可以通过函数address属性直接获取 - function testaddress1() public view returns(address) { - //return address(this.getamount); //0.6.0之前可以使用 - return this.getamount.address; //0.6.0 - - } - function getamount(address) external view returns(uint256) { - return address(this).balance; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/isSRCandidate.sol b/framework/src/test/resources/soliditycode_0.7.6/isSRCandidate.sol deleted file mode 100644 index e8e9b692dec..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/isSRCandidate.sol +++ /dev/null @@ -1,35 +0,0 @@ - - - -contract ContractB{ - address others; -} - -contract TestIsSRCandidate{ - - ContractB contractB = new ContractB(); - - function isSRCandidateTest(address addr) public view returns (bool) { - return address(addr).isSRCandidate; - } - - function zeroAddressTest() public view returns (bool) { - return address(0x0).isSRCandidate; - } - - function localContractAddrTest() public view returns (bool) { - return address(this).isSRCandidate; - } - - function otherContractAddrTest() public view returns (bool) { - return address(contractB).isSRCandidate; - } - - function nonpayableAddrTest(address addr) public view returns (bool) { - return addr.isSRCandidate; - } - - function payableAddrTest(address payable addr) public returns (bool) { - return addr.isSRCandidate; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/mappingGetter.sol b/framework/src/test/resources/soliditycode_0.7.6/mappingGetter.sol deleted file mode 100644 index dbd473717cb..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/mappingGetter.sol +++ /dev/null @@ -1,4 +0,0 @@ -contract mappingGetter { - mapping(bytes => uint256) public balances1; - mapping(string => uint256) public balances2; -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/multiValiSignPerformance01.sol b/framework/src/test/resources/soliditycode_0.7.6/multiValiSignPerformance01.sol deleted file mode 100644 index 74baa963366..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/multiValiSignPerformance01.sol +++ /dev/null @@ -1,37 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract ecrecoverValidateSign { - - using ECVerify for bytes32; - - function validateSign(bytes32 hash,bytes[] memory sig,address[] memory signer) public returns (bool) { - for(uint256 i=0;i=0.5.0 <0.7.0; - -contract A { - uint public x; - function setValue(uint _x) public { - x = _x; - } -} -contract B is A {} -contract C is A {} -// No explicit override required -contract D is B, C {} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/override003.sol b/framework/src/test/resources/soliditycode_0.7.6/override003.sol deleted file mode 100644 index 0ca6a2663d1..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/override003.sol +++ /dev/null @@ -1,20 +0,0 @@ -//pragma solidity ^0.6.0; -contract A { - uint public x; - function setValue(uint _x) public virtual { - x = _x; - } -} - -contract B { - uint public y; - function setValue(uint _y) public virtual { - y = _y; - } -} - -contract C is A, B { - function setValue(uint _x) public override(B,A) { - A.setValue(_x); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/override004.sol b/framework/src/test/resources/soliditycode_0.7.6/override004.sol deleted file mode 100644 index d0cf20525d5..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/override004.sol +++ /dev/null @@ -1,25 +0,0 @@ -//pragma solidity >=0.5.0 <0.7.0; - -contract A { - uint public x = 4; - function setValue(uint _x) public notZero { - x = _x; - } - modifier notZero() virtual { - require(x >= 5,"x must >= 5"); - _; - } -} - -contract B is A { - function setValue2(uint _x) public { - x = _x; - } -} - -contract C is A,B { - modifier notZero override { - require(x >= 6,"x must >= 6"); - _; - } -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/override005.sol b/framework/src/test/resources/soliditycode_0.7.6/override005.sol deleted file mode 100644 index 0ea485ae0a2..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/override005.sol +++ /dev/null @@ -1,39 +0,0 @@ -pragma solidity >= 0.6.0; - -contract Base { - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices public choice2 = ActionChoices.GoRight; - - function stopped() virtual external view returns (bool) { - return true; - } - function i() virtual external view returns (int) { - return 32482980; - } - function i2() virtual external view returns (int) { - return -32482980; - } - function ui() virtual external view returns (uint) { - return 23487820; - } - function origin() virtual external view returns (address) { - return 0x3b0E4a6EdEE231CE0c3433F00F1bbc5FeD409c0B; - } - function b32() virtual external view returns (bytes32) { - return 0xb55a21aaee0ce8f1c8ffaa0dbd23105cb55a21aaee0ce8f1c8ffaa0dbd231050; - } - function choice() virtual external returns (ActionChoices) { - return choice2; - } -} - -contract Test is Base { - - bool override public stopped = false; - int override public i = 32482989; - int override public i2 = -32482989; - uint override public ui = 23487823; - address override public origin = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF; - bytes32 override public b32 = 0xb55a21aaee0ce8f1c8ffaa0dbd23105cb55a21aaee0ce8f1c8ffaa0dbd23105c; - ActionChoices override public choice = ActionChoices.SitStill; -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/overridePrivateFunction.sol b/framework/src/test/resources/soliditycode_0.7.6/overridePrivateFunction.sol deleted file mode 100644 index b0b4d679620..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/overridePrivateFunction.sol +++ /dev/null @@ -1,22 +0,0 @@ -pragma solidity ^0.5.17; - -contract A { - - function test() private pure returns(uint) { - return 1; - } - -} - -contract B is A { - - function basic() private pure returns(uint) { - return 2; - } - function testOverridePrivate() external payable returns(uint) { - return basic(); - } - - constructor() public payable {} -} - diff --git a/framework/src/test/resources/soliditycode_0.7.6/payable001.sol b/framework/src/test/resources/soliditycode_0.7.6/payable001.sol deleted file mode 100644 index 4fe7b20921f..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/payable001.sol +++ /dev/null @@ -1,31 +0,0 @@ - - - -contract A { - constructor() public payable{ - } - - fallback() external payable { - } -} - -contract PayableTest { - -address payable a1; -function receiveMoneyTransfer(address a, uint256 _x) public { -a1 = payable(a); -a1.transfer(_x); -} - -function receiveMoneySend(address a, uint256 x) public { -address payable a2 = payable(a); -a2.send(x); -} - -function receiveMoneyTransferWithContract(A PayableTest, uint256 x) public { -payable(address(PayableTest)).transfer(x); -} - -constructor() public payable{ -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/pedersenHash001.sol b/framework/src/test/resources/soliditycode_0.7.6/pedersenHash001.sol deleted file mode 100644 index 6cad7cb9855..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/pedersenHash001.sol +++ /dev/null @@ -1,18 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract pedersenHashTest { - - function test1() public returns (bool, bytes memory){ - bytes memory empty = ""; - return address(0x1000004).delegatecall(empty); - } - - function test2(bytes memory data) public returns (bool, bytes memory){ - return address(0x1000004).delegatecall(data); - } - - function test3(uint32 hash, bytes32 left, bytes32 right) public returns (bytes32){ - return pedersenHash(hash, left, right); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/pedersenHash002.sol b/framework/src/test/resources/soliditycode_0.7.6/pedersenHash002.sol deleted file mode 100644 index b0a78973ef2..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/pedersenHash002.sol +++ /dev/null @@ -1,320 +0,0 @@ -pragma experimental ABIEncoderV2; - -import "./SafeMath.sol"; - -abstract contract TokenTRC20 { - function transfer(address _to, uint256 _value) public virtual returns (bool success); - - function transferFrom(address _from, address _to, uint256 _value) public virtual returns (bool success); -} - -contract ShieldedTRC20 { - using SafeMath for uint256; - - uint256 public scalingFactor; // used when decimals of TRC20 token is too large. - uint256 public leafCount; - uint256 constant INT64_MAX = 2 ** 63 - 1; - bytes32 public latestRoot; - mapping(bytes32 => bytes32) public nullifiers; // store nullifiers of spent commitments - mapping(bytes32 => bytes32) public roots; // store history root - mapping(uint256 => bytes32) public tree; - mapping(bytes32 => bytes32) public noteCommitment; - bytes32[33] frontier; - bytes32[32] zeroes = [bytes32(0x0100000000000000000000000000000000000000000000000000000000000000), bytes32(0x817de36ab2d57feb077634bca77819c8e0bd298c04f6fed0e6a83cc1356ca155), bytes32(0xffe9fc03f18b176c998806439ff0bb8ad193afdb27b2ccbc88856916dd804e34), bytes32(0xd8283386ef2ef07ebdbb4383c12a739a953a4d6e0d6fb1139a4036d693bfbb6c), bytes32(0xe110de65c907b9dea4ae0bd83a4b0a51bea175646a64c12b4c9f931b2cb31b49), bytes32(0x912d82b2c2bca231f71efcf61737fbf0a08befa0416215aeef53e8bb6d23390a), bytes32(0x8ac9cf9c391e3fd42891d27238a81a8a5c1d3a72b1bcbea8cf44a58ce7389613), bytes32(0xd6c639ac24b46bd19341c91b13fdcab31581ddaf7f1411336a271f3d0aa52813), bytes32(0x7b99abdc3730991cc9274727d7d82d28cb794edbc7034b4f0053ff7c4b680444), bytes32(0x43ff5457f13b926b61df552d4e402ee6dc1463f99a535f9a713439264d5b616b), bytes32(0xba49b659fbd0b7334211ea6a9d9df185c757e70aa81da562fb912b84f49bce72), bytes32(0x4777c8776a3b1e69b73a62fa701fa4f7a6282d9aee2c7a6b82e7937d7081c23c), bytes32(0xec677114c27206f5debc1c1ed66f95e2b1885da5b7be3d736b1de98579473048), bytes32(0x1b77dac4d24fb7258c3c528704c59430b630718bec486421837021cf75dab651), bytes32(0xbd74b25aacb92378a871bf27d225cfc26baca344a1ea35fdd94510f3d157082c), bytes32(0xd6acdedf95f608e09fa53fb43dcd0990475726c5131210c9e5caeab97f0e642f), bytes32(0x1ea6675f9551eeb9dfaaa9247bc9858270d3d3a4c5afa7177a984d5ed1be2451), bytes32(0x6edb16d01907b759977d7650dad7e3ec049af1a3d875380b697c862c9ec5d51c), bytes32(0xcd1c8dbf6e3acc7a80439bc4962cf25b9dce7c896f3a5bd70803fc5a0e33cf00), bytes32(0x6aca8448d8263e547d5ff2950e2ed3839e998d31cbc6ac9fd57bc6002b159216), bytes32(0x8d5fa43e5a10d11605ac7430ba1f5d81fb1b68d29a640405767749e841527673), bytes32(0x08eeab0c13abd6069e6310197bf80f9c1ea6de78fd19cbae24d4a520e6cf3023), bytes32(0x0769557bc682b1bf308646fd0b22e648e8b9e98f57e29f5af40f6edb833e2c49), bytes32(0x4c6937d78f42685f84b43ad3b7b00f81285662f85c6a68ef11d62ad1a3ee0850), bytes32(0xfee0e52802cb0c46b1eb4d376c62697f4759f6c8917fa352571202fd778fd712), bytes32(0x16d6252968971a83da8521d65382e61f0176646d771c91528e3276ee45383e4a), bytes32(0xd2e1642c9a462229289e5b0e3b7f9008e0301cbb93385ee0e21da2545073cb58), bytes32(0xa5122c08ff9c161d9ca6fc462073396c7d7d38e8ee48cdb3bea7e2230134ed6a), bytes32(0x28e7b841dcbc47cceb69d7cb8d94245fb7cb2ba3a7a6bc18f13f945f7dbd6e2a), bytes32(0xe1f34b034d4a3cd28557e2907ebf990c918f64ecb50a94f01d6fda5ca5c7ef72), bytes32(0x12935f14b676509b81eb49ef25f39269ed72309238b4c145803544b646dca62d), bytes32(0xb2eed031d4d6a4f02a097f80b54cc1541d4163c6b6f5971f88b6e41d35c53814)]; - address owner; - TokenTRC20 trc20Token; - - event MintNewLeaf(uint256 position, bytes32 cm, bytes32 cv, bytes32 epk, bytes32[21] c); - event TransferNewLeaf(uint256 position, bytes32 cm, bytes32 cv, bytes32 epk, bytes32[21] c); - event BurnNewLeaf(uint256 position, bytes32 cm, bytes32 cv, bytes32 epk, bytes32[21] c); - event TokenMint(address from, uint256 value); - event TokenBurn(address to, uint256 value, bytes32[3] ciphertext); - event NoteSpent(bytes32 nf); - - constructor (address trc20ContractAddress, uint256 scalingFactorExponent) public { - require(scalingFactorExponent < 77, "The scalingFactorExponent is out of range!"); - scalingFactor = 10 ** scalingFactorExponent; - owner = msg.sender; - trc20Token = TokenTRC20(trc20ContractAddress); - } - // output: cm, cv, epk, proof - function mint(uint256 rawValue, bytes32[9] calldata output, bytes32[2] calldata bindingSignature, bytes32[21] calldata c) external { - address sender = msg.sender; - // transfer the trc20Token from the sender to this contract - bool transferResult = trc20Token.transferFrom(sender, address(this), rawValue); - require(transferResult, "TransferFrom failed!"); - - require(noteCommitment[output[0]] == 0, "Duplicate noteCommitments!"); - uint64 value = rawValueToValue(rawValue); - bytes32 signHash = sha256(abi.encodePacked(address(this), value, output, c)); - (bytes32[] memory ret) = verifyMintProof(output, bindingSignature, value, signHash, frontier, leafCount); - uint256 result = uint256(ret[0]); - require(result == 1, "The proof and signature have not been verified by the contract!"); - - uint256 slot = uint256(ret[1]); - uint256 nodeIndex = leafCount + 2 ** 32 - 1; - tree[nodeIndex] = output[0]; - if (slot == 0) { - frontier[0] = output[0]; - } - for (uint256 i = 1; i < slot + 1; i++) { - nodeIndex = (nodeIndex - 1) / 2; - tree[nodeIndex] = ret[i + 1]; - if (i == slot) { - frontier[slot] = tree[nodeIndex]; - } - } - latestRoot = ret[slot + 2]; - roots[latestRoot] = latestRoot; - noteCommitment[output[0]] = output[0]; - leafCount ++; - - emit MintNewLeaf(leafCount - 1, output[0], output[1], output[2], c); - emit TokenMint(sender, rawValue); - } - //input: nf, anchor, cv, rk, proof - //output: cm, cv, epk, proof - function transfer(bytes32[10][] calldata input, bytes32[2][] calldata spendAuthoritySignature, bytes32[9][] calldata output, bytes32[2] calldata bindingSignature, bytes32[21][] calldata c) external { - require(input.length >= 1 && input.length <= 2, "Input number must be 1 or 2!"); - require(input.length == spendAuthoritySignature.length, "Input number must be equal to spendAuthoritySignature number!"); - require(output.length >= 1 && output.length <= 2, "Output number must be 1 or 2!"); - require(output.length == c.length, "Output number must be equal to c number!"); - - for (uint256 i = 0; i < input.length; i++) { - require(nullifiers[input[i][0]] == 0, "The note has already been spent!"); - require(roots[input[i][1]] != 0, "The anchor must exist!"); - } - for (uint256 i = 0; i < output.length; i++) { - require(noteCommitment[output[i][0]] == 0, "Duplicate noteCommitment!"); - } - - bytes32 signHash = sha256(abi.encodePacked(address(this), input, output, c)); - (bytes32[] memory ret) = verifyTransferProof(input, spendAuthoritySignature, output, bindingSignature, signHash, 0, frontier, leafCount); - uint256 result = uint256(ret[0]); - require(result == 1, "The proof and signature have not been verified by the contract!"); - - uint256 offset = 1; - //ret offset - for (uint256 i = 0; i < output.length; i++) { - uint256 slot = uint256(ret[offset++]); - uint256 nodeIndex = leafCount + 2 ** 32 - 1; - tree[nodeIndex] = output[i][0]; - if (slot == 0) { - frontier[0] = output[i][0]; - } - for (uint256 k = 1; k < slot + 1; k++) { - nodeIndex = (nodeIndex - 1) / 2; - tree[nodeIndex] = ret[offset++]; - if (k == slot) { - frontier[slot] = tree[nodeIndex]; - } - } - leafCount++; - } - latestRoot = ret[offset]; - roots[latestRoot] = latestRoot; - for (uint256 i = 0; i < input.length; i++) { - bytes32 nf = input[i][0]; - nullifiers[nf] = nf; - emit NoteSpent(nf); - } - for (uint256 i = 0; i < output.length; i++) { - noteCommitment[output[i][0]] = output[i][0]; - emit TransferNewLeaf(leafCount - (output.length - i), output[i][0], output[i][1], output[i][2], c[i]); - } - } - //input: nf, anchor, cv, rk, proof - //output: cm, cv, epk, proof - function burn(bytes32[10] calldata input, bytes32[2] calldata spendAuthoritySignature, uint256 rawValue, bytes32[2] calldata bindingSignature, address payTo, bytes32[3] calldata burnCipher, bytes32[9][] calldata output, bytes32[21][] calldata c) external { - uint64 value = rawValueToValue(rawValue); - bytes32 signHash = sha256(abi.encodePacked(address(this), input, output, c, payTo, value)); - - bytes32 nf = input[0]; - bytes32 anchor = input[1]; - require(nullifiers[nf] == 0, "The note has already been spent!"); - require(roots[anchor] != 0, "The anchor must exist!"); - - require(output.length <= 1, "Output number cannot exceed 1!"); - require(output.length == c.length, "Output number must be equal to length of c!"); - - // bytes32 signHash = sha256(abi.encodePacked(address(this), input, payTo, value, output, c)); - if (output.length == 0) { - (bool result) = verifyBurnProof(input, spendAuthoritySignature, value, bindingSignature, signHash); - require(result, "The proof and signature have not been verified by the contract!"); - } else { - transferInBurn(input, spendAuthoritySignature, value, bindingSignature, signHash, output, c); - } - - nullifiers[nf] = nf; - emit NoteSpent(nf); - //Finally, transfer trc20Token from this contract to the nominated address - bool transferResult = trc20Token.transfer(payTo, rawValue); - require(transferResult, "Transfer failed!"); - - emit TokenBurn(payTo, rawValue, burnCipher); - } - - function transferInBurn(bytes32[10] memory input, bytes32[2] memory spendAuthoritySignature, uint64 value, bytes32[2] memory bindingSignature, bytes32 signHash, bytes32[9][] memory output, bytes32[21][] memory c) private { - bytes32 cm = output[0][0]; - require(noteCommitment[cm] == 0, "Duplicate noteCommitment!"); - bytes32[10][] memory inputs = new bytes32[10][](1); - inputs[0] = input; - bytes32[2][] memory spendAuthoritySignatures = new bytes32[2][](1); - spendAuthoritySignatures[0] = spendAuthoritySignature; - (bytes32[] memory ret) = verifyTransferProof(inputs, spendAuthoritySignatures, output, bindingSignature, signHash, value, frontier, leafCount); - uint256 result = uint256(ret[0]); - require(result == 1, "The proof and signature have not been verified by the contract!"); - - uint256 slot = uint256(ret[1]); - uint256 nodeIndex = leafCount + 2 ** 32 - 1; - tree[nodeIndex] = cm; - if (slot == 0) { - frontier[0] = cm; - } - for (uint256 i = 1; i < slot + 1; i++) { - nodeIndex = (nodeIndex - 1) / 2; - tree[nodeIndex] = ret[i + 1]; - if (i == slot) { - frontier[slot] = tree[nodeIndex]; - } - } - latestRoot = ret[slot + 2]; - roots[latestRoot] = latestRoot; - noteCommitment[cm] = cm; - leafCount ++; - - emit BurnNewLeaf(leafCount - 1, cm, output[0][1], output[0][2], c[0]); - } - - //position: index of leafnode, start from 0 - function getPath(uint256 position) public view returns (bytes32, bytes32[32] memory) { - require(position >= 0, "Position should be non-negative!"); - require(position < leafCount, "Position should be smaller than leafCount!"); - uint256 index = position + 2 ** 32 - 1; - bytes32[32] memory path; - uint32 level = ancestorLevel(position); - bytes32 targetNodeValue = getTargetNodeValue(position, level); - for (uint32 i = 0; i < 32; i++) { - if (i == level) { - path[31 - i] = targetNodeValue; - } else { - if (index % 2 == 0) { - path[31 - i] = tree[index - 1]; - } else { - path[31 - i] = tree[index + 1] == 0 ? zeroes[i] : tree[index + 1]; - } - } - index = (index - 1) / 2; - } - return (latestRoot, path); - } - - //position: index of leafnode, start from 0 - function getPathByValueIsZero(uint256 position) public view returns (bytes32, bytes32[32] memory) { - require(position >= 0, "Position should be non-negative!"); - require(position < leafCount, "Position should be smaller than leafCount!"); - uint256 index = position + 2 ** 32 - 1; - bytes32[32] memory path; - uint32 level = ancestorLevel(position); - bytes32 targetNodeValue = getTargetNodeValueByValueIsZero(position, level); - for (uint32 i = 0; i < 32; i++) { - if (i == level) { - path[31 - i] = targetNodeValue; - } else { - if (index % 2 == 0) { - path[31 - i] = tree[index - 1]; - } else { - path[31 - i] = tree[index + 1] == 0 ? zeroes[i] : tree[index + 1]; - } - } - index = (index - 1) / 2; - } - return (latestRoot, path); - } - - function ancestorLevel(uint256 leafIndex) private view returns (uint32) { - uint256 nodeIndex1 = leafIndex + 2 ** 32 - 1; - uint256 nodeIndex2 = leafCount + 2 ** 32 - 2; - uint32 level = 0; - while (((nodeIndex1 - 1) / 2) != ((nodeIndex2 - 1) / 2)) { - nodeIndex1 = (nodeIndex1 - 1) / 2; - nodeIndex2 = (nodeIndex2 - 1) / 2; - level = level + 1; - } - return level; - } - - function getTargetNodeValue(uint256 leafIndex, uint32 level) private view returns (bytes32) { - bytes32 left; - bytes32 right; - uint256 index = leafIndex + 2 ** 32 - 1; - uint256 nodeIndex = leafCount + 2 ** 32 - 2; - bytes32 nodeValue = tree[nodeIndex]; - if (level == 0) { - if (index < nodeIndex) { - return nodeValue; - } - if (index == nodeIndex) { - if (index % 2 == 0) { - return tree[index - 1]; - } else { - return zeroes[0]; - } - } - } - for (uint32 i = 0; i < level; i++) { - if (nodeIndex % 2 == 0) { - left = tree[nodeIndex - 1]; - right = nodeValue; - } else { - left = nodeValue; - right = zeroes[i]; - } - nodeValue = pedersenHash(i, left, right); - nodeIndex = (nodeIndex - 1) / 2; - } - return nodeValue; - } - - function getTargetNodeValueByValueIsZero(uint256 leafIndex, uint32 level) private view returns (bytes32) { - bytes32 left; - bytes32 right; - uint256 index = leafIndex + 2 ** 32 - 1; - uint256 nodeIndex = leafCount + 2 ** 32 - 2; - bytes32 nodeValue = tree[nodeIndex]; - if (level == 0) { - if (index < nodeIndex) { - return nodeValue; - } - if (index == nodeIndex) { - if (index % 2 == 0) { - return tree[index - 1]; - } else { - return zeroes[0]; - } - } - } - for (uint32 i = 0; i < level; i++) { - if (nodeIndex % 2 == 0) { - left = tree[nodeIndex - 1]; - right = nodeValue; - } else { - left = nodeValue; - right = zeroes[i]; - } - left = bytes32(0x0); - right = bytes32(0x0); - nodeValue = pedersenHash(i, left, right); - nodeIndex = (nodeIndex - 1) / 2; - } - return nodeValue; - } - - function rawValueToValue(uint256 rawValue) private view returns (uint64) { - require(rawValue > 0, "Value must be positive!"); - require(rawValue.mod(scalingFactor) == 0, "Value must be integer multiples of scalingFactor!"); - uint256 value = rawValue.div(scalingFactor); - require(value < INT64_MAX); - return uint64(value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest1TestRequireContract.sol b/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest1TestRequireContract.sol deleted file mode 100644 index 16d01911d35..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest1TestRequireContract.sol +++ /dev/null @@ -1,15 +0,0 @@ - -contract TestThrowsContract{ - function testAssert() public { - assert(1==2); - } - function testRequire() public { - require(2==1); - } - function testRevert() public { - revert(); - } - //function testThrow(){ - // throw; - //} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest2TestThrowsContract.sol b/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest2TestThrowsContract.sol deleted file mode 100644 index 1ff73ad6460..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest2TestThrowsContract.sol +++ /dev/null @@ -1,15 +0,0 @@ - -contract TestThrowsContract{ - function testAssert() public { - assert(1==2); - } - function testRequire() public { - require(2==1); - } - function testRevert() public { - revert(); - } - // function testThrow() public { - // throw; - //} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest3TestRevertContract.sol b/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest3TestRevertContract.sol deleted file mode 100644 index b42a8c3fb23..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest3TestRevertContract.sol +++ /dev/null @@ -1,15 +0,0 @@ - -contract TestThrowsContract{ - function testAssert() public { - assert(1==2); - } - function testRequire() public { - require(2==1); - } - function testRevert() public { - revert(); - } - // function testThrow(){ - // throw; - // } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest4noPayableContract.sol b/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest4noPayableContract.sol deleted file mode 100644 index 35f89631e7d..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest4noPayableContract.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract noPayableContract { - -function noPayable() public payable returns (uint){ -return msg.value; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest4noPayableContract_1.sol b/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest4noPayableContract_1.sol deleted file mode 100644 index 5b6dd509f6f..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest4noPayableContract_1.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract noPayableContract { - -function noPayable() public returns (uint){ -return msg.value; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest5noPayableConstructor.sol b/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest5noPayableConstructor.sol deleted file mode 100644 index 097594ab7c9..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest5noPayableConstructor.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract MyContract { - uint money; - - //function MyContract(uint _money) { - constructor(uint _money) public payable{ - require(msg.value >= _money); - money = _money; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest5noPayableConstructor_1.sol b/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest5noPayableConstructor_1.sol deleted file mode 100644 index 5008ec5c9bf..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest5noPayableConstructor_1.sol +++ /dev/null @@ -1,11 +0,0 @@ - - -contract MyContract { - uint money; - - //function MyContract(uint _money) { - constructor(uint _money) public { - require(msg.value >= _money); - money = _money; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest6transferTestContract.sol b/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest6transferTestContract.sol deleted file mode 100644 index 4f171aebb9a..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest6transferTestContract.sol +++ /dev/null @@ -1,8 +0,0 @@ - - -contract transferTestContract { - function tranferTest(address payable addr) public payable{ - addr.transfer(10); - - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest7payableFallbakContract.sol b/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest7payableFallbakContract.sol deleted file mode 100644 index 534726cb1b4..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest7payableFallbakContract.sol +++ /dev/null @@ -1,14 +0,0 @@ - - -contract Test { - fallback() external { x = 1; } - uint x; -} - - -contract Caller { - function callTest(Test test) public { - //test.call(0xabcdef01); // hash does not exist - address(test).call(abi.encode(0xabcdef01)); // hash does not exist - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest8newContractGasNoenough.sol b/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest8newContractGasNoenough.sol deleted file mode 100644 index b8743e8231a..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest8newContractGasNoenough.sol +++ /dev/null @@ -1,19 +0,0 @@ - - -contract Account{ - uint256 public accId; - - // function Account(uint accountId) payable{ - constructor(uint accountId) payable public { - accId = accountId; - } -} - -contract Initialize{ - // Account public account = new Account(10); - - function newAccount() public { - Account account = new Account(1); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest9MessageUsedErrorFeed.sol b/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest9MessageUsedErrorFeed.sol deleted file mode 100644 index 18142d20ee8..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontest9MessageUsedErrorFeed.sol +++ /dev/null @@ -1,18 +0,0 @@ - - -contract MathedFeed { - - function divideMathed() public returns (uint ret) { - uint x=1; - uint y=0; - return x/y; - } -} - - -contract MathedUseContract { - - function MathedUse(address addr) public returns (uint) { - return MathedFeed(addr).divideMathed(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontestFunctionUsedErrorFeed.sol b/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontestFunctionUsedErrorFeed.sol deleted file mode 100644 index 64243dffd7c..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/requireExceptiontestFunctionUsedErrorFeed.sol +++ /dev/null @@ -1,17 +0,0 @@ - - -contract MessageFeed { - - function mValue() payable public returns (uint ret) { - return msg.value; - } -} - -contract MessageUseContract { - function inputValue() payable public returns (uint){ - return msg.value; - } - function messageUse(address addr) payable public returns (uint) { - return MessageFeed(addr).mValue{value:1}(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/selector.sol b/framework/src/test/resources/soliditycode_0.7.6/selector.sol deleted file mode 100644 index 5805a6e8d22..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/selector.sol +++ /dev/null @@ -1,21 +0,0 @@ - - -library A { - function getBalance(address) public view returns (uint256) { - return address(this).balance; - } - - function getamount(address) external view returns (uint256) { - return address(this).balance; - } -} - -contract testSelector { - using A for address; - - - function getselector2() public view returns (bytes4, bytes4) { - return (A.getBalance.selector, A.getamount.selector); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/slotAndOffsetNewGrammer.sol b/framework/src/test/resources/soliditycode_0.7.6/slotAndOffsetNewGrammer.sol deleted file mode 100644 index b4c2b0ed516..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/slotAndOffsetNewGrammer.sol +++ /dev/null @@ -1,32 +0,0 @@ -contract A { - uint b; - uint a; - uint c; - uint d; - uint e; - - function getA() external returns(uint,uint) { - uint slot; - uint offset; - assembly { -// old grammer -// slot := a_slot -// offset := a_offset - slot := a.slot - offset := a.offset - } - return (slot, offset); - } - - function getE() external returns(uint,uint) { - uint slot; - uint offset; - assembly { -// slot := e_slot -// offset := e_offset - slot := e.slot - offset := e.offset - } - return (slot, offset); - } -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/stackContract001.sol b/framework/src/test/resources/soliditycode_0.7.6/stackContract001.sol deleted file mode 100644 index c2e8f2f7611..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/stackContract001.sol +++ /dev/null @@ -1,61 +0,0 @@ - - -contract A{ - event log(uint256); - constructor() payable public{ - emit log(withdrawreward()); - emit log(address(this).rewardbalance); - } - function withdrawRewardTest() public returns (uint256){ - return withdrawreward(); - } - - function test() public{ - emit log(123); - } -} - -contract B{ - event log(uint256); - constructor() payable public{ - emit log(withdrawreward()); - emit log(address(this).rewardbalance); - } - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } - function rewardBalance(address addr) public view returns (uint256){ - return addr.rewardbalance; - } - - function nullAddressTest() public view returns (uint256) { - return address(0x0).rewardbalance; - } - - function localContractAddrTest() public view returns (uint256) { - address payable localContract = address(uint160(address(this))); - return localContract.rewardbalance; - } - - function withdrawRewardTest() public returns (uint256){ - return withdrawreward(); - } - - function contractBWithdrawRewardTest(address contractB) public returns (uint) { - return B(contractB).withdrawRewardTest(); - } - - function createA() public returns (address){ - return address(new A()); - } - - function callA(address Addr) public{ - A(Addr).test(); - } -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/stackSuicide001.sol b/framework/src/test/resources/soliditycode_0.7.6/stackSuicide001.sol deleted file mode 100644 index d1fc520ddb2..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/stackSuicide001.sol +++ /dev/null @@ -1,84 +0,0 @@ - -contract testStakeSuicide{ - B b; - constructor() payable public{} - function deployB() payable public returns (B addrB){ - b = (new B).value(1000000000)(); - return b; - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } - function SelfdestructTest2(address sr, uint256 amount, address payable target) public{ - stake(sr, amount); - selfdestruct(target); - } - function Stake(address sr, uint256 amount) public payable returns (bool result){ - return stake(sr, amount); - } - function Stake2(address sr, uint256 amount) public returns (bool result){ - stake(sr, amount); - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function UnStake2() public returns (bool result){ - unstake(); - return unstake(); - } - function WithdrawReward() public { - withdrawreward(); - } - function RewardBalance(address addr) view public returns (uint256 balance) { - return addr.rewardbalance; - } - function revertTest1(address sr, uint256 amount, address payable transferAddr) public{ - transferAddr.transfer(1000000); - stake(sr, amount); - transferAddr.transfer(2000000); - stake(sr, 1000000000000000);//stake more than balance to fail - transferAddr.transfer(4000000); - } - function revertTest2(address payable transferAddr) public{ - transferAddr.transfer(1000000); - unstake(); - transferAddr.transfer(2000000); - unstake();//unstake twice to fail - transferAddr.transfer(4000000); - } - - function BStake(address sr, uint256 amount) public returns (bool result){ - return b.Stake(sr, amount); - } - function BUnStake() public returns (bool result){ - return b.UnStake(); - } - function transfer(address payable add,uint256 num) public { - return add.transfer(num); - } -} - -contract B{ - constructor() payable public{} - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } - - function deploy(bytes memory code, uint256 salt) public returns(address) { - address addr; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - return addr; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/stateVariableShadowing.sol b/framework/src/test/resources/soliditycode_0.7.6/stateVariableShadowing.sol deleted file mode 100644 index a9109ee296c..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/stateVariableShadowing.sol +++ /dev/null @@ -1,21 +0,0 @@ -contract test { -// uint public x; -// function setValue1(uint _x) public returns (uint){ -// x = _x; -// return x; -// } - uint public y; - function setValue3(uint _x) public returns (uint){ - y = _x; - return y; - } -} - -contract stateVariableShadowing is test { - uint public x; - function setValue2(uint _x) public returns (uint){ - x = _x; - return x; - } -} - diff --git a/framework/src/test/resources/soliditycode_0.7.6/stringSplit.sol b/framework/src/test/resources/soliditycode_0.7.6/stringSplit.sol deleted file mode 100644 index 84231f2d1fe..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/stringSplit.sol +++ /dev/null @@ -1,45 +0,0 @@ - - -contract testStringSplit { -string s1 = "s""1""2"",./"; -string s2 = "s123?\\'."; -string s3 = hex"41"hex"42"; -string s4 = hex"4142"; - -function getS1() public view returns (string memory) { -return s1; -} - -function getS1N1() public pure returns (string memory) { -string memory n1 = "s""1""2"",./"; -return n1; -} - -function getS2() public view returns (string memory) { -return s2; -} - -function getS2N2() public pure returns (string memory) { -string memory n2 = "s123?\'."; -return n2; -} - -function getS3() public view returns (string memory) { -return s3; -} - -function getS3N3() public pure returns (string memory) { -string memory n3 = hex"41"hex"42"; -return n3; -} - -function getS4() public view returns (string memory) { -return s4; -} - -function getS4N4() public pure returns (string memory) { -string memory n4 = hex"4142"; -return n4; -} - -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/suicide001.sol b/framework/src/test/resources/soliditycode_0.7.6/suicide001.sol deleted file mode 100644 index 241a406d6a2..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/suicide001.sol +++ /dev/null @@ -1,32 +0,0 @@ -contract factory { - constructor() payable public { - } - - function create1() payable public returns (address){ - Caller add = (new Caller){value:0}(); - return address(add); - } - - function kill() payable public{ - selfdestruct(msg.sender); - } - - function create2(bytes memory code, uint256 salt) public returns(address){ - Caller addr; - Caller addr1; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - return address(addr); - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/suicide002.sol b/framework/src/test/resources/soliditycode_0.7.6/suicide002.sol deleted file mode 100644 index 160ab64f320..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/suicide002.sol +++ /dev/null @@ -1,43 +0,0 @@ -contract Factory { - uint256 public num; - event Deployed(address addr, uint256 salt, address sender); - constructor() public { - } - function deploy(bytes memory code, uint256 salt) public returns(address){ - TestConstract addr; - TestConstract addr1; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - - addr.testSuicideNonexistentTarget(msg.sender); - addr.set(); - - assembly { - addr1 := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(address(addr), salt, msg.sender); - return address(addr); - } -} - - - -contract TestConstract { - uint public i=1; - constructor () public { - } - - function set() public{ - i=9; - } - function testSuicideNonexistentTarget(address payable nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/testOutOfMem.sol b/framework/src/test/resources/soliditycode_0.7.6/testOutOfMem.sol deleted file mode 100644 index 8d285b28b7d..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/testOutOfMem.sol +++ /dev/null @@ -1,7 +0,0 @@ -contract Test { - function testOutOfMem(uint256 x) public returns(bytes32 r) { - uint[] memory memVar; - memVar = new uint[](x); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/testStakeSuicide.sol b/framework/src/test/resources/soliditycode_0.7.6/testStakeSuicide.sol deleted file mode 100644 index 3342a5607f7..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/testStakeSuicide.sol +++ /dev/null @@ -1,71 +0,0 @@ - -contract testStakeSuicide{ - B b; - constructor() payable public{} - function deployB() payable public returns (B addrB){ - b = (new B).value(1000000000)(); - return b; - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } - function SelfdestructTest2(address sr, uint256 amount, address payable target) public{ - stake(sr, amount); - selfdestruct(target); - } - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - function Stake2(address sr, uint256 amount) public returns (bool result){ - stake(sr, amount); - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function UnStake2() public returns (bool result){ - unstake(); - return unstake(); - } - function WithdrawReward() public { - withdrawreward(); - } - function RewardBalance(address addr) view public returns (uint256 balance) { - return addr.rewardbalance; - } - function revertTest1(address sr, uint256 amount, address payable transferAddr) public{ - transferAddr.transfer(1000000); - stake(sr, amount); - transferAddr.transfer(2000000); - stake(sr, 1000000000000000);//stake more than balance to fail - transferAddr.transfer(4000000); - } - function revertTest2(address payable transferAddr) public{ - transferAddr.transfer(1000000); - unstake(); - transferAddr.transfer(2000000); - unstake();//unstake twice to fail - transferAddr.transfer(4000000); - } - function BStake(address sr, uint256 amount) public returns (bool result){ - return b.Stake(sr, amount); - } - function BUnStake() public returns (bool result){ - return b.UnStake(); - } - function BSelfdestructTest(address payable target) public{ - b.SelfdestructTest(target); - } -} -contract B{ - constructor() payable public{} - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - function UnStake() public returns (bool result){ - return unstake(); - } - function SelfdestructTest(address payable target) public{ - selfdestruct(target); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/tryCatch001.sol b/framework/src/test/resources/soliditycode_0.7.6/tryCatch001.sol deleted file mode 100644 index 283db92e159..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/tryCatch001.sol +++ /dev/null @@ -1,105 +0,0 @@ - - -enum ErrorType { - Revert_Error, //0 - RevertWithMsg_Error, //1 - Require_Error, //2 - RequirewithMsg_Error, //3 - Assert_Error, //4 - Tansfer_Error, //5 - Send_Error, //6 - Math_Error, //7 - ArrayOverFlow_Error //8 -} -contract errorContract { - uint256[] arraryUint ; - - function errorSwitch(uint256 errorType) public returns(string memory) { - if (ErrorType(errorType) == ErrorType.Revert_Error){ - revert(); - } else if (ErrorType(errorType) == ErrorType.RevertWithMsg_Error){ - revert("Revert Msg."); - } else if (ErrorType(errorType) == ErrorType.Require_Error) { - require(0>1); - } else if (ErrorType(errorType) == ErrorType.RequirewithMsg_Error) { - require(0>1,"Require Msg."); - } else if (ErrorType(errorType) == ErrorType.Assert_Error) { - assert(1<0); - } else if (ErrorType(errorType) == ErrorType.Tansfer_Error) { - payable(msg.sender).transfer(1); - } else if (ErrorType(errorType) == ErrorType.Send_Error) { - payable(msg.sender).send(1); - } else if (ErrorType(errorType) == ErrorType.Math_Error) { - uint256 a = 1; - uint256 b = 0; - uint256 n = a / b; - } else if (ErrorType(errorType) == ErrorType.ArrayOverFlow_Error) { - arraryUint.pop(); - } - return "success"; - - } - - function callFun(string memory functionStr, string memory argsStr) public{ - address(this).call(abi.encodeWithSignature(functionStr, argsStr)); - } - -} - -contract NewContract { - uint256[] arraryUint ; - - constructor(uint256 errorType) public payable{ - if (ErrorType(errorType) == ErrorType.Revert_Error){ - revert(); - } else if (ErrorType(errorType) == ErrorType.RevertWithMsg_Error){ - revert("Revert Msg."); - } else if (ErrorType(errorType) == ErrorType.Require_Error) { - require(0>1); - } else if (ErrorType(errorType) == ErrorType.RequirewithMsg_Error) { - require(0>1,"Require Msg."); - } else if (ErrorType(errorType) == ErrorType.Assert_Error) { - assert(1<0); - } else if (ErrorType(errorType) == ErrorType.Tansfer_Error) { - payable(msg.sender).transfer(1); - } else if (ErrorType(errorType) == ErrorType.Send_Error) { - payable(msg.sender).send(1); - } else if (ErrorType(errorType) == ErrorType.Math_Error) { - uint256 a = 1; - uint256 b = 0; - uint256 n = a / b; - } else if (ErrorType(errorType) == ErrorType.ArrayOverFlow_Error) { - arraryUint.pop(); - } - } -} - -contract tryTest { - function getData(errorContract inter, string memory functionStr, string memory argsStr) public payable returns(string memory) { - try inter.callFun(functionStr,argsStr) { - return "123"; - } catch Error(string memory errorMsg/* 出错原因 */) { - return errorMsg; - } catch (bytes memory) { - return "3"; - } - } - - function getErrorSwitch(errorContract add, uint256 errorType ) public payable returns(string memory) { - try add.errorSwitch(errorType) returns (string memory Msg) { - return Msg; - } catch Error(string memory errorMsg/* 出错原因 */) { - return errorMsg; - } catch (bytes memory) { - return "NoErrorMsg"; - } - } - - function catchNewErrorSwitch(uint256 errorType) public returns (address nc){ - try new NewContract(errorType) returns (NewContract nc){ - return address(nc); - }catch { - return address(0x00); - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue001.sol b/framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue001.sol deleted file mode 100644 index 5388ed68473..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue001.sol +++ /dev/null @@ -1,25 +0,0 @@ - -contract tvmAssetIssue001 { - constructor() payable public{} - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - return assetissue(name, abbr, totalSupply, precision); - } - - function updateAsset(trcToken tokenId, string memory url, string memory desc) public returns (bool) { - return updateasset(tokenId, bytes(url), bytes(desc)); - } - - function updateOtherAccountAsset(string memory url, string memory desc) public returns (bool) { - trcToken tokenId = trcToken(1000004); - return updateasset(tokenId, bytes(url), bytes(desc)); - } - - function updateAssetOnBytes(trcToken tokenId, bytes memory url, bytes memory desc) public returns (bool) { - return updateasset(tokenId, url, desc); - } - - function transferToken(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue002.sol b/framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue002.sol deleted file mode 100644 index 87c1206b778..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue002.sol +++ /dev/null @@ -1,15 +0,0 @@ - - -contract tvmAssetIssue002 { - constructor() payable public{} - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - assetissue(name, abbr, totalSupply, precision); - return assetissue(name, abbr, totalSupply, precision); - } - - function updateAsset(trcToken tokenId, string memory url1, string memory desc1, string memory url2, string memory desc2) public returns (bool) { - updateasset(tokenId, bytes(url1), bytes(desc1)); - return updateasset(tokenId, bytes(url2), bytes(desc2)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue003.sol b/framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue003.sol deleted file mode 100644 index f5ce5e0dc3e..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue003.sol +++ /dev/null @@ -1,23 +0,0 @@ - - -contract tvmAssetIssue003 { - constructor() payable public{} - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - return assetissue(name, abbr, totalSupply, precision); - } - - function tokenIssueAndTransfer(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision, address addr) public { - address payable newaddress = address(uint160(addr)); - newaddress.transfer(100000000); - assetissue(name, abbr, totalSupply, precision); - newaddress.transfer(100000000); - } - - function updateAssetAndTransfer(trcToken tokenId, string memory url, string memory desc, address addr) public { - address payable newaddress = address(uint160(addr)); - newaddress.transfer(100000000); - updateasset(tokenId, bytes(url), bytes(desc)); - newaddress.transfer(100000000); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue004.sol b/framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue004.sol deleted file mode 100644 index c8332de8f45..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue004.sol +++ /dev/null @@ -1,39 +0,0 @@ - - -contract A { - - constructor() payable public{} - fallback() payable external {} - - function tokenIssueA(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint){ - return assetissue(name, abbr, totalSupply, precision); - } - - function updateAssetA(trcToken tokenId, string memory url, string memory desc) public returns (bool) { - return updateasset(tokenId, bytes(url), bytes(desc)); - } - - function transferToken(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } -} - -contract tvmAssetIssue004 { - - A a; - - constructor() payable public{} - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - return a.tokenIssueA(name, abbr, totalSupply, precision); - } - - function updateAsset(trcToken tokenId, string memory url, string memory desc) public returns (bool) { - return a.updateAssetA(tokenId, url, desc); - } - - function getContractAddress() public payable returns (address) { - a = (new A).value(1024000000)(); - return address(a); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue005.sol b/framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue005.sol deleted file mode 100644 index 8c36d050ff8..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/tvmAssetIssue005.sol +++ /dev/null @@ -1,45 +0,0 @@ - - -contract tvmAssetIssue005 { - constructor() payable public{} - - fallback() external payable { - } - - function tokenIssue(bytes32 name, bytes32 abbr, uint64 totalSupply, uint8 precision) public returns (uint) { - return assetissue(name, abbr, totalSupply, precision); - } - - function updateAsset(trcToken tokenId, string memory url, string memory desc) public returns (bool) { - return updateasset(tokenId, bytes(url), bytes(desc)); - } - - function updateAssetOnBytes(trcToken tokenId, bytes memory url, bytes memory desc) public returns (bool) { - return updateasset(tokenId, url, desc); - } - - function transferToken(address payable toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - - function SelfdestructTest(address payable target) public { - selfdestruct(target); - } -} - -contract B { - event Deployed(address addr, uint256 salt); - - function deploy(uint256 salt) public returns (address) { - address addr; - bytes memory code = type(tvmAssetIssue005).creationCode; - assembly { - addr := create2(0, add(code, 0x20), mload(code), salt) - if iszero(extcodesize(addr)) { - revert(0, 0) - } - } - emit Deployed(addr, salt); - return addr; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/typeName.sol b/framework/src/test/resources/soliditycode_0.7.6/typeName.sol deleted file mode 100644 index 5b44abd1bbb..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/typeName.sol +++ /dev/null @@ -1,5 +0,0 @@ -contract TypeName { - function testTypeName() public returns (string memory){ - return type(TypeName).name; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/unStake001.sol b/framework/src/test/resources/soliditycode_0.7.6/unStake001.sol deleted file mode 100644 index 03734fecfa5..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/unStake001.sol +++ /dev/null @@ -1,90 +0,0 @@ - - -contract unStakeTest { - B b; - constructor() payable public{} - function deployB() payable public returns (B addrB){ - b = (new B).value(1000000000)(); - return b; - } - - function selfdestructTest(address payable target) public { - selfdestruct(target); - } - - function selfdestructTest2(address sr, uint256 amount, address payable target) public { - stake(sr, amount); - selfdestruct(target); - } - - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - - function stake2(address sr, uint256 amount) public returns (bool result){ - stake(sr, amount); - return stake(sr, amount); - } - - function unStake() public returns (bool result){ - return unstake(); - } - - function unStake2() public returns (bool result){ - unstake(); - return unstake(); - } - - function withdrawReward() public returns (uint256 amount) { - return withdrawreward(); - } - - function rewardBalance(address addr) view public returns (uint256 balance) { - return addr.rewardbalance; - } - - function revertTest1(address sr, uint256 amount, address payable transferAddr) public { - transferAddr.transfer(1000000); - stake(sr, amount); - transferAddr.transfer(2000000); - stake(sr, 1000000000000000); - //stake more than balance to fail - transferAddr.transfer(4000000); - } - - function revertTest2(address payable transferAddr) public { - transferAddr.transfer(1000000); - unstake(); - transferAddr.transfer(2000000); - unstake(); - //unstake twice to fail - transferAddr.transfer(4000000); - } - - function BStake(address sr, uint256 amount) public returns (bool result){ - return b.Stake(sr, amount); - } - - function BUnStake() public returns (bool result){ - return b.UnStake(); - } - - function BSelfdestructTest(address payable target) public { - b.SelfdestructTest(target); - } -} - -contract B { - constructor() payable public{} - function Stake(address sr, uint256 amount) public returns (bool result){ - return stake(sr, amount); - } - - function UnStake() public returns (bool result){ - return unstake(); - } - - function SelfdestructTest(address payable target) public { - selfdestruct(target); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/validatemultisign001.sol b/framework/src/test/resources/soliditycode_0.7.6/validatemultisign001.sol deleted file mode 100644 index cc0a742d0c5..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/validatemultisign001.sol +++ /dev/null @@ -1,15 +0,0 @@ -pragma experimental ABIEncoderV2; - -contract validatemultisignTest { - function testmulti(address a, uint256 perid, bytes32 hash, bytes[] memory signatures) public returns (bool){ - return validatemultisign(a, perid, hash, signatures); - } - - function testbatch(bytes32 hash, bytes[] memory signatures, address[] memory addresses) public returns (bytes32){ - return batchvalidatesign(hash, signatures, addresses); - } - - function testMultiPrecompileContract(bytes memory data) public returns(bool, bytes memory){ - return address(0xa).delegatecall(data); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/verifyTransferProof001.sol b/framework/src/test/resources/soliditycode_0.7.6/verifyTransferProof001.sol deleted file mode 100644 index 587b4defd10..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/verifyTransferProof001.sol +++ /dev/null @@ -1,15 +0,0 @@ -contract verifyTransferProofTest { - - function test1() public returns (bool, bytes memory){ - bytes memory empty = ""; - return address(0x1000002).delegatecall(empty); - } - - function test2(bytes memory data) public returns (bool, bytes memory){ - return address(0x1000002).delegatecall(data); - } - - function test3(bytes32[10][] memory input, bytes32[2][] memory spendAuthoritySignature, bytes32[9][] memory output, bytes32[2] memory bindingSignature, bytes32 signHash, uint64 valueBalance, bytes32[33] memory frontier, uint256 leafCount) public returns (bytes32[] memory){ - return verifyTransferProof(input, spendAuthoritySignature, output, bindingSignature, signHash, valueBalance, frontier, leafCount); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_0.7.6/virtual001.sol b/framework/src/test/resources/soliditycode_0.7.6/virtual001.sol deleted file mode 100644 index f7967626764..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/virtual001.sol +++ /dev/null @@ -1,19 +0,0 @@ -//pragma solidity ^0.6.0; -interface X { - function setValue(uint _x) external; -} -abstract contract Y { - function setBool(bool _y) external virtual ; -} -contract Y2 { - string public z; - function setString(string calldata _z) external virtual { z = "123"; } -} - -contract Z is X,Y,Y2 { - uint public x; - bool public y; - function setValue(uint _x) external override { x = _x; } - function setBool(bool _y) external override { y = _y; } - function setString(string calldata _z) external override { z = _z; } -} diff --git a/framework/src/test/resources/soliditycode_0.7.6/walletTestMutiSign004.sol b/framework/src/test/resources/soliditycode_0.7.6/walletTestMutiSign004.sol deleted file mode 100644 index 7b943aee5c1..00000000000 --- a/framework/src/test/resources/soliditycode_0.7.6/walletTestMutiSign004.sol +++ /dev/null @@ -1,51 +0,0 @@ -contract timeoutTest { - string public iarray1; - // cpu - function oneCpu() public { - require(1==1); - } - - function storage8Char() public { - iarray1 = "12345678"; - } - - function testUseCpu(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - } - return count; - } - - - uint256[] public iarray; - uint public calculatedFibNumber; - mapping(address=>mapping(address=>uint256)) public m; - - function testUseStorage(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - iarray.push(i); - } - return count; - } - - // stack - //uint n = 0; - uint yy = 0; - function test() public { - //n += 1; - yy += 1; - test(); - } - - function setFibonacci(uint n) public returns (uint256){ - calculatedFibNumber = fibonacci(n); - return calculatedFibNumber; - } - - function fibonacci(uint n) internal returns (uint) { - return fibonacci(n - 1) + fibonacci(n - 2); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/TransferFailed001.sol b/framework/src/test/resources/soliditycode_v0.4.25/TransferFailed001.sol deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/framework/src/test/resources/soliditycode_v0.4.25/TransferFailed005.sol b/framework/src/test/resources/soliditycode_v0.4.25/TransferFailed005.sol deleted file mode 100644 index d3179a30191..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/TransferFailed005.sol +++ /dev/null @@ -1,106 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - function testTransferTokenCompiledLongMax() payable public{ - address(0x1).transferToken(1,9223372036855775827); - } - - function testTransferTokenCompiledLongMin() payable public{ - //address(0x1).transferToken(1,-9223372036855775828); - } - - function testTransferTokenCompiledLongMin1() payable public{ - address(0x1).tokenBalance(trcToken(-9223372036855775828)); - } - - function testTransferTokenCompiledLongMax1() payable public{ - address(0x1).tokenBalance(trcToken(9223372036855775827)); - } - - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address caller) public returns (bool){ - return caller.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller).value(i)(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.send(i); - } - - function testTransferTrxNonexistentTarget(uint256 i,address nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.transfer(i); - } - - function testTransferTokenNonexistentTarget(uint256 i,address nonexistentTarget, trcToken tokenId) payable public { - require(address(this).balance >= i); - nonexistentTarget.transferToken(i, tokenId); - } - - function testCallTrxNonexistentTarget(uint256 i,address nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address self = address(uint160(address(this))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address self = address(uint160(address(this))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - require(address(this).balance >= i); - address self = address(uint160(address(this))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256 ){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/TransferFailed007.sol b/framework/src/test/resources/soliditycode_v0.4.25/TransferFailed007.sol deleted file mode 100644 index ffd6f10c486..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/TransferFailed007.sol +++ /dev/null @@ -1,90 +0,0 @@ -contract EnergyOfTransferFailedTest { - constructor() payable public { - - } - // InsufficientBalance - function testTransferTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.transfer(i); - } - - function testSendTrxInsufficientBalance(uint256 i) payable public{ - msg.sender.send(i); - } - - function testTransferTokenInsufficientBalance(uint256 i,trcToken tokenId) payable public{ - msg.sender.transferToken(i, tokenId); - } - - function testCallTrxInsufficientBalance(uint256 i,address caller) public returns (bool){ - return caller.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testCreateTrxInsufficientBalance(uint256 i) payable public { - (new Caller).value(i)(); - } - - // NonexistentTarget - - function testSendTrxNonexistentTarget(uint256 i,address nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.send(i); - } - - function testTransferTrxNonexistentTarget(uint256 i,address nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.transfer(i); - } - - function testTransferTokenNonexistentTarget(uint256 i,address nonexistentTarget, trcToken tokenId) payable public { - require(address(this).balance >= i); - nonexistentTarget.transferToken(i, tokenId); - } - - function testCallTrxNonexistentTarget(uint256 i,address nonexistentTarget) payable public { - require(address(this).balance >= i); - nonexistentTarget.call.value(i)(abi.encodeWithSignature("test()")); - } - - function testSuicideNonexistentTarget(address nonexistentTarget) payable public { - selfdestruct(nonexistentTarget); - } - - // target is self - function testTransferTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address self = address(uint160(address(this))); - self.transfer(i); - } - - function testSendTrxSelf(uint256 i) payable public{ - require(address(this).balance >= i); - address self = address(uint160(address(this))); - self.send(i); - } - - function testTransferTokenSelf(uint256 i,trcToken tokenId) payable public{ - require(address(this).balance >= i); - address self = address(uint160(address(this))); - self.transferToken(i, tokenId); - } - - event Deployed(address addr, uint256 salt, address sender); - function deploy(bytes memory code, uint256 salt) public returns(address){ - address addr; - assembly { - addr := create2(10, add(code, 0x20), mload(code), salt) - //if iszero(extcodesize(addr)) { - // revert(0, 0) - //} - } - //emit Deployed(addr, salt, msg.sender); - return addr; - } -} - - - -contract Caller { - constructor() payable public {} - function test() payable public returns (uint256 ){return 1;} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/addMsg001Nonpayable.sol b/framework/src/test/resources/soliditycode_v0.4.25/addMsg001Nonpayable.sol deleted file mode 100644 index 7b124f0e870..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/addMsg001Nonpayable.sol +++ /dev/null @@ -1,20 +0,0 @@ -//pragma solidity ^0.4.24; - -contract IllegalDecorate { - -event log(uint256); -constructor() payable public{} - -function() payable public{} - -function transferTokenWithOutPayable(address toAddress, uint256 tokenValue) public { -// function transferTokenWithValue(address toAddress, uint256 tokenValue) payable public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); - -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/addMsg002View.sol b/framework/src/test/resources/soliditycode_v0.4.25/addMsg002View.sol deleted file mode 100644 index 97c07ace501..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/addMsg002View.sol +++ /dev/null @@ -1,20 +0,0 @@ -//pragma solidity ^0.4.24; - -contract IllegalDecorate { - -constructor() payable public{} - -function() payable public{} - -event log(uint256); - -function transferTokenWithView(address toAddress, uint256 tokenValue) public view { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} - diff --git a/framework/src/test/resources/soliditycode_v0.4.25/addMsg003Constant.sol b/framework/src/test/resources/soliditycode_v0.4.25/addMsg003Constant.sol deleted file mode 100644 index 4cc69e05c90..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/addMsg003Constant.sol +++ /dev/null @@ -1,19 +0,0 @@ -//pragma solidity ^0.4.24; - -contract IllegalDecorate { - -constructor() payable public{} - -function() payable public{} - -event log(uint256); - -function transferTokenWithConstant(address toAddress, uint256 tokenValue) public constant { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/addMsg004Pure.sol b/framework/src/test/resources/soliditycode_v0.4.25/addMsg004Pure.sol deleted file mode 100644 index 886e5d2ea0f..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/addMsg004Pure.sol +++ /dev/null @@ -1,19 +0,0 @@ -//pragma solidity ^0.4.24; - -contract IllegalDecorate { - -constructor() payable public{} - -function() payable public{} - -event log(uint256); - -function transferTokenWithPure(address toAddress, uint256 tokenValue) public pure { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/addTransferToken001Nonpayable.sol b/framework/src/test/resources/soliditycode_v0.4.25/addTransferToken001Nonpayable.sol deleted file mode 100644 index b6c69fca887..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/addTransferToken001Nonpayable.sol +++ /dev/null @@ -1,15 +0,0 @@ -//pragma solidity ^0.4.24; - - contract IllegalDecorate { - - constructor() payable public{} - - function() payable public{} - - function transferTokenWithOutPayable(address toAddress, uint256 tokenValue)public { - - toAddress.transferToken(tokenValue, 0x6e6d62); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/addTransferToken002View.sol b/framework/src/test/resources/soliditycode_v0.4.25/addTransferToken002View.sol deleted file mode 100644 index fc390f12b53..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/addTransferToken002View.sol +++ /dev/null @@ -1,15 +0,0 @@ -//pragma solidity ^0.4.24; - -contract IllegalDecorate { - - constructor() payable public{} - - function() payable public{} - - function transferTokenWithView(address toAddress, uint256 tokenValue) public view { - - toAddress.transferToken(tokenValue, 0x6e6d62); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/addTransferToken003Constant.sol b/framework/src/test/resources/soliditycode_v0.4.25/addTransferToken003Constant.sol deleted file mode 100644 index 38c034f6bfb..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/addTransferToken003Constant.sol +++ /dev/null @@ -1,15 +0,0 @@ -//pragma solidity ^0.4.24; - -contract IllegalDecorate { - - constructor() payable public{} - - function() payable public{} - - function transferTokenWithConstant(address toAddress, uint256 tokenValue)public constant { - - toAddress.transferToken(tokenValue, 0x6e6d62); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/addTransferToken004Pure.sol b/framework/src/test/resources/soliditycode_v0.4.25/addTransferToken004Pure.sol deleted file mode 100644 index 085fd1bbbdb..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/addTransferToken004Pure.sol +++ /dev/null @@ -1,15 +0,0 @@ -//pragma solidity ^0.4.24; - -contract IllegalDecorate { - - constructor() payable public{} - - function() payable public{} - - function transferTokenWithPure(address toAddress, uint256 tokenValue) public pure { - - toAddress.transferToken(tokenValue, 0x6e6d62); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/addTrcToken001Assemble.sol b/framework/src/test/resources/soliditycode_v0.4.25/addTrcToken001Assemble.sol deleted file mode 100644 index a0015c9e75b..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/addTrcToken001Assemble.sol +++ /dev/null @@ -1,81 +0,0 @@ -//pragma solidity ^0.4.24; - -contract InAssemble { - -mapping(trcToken => uint256) tokenCnt; -mapping(uint256 => mapping(trcToken => trcToken)) cntTokenToken; -constructor () payable {} -function getBalance(address addr) constant returns(uint256 r) { -assembly{ -r := balance(addr) -} -} - -function getTokenBalanceConstant(address addr, trcToken tokenId) constant returns(uint256 r) { -assembly{ -r := tokenbalance(tokenId, addr) -} -} - -function getTokenBalance(address addr, trcToken tokenId) returns(uint256 r) { -assembly{ -r := tokenbalance(tokenId, addr) -} -} - -function transferTokenInAssembly(address addr, trcToken tokenId, uint256 tokenValue) payable { -bytes4 sig = bytes4(keccak256("()")); // function signature - -assembly { -let x := mload(0x40) // get empty storage location -mstore(x,sig) // 4 bytes - place signature in empty storage - -let ret := calltoken(gas, addr, tokenValue, tokenId, -x, // input -0x04, // input size = 4 bytes -x, // output stored at input location, save space -0x0 // output size = 0 bytes -) - -// let ret := calltoken(gas, addr, tokenValue, -// x, // input -// 0x04, // input size = 4 bytes -// x, // output stored at input location, save space -// 0x0 // output size = 0 bytes -// ) // ERROR - - -mstore(0x40, add(x,0x20)) // update free memory pointer -} - -// assembly { -// let x := mload(0x40) //Find empty storage location using "free memory pointer" -// mstore(x,sig) //Place signature at begining of empty storage -// mstore(add(x,0x04),a) //Place first argument directly next to signature -// mstore(add(x,0x24),b) //Place second argument next to first, padded to 32 bytes - -// let success := call( //This is the critical change (Pop the top stack value) -// 5000, //5k gas -// addr, //To addr -// 0, //No value -// x, /Inputs are stored at location x -// 0x44, //Inputs are 68 bytes long -// x, //Store output over input (saves space) -// 0x20) //Outputs are 32 bytes long - -// c := mload(x) //Assign output value to c -// mstore(0x40,add(x,0x44)) // Set storage pointer to empty space -// } - -} - -function trcTokenInMap(trcToken tokenId, uint256 tokenValue) returns(uint256 r) { -tokenCnt[tokenId] += tokenValue; -r = tokenCnt[tokenId]; -} - -function cntTokenTokenInMap(trcToken tokenId1, trcToken tokenId2, uint256 tokenValue) returns(trcToken r) { -cntTokenToken[tokenValue][tokenId1] = tokenId2; -r = cntTokenToken[tokenValue][tokenId1]; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/addTrcToken002Cat.sol b/framework/src/test/resources/soliditycode_v0.4.25/addTrcToken002Cat.sol deleted file mode 100644 index 0858c6442fb..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/addTrcToken002Cat.sol +++ /dev/null @@ -1,2017 +0,0 @@ -//pragma solidity ^0.4.11; - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - function Ownable() { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -contract ERC721 { - // Required methods - function totalSupply() public view returns (uint256 total); - function balanceOf(address _owner) public view returns (uint256 balance); - function ownerOf(uint256 _tokenId) external view returns (address owner); - function approve(address _to, uint256 _tokenId) external; - function transfer(address _to, uint256 _tokenId) external; - function transferFrom(address _from, address _to, uint256 _tokenId) external; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) external view returns (bool); -} - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - - function isGeneScience() public pure returns (bool){ - return true; - } - - /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor - /// @param genes1 genes of mom - /// @param genes2 genes of sire - /// @return the genes that are supposed to be passed down the child - function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - - return (genes1+genes2+targetBlock)/2; - - -} -} - - - - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() public onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - Transfer(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(now), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - uint256 newKittenId = kitties.push(_kitty) - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(0, _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { - /// @dev Given a token Id, returns a byte array that is supposed to be converted into string. - function getMetadata(uint256 _tokenId, string) public view returns (bytes32[4] buffer, uint256 count) { - if (_tokenId == 1) { - buffer[0] = "Hello World! :D"; - count = 15; - } else if (_tokenId == 2) { - buffer[0] = "I would definitely choose a medi"; - buffer[1] = "um length string."; - count = 49; - } else if (_tokenId == 3) { - buffer[0] = "Lorem ipsum dolor sit amet, mi e"; - buffer[1] = "st accumsan dapibus augue lorem,"; - buffer[2] = " tristique vestibulum id, libero"; - buffer[3] = " suscipit varius sapien aliquam."; - count = 128; - } - } -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is KittyBase, ERC721 { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public view returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() public view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - external - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] _rawBytes, uint256 _stringLength) private view returns (string) { - var outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string _preferredTransport) external view returns (string infoUrl) { - require(erc721Metadata != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2 sun; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.send(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - - // Represents an auction on an NFT - struct Auction { - // Current owner of NFT - address seller; - // Price (in wei) at beginning of auction - uint128 startingPrice; - // Price (in wei) at end of auction - uint128 endingPrice; - // Duration (in seconds) of auction - uint64 duration; - // Time when auction started - // NOTE: 0 if this auction has been concluded - uint64 startedAt; - } - - // Reference to contract tracking NFT ownership - ERC721 public nonFungibleContract; - - // Cut owner takes on each auction, measured in basis points (1/100 of a percent). - // Values 0-10,000 map to 0%-100% - uint256 public ownerCut; - - // Map from token ID to their corresponding auction. - mapping (uint256 => Auction) tokenIdToAuction; - - event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); - event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); - event AuctionCancelled(uint256 tokenId); - - /// @dev Returns true if the claimant owns the token. - /// @param _claimant - Address claiming to own the token. - /// @param _tokenId - ID of token whose ownership to verify. - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return (nonFungibleContract.ownerOf(_tokenId) == _claimant); - } - - /// @dev Escrows the NFT, assigning ownership to this contract. - /// Throws if the escrow fails. - /// @param _owner - Current owner address of token to escrow. - /// @param _tokenId - ID of token whose approval to verify. - function _escrow(address _owner, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transferFrom(_owner, this, _tokenId); - } - - /// @dev Transfers an NFT owned by this contract to another address. - /// Returns true if the transfer succeeds. - /// @param _receiver - Address to transfer NFT to. - /// @param _tokenId - ID of token to transfer. - function _transfer(address _receiver, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transfer(_receiver, _tokenId); - } - - /// @dev Adds an auction to the list of open auctions. Also fires the - /// AuctionCreated event. - /// @param _tokenId The ID of the token to be put on auction. - /// @param _auction Auction to add. - function _addAuction(uint256 _tokenId, Auction _auction) internal { - // Require that all auctions have a duration of - // at least one minute. (Keeps our math from getting hairy!) - require(_auction.duration >= 1 minutes); - - tokenIdToAuction[_tokenId] = _auction; - - AuctionCreated( - uint256(_tokenId), - uint256(_auction.startingPrice), - uint256(_auction.endingPrice), - uint256(_auction.duration) - ); - } - - /// @dev Cancels an auction unconditionally. - function _cancelAuction(uint256 _tokenId, address _seller) internal { - _removeAuction(_tokenId); - _transfer(_seller, _tokenId); - AuctionCancelled(_tokenId); - } - - /// @dev Computes the price and transfers winnings. - /// Does NOT transfer ownership of token. - function _bid(uint256 _tokenId, uint256 _bidAmount) - internal - returns (uint256) - { - // Get a reference to the auction struct - Auction storage auction = tokenIdToAuction[_tokenId]; - - // Explicitly check that this auction is currently live. - // (Because of how Ethereum mappings work, we can't just count - // on the lookup above failing. An invalid _tokenId will just - // return an auction object that is all zeros.) - require(_isOnAuction(auction)); - - // Check that the bid is greater than or equal to the current price - uint256 price = _currentPrice(auction); - require(_bidAmount >= price); - - // Grab a reference to the seller before the auction struct - // gets deleted. - address seller = auction.seller; - - // The bid is good! Remove the auction before sending the fees - // to the sender so we can't have a reentrancy attack. - _removeAuction(_tokenId); - - // Transfer proceeds to seller (if there are any!) - if (price > 0) { - // Calculate the auctioneer's cut. - // (NOTE: _computeCut() is guaranteed to return a - // value <= price, so this subtraction can't go negative.) - uint256 auctioneerCut = _computeCut(price); - uint256 sellerProceeds = price - auctioneerCut; - - // NOTE: Doing a transfer() in the middle of a complex - // method like this is generally discouraged because of - // reentrancy attacks and DoS attacks if the seller is - // a contract with an invalid fallback function. We explicitly - // guard against reentrancy attacks by removing the auction - // before calling transfer(), and the only thing the seller - // can DoS is the sale of their own asset! (And if it's an - // accident, they can call cancelAuction(). ) - seller.transfer(sellerProceeds); - } - - // Calculate any excess funds included with the bid. If the excess - // is anything worth worrying about, transfer it back to bidder. - // NOTE: We checked above that the bid amount is greater than or - // equal to the price so this cannot underflow. - uint256 bidExcess = _bidAmount - price; - - // Return the funds. Similar to the previous transfer, this is - // not susceptible to a re-entry attack because the auction is - // removed before any transfers occur. - msg.sender.transfer(bidExcess); - - // Tell the world! - AuctionSuccessful(_tokenId, price, msg.sender); - - return price; - } - - /// @dev Removes an auction from the list of open auctions. - /// @param _tokenId - ID of NFT on auction. - function _removeAuction(uint256 _tokenId) internal { - delete tokenIdToAuction[_tokenId]; - } - - /// @dev Returns true if the NFT is on auction. - /// @param _auction - Auction to check. - function _isOnAuction(Auction storage _auction) internal view returns (bool) { - return (_auction.startedAt > 0); - } - - /// @dev Returns current price of an NFT on auction. Broken into two - /// functions (this one, that computes the duration from the auction - /// structure, and the other that does the price computation) so we - /// can easily test that the price computation works correctly. - function _currentPrice(Auction storage _auction) - internal - view - returns (uint256) - { - uint256 secondsPassed = 0; - - // A bit of insurance against negative values (or wraparound). - // Probably not necessary (since Ethereum guarnatees that the - // now variable doesn't ever go backwards). - if (now > _auction.startedAt) { - secondsPassed = now - _auction.startedAt; - } - - return _computeCurrentPrice( - _auction.startingPrice, - _auction.endingPrice, - _auction.duration, - secondsPassed - ); - } - - /// @dev Computes the current price of an auction. Factored out - /// from _currentPrice so we can run extensive unit tests. - /// When testing, make this function public and turn on - /// `Current price computation` test suite. - function _computeCurrentPrice( - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - uint256 _secondsPassed - ) - internal - pure - returns (uint256) - { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our public functions carefully cap the maximum values for - // time (at 64-bits) and currency (at 128-bits). _duration is - // also known to be non-zero (see the require() statement in - // _addAuction()) - if (_secondsPassed >= _duration) { - // We've reached the end of the dynamic pricing portion - // of the auction, just return the end price. - return _endingPrice; - } else { - // Starting price can be higher than ending price (and often is!), so - // this delta can be negative. - int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - - // This multiplication can't overflow, _secondsPassed will easily fit within - // 64-bits, and totalPriceChange will easily fit within 128-bits, their product - // will always fit within 256-bits. - int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - - // currentPriceChange can be negative, but if so, will have a magnitude - // less that _startingPrice. Thus, this result will always end up positive. - int256 currentPrice = int256(_startingPrice) + currentPriceChange; - - return uint256(currentPrice); - } - } - - /// @dev Computes owner's cut of a sale. - /// @param _price - Sale price of NFT. - function _computeCut(uint256 _price) internal view returns (uint256) { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our entry functions carefully cap the maximum values for - // currency (at 128-bits), and ownerCut <= 10000 (see the require() - // statement in the ClockAuction constructor). The result of this - // function is always guaranteed to be <= _price. - return _price * ownerCut / 10000; - } - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { - event Pause(); - event Unpause(); - - bool public paused = false; - - - /** - * @dev modifier to allow actions only when the contract IS paused - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev modifier to allow actions only when the contract IS NOT paused - */ - modifier whenPaused { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyOwner whenNotPaused returns (bool) { - paused = true; - Pause(); - return true; - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyOwner whenPaused returns (bool) { - paused = false; - Unpause(); - return true; - } -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - - /// @dev The ERC-165 interface signature for ERC-721. - /// Ref: https://github.com/ethereum/EIPs/issues/165 - /// Ref: https://github.com/ethereum/EIPs/issues/721 - bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - - /// @dev Constructor creates a reference to the NFT ownership contract - /// and verifies the owner cut is in the valid range. - /// @param _nftAddress - address of a deployed contract implementing - /// the Nonfungible Interface. - /// @param _cut - percent cut the owner takes on each auction, must be - /// between 0-10,000. - function ClockAuction(address _nftAddress, uint256 _cut) public { - require(_cut <= 10000); - ownerCut = _cut; - - ERC721 candidateContract = ERC721(_nftAddress); - require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); - nonFungibleContract = candidateContract; - } - - /// @dev Remove all Ether from the contract, which is the owner's cuts - /// as well as any Ether sent directly to the contract address. - /// Always transfers to the NFT contract, but can be called either by - /// the owner or the NFT contract. - function withdrawBalance() external { - address nftAddress = address(nonFungibleContract); - - require( - msg.sender == owner || - msg.sender == nftAddress - ); - // We are using this boolean method to make sure that even if one fails it will still work - bool res = nftAddress.send(this.balance); - } - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of time to move between starting - /// price and ending price (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address _seller - ) - external - whenNotPaused - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(_owns(msg.sender, _tokenId)); - _escrow(msg.sender, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Bids on an open auction, completing the auction and transferring - /// ownership of the NFT if enough Ether is supplied. - /// @param _tokenId - ID of token to bid on. - function bid(uint256 _tokenId) - external - payable - whenNotPaused - { - // _bid will throw if the bid or funds transfer fails - _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - } - - /// @dev Cancels an auction that hasn't been won yet. - /// Returns the NFT to original owner. - /// @notice This is a state-modifying function that can - /// be called while the contract is paused. - /// @param _tokenId - ID of token on auction - function cancelAuction(uint256 _tokenId) - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - address seller = auction.seller; - require(msg.sender == seller); - _cancelAuction(_tokenId, seller); - } - - /// @dev Cancels an auction when the contract is paused. - /// Only the owner may do this, and NFTs are returned to - /// the seller. This should only be used in emergencies. - /// @param _tokenId - ID of the NFT on auction to cancel. - function cancelAuctionWhenPaused(uint256 _tokenId) - whenPaused - onlyOwner - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - _cancelAuction(_tokenId, auction.seller); - } - - /// @dev Returns auction info for an NFT on auction. - /// @param _tokenId - ID of NFT on auction. - function getAuction(uint256 _tokenId) - external - view - returns - ( - address seller, - uint256 startingPrice, - uint256 endingPrice, - uint256 duration, - uint256 startedAt - ) { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return ( - auction.seller, - auction.startingPrice, - auction.endingPrice, - auction.duration, - auction.startedAt - ); - } - - /// @dev Returns the current price of an auction. - /// @param _tokenId - ID of the token price we are checking. - function getCurrentPrice(uint256 _tokenId) - external - view - returns (uint256) - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return _currentPrice(auction); - } - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSiringAuctionAddress() call. - bool public isSiringClockAuction = true; - - // Delegate constructor - function SiringClockAuction(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. Since this function is wrapped, - /// require sender to be KittyCore contract. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Places a bid for siring. Requires the sender - /// is the KittyCore contract because all bid methods - /// should be wrapped. Also returns the kitty to the - /// seller rather than the winner. - function bid(uint256 _tokenId) - external - payable - { - require(msg.sender == address(nonFungibleContract)); - address seller = tokenIdToAuction[_tokenId].seller; - // _bid checks that token ID is valid and will throw if bid fails - _bid(_tokenId, msg.value); - // We transfer the kitty back to the seller, the winner will get - // the offspring - _transfer(seller, _tokenId); - } - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSaleAuctionAddress() call. - bool public isSaleClockAuction = true; - - // Tracks last 5 sale price of gen0 kitty sales - uint256 public gen0SaleCount; - uint256[5] public lastGen0SalePrices; - - // Delegate constructor - function SaleClockAuction(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Updates lastSalePrice if seller is the nft contract - /// Otherwise, works the same as default bid method. - function bid(uint256 _tokenId) - external - payable - { - // _bid verifies token ID size - address seller = tokenIdToAuction[_tokenId].seller; - uint256 price = _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - - // If not a gen0 auction, exit - if (seller == address(nonFungibleContract)) { - // Track gen0 sale prices - lastGen0SalePrices[gen0SaleCount % 5] = price; - gen0SaleCount++; - } - } - - function averageGen0SalePrice() external view returns (uint256) { - uint256 sum = 0; - for (uint256 i = 0; i < 5; i++) { - sum += lastGen0SalePrices[i]; - } - return sum / 5; - } - -} - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, saleAuction); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, siringAuction); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid.value(msg.value - autoBirthFee)(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10 sun; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, saleAuction); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(this) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - function KittyCore() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - ContractUpgrade(_v2Address); - } - - /// @notice No tipping! - /// @dev Reject all Ether from being sent here, unless it's from one of the - /// two auction contracts. (Hopefully, we can prevent user accidents.) - function() external payable { - require( - msg.sender == address(saleAuction) || - msg.sender == address(siringAuction) - ); - } - - /// @notice Returns all the relevant information about a specific kitty. - /// @param _id The ID of the kitty of interest. - function getKitty(uint256 _id) - external - view - returns ( - bool isGestating, - bool isReady, - uint256 cooldownIndex, - uint256 nextActionAt, - uint256 siringWithId, - uint256 birthTime, - uint256 matronId, - uint256 sireId, - uint256 generation, - uint256 genes - ) { - Kitty storage kit = kitties[_id]; - - // if this variable is 0 then it's not gestating - isGestating = (kit.siringWithId != 0); - isReady = (kit.cooldownEndBlock <= block.number); - cooldownIndex = uint256(kit.cooldownIndex); - nextActionAt = uint256(kit.cooldownEndBlock); - siringWithId = uint256(kit.siringWithId); - birthTime = uint256(kit.birthTime); - matronId = uint256(kit.matronId); - sireId = uint256(kit.sireId); - generation = uint256(kit.generation); - genes = kit.genes; - } - - /// @dev Override unpause so it requires all external contract addresses - /// to be set before contract can be unpaused. Also, we can't have - /// newContractAddress set either, because then the contract was upgraded. - /// @notice This is public rather than external so we can call super.unpause - /// without using an expensive CALL. - function unpause(address toAddress, uint256 tokenValue, trcToken tokenId) public onlyCEO whenPaused returns (uint256 r) { - require(saleAuction != address(0)); - require(siringAuction != address(0)); - require(geneScience != address(0)); - require(newContractAddress == address(0)); - toAddress.transferToken(tokenValue, tokenId); - r = address(this).tokenBalance(tokenId); - // Actually unpause the contract. - super.unpause(); - } - - // @dev Allows the CFO to capture the balance available to the contract. - function withdrawBalance() external onlyCFO { - uint256 balance = this.balance; - // Subtract all the currently pregnant kittens we have, plus 1 of margin. - uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - - if (balance > subtractFees) { - cfoAddress.send(balance - subtractFees); - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/addTrcToken002Cat_withFinny.sol b/framework/src/test/resources/soliditycode_v0.4.25/addTrcToken002Cat_withFinny.sol deleted file mode 100644 index 5839b983a32..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/addTrcToken002Cat_withFinny.sol +++ /dev/null @@ -1,2017 +0,0 @@ -//pragma solidity ^0.4.11; - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - function Ownable() { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -contract ERC721 { - // Required methods - function totalSupply() public view returns (uint256 total); - function balanceOf(address _owner) public view returns (uint256 balance); - function ownerOf(uint256 _tokenId) external view returns (address owner); - function approve(address _to, uint256 _tokenId) external; - function transfer(address _to, uint256 _tokenId) external; - function transferFrom(address _from, address _to, uint256 _tokenId) external; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) external view returns (bool); -} - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - - function isGeneScience() public pure returns (bool){ - return true; - } - - /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor - /// @param genes1 genes of mom - /// @param genes2 genes of sire - /// @return the genes that are supposed to be passed down the child - function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - - return (genes1+genes2+targetBlock)/2; - - -} -} - - - - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() public onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - Transfer(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(now), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - uint256 newKittenId = kitties.push(_kitty) - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(0, _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { - /// @dev Given a token Id, returns a byte array that is supposed to be converted into string. - function getMetadata(uint256 _tokenId, string) public view returns (bytes32[4] buffer, uint256 count) { - if (_tokenId == 1) { - buffer[0] = "Hello World! :D"; - count = 15; - } else if (_tokenId == 2) { - buffer[0] = "I would definitely choose a medi"; - buffer[1] = "um length string."; - count = 49; - } else if (_tokenId == 3) { - buffer[0] = "Lorem ipsum dolor sit amet, mi e"; - buffer[1] = "st accumsan dapibus augue lorem,"; - buffer[2] = " tristique vestibulum id, libero"; - buffer[3] = " suscipit varius sapien aliquam."; - count = 128; - } - } -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is KittyBase, ERC721 { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public view returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() public view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - external - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] _rawBytes, uint256 _stringLength) private view returns (string) { - var outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string _preferredTransport) external view returns (string infoUrl) { - require(erc721Metadata != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2 finny; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.send(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - - // Represents an auction on an NFT - struct Auction { - // Current owner of NFT - address seller; - // Price (in wei) at beginning of auction - uint128 startingPrice; - // Price (in wei) at end of auction - uint128 endingPrice; - // Duration (in seconds) of auction - uint64 duration; - // Time when auction started - // NOTE: 0 if this auction has been concluded - uint64 startedAt; - } - - // Reference to contract tracking NFT ownership - ERC721 public nonFungibleContract; - - // Cut owner takes on each auction, measured in basis points (1/100 of a percent). - // Values 0-10,000 map to 0%-100% - uint256 public ownerCut; - - // Map from token ID to their corresponding auction. - mapping (uint256 => Auction) tokenIdToAuction; - - event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); - event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); - event AuctionCancelled(uint256 tokenId); - - /// @dev Returns true if the claimant owns the token. - /// @param _claimant - Address claiming to own the token. - /// @param _tokenId - ID of token whose ownership to verify. - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return (nonFungibleContract.ownerOf(_tokenId) == _claimant); - } - - /// @dev Escrows the NFT, assigning ownership to this contract. - /// Throws if the escrow fails. - /// @param _owner - Current owner address of token to escrow. - /// @param _tokenId - ID of token whose approval to verify. - function _escrow(address _owner, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transferFrom(_owner, this, _tokenId); - } - - /// @dev Transfers an NFT owned by this contract to another address. - /// Returns true if the transfer succeeds. - /// @param _receiver - Address to transfer NFT to. - /// @param _tokenId - ID of token to transfer. - function _transfer(address _receiver, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transfer(_receiver, _tokenId); - } - - /// @dev Adds an auction to the list of open auctions. Also fires the - /// AuctionCreated event. - /// @param _tokenId The ID of the token to be put on auction. - /// @param _auction Auction to add. - function _addAuction(uint256 _tokenId, Auction _auction) internal { - // Require that all auctions have a duration of - // at least one minute. (Keeps our math from getting hairy!) - require(_auction.duration >= 1 minutes); - - tokenIdToAuction[_tokenId] = _auction; - - AuctionCreated( - uint256(_tokenId), - uint256(_auction.startingPrice), - uint256(_auction.endingPrice), - uint256(_auction.duration) - ); - } - - /// @dev Cancels an auction unconditionally. - function _cancelAuction(uint256 _tokenId, address _seller) internal { - _removeAuction(_tokenId); - _transfer(_seller, _tokenId); - AuctionCancelled(_tokenId); - } - - /// @dev Computes the price and transfers winnings. - /// Does NOT transfer ownership of token. - function _bid(uint256 _tokenId, uint256 _bidAmount) - internal - returns (uint256) - { - // Get a reference to the auction struct - Auction storage auction = tokenIdToAuction[_tokenId]; - - // Explicitly check that this auction is currently live. - // (Because of how Ethereum mappings work, we can't just count - // on the lookup above failing. An invalid _tokenId will just - // return an auction object that is all zeros.) - require(_isOnAuction(auction)); - - // Check that the bid is greater than or equal to the current price - uint256 price = _currentPrice(auction); - require(_bidAmount >= price); - - // Grab a reference to the seller before the auction struct - // gets deleted. - address seller = auction.seller; - - // The bid is good! Remove the auction before sending the fees - // to the sender so we can't have a reentrancy attack. - _removeAuction(_tokenId); - - // Transfer proceeds to seller (if there are any!) - if (price > 0) { - // Calculate the auctioneer's cut. - // (NOTE: _computeCut() is guaranteed to return a - // value <= price, so this subtraction can't go negative.) - uint256 auctioneerCut = _computeCut(price); - uint256 sellerProceeds = price - auctioneerCut; - - // NOTE: Doing a transfer() in the middle of a complex - // method like this is generally discouraged because of - // reentrancy attacks and DoS attacks if the seller is - // a contract with an invalid fallback function. We explicitly - // guard against reentrancy attacks by removing the auction - // before calling transfer(), and the only thing the seller - // can DoS is the sale of their own asset! (And if it's an - // accident, they can call cancelAuction(). ) - seller.transfer(sellerProceeds); - } - - // Calculate any excess funds included with the bid. If the excess - // is anything worth worrying about, transfer it back to bidder. - // NOTE: We checked above that the bid amount is greater than or - // equal to the price so this cannot underflow. - uint256 bidExcess = _bidAmount - price; - - // Return the funds. Similar to the previous transfer, this is - // not susceptible to a re-entry attack because the auction is - // removed before any transfers occur. - msg.sender.transfer(bidExcess); - - // Tell the world! - AuctionSuccessful(_tokenId, price, msg.sender); - - return price; - } - - /// @dev Removes an auction from the list of open auctions. - /// @param _tokenId - ID of NFT on auction. - function _removeAuction(uint256 _tokenId) internal { - delete tokenIdToAuction[_tokenId]; - } - - /// @dev Returns true if the NFT is on auction. - /// @param _auction - Auction to check. - function _isOnAuction(Auction storage _auction) internal view returns (bool) { - return (_auction.startedAt > 0); - } - - /// @dev Returns current price of an NFT on auction. Broken into two - /// functions (this one, that computes the duration from the auction - /// structure, and the other that does the price computation) so we - /// can easily test that the price computation works correctly. - function _currentPrice(Auction storage _auction) - internal - view - returns (uint256) - { - uint256 secondsPassed = 0; - - // A bit of insurance against negative values (or wraparound). - // Probably not necessary (since Ethereum guarnatees that the - // now variable doesn't ever go backwards). - if (now > _auction.startedAt) { - secondsPassed = now - _auction.startedAt; - } - - return _computeCurrentPrice( - _auction.startingPrice, - _auction.endingPrice, - _auction.duration, - secondsPassed - ); - } - - /// @dev Computes the current price of an auction. Factored out - /// from _currentPrice so we can run extensive unit tests. - /// When testing, make this function public and turn on - /// `Current price computation` test suite. - function _computeCurrentPrice( - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - uint256 _secondsPassed - ) - internal - pure - returns (uint256) - { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our public functions carefully cap the maximum values for - // time (at 64-bits) and currency (at 128-bits). _duration is - // also known to be non-zero (see the require() statement in - // _addAuction()) - if (_secondsPassed >= _duration) { - // We've reached the end of the dynamic pricing portion - // of the auction, just return the end price. - return _endingPrice; - } else { - // Starting price can be higher than ending price (and often is!), so - // this delta can be negative. - int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - - // This multiplication can't overflow, _secondsPassed will easily fit within - // 64-bits, and totalPriceChange will easily fit within 128-bits, their product - // will always fit within 256-bits. - int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - - // currentPriceChange can be negative, but if so, will have a magnitude - // less that _startingPrice. Thus, this result will always end up positive. - int256 currentPrice = int256(_startingPrice) + currentPriceChange; - - return uint256(currentPrice); - } - } - - /// @dev Computes owner's cut of a sale. - /// @param _price - Sale price of NFT. - function _computeCut(uint256 _price) internal view returns (uint256) { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our entry functions carefully cap the maximum values for - // currency (at 128-bits), and ownerCut <= 10000 (see the require() - // statement in the ClockAuction constructor). The result of this - // function is always guaranteed to be <= _price. - return _price * ownerCut / 10000; - } - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { - event Pause(); - event Unpause(); - - bool public paused = false; - - - /** - * @dev modifier to allow actions only when the contract IS paused - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev modifier to allow actions only when the contract IS NOT paused - */ - modifier whenPaused { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyOwner whenNotPaused returns (bool) { - paused = true; - Pause(); - return true; - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyOwner whenPaused returns (bool) { - paused = false; - Unpause(); - return true; - } -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - - /// @dev The ERC-165 interface signature for ERC-721. - /// Ref: https://github.com/ethereum/EIPs/issues/165 - /// Ref: https://github.com/ethereum/EIPs/issues/721 - bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - - /// @dev Constructor creates a reference to the NFT ownership contract - /// and verifies the owner cut is in the valid range. - /// @param _nftAddress - address of a deployed contract implementing - /// the Nonfungible Interface. - /// @param _cut - percent cut the owner takes on each auction, must be - /// between 0-10,000. - function ClockAuction(address _nftAddress, uint256 _cut) public { - require(_cut <= 10000); - ownerCut = _cut; - - ERC721 candidateContract = ERC721(_nftAddress); - require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); - nonFungibleContract = candidateContract; - } - - /// @dev Remove all Ether from the contract, which is the owner's cuts - /// as well as any Ether sent directly to the contract address. - /// Always transfers to the NFT contract, but can be called either by - /// the owner or the NFT contract. - function withdrawBalance() external { - address nftAddress = address(nonFungibleContract); - - require( - msg.sender == owner || - msg.sender == nftAddress - ); - // We are using this boolean method to make sure that even if one fails it will still work - bool res = nftAddress.send(this.balance); - } - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of time to move between starting - /// price and ending price (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address _seller - ) - external - whenNotPaused - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(_owns(msg.sender, _tokenId)); - _escrow(msg.sender, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Bids on an open auction, completing the auction and transferring - /// ownership of the NFT if enough Ether is supplied. - /// @param _tokenId - ID of token to bid on. - function bid(uint256 _tokenId) - external - payable - whenNotPaused - { - // _bid will throw if the bid or funds transfer fails - _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - } - - /// @dev Cancels an auction that hasn't been won yet. - /// Returns the NFT to original owner. - /// @notice This is a state-modifying function that can - /// be called while the contract is paused. - /// @param _tokenId - ID of token on auction - function cancelAuction(uint256 _tokenId) - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - address seller = auction.seller; - require(msg.sender == seller); - _cancelAuction(_tokenId, seller); - } - - /// @dev Cancels an auction when the contract is paused. - /// Only the owner may do this, and NFTs are returned to - /// the seller. This should only be used in emergencies. - /// @param _tokenId - ID of the NFT on auction to cancel. - function cancelAuctionWhenPaused(uint256 _tokenId) - whenPaused - onlyOwner - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - _cancelAuction(_tokenId, auction.seller); - } - - /// @dev Returns auction info for an NFT on auction. - /// @param _tokenId - ID of NFT on auction. - function getAuction(uint256 _tokenId) - external - view - returns - ( - address seller, - uint256 startingPrice, - uint256 endingPrice, - uint256 duration, - uint256 startedAt - ) { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return ( - auction.seller, - auction.startingPrice, - auction.endingPrice, - auction.duration, - auction.startedAt - ); - } - - /// @dev Returns the current price of an auction. - /// @param _tokenId - ID of the token price we are checking. - function getCurrentPrice(uint256 _tokenId) - external - view - returns (uint256) - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return _currentPrice(auction); - } - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSiringAuctionAddress() call. - bool public isSiringClockAuction = true; - - // Delegate constructor - function SiringClockAuction(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. Since this function is wrapped, - /// require sender to be KittyCore contract. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Places a bid for siring. Requires the sender - /// is the KittyCore contract because all bid methods - /// should be wrapped. Also returns the kitty to the - /// seller rather than the winner. - function bid(uint256 _tokenId) - external - payable - { - require(msg.sender == address(nonFungibleContract)); - address seller = tokenIdToAuction[_tokenId].seller; - // _bid checks that token ID is valid and will throw if bid fails - _bid(_tokenId, msg.value); - // We transfer the kitty back to the seller, the winner will get - // the offspring - _transfer(seller, _tokenId); - } - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSaleAuctionAddress() call. - bool public isSaleClockAuction = true; - - // Tracks last 5 sale price of gen0 kitty sales - uint256 public gen0SaleCount; - uint256[5] public lastGen0SalePrices; - - // Delegate constructor - function SaleClockAuction(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Updates lastSalePrice if seller is the nft contract - /// Otherwise, works the same as default bid method. - function bid(uint256 _tokenId) - external - payable - { - // _bid verifies token ID size - address seller = tokenIdToAuction[_tokenId].seller; - uint256 price = _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - - // If not a gen0 auction, exit - if (seller == address(nonFungibleContract)) { - // Track gen0 sale prices - lastGen0SalePrices[gen0SaleCount % 5] = price; - gen0SaleCount++; - } - } - - function averageGen0SalePrice() external view returns (uint256) { - uint256 sum = 0; - for (uint256 i = 0; i < 5; i++) { - sum += lastGen0SalePrices[i]; - } - return sum / 5; - } - -} - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, saleAuction); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, siringAuction); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid.value(msg.value - autoBirthFee)(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10 finny; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, saleAuction); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(this) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - function KittyCore() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - ContractUpgrade(_v2Address); - } - - /// @notice No tipping! - /// @dev Reject all Ether from being sent here, unless it's from one of the - /// two auction contracts. (Hopefully, we can prevent user accidents.) - function() external payable { - require( - msg.sender == address(saleAuction) || - msg.sender == address(siringAuction) - ); - } - - /// @notice Returns all the relevant information about a specific kitty. - /// @param _id The ID of the kitty of interest. - function getKitty(uint256 _id) - external - view - returns ( - bool isGestating, - bool isReady, - uint256 cooldownIndex, - uint256 nextActionAt, - uint256 siringWithId, - uint256 birthTime, - uint256 matronId, - uint256 sireId, - uint256 generation, - uint256 genes - ) { - Kitty storage kit = kitties[_id]; - - // if this variable is 0 then it's not gestating - isGestating = (kit.siringWithId != 0); - isReady = (kit.cooldownEndBlock <= block.number); - cooldownIndex = uint256(kit.cooldownIndex); - nextActionAt = uint256(kit.cooldownEndBlock); - siringWithId = uint256(kit.siringWithId); - birthTime = uint256(kit.birthTime); - matronId = uint256(kit.matronId); - sireId = uint256(kit.sireId); - generation = uint256(kit.generation); - genes = kit.genes; - } - - /// @dev Override unpause so it requires all external contract addresses - /// to be set before contract can be unpaused. Also, we can't have - /// newContractAddress set either, because then the contract was upgraded. - /// @notice This is public rather than external so we can call super.unpause - /// without using an expensive CALL. - function unpause(address toAddress, uint256 tokenValue, trcToken tokenId) public onlyCEO whenPaused returns (uint256 r) { - require(saleAuction != address(0)); - require(siringAuction != address(0)); - require(geneScience != address(0)); - require(newContractAddress == address(0)); - toAddress.transferToken(tokenValue, tokenId); - r = address(this).tokenBalance(tokenId); - // Actually unpause the contract. - super.unpause(); - } - - // @dev Allows the CFO to capture the balance available to the contract. - function withdrawBalance() external onlyCFO { - uint256 balance = this.balance; - // Subtract all the currently pregnant kittens we have, plus 1 of margin. - uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - - if (balance > subtractFees) { - cfoAddress.send(balance - subtractFees); - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest1DivideInt.sol b/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest1DivideInt.sol deleted file mode 100644 index 8ed20cd1cab..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest1DivideInt.sol +++ /dev/null @@ -1,7 +0,0 @@ -pragma solidity ^0.4.0; - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest2FindArgsContractMinTest.sol b/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest2FindArgsContractMinTest.sol deleted file mode 100644 index af54558bc98..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest2FindArgsContractMinTest.sol +++ /dev/null @@ -1,10 +0,0 @@ -pragma solidity ^0.4.0; -contract findArgsIContract{ -function findArgsByIndex1(uint i)public returns (uint z) { -uint[] memory a = new uint[](3); -a[0]=1; -a[1]=2; -a[2]=3; -return a[i]; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest3ByteMinContract.sol b/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest3ByteMinContract.sol deleted file mode 100644 index d2e8637612d..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest3ByteMinContract.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma solidity ^0.4.0; -contract byteContract { -bytes b; -function testBytesGet(uint i) returns (bytes1){ -b = new bytes(3); -b[0]=12; -b[1]=13; -b[2]=14; -return b[i]; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest4Enum.sol b/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest4Enum.sol deleted file mode 100644 index 5d7164d27d1..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest4Enum.sol +++ /dev/null @@ -1,13 +0,0 @@ -pragma solidity ^0.4.4; - -contract enumContract { - enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } - ActionChoices _choice; - function setGoStraight(ActionChoices choice) public { - _choice = choice; - } - - function getChoice() public returns (ActionChoices) { - return _choice; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest5MoveRight.sol b/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest5MoveRight.sol deleted file mode 100644 index c0d15a7aa09..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest5MoveRight.sol +++ /dev/null @@ -1,7 +0,0 @@ -pragma solidity ^0.4.0; - -contract binaryRightContract{ - function binaryMoveR(int i)public returns (int z) { - return z = 5 >> i; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest6UninitializedContract.sol b/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest6UninitializedContract.sol deleted file mode 100644 index dbfa3e01bc0..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest6UninitializedContract.sol +++ /dev/null @@ -1,27 +0,0 @@ -pragma solidity ^0.4.0; -contract uni { -function b(int x, int y) internal returns (int) -{ - return x * y; -} - -function test1() external returns (int) -{ - // Variable containing a function pointer - function (int, int) internal returns (int) funcPtr; - - funcPtr = b; - - // This call to funcPtr will succeed - return funcPtr(4, 5); -} - -function test2() external returns (int) -{ - // Variable containing a function pointer - function (int, int) internal returns (int) funcPtr; - - // This call will fail because funcPtr is still a zero-initialized function pointer - return funcPtr(4, 5); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest7TestAssertContract.sol b/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest7TestAssertContract.sol deleted file mode 100644 index 842b8c174e5..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/assertExceptiontest7TestAssertContract.sol +++ /dev/null @@ -1,17 +0,0 @@ -pragma solidity ^0.4.0; - - -contract TestThrowsContract{ - function testAssert(){ - assert(1==2); - } - function testRequire(){ - require(2==1); - } - function testRevert(){ - revert(); - } - function testThrow(){ - throw; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/codeSaftySupport.sol b/framework/src/test/resources/soliditycode_v0.4.25/codeSaftySupport.sol deleted file mode 100644 index 7ae081877b6..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/codeSaftySupport.sol +++ /dev/null @@ -1,19 +0,0 @@ -pragma solidity ^0.4.24; - -contract IllegalDecorate { - -constructor() payable public{} - -function() payable external{} - -event log(uint256); - -function transferToken(address toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/codeSaftyUnsupport.sol b/framework/src/test/resources/soliditycode_v0.4.25/codeSaftyUnsupport.sol deleted file mode 100644 index ff561614780..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/codeSaftyUnsupport.sol +++ /dev/null @@ -1,50 +0,0 @@ - pragma solidity ^0.4.24; -contract SubC { -event log(string); - -function () payable {} - -function receiveToken() payable {} - -function getBalance() constant public returns (uint256 r){ -r = address(this).balance; -} -} -contract UseDot { -constructor() payable public{} -function() payable public{} -mapping(address => mapping(trcToken => uint256)) sender_tokens; - -function trigger1(address addr) payable public { - //SubC(addr).call.value(1000).tokenId(0x6e6d62)(bytes4(sha3("receiveToken()"))); // ERROR -} - -function trigger2(address addr) payable public { - //addr.transferToken.value(10)(10, 0x6e6d62); // ERROR -} - -function trigger3(address addr) payable public { -// SubC(addr).receiveToken.tokenvalue(10)(); // ERROR -} - -function trigger4(address addr) payable public { -// SubC(addr).receiveToken.tokenId(0x6e6d62)(); // ERROR -} - -function trigger5(address addr) payable public { -SubC(addr).receiveToken.value(10)(); -} -function trigger6(address addr, trcToken tokenId) payable public { -SubC(addr).call.value(1000)(bytes4(sha3("transferToken(uint256, trcToken)")), 10, tokenId); -} - -function trigger7(address addr) payable public { - //sender_tokens[msg.sender][msg.tokenid] += msg.tokenvalue; // compile success, no necessary to trigger -} -function trigger8(address addr) public payable returns(bytes r){ - //r = msg.data; // compile success, no necessary to trigger -} -function getBalance() public returns (uint256 r){ -r = address(this).balance; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGetterContract.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGetterContract.sol deleted file mode 100644 index deed0aeabd2..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGetterContract.sol +++ /dev/null @@ -1,17 +0,0 @@ -//pragma solidity ^0.4.0; - - -contract getterContract{ - -constructor() public payable{} -function() external payable{} - -uint public c = msg.value; - -function getDataUsingAccessor() returns (uint){ - -return c; - -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test1Grammar001.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test1Grammar001.sol deleted file mode 100644 index f433ed3585f..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test1Grammar001.sol +++ /dev/null @@ -1,14 +0,0 @@ -pragma solidity ^0.4.16; -contract FunctionSelector { - function select(bool useB, uint x) public returns (uint z) { - var f = a; - if (useB) f = b; - return f(x); - } -function a(uint x) public returns (uint z) { - return x * x; - } -function b(uint x) public returns (uint z) { - return 2 * x; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test2Grammar002.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test2Grammar002.sol deleted file mode 100644 index da9ff8caa56..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test2Grammar002.sol +++ /dev/null @@ -1,44 +0,0 @@ -pragma solidity ^0.4.16; -library Set { - // We define a new struct datatype that will be used to - // hold its data in the calling contract. - struct Data { mapping(uint => bool) flags; } - - // Note that the first parameter is of type "storage - // reference" and thus only its storage address and not - // its contents is passed as part of the call. This is a - // special feature of library functions. It is idiomatic - // to call the first parameter 'self', if the function can - // be seen as a method of that object. - function insert(Data storage self, uint value) public returns (bool) { - if (self.flags[value]) - return false; // already there - self.flags[value] = true; - return true; - } - - function remove(Data storage self, uint value) public returns (bool) { - if (!self.flags[value]) - return false; // not there - self.flags[value] = false; - return true; - } - - function contains(Data storage self, uint value) public returns (bool) { - return self.flags[value]; - } -} - - -contract C { - Set.Data knownValues; - - function register(uint value) { - // The library functions can be called without a - // specific instance of the library, since the - // "instance" will be the current contract. - if (!Set.insert(knownValues, value)) - throw; - } - // In this contract, we can also directly access knownValues.flags, if we want. -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test3Grammar003.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test3Grammar003.sol deleted file mode 100644 index 4d3f87ebe3e..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test3Grammar003.sol +++ /dev/null @@ -1,44 +0,0 @@ -pragma solidity ^0.4.11; - -library Set { - struct Data { mapping(uint => bool) flags; } - - function insert(Data storage self, uint value) public - returns (bool) - { - if (self.flags[value]) - return false; // already there - self.flags[value] = true; - return true; - } - - function remove(Data storage self, uint value) public - returns (bool) - { - if (!self.flags[value]) - return false; // not there - self.flags[value] = false; - return true; - } - - function contains(Data storage self, uint value) public - returns (bool) - { - return self.flags[value]; - } -} - - -contract C { - using Set for Set.Data; // this is the crucial change - Set.Data knownValues; - - function register(uint value) { - // Here, all variables of type Set.Data have - // corresponding member functions. - // The following function call is identical to - // Set.insert(knownValues, value) - if (!knownValues.insert(value)) - throw; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test4Grammar004.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test4Grammar004.sol deleted file mode 100644 index 78bc620c81f..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test4Grammar004.sol +++ /dev/null @@ -1,31 +0,0 @@ -pragma solidity ^0.4.0; - -library Search { - function indexOf(uint[] storage self, uint value) public returns (uint) { - for (uint i = 0; i < self.length; i++) - if (self[i] == value) return i; - return uint(-1); - } -} - - -contract C { - using Search for uint[]; - uint[] public data; - - function append(uint value) { - data.push(value); - } - - function replace(uint _old, uint _new) { - // This performs the library function call - uint index = data.indexOf(_old); - if (index == uint(-1)) - data.push(_new); - else - data[index] = _new; - } - function getData(uint256 index) public returns(uint256){ - return data[index]; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test5Grammar006.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test5Grammar006.sol deleted file mode 100644 index 5bba3d4bba0..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar001test5Grammar006.sol +++ /dev/null @@ -1,36 +0,0 @@ - pragma solidity ^0.4.0; -contract InfoFeed { -function d1(uint x){ - assembly{ - function f(x) -> y { switch x case 0 { y := 1 } default { y := mul(x, f(sub(x, 1))) } } - } - } - function d2(uint x){ - assembly { x := mul(1, add(2, 3))} - } - function f(uint x) { - assembly { x := sub(x, 1) } - - } - function d(uint x){ - assembly{ - let x := add(2, 3) let y := mload(0x40) x := add(x, y) - } - } - function d4(uint x){ - assembly{let x := 10 repeat: x := sub(x, 1) jumpi(repeat, eq(x, 0)) - } - } - function d5(uint x){ - assembly{ - function f(x) -> y { switch x case 0 { y := mul(x, 2) } default { y := 0 } } - - } - } - - function d6(uint x){ - assembly{ - function f(x) -> y { for { let i := 0 } lt(i, x) { i := add(i, 1) } { y := mul(2, y) } } - } - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test1Grammar007_1.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test1Grammar007_1.sol deleted file mode 100644 index 752d3613be2..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test1Grammar007_1.sol +++ /dev/null @@ -1,60 +0,0 @@ -pragma solidity ^0.4.19; -contract Doug{ - mapping (bytes32 => uint) public contracts; - function Doug() { - contracts['hww'] = 1; - contracts['brian'] = 2; - contracts['zzy'] = 7; - } - - function getDougName(string _name) public view returns(string) { - return _name; - } - - function getDougAge(uint _age) public pure returns(uint) { - return 3 ** _age; - } -} - -contract DogInterface { - function getDougAge(uint _age) returns (uint); - function contracts(bytes32 name) returns (uint); -} -contract main{ - - event FetchContract(address dogInterfaceAddress, address sender, bytes32 name); - - address public DOUG; - - address dogInterfaceAddress; - DogInterface dogContract ; - - function setDOUG(address _doug) { - DOUG = _doug; - } - - constructor(address addr) public{ - dogInterfaceAddress = addr; - dogContract = DogInterface(dogInterfaceAddress); - } - - function dougOfage(uint _age) public view returns(uint) { - - uint num = dogContract.getDougAge(_age); - return _age+num; - // return num; - } - - function uintOfName(bytes32 _name) returns (uint) { - - dogContract.contracts(_name); - FetchContract(dogInterfaceAddress, msg.sender, _name); - - } - - // function getTest(string _name) public view returns(string) { - // string memory newName = _name ; - // DogInterface(DOUG).getDougName(newName); - // return newName; - // } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test1Grammar007_2.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test1Grammar007_2.sol deleted file mode 100644 index 8078507e7b2..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test1Grammar007_2.sol +++ /dev/null @@ -1,60 +0,0 @@ -pragma solidity ^0.4.19; -contract Doug{ - mapping (bytes32 => uint) public contracts; - function Doug() { - contracts['hww'] = 1; - contracts['brian'] = 2; - contracts['zzy'] = 7; - } - - function getDougName(string _name) public view returns(string) { - return _name; - } - - function getDougAge(uint _age) public pure returns(uint) { - return 3 ** _age; - } -} - -contract DogInterface { - function getDougAge(uint _age) returns (uint); - function contracts(bytes32 name) returns (uint); -} -contract main{ - - event FetchContract(address dogInterfaceAddress, address sender, bytes32 name); - - address public DOUG; - - address dogInterfaceAddress; - DogInterface dogContract ; - - function setDOUG(address _doug) { - DOUG = _doug; - } - - constructor(address addr) public{ - dogInterfaceAddress = addr; - dogContract = DogInterface(dogInterfaceAddress); - } - - function dougOfage(uint _age) public view returns(uint) { - - uint num = dogContract.getDougAge(_age); - return _age+num; - // return num; - } - - function uintOfName(bytes32 _name) returns (uint) { - - dogContract.contracts(_name); - FetchContract(dogInterfaceAddress, msg.sender, _name); - - } - - // function getTest(string _name) public view returns(string) { - // string memory newName = _name ; - // DogInterface(DOUG).getDougName(newName); - // return newName; - // } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test2Grammar008.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test2Grammar008.sol deleted file mode 100644 index fb4338de0d8..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test2Grammar008.sol +++ /dev/null @@ -1,14 +0,0 @@ -pragma solidity ^0.4.19; -contract Feline { - function utterance() public returns (bytes32); - - function getContractName() public returns (string){ - return "Feline"; - } -} - - -contract Cat is Feline { - function utterance() public returns (bytes32) { return "miaow"; } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test3Grammar010.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test3Grammar010.sol deleted file mode 100644 index 43ff2e0aef3..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test3Grammar010.sol +++ /dev/null @@ -1,10 +0,0 @@ -pragma solidity ^0.4.0; -contract InfoFeed { -function info() public payable returns (uint ret) { return 42; } -} -contract Consumer { -constructor() payable public{} -InfoFeed feed; -function setFeed(address addr) public { feed = InfoFeed(addr); } -function callFeed() public payable{ feed.info.value(10).gas(800)(); } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test4Grammar011.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test4Grammar011.sol deleted file mode 100644 index 0b673512248..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test4Grammar011.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma solidity ^0.4.0; -contract C { -function f(uint key, uint value) public returns(uint) { -return key; -// do something -} -function g() public { -// named arguments -f({value: 2, key: 3}); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test4Grammar012.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test4Grammar012.sol deleted file mode 100644 index 3c72e608e24..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test4Grammar012.sol +++ /dev/null @@ -1,24 +0,0 @@ -pragma solidity ^0.4.24; -contract rTest { -function info() public payable returns (uint,address,bytes4,uint,uint,uint,address,uint) { -//function info() public payable returns (address ,uint,uint,uint,bytes32,uint,bytes,uint,address,bytes4,uint,uint,uint,address,uint) { -//var a = block.coinbase ; -//var b = block.difficulty; -//var c = block.gaslimit; -//var d = block.number; -//var e = block.blockhash(0); -//var e = d; -//var f = block.timestamp; -//bytes memory g = msg.data; -var h = msg.gas; -var i = msg.sender; -var j = msg.sig; -var k = msg.value; -var l = now; -var m = tx.gasprice; -var n = tx.origin; -var o = this.balance; -return (h,i,j,k,l,m,n,o); -//return (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test6Grammar013.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test6Grammar013.sol deleted file mode 100644 index f29197bccc3..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar002test6Grammar013.sol +++ /dev/null @@ -1,22 +0,0 @@ -pragma solidity ^0.4.4; -contract Counter { -uint count = 0; -address owner; -function Counter() { -owner = msg.sender; -} -function increment() public { -uint step = 10; -if (owner == msg.sender) { -count = count + step; -} -} -function getCount() public returns (uint) { -return count; -} -function kill() { -if (owner == msg.sender) { -selfdestruct(owner); -} -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test1Grammar014.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test1Grammar014.sol deleted file mode 100644 index c55b5b391a3..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test1Grammar014.sol +++ /dev/null @@ -1,59 +0,0 @@ -pragma solidity ^0.4.4; -contract A { -uint256 public numberForB; -address public senderForB; -function callTest(address bAddress, uint256 _number) { -bAddress.call(bytes4(sha3("setValue(uint256)")), _number); // B's storage is set, A is not modified -} -function callcodeTest(address bAddress, uint256 _number) { -bAddress.callcode(bytes4(sha3("setValue(uint256)")), _number); // A's storage is set, B is not modified -} -function delegatecallTest(address bAddress, uint256 _number) { -bAddress.delegatecall(bytes4(sha3("setValue(uint256)")), _number); // A's storage is set, B is not modified -} - -function callAddTest(address bAddress) { -bAddress.call(bytes4(sha3("add()"))); // B's storage is set, A is not modified -bAddress.call(bytes4(sha3("add()"))); // B's storage is set, A is not modified -} -function getnumberForB() public returns(uint256){ - return numberForB; - } - function getsenderForB() public returns(address){ - return senderForB; - } -} -contract B { -uint256 public numberForB; -address public senderForB; -address public addr11; -mapping(uint256=>address) public addr1; -mapping(uint256=>address) public addr2; -function setValue(uint256 _number) { -numberForB = _number; -senderForB = msg.sender; -// senderForB is A if invoked by A's callTest. B's storage will be updated -// senderForB is A if invoked by A's callcodeTest. None of B's storage is updated -// senderForB is OWNER if invoked by A's delegatecallTest. None of B's storage is updated -} - -function add() public{ -numberForB=numberForB+1; -C c1 = new C(); -addr1[numberForB]=c1.getAddress(); -addr11 = c1.getAddress(); -C c2 = new C(); -addr2[numberForB] = c2.getAddress(); -} -function getnumberForB() public returns(uint256){ - return numberForB; - } - function getsenderForB() public returns(address){ - return senderForB; - } -} -contract C { -function getAddress() public view returns(address){ -return address(this); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test2Grammar015.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test2Grammar015.sol deleted file mode 100644 index 4e704628f4b..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test2Grammar015.sol +++ /dev/null @@ -1,37 +0,0 @@ -pragma solidity ^0.4.0; - -contract ExecuteFallback{ - - //回退事件,会把调用的数据打印出来 - event FallbackCalled(bytes data); - //fallback函数,注意是没有名字的,没有参数,没有返回值的 - function(){ - FallbackCalled(msg.data); - } - - //调用已存在函数的事件,会把调用的原始数据,请求参数打印出来 - event ExistFuncCalled(bytes data, uint256 para); - //一个存在的函数 - function existFunc(uint256 para){ - ExistFuncCalled(msg.data, para); - } - - // 模拟从外部对一个存在的函数发起一个调用,将直接调用函数 - function callExistFunc(){ - bytes4 funcIdentifier = bytes4(keccak256("existFunc(uint256)")); - this.call(funcIdentifier, uint256(1)); - } - - //模拟从外部对一个不存在的函数发起一个调用,由于匹配不到函数,将调用回退函数 - function callNonExistFunc(){ - bytes4 funcIdentifier = bytes4(keccak256("functionNotExist()")); - this.call(funcIdentifier); - } - - function ExistFuncCalledTopic() view returns(bytes32){ - return keccak256("ExistFuncCalled(bytes,uint256)"); - } - function FallbackCalledTopic() view returns(bytes32){ - return keccak256("FallbackCalled(bytes)"); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test3Grammar016.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test3Grammar016.sol deleted file mode 100644 index a39a0a08d96..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test3Grammar016.sol +++ /dev/null @@ -1,23 +0,0 @@ -pragma solidity ^0.4.0; -contract C { -uint private data; -function f(uint a) private returns(uint b) { return a + 1; } -function setData(uint a) public { data = a; } -function getData() public returns(uint) { return data; } -function compute(uint a, uint b) internal returns (uint) { return a+b; } -} -contract D { -function readData() public{ -C c = new C(); -//uint local = c.f(7); // error: member "f" is not visible -c.setData(3); -uint local = c.getData(); -// local = c.compute(3, 5); // error: member "compute" is not visible -} -} -contract E is C { -function g() public { -C c = new C(); -uint val = compute(3, 5); // access to internal member (from derived to parent contract) -} -} diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test4Grammar017.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test4Grammar017.sol deleted file mode 100644 index 3387a9c30bd..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test4Grammar017.sol +++ /dev/null @@ -1,47 +0,0 @@ -pragma solidity ^0.4.0; -contract CrowdFunding{ -struct Funder{ -address addr; -uint amount; -} - -struct Campaign{ -address beneficiary; -uint goal; -uint amount; -uint funderNum; -mapping(uint => Funder) funders; -} - -uint compaingnID; -mapping (uint => Campaign) campaigns; - -function candidate(address beneficiary, uint goal) returns (uint compaingnID){ -// initialize -campaigns[compaingnID++] = Campaign(beneficiary, goal, 0, 0); -} - -function vote(uint compaingnID) payable { -Campaign c = campaigns[compaingnID]; - -//another way to initialize -c.funders[c.funderNum++] = Funder({addr: msg.sender, amount: msg.value}); -c.amount += msg.value; -} - -function check(uint comapingnId) returns (bool){ -Campaign c = campaigns[comapingnId]; - -if(c.amount < c.goal){ -return false; -} - -uint amount = c.amount; -// incase send much more -c.amount = 0; -if(!c.beneficiary.send(amount)){ -throw; -} -return true; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test5Grammar018.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test5Grammar018.sol deleted file mode 100644 index 4fdaf52a29f..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test5Grammar018.sol +++ /dev/null @@ -1,36 +0,0 @@ -pragma solidity ^0.4.0; - - -contract Grammar18{ - function testAddmod() public returns (uint z) { - //计算(x + y)%k,其中以任意精度执行加法,并且不在2 ** 256处围绕 - z=addmod(2, 2, 3); - return z; - } - function testMulmod() public returns (uint z) { -//计算(x * y)%k,其中乘法以任意精度执行,并且不会在2 ** 256处循环。 - z=mulmod(2, 3, 4); - return z; - } - - function testKeccak256() public returns(bytes32){ - //计算的(紧凑)参数的Ethereum-SHA-3(Keccak-256)的散列 - return keccak256("11"); - } - - function testSha256() public returns(bytes32){ - //计算(紧密包装)参数的SHA-256散列 - return sha256("11"); - } - function testSha3() public returns(bytes32){ - //计算(紧密包装)参数的SHA-256散列 - return sha3("11"); - } - - function testRipemd160() public returns(bytes32){ - //计算(紧密包装)参数的RIPEMD-160哈希值 - return ripemd160("11"); - } - - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test6Grammar019.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test6Grammar019.sol deleted file mode 100644 index 3b2d5f2263c..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test6Grammar019.sol +++ /dev/null @@ -1,12 +0,0 @@ -pragma solidity ^0.4.0; -contract timetest { - -function timetest() public { -require( 1 == 1 seconds); -require(1 minutes == 60 seconds); -require(1 hours == 60 minutes); -require(1 days == 24 hours); -require(1 weeks == 7 days); -require(1 years == 365 days); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test7Grammar020.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test7Grammar020.sol deleted file mode 100644 index d5157c18c47..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractGrammar003test7Grammar020.sol +++ /dev/null @@ -1,7 +0,0 @@ -pragma solidity ^0.4.0; -contract trxtest { - -function test() public { -require(1 trx == 1000000 sun); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInnerContract.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInnerContract.sol deleted file mode 100644 index 02402acd217..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInnerContract.sol +++ /dev/null @@ -1,31 +0,0 @@ -//pragma solidity ^0.4.0; - - - -contract InnerContract { - - - constructor() public payable{} - function() external payable{} - function messageI() payable returns (uint ret) { - - - - } - -} - - - -contract OuterContract { - - constructor() public payable{} - function() external payable{} - - function callInner(address addr) payable returns (uint) { - - return InnerContract(addr).messageI.value(1)(); - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction001.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction001.sol deleted file mode 100644 index 1f13e067773..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction001.sol +++ /dev/null @@ -1,42 +0,0 @@ -pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable public{} - function test1(address cAddr) public payable{ - B b1 = (new B).value(10)();//1.1 - B b2 = new B();//1.2 - b2.transfer(5);//1.3 - b2.callCGetZero(cAddr, 1);//1.4 - b2.callCGetZero(cAddr,2);//1.6 - } - function test2(address cAddress,uint256 amount) public payable{ - cAddress.call.value(amount)(bytes4(keccak256("newBAndTransfer()")));//2.1 - cAddress.call.value(amount + 1)(bytes4(keccak256("newBAndTransfer()")));//2.6 - } -} - -contract B{ - constructor() payable public{} - function() payable public{} - function getOne() payable returns(uint256){ - return 1; - } - function callCGetZero(address cAddress,uint256 amount){ - cAddress.call.value(amount)(bytes4(keccak256("getZero()")));//1.5,1.7 - } -} - -contract C{ - constructor() payable public{} - function() payable public{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - B b1 = (new B).value(7)();//2.2,2.7 - b1.getOne();//2.3,2.8 - B b2 = (new B).value(3)();//2.4,2.9 - b2.getOne();//2.5,2.10 - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction002.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction002.sol deleted file mode 100644 index b5fd94f5a0e..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction002.sol +++ /dev/null @@ -1,20 +0,0 @@ -pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable public{} - - function test2(address cAddress,uint256 amount) public payable{ - cAddress.call.value(amount)();//2.1 - } -} - - -contract C{ - constructor() payable public{} - function() payable public{} - function getZero() payable public returns(uint256){ - return 0; - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction003.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction003.sol deleted file mode 100644 index ab8841419e7..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction003.sol +++ /dev/null @@ -1,31 +0,0 @@ -pragma solidity ^0.4.24; - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer() payable public{ - B b = (new B).value(10)();//1 - - } - function getBalance() returns(uint256){ - return this.balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable returns(bool) { - return true; - } - constructor() public payable {} - function payC(address c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() public returns(uint256){ - return this.balance; - } - function () payable{} - } - diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction004.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction004.sol deleted file mode 100644 index 8a03691b172..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction004.sol +++ /dev/null @@ -1,24 +0,0 @@ -pragma solidity ^0.4.24; - -contract A{ - constructor () payable public{} - function suicide(address toAddress) public payable{ - selfdestruct(toAddress); - } - function () payable public{} - function getBalance() public view returns(uint256){ - return this.balance; - } -} -contract B{ - function kill(address contractAddres, address toAddress) payable public { - contractAddres.call(bytes4(keccak256("suicide(address)")),address(this)); - } - function kill2(){ - A a = new A(); - a.suicide(this); - } - function getBalance() public view returns(uint256){ - return this.balance; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction005.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction005.sol deleted file mode 100644 index d4042dba94a..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction005.sol +++ /dev/null @@ -1,54 +0,0 @@ -pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable public{} - function test1() public payable{ - B b1 = (new B).value(10)();//1.1 - b1.callCGetZero(false); - b1.callCGetZero(true);//1.4 - } - function test2() public payable{ - C c1 = (new C).value(10)();//1.1 - c1.newBAndTransfer(false); - c1.newBAndTransfer(true);//1.4 - - } - function getBalance() view public returns(uint256){ - return this.balance; - } -} - -contract B{ - constructor() payable public{} - function() payable public{} - function getOne() payable returns(uint256){ - return 1; - } - function callCGetZero(bool success) payable{ - if(!success){ - assert(1==2); - } - } - function getBalance() view public returns(uint256){ - return this.balance; - } -} - -contract C{ - uint256 public flag=0; - constructor() payable public{} - function() payable public{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer(bool success) payable public returns(uint256){ - flag = 1; - if(!success){ - require(2==1); - } - } - function getFlag() public returns(uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction006.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction006.sol deleted file mode 100644 index 885966df74f..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction001testInternalTransaction006.sol +++ /dev/null @@ -1,54 +0,0 @@ -pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable public{} - function test1() public payable{ - B b1 = (new B).value(10)();//1.1 - b1.callCGetZero(true);//1.4 - b1.callCGetZero(false); - } - function test2() public payable{ - C c1 = (new C).value(10)();//1.1 - c1.newBAndTransfer(true);//1.4 - c1.newBAndTransfer(false); - - } - function getBalance() view public returns(uint256){ - return this.balance; - } -} - -contract B{ - constructor() payable public{} - function() payable public{} - function getOne() payable returns(uint256){ - return 1; - } - function callCGetZero(bool success) payable{ - if(!success){ - assert(1==2); - } - } - function getBalance() view public returns(uint256){ - return this.balance; - } -} - -contract C{ - uint256 public flag=0; - constructor() payable public{} - function() payable public{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer(bool success) payable public returns(uint256){ - flag = 1; - if(!success){ - require(2==1); - } - } - function getFlag() public returns(uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test1InternalTransaction007.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test1InternalTransaction007.sol deleted file mode 100644 index fc1eb39c36e..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test1InternalTransaction007.sol +++ /dev/null @@ -1,38 +0,0 @@ -pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable public{} - function test1(address cAddr) public payable{ - B b1 = (new B).value(10)();//1.1 - B b2 = new B();//1.2 - b2.transfer(5);//1.3 - b2.callCGetZero();//1.4 - } - function test2(address cAddress,uint256 amount) public payable{ - cAddress.call.value(amount)(bytes4(keccak256("newBAndTransfer()")));//2.1 - } -} - -contract B{ - constructor() payable public{} - function() payable public{} - function getOne() payable returns(uint256){ - return 1; - } - function callCGetZero(){ - assert(1==2); - - } -} - -contract C{ - constructor() payable public{} - function() payable public{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test2InternalTransaction008.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test2InternalTransaction008.sol deleted file mode 100644 index f728c2a8bf6..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test2InternalTransaction008.sol +++ /dev/null @@ -1,60 +0,0 @@ -pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable public{} - - function testAssert(address bAddress,uint256 amount) public payable{ - bAddress.call.value(amount).gas(1000000)(bytes4(keccak256("callCGetZero(bool)")),false);//2.1 - bAddress.call.value(amount).gas(1000000)(bytes4(keccak256("callCGetZero(bool)")),true); - } - function testRequire(address cAddress,uint256 amount) public payable{ - cAddress.call.value(amount).gas(1000000)(bytes4(keccak256("newBAndTransfer(bool)")),false);//2.1 - cAddress.call.value(amount).gas(1000000)(bytes4(keccak256("newBAndTransfer(bool)")),true); - } - function testAssert1(address bAddress,uint256 amount) public payable{ - bAddress.call.value(amount).gas(1000000)(bytes4(keccak256("callCGetZero(bool)")),true); - bAddress.call.value(amount).gas(1000000)(bytes4(keccak256("callCGetZero(bool)")),false);//2.1 - } - function testtRequire2(address cAddress,uint256 amount) public payable{ - cAddress.call.value(amount).gas(1000000)(bytes4(keccak256("newBAndTransfer(bool)")),true); - cAddress.call.value(amount).gas(1000000)(bytes4(keccak256("newBAndTransfer(bool)")),false);//2.1 - } - function getBalance() view public returns(uint256){ - return this.balance; - } -} - -contract B{ - constructor() payable public{} - function() payable public{} - function getOne() payable returns(uint256){ - return 1; - } - function callCGetZero(bool success) payable{ - if(!success){ - assert(1==2); - } - } - function getBalance() view public returns(uint256){ - return this.balance; - } -} - -contract C{ - uint256 public flag=0; - constructor() payable public{} - function() payable public{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer(bool success) payable public returns(uint256){ - flag = 1; - if(!success){ - require(2==1); - } - } - function getFlag() public returns(uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test3InternalTransaction009.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test3InternalTransaction009.sol deleted file mode 100644 index 199c0884182..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test3InternalTransaction009.sol +++ /dev/null @@ -1,47 +0,0 @@ -pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable public{} - function test1(address cAddr,address dcontract,address baddress) public payable{ - B b1 = (new B).value(10)();//1.1 - b1.transfer(5);//1.3 - b1.callCGetZero(cAddr, 1);//1.4 - b1.getOne(dcontract,baddress); - } -} - -contract B{ - constructor() payable public{} - function() payable public{} - function getOne(address contractAddres, address toAddress) payable public{ - contractAddres.call(bytes4(keccak256("suicide1(address)")),address(this)); - - } - function callCGetZero(address cAddress,uint256 amount){ - cAddress.call.value(amount)(bytes4(keccak256("getZero()")));//1.5,1.7 - } -} - -contract C{ - constructor() payable public{} - function() payable public{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public{ - B b1 = (new B).value(7)();//2.2,2.7 - B b2 = (new B).value(3)();//2.4,2.9 - } -} - -contract D{ - constructor () payable public{} - function suicide1(address toAddress) public payable{ - selfdestruct(toAddress); - } - function () payable public{} - function getBalance() public view returns(uint256){ - return this.balance; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test4InternalTransaction010.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test4InternalTransaction010.sol deleted file mode 100644 index 7c10d407461..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test4InternalTransaction010.sol +++ /dev/null @@ -1,188 +0,0 @@ -pragma solidity ^0.4.24; - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - - } - function transfer2() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - - } - function getBalance() returns(uint256){ - return this.balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable returns(bool) { - return true; - } - constructor() public payable {} - function payC(address c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() returns(uint256){ - return this.balance; - } - function () payable{} - } - diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test5InternalTransaction012.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test5InternalTransaction012.sol deleted file mode 100644 index 3dd0c1b2cae..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction002test5InternalTransaction012.sol +++ /dev/null @@ -1,51 +0,0 @@ -pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable public{} - function test1(address bAddr,address eAddr) public payable{ - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - } - -} - -contract B{ - constructor() payable public{} - function() payable public{} - function getOne() payable returns(uint256){ - return 1; - } - function testNN(address eAddress) public payable{ - D d1=(new D).value(1000)(); - d1.getOne(eAddress); - } -} - -contract C{ - constructor() payable public{} - function() payable public{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - function() payable public{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract D{ - constructor() payable public{} - function() payable public{} - function getOne(address eAddress) payable returns(uint256){ - eAddress.call.value(1)(bytes4(keccak256("getZero()")));//2.1 - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction013.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction013.sol deleted file mode 100644 index 4e48646270f..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction013.sol +++ /dev/null @@ -1,56 +0,0 @@ -pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable public{} - function test1(address dAddr) public payable{ - B b1 = (new B).value(10)();//1.1 - b1.testNN(dAddr,2);//1.6 - // C c1 = (new C).value(1000000000000)();//1.2 - // E e1 = (new E).value(1)();//1.2 - } - function test2(address cAddress,uint256 amount) public payable{ - cAddress.call.value(amount)(bytes4(keccak256("newBAndTransfer()")));//2.1 - } -} - -contract B{ - constructor() payable public{} - function() payable public{} - function getOne() payable returns(uint256){ - return 1; - } - function testNN(address dAddress,uint256 amount) public payable{ - // D d1=(new D)(); - dAddress.call.value(amount)(bytes4(keccak256("getOne()")));//2.1 - } -} - -contract C{ - constructor() payable public{} - function() payable public{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - function() payable public{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract D{ - constructor() payable public{} - function() payable public{} - function getOne() payable returns(uint256){ - E e = (new E).value(5)(); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction014.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction014.sol deleted file mode 100644 index 46e1f8e0eed..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction014.sol +++ /dev/null @@ -1,40 +0,0 @@ -pragma solidity ^0.4.24; - -contract callerContract { - constructor() payable{} - function() payable{} - function sendToB(address called_address,address c) public payable{ - called_address.delegatecall(bytes4(keccak256("transferTo(address)")),c); - } - function sendToB2(address called_address,address c) public payable{ - called_address.call(bytes4(keccak256("transferTo(address)")),c); - } - function sendToB3(address called_address,address c) public payable{ - called_address.callcode(bytes4(keccak256("transferTo(address)")),c); - } -} - - contract calledContract { - function() payable{} - constructor() payable {} - function transferTo(address toAddress)public payable{ - toAddress.transfer(5); - } - - function setIinC(address c) public payable{ - c.call.value(5)(bytes4(keccak256("setI()"))); - } - - } - - contract c{ - uint256 public i=0; - constructor() public payable{} - function getBalance() public view returns(uint256){ - return this.balance; - } - function setI() payable{ - i=5; - } - function() payable{} - } diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction015.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction015.sol deleted file mode 100644 index 61666b44892..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction015.sol +++ /dev/null @@ -1,60 +0,0 @@ -pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable public{} - function test1(address dAddr,address eAddr) public payable{ - B b1 = (new B).value(10)();//1.1 - b1.testNN(dAddr,2,eAddr);//1.6 - // C c1 = (new C).value(1000000000000)();//1.2 - // E e1 = (new E).value(1)();//1.2 - } - function test2(address cAddress,uint256 amount) public payable{ - cAddress.call.value(amount)(bytes4(keccak256("newBAndTransfer()")));//2.1 - } -} - -contract B{ - constructor() payable public{} - function() payable public{} - function getOne() payable returns(uint256){ - return 1; - } - function testNN(address dAddress,uint256 amount,address eAddress) public payable{ - // D d1=(new D)(); - dAddress.call.value(amount)(bytes4(keccak256("getOne(address)")),address(this));//2.1 - } -} - -contract C{ - constructor() payable public{} - function() payable public{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - function() payable public{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } - function suicide(address toAddress) public payable{ - selfdestruct(toAddress); - } -} -contract D{ - constructor() payable public{} - function() payable public{} - function getOne(address eAddress) payable public{ - E e = (new E).value(5)(); - e.suicide(eAddress); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction016.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction016.sol deleted file mode 100644 index b0cbe16af4d..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction016.sol +++ /dev/null @@ -1,184 +0,0 @@ -pragma solidity ^0.4.24; - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - - B b1=(new B).value(1)();//1 - b1.suicide(this); - } - function transfer2() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - B b1=(new B).value(1)();//1 - b1.suicide(this); - } - function getBalance() returns(uint256){ - return this.balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable returns(bool) { - return true; - } - constructor() public payable {} - function payC(address c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() returns(uint256){ - return this.balance; - } - function () payable{} - function suicide(address toAddress) public payable{ - selfdestruct(toAddress); - } - } - diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction017.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction017.sol deleted file mode 100644 index 2352e61b733..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction017.sol +++ /dev/null @@ -1,194 +0,0 @@ -pragma solidity ^0.4.24; - - contract A{ - uint256 public num = 0; - constructor() public payable{} - function transfer(address Address) payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - - B b=(new B).value(1)();//1 - selfdestruct(Address); - } - function transfer2() payable public{ - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - (new B).value(1)();//1 - - } - function getBalance() public returns(uint256){ - return this.balance; - } - } - contract B{ - uint256 public num = 0; - function f() payable returns(bool) { - return true; - } - constructor() public payable {} - function payC(address c, bool isRevert) public{ - c.transfer(1);//4 - if (isRevert) { - revert(); - } - } - function getBalance() returns(uint256){ - return this.balance; - } - function () payable{} - } - diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction018.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction018.sol deleted file mode 100644 index 6341ee61b06..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractInternalTransaction003testInternalTransaction018.sol +++ /dev/null @@ -1,149 +0,0 @@ -pragma solidity ^0.4.24; - -contract A{ - constructor() payable public{} - function() payable public{} - function test1(address bAddr,address eAddr) public payable{ - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - bAddr.call.value(1)(bytes4(keccak256("testNN(address)")),eAddr);//2.1 - - - } - -} - -contract B{ - constructor() payable public{} - function() payable public{} - function getOne() payable returns(uint256){ - return 1; - } - function testNN(address eAddress) public payable{ - D d1=(new D).value(100)(); - d1.getOne(eAddress); - } -} - -contract C{ - constructor() payable public{} - function() payable public{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract E{ - constructor() payable public{} - function() payable public{} - function getZero() payable public returns(uint256){ - return 0; - } - function newBAndTransfer() payable public returns(uint256){ - require(2==1); - } -} -contract D{ - constructor() payable public{} - function() payable public{} - function getOne(address eAddress) payable returns(uint256){ - eAddress.call.value(1)(bytes4(keccak256("getZero()")));//2.1 - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage001.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage001.sol deleted file mode 100644 index 4c04cf5c6fb..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage001.sol +++ /dev/null @@ -1,9 +0,0 @@ -//pragma solidity ^0.4.0; - -contract divideIHaveArgsReturnStorage{ -constructor() payable public{} -function() payable external{} -function divideIHaveArgsReturn(int x,int y) public payable returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage002.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage002.sol deleted file mode 100644 index ca38896acee..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage002.sol +++ /dev/null @@ -1,7 +0,0 @@ -//pragma solidity ^0.4.0; - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage003.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage003.sol deleted file mode 100644 index ca38896acee..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage003.sol +++ /dev/null @@ -1,7 +0,0 @@ -//pragma solidity ^0.4.0; - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage004.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage004.sol deleted file mode 100644 index ca38896acee..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage004.sol +++ /dev/null @@ -1,7 +0,0 @@ -//pragma solidity ^0.4.0; - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage005.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage005.sol deleted file mode 100644 index 7b943aee5c1..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage005.sol +++ /dev/null @@ -1,51 +0,0 @@ -contract timeoutTest { - string public iarray1; - // cpu - function oneCpu() public { - require(1==1); - } - - function storage8Char() public { - iarray1 = "12345678"; - } - - function testUseCpu(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - } - return count; - } - - - uint256[] public iarray; - uint public calculatedFibNumber; - mapping(address=>mapping(address=>uint256)) public m; - - function testUseStorage(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - iarray.push(i); - } - return count; - } - - // stack - //uint n = 0; - uint yy = 0; - function test() public { - //n += 1; - yy += 1; - test(); - } - - function setFibonacci(uint n) public returns (uint256){ - calculatedFibNumber = fibonacci(n); - return calculatedFibNumber; - } - - function fibonacci(uint n) internal returns (uint) { - return fibonacci(n - 1) + fibonacci(n - 2); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage006.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage006.sol deleted file mode 100644 index 9b16ff63368..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractLinkage006.sol +++ /dev/null @@ -1,18 +0,0 @@ -//pragma solidity ^0.4.0; -contract AA{ - uint256 public count=0; - constructor () payable public{} - function init(address addr, uint256 max) payable public { - count =0; - this.hack(addr,max); - } - function hack(address addr, uint256 max) payable public { - while (count < max) { - count = count +1; - this.hack(addr,max); - } - if (count == max) { - addr.send(20); - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractOriginEnergyLimit001.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractOriginEnergyLimit001.sol deleted file mode 100644 index af80b15cc8b..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractOriginEnergyLimit001.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma solidity ^0.4.0; - -contract findArgsContractTest{ - function findArgsByIndexTest(uint i) public returns (uint z) { - uint[] memory a = new uint[](3); - a[0]=1; - a[1]=2; - a[2]=3; - return a[i]; - } -} diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractOriginEnergyLimit004.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractOriginEnergyLimit004.sol deleted file mode 100644 index af80b15cc8b..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractOriginEnergyLimit004.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma solidity ^0.4.0; - -contract findArgsContractTest{ - function findArgsByIndexTest(uint i) public returns (uint z) { - uint[] memory a = new uint[](3); - a[0]=1; - a[1]=2; - a[2]=3; - return a[i]; - } -} diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractOtherToTrcToken.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractOtherToTrcToken.sol deleted file mode 100644 index 1fcff0c039f..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractOtherToTrcToken.sol +++ /dev/null @@ -1,40 +0,0 @@ -pragma solidity ^0.4.24; -contract ConvertType { - -constructor() payable public{} - -function() payable external{} - -//function stringToTrctoken(address payable toAddress, string memory tokenStr, uint256 tokenValue) public { -// trcToken t = trcToken(tokenStr); // ERROR -// toAddress.transferToken(tokenValue, tokenStr); // ERROR -//} - -function uint256ToTrctoken(address toAddress,uint256 tokenValue, uint256 tokenInt) public { - trcToken t = trcToken(tokenInt); // OK - toAddress.transferToken(tokenValue, t); // OK - toAddress.transferToken(tokenValue, tokenInt); // OK -} - -function addressToTrctoken(address toAddress, uint256 tokenValue, address adr) public { - trcToken t = trcToken(adr); // OK - toAddress.transferToken(tokenValue, t); // OK -//toAddress.transferToken(tokenValue, adr); // ERROR -} - -//function bytesToTrctoken(address payable toAddress, bytes memory b, uint256 tokenValue) public { - // trcToken t = trcToken(b); // ERROR - // toAddress.transferToken(tokenValue, b); // ERROR -//} - -function bytes32ToTrctoken(address toAddress, uint256 tokenValue, bytes32 b32) public { - trcToken t = trcToken(b32); // OK - toAddress.transferToken(tokenValue, t); // OK -// toAddress.transferToken(tokenValue, b32); // ERROR -} - -//function arrayToTrctoken(address payable toAddress, uint256[] memory arr, uint256 tokenValue) public { -//trcToken t = trcToken(arr); // ERROR -// toAddress.transferToken(tokenValue, arr); // ERROR -//} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario001.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractScenario001.sol deleted file mode 100644 index ca38896acee..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario001.sol +++ /dev/null @@ -1,7 +0,0 @@ -//pragma solidity ^0.4.0; - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario002.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractScenario002.sol deleted file mode 100644 index c096bbff619..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario002.sol +++ /dev/null @@ -1,53 +0,0 @@ -//pragma solidity ^0.4.0; -contract TronNative{ - - address public voteContractAddress= address(0x10001); - address public freezeBalanceAddress = address(0x10002); - address public unFreezeBalanceAddress = address(0x10003); - address public withdrawBalanceAddress = address(0x10004); - address public approveProposalAddress = address(0x10005); - address public createProposalAddress = address(0x10006); - address public deleteProposalAddress = address(0x10007); - constructor () payable public {} - - function voteForSingleWitness (address witnessAddr, uint256 voteValue) public{ - // method 1: - voteContractAddress.delegatecall(abi.encode(witnessAddr,voteValue)); - } - - function voteUsingAssembly (address witnessAddr, uint256 voteValue) public{ - // method 2: - assembly{ - mstore(0x80,witnessAddr) - mstore(0xa0,voteValue) - // gas, address, in, size, out, size - if iszero(delegatecall(0, 0x10001, 0x80, 0x40, 0x80, 0x0)) { - revert(0, 0) - } - } - } - - function freezeBalance(uint256 frozen_Balance,uint256 frozen_Duration) public { - freezeBalanceAddress.delegatecall(abi.encode(frozen_Balance,frozen_Duration)); - } - - function unFreezeBalance() public { - unFreezeBalanceAddress.delegatecall(""); - } - - function withdrawBalance() public { - withdrawBalanceAddress.delegatecall(""); - } - - function approveProposal(uint256 id, bool isApprove) public { - approveProposalAddress.delegatecall(abi.encode(id,isApprove)); - } - - function createProposal(bytes32 [] memory data) public { - createProposalAddress.delegatecall(abi.encode(data)); - } - - function deleteProposal(uint256 id) public{ - deleteProposalAddress.delegatecall(abi.encode(id)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario003.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractScenario003.sol deleted file mode 100644 index ca38896acee..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario003.sol +++ /dev/null @@ -1,7 +0,0 @@ -//pragma solidity ^0.4.0; - -contract divideIHaveArgsReturnStorage{ -function divideIHaveArgsReturn(int x,int y) public returns (int z) { -return z = x / y; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario004.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractScenario004.sol deleted file mode 100644 index b3ca2687b4c..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario004.sol +++ /dev/null @@ -1,88 +0,0 @@ -//pragma solidity ^0.4.11; - -contract TronToken { - - string public name = "Tronix"; // token name - string public symbol = "TRX"; // token symbol - uint256 public decimals = 6; // token digit - - mapping (address => uint256) public balanceOf; - mapping (address => mapping (address => uint256)) public allowance; - - uint256 public totalSupply = 0; - bool public stopped = false; - - uint256 constant valueFounder = 100000000000000000; - address owner = address(0x0); - - modifier isOwner { - assert(owner == msg.sender); - _; - } - - modifier isRunning { - assert (!stopped); - _; - } - - modifier validAddress { - assert(address(0x0) != msg.sender); - _; - } - - constructor(address _addressFounder) public { - owner = msg.sender; - totalSupply = valueFounder; - balanceOf[_addressFounder] = valueFounder; - emit Transfer(address(0x0), _addressFounder, valueFounder); - } - - function transfer(address _to, uint256 _value) isRunning validAddress public returns (bool success) { - require(balanceOf[msg.sender] >= _value); - require(balanceOf[_to] + _value >= balanceOf[_to]); - balanceOf[msg.sender] -= _value; - balanceOf[_to] += _value; - emit Transfer(msg.sender, _to, _value); - return true; - } - - function transferFrom(address _from, address _to, uint256 _value) isRunning validAddress public returns (bool success) { - require(balanceOf[_from] >= _value); - require(balanceOf[_to] + _value >= balanceOf[_to]); - require(allowance[_from][msg.sender] >= _value); - balanceOf[_to] += _value; - balanceOf[_from] -= _value; - allowance[_from][msg.sender] -= _value; - emit Transfer(_from, _to, _value); - return true; - } - - function approve(address _spender, uint256 _value) isRunning validAddress public returns (bool success) { - require(_value == 0 || allowance[msg.sender][_spender] == 0); - allowance[msg.sender][_spender] = _value; - emit Approval(msg.sender, _spender, _value); - return true; - } - - function stop() isOwner public { - stopped = true; - } - - function start() isOwner public { - stopped = false; - } - - function setName(string memory _name) isOwner public { - name = _name; - } - - function burn(uint256 _value) public { - require(balanceOf[msg.sender] >= _value); - balanceOf[msg.sender] -= _value; - balanceOf[address(0x0)] += _value; - emit Transfer(msg.sender, address(0x0), _value); - } - - event Transfer(address indexed _from, address indexed _to, uint256 _value); - event Approval(address indexed _owner, address indexed _spender, uint256 _value); -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario005.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractScenario005.sol deleted file mode 100644 index f4bec71761c..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario005.sol +++ /dev/null @@ -1,103 +0,0 @@ -//pragma solidity ^0.4.16; - -interface token { - function transfer(address receiver, uint amount); -} - -contract Crowdsale { - address public beneficiary = 0x1B228F5D9F934C7BB18AAA86F90418932888E7B4; // 募资成功后的收款方 - uint public fundingGoal = 10000000; // 募资额度 - uint public amountRaised = 1000000; // 参与数量 - uint public deadline; // 募资截止期 - - uint public price; // token 与以太坊的汇率 , token卖多少钱 - token public tokenReward; // 要卖的token - - mapping(address => uint256) public balanceOf; - - bool fundingGoalReached = false; // 众筹是否达到目标 - bool crowdsaleClosed = false; // 众筹是否结束 - - /** - * 事件可以用来跟踪信息 - **/ - event GoalReached(address recipient, uint totalAmountRaised); - event FundTransfer(address backer, uint amount, bool isContribution); - - /** - * 构造函数, 设置相关属性 - */ - function Crowdsale( - address ifSuccessfulSendTo, - uint fundingGoalInEthers, - uint durationInMinutes, - uint finneyCostOfEachToken, - address addressOfTokenUsedAsReward) { - beneficiary = ifSuccessfulSendTo; - fundingGoal = fundingGoalInEthers * 1 sun; - deadline = now + durationInMinutes * 1 minutes; - price = finneyCostOfEachToken * 1 sun; - tokenReward = token(addressOfTokenUsedAsReward); // 传入已发布的 token 合约的地址来创建实例 - } - - /** - * 无函数名的Fallback函数, - * 在向合约转账时,这个函数会被调用 - */ - function () payable { - require(!crowdsaleClosed); - uint amount = msg.value; - balanceOf[msg.sender] += amount; - amountRaised += amount; - tokenReward.transfer(msg.sender, amount / price); - FundTransfer(msg.sender, amount, true); - } - - /** - * 定义函数修改器modifier(作用和Python的装饰器很相似) - * 用于在函数执行前检查某种前置条件(判断通过之后才会继续执行该方法) - * _ 表示继续执行之后的代码 - **/ - modifier afterDeadline() { if (now >= deadline) _; } - - /** - * 判断众筹是否完成融资目标, 这个方法使用了afterDeadline函数修改器 - * - */ - function checkGoalReached() afterDeadline { - if (amountRaised >= fundingGoal) { - fundingGoalReached = true; - GoalReached(beneficiary, amountRaised); - } - crowdsaleClosed = true; - } - - - /** - * 完成融资目标时,融资款发送到收款方 - * 未完成融资目标时,执行退款 - * - */ - function safeWithdrawal() afterDeadline { - if (!fundingGoalReached) { - uint amount = balanceOf[msg.sender]; - balanceOf[msg.sender] = 0; - if (amount > 0) { - if (msg.sender.send(amount)) { - FundTransfer(msg.sender, amount, false); - } else { - balanceOf[msg.sender] = amount; - } - } - } - - if (fundingGoalReached && beneficiary == msg.sender) { - if (beneficiary.send(amountRaised)) { - FundTransfer(beneficiary, amountRaised, false); - } else { - //If we fail to send the funds to beneficiary, unlock funders balance - fundingGoalReached = false; - } - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario006.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractScenario006.sol deleted file mode 100644 index af55371cb6e..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario006.sol +++ /dev/null @@ -1,1954 +0,0 @@ -//pragma solidity ^0.4.24; - -interface PlayerBookInterface { - function getPlayerID(address _addr) external returns (uint256); - function getPlayerName(uint256 _pID) external view returns (bytes32); - function getPlayerLAff(uint256 _pID) external view returns (uint256); - function getPlayerAddr(uint256 _pID) external view returns (address); - function getNameFee() external view returns (uint256); - function registerNameXIDFromDapp(address _addr, bytes32 _name, uint256 _affCode, bool _all) external payable returns(bool, uint256); - function registerNameXaddrFromDapp(address _addr, bytes32 _name, address _affCode, bool _all) external payable returns(bool, uint256); - function registerNameXnameFromDapp(address _addr, bytes32 _name, bytes32 _affCode, bool _all) external payable returns(bool, uint256); - function isDev(address _who) external view returns(bool); -} - - -/** -* @title -Name Filter- v0.1.9 -* ┌┬┐┌─┐┌─┐┌┬┐ ╦╦ ╦╔═╗╔╦╗ ┌─┐┬─┐┌─┐┌─┐┌─┐┌┐┌┌┬┐┌─┐ -* │ ├┤ ├─┤│││ ║║ ║╚═╗ ║ ├─┘├┬┘├┤ └─┐├┤ │││ │ └─┐ -* ┴ └─┘┴ ┴┴ ┴ ╚╝╚═╝╚═╝ ╩ ┴ ┴└─└─┘└─┘└─┘┘└┘ ┴ └─┘ -* _____ _____ -* (, / /) /) /) (, / /) /) -* ┌─┐ / _ (/_ // // / _ // _ __ _(/ -* ├─┤ ___/___(/_/(__(_/_(/_(/_ ___/__/_)_(/_(_(_/ (_(_(_ -* ┴ ┴ / / .-/ _____ (__ / -* (__ / (_/ (, / /)™ -* / __ __ __ __ _ __ __ _ _/_ _ _(/ -* ┌─┐┬─┐┌─┐┌┬┐┬ ┬┌─┐┌┬┐ /__/ (_(__(_)/ (_/_)_(_)/ (_(_(_(__(/_(_(_ -* ├─┘├┬┘│ │ │││ ││ │ (__ / .-/ © Jekyll Island Inc. 2018 -* ┴ ┴└─└─┘─┴┘└─┘└─┘ ┴ (_/ -* _ __ _ ____ ____ _ _ _____ ____ ___ -*=============| |\ | / /\ | |\/| | |_ =====| |_ | | | | | | | |_ | |_)==============* -*=============|_| \| /_/--\ |_| | |_|__=====|_| |_| |_|__ |_| |_|__ |_| \==============* -* -* ╔═╗┌─┐┌┐┌┌┬┐┬─┐┌─┐┌─┐┌┬┐ ╔═╗┌─┐┌┬┐┌─┐ ┌──────────┐ -* ║ │ ││││ │ ├┬┘├─┤│ │ ║ │ │ ││├┤ │ Inventor │ -* ╚═╝└─┘┘└┘ ┴ ┴└─┴ ┴└─┘ ┴ ╚═╝└─┘─┴┘└─┘ └──────────┘ -*/ - -library NameFilter { - /** - * @dev filters name strings - * -converts uppercase to lower case. - * -makes sure it does not start/end with a space - * -makes sure it does not contain multiple spaces in a row - * -cannot be only numbers - * -cannot start with 0x - * -restricts characters to A-Z, a-z, 0-9, and space. - * @return reprocessed string in bytes32 format - */ - function nameFilter(string _input) - internal - pure - returns(bytes32) - { - bytes memory _temp = bytes(_input); - uint256 _length = _temp.length; - - //sorry limited to 32 characters - require (_length <= 32 && _length > 0, "string must be between 1 and 32 characters"); - // make sure it doesnt start with or end with space - require(_temp[0] != 0x20 && _temp[_length-1] != 0x20, "string cannot start or end with space"); - // make sure first two characters are not 0x - if (_temp[0] == 0x30) - { - require(_temp[1] != 0x78, "string cannot start with 0x"); - require(_temp[1] != 0x58, "string cannot start with 0X"); - } - - // create a bool to track if we have a non number character - bool _hasNonNumber; - - // convert & check - for (uint256 i = 0; i < _length; i++) - { - // if its uppercase A-Z - if (_temp[i] > 0x40 && _temp[i] < 0x5b) - { - // convert to lower case a-z - _temp[i] = byte(uint(_temp[i]) + 32); - - // we have a non number - if (_hasNonNumber == false) - _hasNonNumber = true; - } else { - require - ( - // require character is a space - _temp[i] == 0x20 || - // OR lowercase a-z - (_temp[i] > 0x60 && _temp[i] < 0x7b) || - // or 0-9 - (_temp[i] > 0x2f && _temp[i] < 0x3a), - "string contains invalid characters" - ); - // make sure theres not 2x spaces in a row - if (_temp[i] == 0x20) - require( _temp[i+1] != 0x20, "string cannot contain consecutive spaces"); - - // see if we have a character other than a number - if (_hasNonNumber == false && (_temp[i] < 0x30 || _temp[i] > 0x39)) - _hasNonNumber = true; - } - } - - require(_hasNonNumber == true, "string cannot be only numbers"); - - bytes32 _ret; - assembly { - _ret := mload(add(_temp, 32)) - } - return (_ret); - } -} - - -library SafeMath { - - /** - * @dev Multiplies two numbers, throws on overflow. - */ - function mul(uint256 a, uint256 b) - internal - pure - returns (uint256 c) - { - if (a == 0) { - return 0; - } - c = a * b; - require(c / a == b, "SafeMath mul failed"); - return c; - } - - /** - * @dev Integer division of two numbers, truncating the quotient. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - // assert(b > 0); // Solidity automatically throws when dividing by 0 - uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - return c; - } - - /** - * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). - */ - function sub(uint256 a, uint256 b) - internal - pure - returns (uint256) - { - require(b <= a, "SafeMath sub failed"); - return a - b; - } - - /** - * @dev Adds two numbers, throws on overflow. - */ - function add(uint256 a, uint256 b) - internal - pure - returns (uint256 c) - { - c = a + b; - require(c >= a, "SafeMath add failed"); - return c; - } - - /** - * @dev gives square root of given x. - */ - function sqrt(uint256 x) - internal - pure - returns (uint256 y) - { - uint256 z = ((add(x,1)) / 2); - y = x; - while (z < y) - { - y = z; - z = ((add((x / z),z)) / 2); - } - } - - /** - * @dev gives square. multiplies x by x - */ - function sq(uint256 x) - internal - pure - returns (uint256) - { - return (mul(x,x)); - } - - /** - * @dev x to the power of y - */ - function pwr(uint256 x, uint256 y) - internal - pure - returns (uint256) - { - if (x==0) - return (0); - else if (y==0) - return (1); - else - { - uint256 z = x; - for (uint256 i=1; i < y; i++) - z = mul(z,x); - return (z); - } - } -} - -//============================================================================== -// | _ _ _ | _ . -// |<(/_\/ (_(_||(_ . -//=======/====================================================================== -library F3DKeysCalcLong { - using SafeMath for *; - /** - * @dev calculates number of keys received given X eth - * @param _curEth current amount of eth in contract - * @param _newEth eth being spent - * @return amount of ticket purchased - */ - function keysRec(uint256 _curEth, uint256 _newEth) - internal - pure - returns (uint256) - { - return(keys((_curEth).add(_newEth)).sub(keys(_curEth))); - } - - /** - * @dev calculates amount of eth received if you sold X keys - * @param _curKeys current amount of keys that exist - * @param _sellKeys amount of keys you wish to sell - * @return amount of eth received - */ - function ethRec(uint256 _curKeys, uint256 _sellKeys) - internal - pure - returns (uint256) - { - return((eth(_curKeys)).sub(eth(_curKeys.sub(_sellKeys)))); - } - - /** - * @dev calculates how many keys would exist with given an amount of eth - * @param _eth eth "in contract" - * @return number of keys that would exist - */ - function keys(uint256 _eth) - internal - pure - returns(uint256) - { - return ((((((_eth).mul(1000000000000000000)).mul(312500000000000000000000000)).add(5624988281256103515625000000000000000000000000000000000000000000)).sqrt()).sub(74999921875000000000000000000000)) / (156250000); - } - - /** - * @dev calculates how much eth would be in contract given a number of keys - * @param _keys number of keys "in contract" - * @return eth that would exists - */ - function eth(uint256 _keys) - internal - pure - returns(uint256) - { - return ((78125000).mul(_keys.sq()).add(((149999843750000).mul(_keys.mul(1000000000000000000))) / (2))) / ((1000000000000000000).sq()); - } -} - -library F3Ddatasets { - //compressedData key - // [76-33][32][31][30][29][28-18][17][16-6][5-3][2][1][0] - // 0 - new player (bool) - // 1 - joined round (bool) - // 2 - new leader (bool) - // 3-5 - air drop tracker (uint 0-999) - // 6-16 - round end time - // 17 - winnerTeam - // 18 - 28 timestamp - // 29 - team - // 30 - 0 = reinvest (round), 1 = buy (round), 2 = buy (ico), 3 = reinvest (ico) - // 31 - airdrop happened bool - // 32 - airdrop tier - // 33 - airdrop amount won - //compressedIDs key - // [77-52][51-26][25-0] - // 0-25 - pID - // 26-51 - winPID - // 52-77 - rID - struct EventReturns { - uint256 compressedData; - uint256 compressedIDs; - address winnerAddr; // winner address - bytes32 winnerName; // winner name - uint256 amountWon; // amount won - uint256 newPot; // amount in new pot - uint256 P3DAmount; // amount distributed to p3d - uint256 genAmount; // amount distributed to gen - uint256 potAmount; // amount added to pot - } - struct Player { - address addr; // player address - bytes32 name; // player name - uint256 win; // winnings vault - uint256 gen; // general vault - uint256 aff; // affiliate vault - uint256 lrnd; // last round played - uint256 laff; // last affiliate id used - } - struct PlayerRounds { - uint256 eth; // eth player has added to round (used for eth limiter) - uint256 keys; // keys - uint256 mask; // player mask - uint256 ico; // ICO phase investment - } - struct Round { - uint256 plyr; // pID of player in lead - uint256 team; // tID of team in lead - uint256 end; // time ends/ended - bool ended; // has round end function been ran - uint256 strt; // time round started - uint256 keys; // keys - uint256 eth; // total eth in - uint256 pot; // eth to pot (during round) / final amount paid to winner (after round ends) - uint256 mask; // global mask - uint256 ico; // total eth sent in during ICO phase - uint256 icoGen; // total eth for gen during ICO phase - uint256 icoAvg; // average key price for ICO phase - } - struct TeamFee { - uint256 gen; // % of buy in thats paid to key holders of current round - uint256 p3d; // % of buy in thats paid to p3d holders - } - struct PotSplit { - uint256 gen; // % of pot thats paid to key holders of current round - uint256 p3d; // % of pot thats paid to p3d holders - } -} - -contract F3Devents { - // fired whenever a player registers a name - event onNewName - ( - uint256 indexed playerID, - address indexed playerAddress, - bytes32 indexed playerName, - bool isNewPlayer, - uint256 affiliateID, - address affiliateAddress, - bytes32 affiliateName, - uint256 amountPaid, - uint256 timeStamp - ); - - // fired at end of buy or reload - event onEndTx - ( - uint256 compressedData, - uint256 compressedIDs, - bytes32 playerName, - address playerAddress, - uint256 ethIn, - uint256 keysBought, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount, - uint256 potAmount, - uint256 airDropPot - ); - - // fired whenever theres a withdraw - event onWithdraw - ( - uint256 indexed playerID, - address playerAddress, - bytes32 playerName, - uint256 ethOut, - uint256 timeStamp - ); - - // fired whenever a withdraw forces end round to be ran - event onWithdrawAndDistribute - ( - address playerAddress, - bytes32 playerName, - uint256 ethOut, - uint256 compressedData, - uint256 compressedIDs, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount - ); - - // (fomo3d long only) fired whenever a player tries a buy after round timer - // hit zero, and causes end round to be ran. - event onBuyAndDistribute - ( - address playerAddress, - bytes32 playerName, - uint256 ethIn, - uint256 compressedData, - uint256 compressedIDs, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount - ); - - // (fomo3d long only) fired whenever a player tries a reload after round timer - // hit zero, and causes end round to be ran. - event onReLoadAndDistribute - ( - address playerAddress, - bytes32 playerName, - uint256 compressedData, - uint256 compressedIDs, - address winnerAddr, - bytes32 winnerName, - uint256 amountWon, - uint256 newPot, - uint256 P3DAmount, - uint256 genAmount - ); - - // fired whenever an affiliate is paid - event onAffiliatePayout - ( - uint256 indexed affiliateID, - address affiliateAddress, - bytes32 affiliateName, - uint256 indexed roundID, - uint256 indexed buyerID, - uint256 amount, - uint256 timeStamp - ); - - // received pot swap deposit - event onPotSwapDeposit - ( - uint256 roundID, - uint256 amountAddedToPot - ); -} - - - -contract FoMo3Dlong is F3Devents { - using SafeMath for *; - using NameFilter for string; - using F3DKeysCalcLong for uint256; - - address public otherF3D_; - address public Divies; - address public Jekyll_Island_Inc; - PlayerBookInterface public playerBook;// =PlayerBookInterface(0x0dcd2f752394c41875e259e00bb44fd505297caf);//new PlayerBook();// - // TeamJustInterface constant private teamJust = TeamJustInterface(0x3a5f8140b9213a0f733a6a639857c9df43ee3f5a);// new TeamJust();// - - //============================================================================== - // _ _ _ |`. _ _ _ |_ | _ _ . - // (_(_)| |~|~|(_||_|| (_||_)|(/__\ . (game settings) - //=================_|=========================================================== - string constant public name = "FoMo3D Long Official"; - string constant public symbol = "F3D"; - uint256 private rndExtra_ = 30;//extSettings.getLongExtra(); // length of the very first ICO - uint256 private rndGap_ = 30; //extSettings.getLongGap(); // length of ICO phase, set to 1 year for EOS. - uint256 constant private rndInit_ = 1 hours; // round timer starts at this - uint256 constant private rndInc_ = 30 seconds; // every full key purchased adds this much to the timer - uint256 constant private rndMax_ = 24 hours; // max length a round timer can be - //============================================================================== - // _| _ _|_ _ _ _ _|_ _ . - // (_|(_| | (_| _\(/_ | |_||_) . (data used to store game info that changes) - //=============================|================================================ - uint256 public airDropPot_; // person who gets the airdrop wins part of this pot - uint256 public airDropTracker_ = 0; // incremented each time a "qualified" tx occurs. used to determine winning air drop - uint256 public rID_; // round id number / total rounds that have happened - //**************** - // PLAYER DATA - //**************** - mapping(address => uint256) public pIDxAddr_; // (addr => pID) returns player id by address - mapping(bytes32 => uint256) public pIDxName_; // (name => pID) returns player id by name - mapping(uint256 => F3Ddatasets.Player) public plyr_; // (pID => data) player data - mapping(uint256 => mapping(uint256 => F3Ddatasets.PlayerRounds)) public plyrRnds_; // (pID => rID => data) player round data by player id & round id - mapping(uint256 => mapping(bytes32 => bool)) public plyrNames_; // (pID => name => bool) list of names a player owns. (used so you can change your display name amongst any name you own) - //**************** - // ROUND DATA - //**************** - mapping(uint256 => F3Ddatasets.Round) public round_; // (rID => data) round data - mapping(uint256 => mapping(uint256 => uint256)) public rndTmEth_; // (rID => tID => data) eth in per team, by round id and team id - //**************** - // TEAM FEE DATA - //**************** - mapping(uint256 => F3Ddatasets.TeamFee) public fees_; // (team => fees) fee distribution by team - mapping(uint256 => F3Ddatasets.PotSplit) public potSplit_; // (team => fees) pot split distribution by team - - function setPlayerBook(address _playerBook) external { - require(msg.sender == owner, 'only dev!'); - require(address(playerBook) == address(0), 'already set!'); - playerBook = PlayerBookInterface(_playerBook); - } - - address public owner; - - //============================================================================== - // _ _ _ __|_ _ __|_ _ _ . - // (_(_)| |_\ | | |_|(_ | (_)| . (initial data setup upon contract deploy) - //============================================================================== - constructor() - public - { - owner = msg.sender; - // Team allocation structures - // 0 = whales - // 1 = bears - // 2 = sneks - // 3 = bulls - - // Team allocation percentages - // (F3D, P3D) + (Pot , Referrals, Community) - // Referrals / Community rewards are mathematically designed to come from the winner's share of the pot. - fees_[0] = F3Ddatasets.TeamFee(30, 6); - //50% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - fees_[1] = F3Ddatasets.TeamFee(43, 0); - //43% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - fees_[2] = F3Ddatasets.TeamFee(56, 10); - //20% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - fees_[3] = F3Ddatasets.TeamFee(43, 8); - //35% to pot, 10% to aff, 2% to com, 1% to pot swap, 1% to air drop pot - - // how to split up the final pot based on which team was picked - // (F3D, P3D) - potSplit_[0] = F3Ddatasets.PotSplit(15, 10); - //48% to winner, 25% to next round, 2% to com - potSplit_[1] = F3Ddatasets.PotSplit(25, 0); - //48% to winner, 25% to next round, 2% to com - potSplit_[2] = F3Ddatasets.PotSplit(20, 20); - //48% to winner, 10% to next round, 2% to com - potSplit_[3] = F3Ddatasets.PotSplit(30, 10); - //48% to winner, 10% to next round, 2% to com - } - //============================================================================== - // _ _ _ _|. |`. _ _ _ . - // | | |(_)(_||~|~|(/_| _\ . (these are safety checks) - //============================================================================== - /** - * @dev used to make sure no one can interact with contract until it has - * been activated. - */ - modifier isActivated() { - require(activated_ == true, "its not ready yet. check ?eta in discord"); - _; - } - - /** - * @dev prevents contracts from interacting with fomo3d - */ - modifier isHuman() { - address _addr = msg.sender; - uint256 _codeLength; - - assembly {_codeLength := extcodesize(_addr)} - require(_codeLength == 0, "sorry humans only"); - _; - } - - modifier onlyDevs() - { - require(playerBook.isDev(msg.sender) == true, "msg sender is not a dev"); - _; - } - - /** - * @dev sets boundaries for incoming tx - */ - modifier isWithinLimits(uint256 _eth) { - require(_eth >= 1000000000, "pocket lint: not a valid currency"); - require(_eth <= 100000000000000000000000, "no vitalik, no"); - _; - } - - //============================================================================== - // _ |_ |. _ |` _ __|_. _ _ _ . - // |_)|_||_)||(_ ~|~|_|| |(_ | |(_)| |_\ . (use these to interact with contract) - //====|========================================================================= - /** - * @dev emergency buy uses last stored affiliate ID and team snek - */ - function() - isActivated() - isHuman() - isWithinLimits(msg.value) - public - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // buy core - buyCore(_pID, plyr_[_pID].laff, 2, _eventData_); - } - - /** - * @dev converts all incoming ethereum to keys. - * -functionhash- 0x8f38f309 (using ID for affiliate) - * -functionhash- 0x98a0871d (using address for affiliate) - * -functionhash- 0xa65b37a1 (using name for affiliate) - * @param _affCode the ID/address/name of the player who gets the affiliate fee - * @param _team what team is the player playing for? - */ - function buyXid(uint256 _affCode, uint256 _team) - isActivated() - isHuman() - isWithinLimits(msg.value) - public - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == 0 || _affCode == _pID) - { - // use last stored affiliate code - _affCode = plyr_[_pID].laff; - - // if affiliate code was given & its not the same as previously stored - } else if (_affCode != plyr_[_pID].laff) { - // update last affiliate - plyr_[_pID].laff = _affCode; - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // buy core - buyCore(_pID, _affCode, _team, _eventData_); - } - - function buyXaddr(address _affCode, uint256 _team) - isActivated() - isHuman() - isWithinLimits(msg.value) - public - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == address(0) || _affCode == msg.sender) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxAddr_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // buy core - buyCore(_pID, _affID, _team, _eventData_); - } - - function buyXname(bytes32 _affCode, uint256 _team) - isActivated() - isHuman() - isWithinLimits(msg.value) - public - payable - { - // set up our tx event data and determine if player is new or not - F3Ddatasets.EventReturns memory _eventData_ = determinePID(_eventData_); - - // fetch player id - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == '' || _affCode == plyr_[_pID].name) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxName_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // buy core - buyCore(_pID, _affID, _team, _eventData_); - } - - /** - * @dev essentially the same as buy, but instead of you sending ether - * from your wallet, it uses your unwithdrawn earnings. - * -functionhash- 0x349cdcac (using ID for affiliate) - * -functionhash- 0x82bfc739 (using address for affiliate) - * -functionhash- 0x079ce327 (using name for affiliate) - * @param _affCode the ID/address/name of the player who gets the affiliate fee - * @param _team what team is the player playing for? - * @param _eth amount of earnings to use (remainder returned to gen vault) - */ - function reLoadXid(uint256 _affCode, uint256 _team, uint256 _eth) - isActivated() - isHuman() - isWithinLimits(_eth) - public - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == 0 || _affCode == _pID) - { - // use last stored affiliate code - _affCode = plyr_[_pID].laff; - - // if affiliate code was given & its not the same as previously stored - } else if (_affCode != plyr_[_pID].laff) { - // update last affiliate - plyr_[_pID].laff = _affCode; - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // reload core - reLoadCore(_pID, _affCode, _team, _eth, _eventData_); - } - - function reLoadXaddr(address _affCode, uint256 _team, uint256 _eth) - isActivated() - isHuman() - isWithinLimits(_eth) - public - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == address(0) || _affCode == msg.sender) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxAddr_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // reload core - reLoadCore(_pID, _affID, _team, _eth, _eventData_); - } - - function reLoadXname(bytes32 _affCode, uint256 _team, uint256 _eth) - isActivated() - isHuman() - isWithinLimits(_eth) - public - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // manage affiliate residuals - uint256 _affID; - // if no affiliate code was given or player tried to use their own, lolz - if (_affCode == '' || _affCode == plyr_[_pID].name) - { - // use last stored affiliate code - _affID = plyr_[_pID].laff; - - // if affiliate code was given - } else { - // get affiliate ID from aff Code - _affID = pIDxName_[_affCode]; - - // if affID is not the same as previously stored - if (_affID != plyr_[_pID].laff) - { - // update last affiliate - plyr_[_pID].laff = _affID; - } - } - - // verify a valid team was selected - _team = verifyTeam(_team); - - // reload core - reLoadCore(_pID, _affID, _team, _eth, _eventData_); - } - - /** - * @dev withdraws all of your earnings. - * -functionhash- 0x3ccfd60b - */ - function withdraw() - isActivated() - isHuman() - public - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - // fetch player ID - uint256 _pID = pIDxAddr_[msg.sender]; - - // setup temp var for player eth - uint256 _eth; - - // check to see if round has ended and no one has run round end yet - if (_now > round_[_rID].end && round_[_rID].ended == false && round_[_rID].plyr != 0) - { - // set up our tx event data - F3Ddatasets.EventReturns memory _eventData_; - - // end the round (distributes pot) - round_[_rID].ended = true; - _eventData_ = endRound(_eventData_); - - // get their earnings - _eth = withdrawEarnings(_pID); - - // gib moni - if (_eth > 0) - plyr_[_pID].addr.transfer(_eth); - - // build event data - _eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID; - - // fire withdraw and distribute event - emit F3Devents.onWithdrawAndDistribute - ( - msg.sender, - plyr_[_pID].name, - _eth, - _eventData_.compressedData, - _eventData_.compressedIDs, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount - ); - - // in any other situation - } else { - // get their earnings - _eth = withdrawEarnings(_pID); - - // gib moni - if (_eth > 0) - plyr_[_pID].addr.transfer(_eth); - - // fire withdraw event - emit F3Devents.onWithdraw(_pID, msg.sender, plyr_[_pID].name, _eth, _now); - } - } - - /** - * @dev use these to register names. they are just wrappers that will send the - * registration requests to the PlayerBook contract. So registering here is the - * same as registering there. UI will always display the last name you registered. - * but you will still own all previously registered names to use as affiliate - * links. - * - must pay a registration fee. - * - name must be unique - * - names will be converted to lowercase - * - name cannot start or end with a space - * - cannot have more than 1 space in a row - * - cannot be only numbers - * - cannot start with 0x - * - name must be at least 1 char - * - max length of 32 characters long - * - allowed characters: a-z, 0-9, and space - * -functionhash- 0x921dec21 (using ID for affiliate) - * -functionhash- 0x3ddd4698 (using address for affiliate) - * -functionhash- 0x685ffd83 (using name for affiliate) - * @param _nameString players desired name - * @param _affCode affiliate ID, address, or name of who referred you - * @param _all set to true if you want this to push your info to all games - * (this might cost a lot of gas) - */ - function registerNameXID(string _nameString, uint256 _affCode, bool _all) - isHuman() - public - payable - { - bytes32 _name = _nameString.nameFilter(); - address _addr = msg.sender; - uint256 _paid = msg.value; - (bool _isNewPlayer, uint256 _affID) = playerBook.registerNameXIDFromDapp.value(_paid)(_addr, _name, _affCode, _all); - - uint256 _pID = pIDxAddr_[_addr]; - - // fire event - emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, now); - } - - function registerNameXaddr(string _nameString, address _affCode, bool _all) - isHuman() - public - payable - { - bytes32 _name = _nameString.nameFilter(); - address _addr = msg.sender; - uint256 _paid = msg.value; - (bool _isNewPlayer, uint256 _affID) = playerBook.registerNameXaddrFromDapp.value(msg.value)(msg.sender, _name, _affCode, _all); - - uint256 _pID = pIDxAddr_[_addr]; - - // fire event - emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, now); - } - - function registerNameXname(string _nameString, bytes32 _affCode, bool _all) - isHuman() - public - payable - { - bytes32 _name = _nameString.nameFilter(); - address _addr = msg.sender; - uint256 _paid = msg.value; - (bool _isNewPlayer, uint256 _affID) = playerBook.registerNameXnameFromDapp.value(msg.value)(msg.sender, _name, _affCode, _all); - - uint256 _pID = pIDxAddr_[_addr]; - - // fire event - emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, now); - } - //============================================================================== - // _ _ _|__|_ _ _ _ . - // (_|(/_ | | (/_| _\ . (for UI & viewing things on etherscan) - //=====_|======================================================================= - /** - * @dev return the price buyer will pay for next 1 individual key. - * -functionhash- 0x018a25e8 - * @return price for next key bought (in wei format) - */ - function getBuyPrice() - public - view - returns (uint256) - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - // are we in a round? - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - return ((round_[_rID].keys.add(1000000000000000000)).ethRec(1000000000000000000)); - else // rounds over. need price for new round - return (75000000000000); - // init - } - - /** - * @dev returns time left. dont spam this, you'll ddos yourself from your node - * provider - * -functionhash- 0xc7e284b8 - * @return time left in seconds - */ - function getTimeLeft() - public - view - returns (uint256) - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - if (_now < round_[_rID].end) - if (_now > round_[_rID].strt + rndGap_) - return ((round_[_rID].end).sub(_now)); - else - return ((round_[_rID].strt + rndGap_).sub(_now)); - else - return (0); - } - - /** - * @dev returns player earnings per vaults - * -functionhash- 0x63066434 - * @return winnings vault - * @return general vault - * @return affiliate vault - */ - function getPlayerVaults(uint256 _pID) - public - view - returns (uint256, uint256, uint256) - { - // setup local rID - uint256 _rID = rID_; - - // if round has ended. but round end has not been run (so contract has not distributed winnings) - if (now > round_[_rID].end && round_[_rID].ended == false && round_[_rID].plyr != 0) - { - // if player is winner - if (round_[_rID].plyr == _pID) - { - return - ( - (plyr_[_pID].win).add(((round_[_rID].pot).mul(48)) / 100), - (plyr_[_pID].gen).add(getPlayerVaultsHelper(_pID, _rID).sub(plyrRnds_[_pID][_rID].mask)), - plyr_[_pID].aff - ); - // if player is not the winner - } else { - return - ( - plyr_[_pID].win, - (plyr_[_pID].gen).add(getPlayerVaultsHelper(_pID, _rID).sub(plyrRnds_[_pID][_rID].mask)), - plyr_[_pID].aff - ); - } - - // if round is still going on, or round has ended and round end has been ran - } else { - return - ( - plyr_[_pID].win, - (plyr_[_pID].gen).add(calcUnMaskedEarnings(_pID, plyr_[_pID].lrnd)), - plyr_[_pID].aff - ); - } - } - - /** - * solidity hates stack limits. this lets us avoid that hate - */ - function getPlayerVaultsHelper(uint256 _pID, uint256 _rID) - private - view - returns (uint256) - { - return (((((round_[_rID].mask).add(((((round_[_rID].pot).mul(potSplit_[round_[_rID].team].gen)) / 100).mul(1000000000000000000)) / (round_[_rID].keys))).mul(plyrRnds_[_pID][_rID].keys)) / 1000000000000000000)); - } - - /** - * @dev returns all current round info needed for front end - * -functionhash- 0x747dff42 - * @return eth invested during ICO phase - * @return round id - * @return total keys for round - * @return time round ends - * @return time round started - * @return current pot - * @return current team ID & player ID in lead - * @return current player in leads address - * @return current player in leads name - * @return whales eth in for round - * @return bears eth in for round - * @return sneks eth in for round - * @return bulls eth in for round - * @return airdrop tracker # & airdrop pot - */ - function getCurrentRoundInfo() - public - view - returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256, address, bytes32, uint256, uint256, uint256, uint256, uint256) - { - // setup local rID - uint256 _rID = rID_; - - return - ( - round_[_rID].ico, //0 - _rID, //1 - round_[_rID].keys, //2 - round_[_rID].end, //3 - round_[_rID].strt, //4 - round_[_rID].pot, //5 - (round_[_rID].team + (round_[_rID].plyr * 10)), //6 - plyr_[round_[_rID].plyr].addr, //7 - plyr_[round_[_rID].plyr].name, //8 - rndTmEth_[_rID][0], //9 - rndTmEth_[_rID][1], //10 - rndTmEth_[_rID][2], //11 - rndTmEth_[_rID][3], //12 - airDropTracker_ + (airDropPot_ * 1000) //13 - ); - } - - /** - * @dev returns player info based on address. if no address is given, it will - * use msg.sender - * -functionhash- 0xee0b5d8b - * @param _addr address of the player you want to lookup - * @return player ID - * @return player name - * @return keys owned (current round) - * @return winnings vault - * @return general vault - * @return affiliate vault - * @return player round eth - */ - function getPlayerInfoByAddress(address _addr) - public - view - returns (uint256, bytes32, uint256, uint256, uint256, uint256, uint256) - { - // setup local rID - uint256 _rID = rID_; - - if (_addr == address(0)) - { - _addr == msg.sender; - } - uint256 _pID = pIDxAddr_[_addr]; - - return - ( - _pID, //0 - plyr_[_pID].name, //1 - plyrRnds_[_pID][_rID].keys, //2 - plyr_[_pID].win, //3 - (plyr_[_pID].gen).add(calcUnMaskedEarnings(_pID, plyr_[_pID].lrnd)), //4 - plyr_[_pID].aff, //5 - plyrRnds_[_pID][_rID].eth //6 - ); - } - - //============================================================================== - // _ _ _ _ | _ _ . _ . - // (_(_)| (/_ |(_)(_||(_ . (this + tools + calcs + modules = our softwares engine) - //=====================_|======================================================= - /** - * @dev logic runs whenever a buy order is executed. determines how to handle - * incoming eth depending on if we are in an active round or not - */ - function buyCore(uint256 _pID, uint256 _affID, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) - private - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - // if round is active - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - { - // call core - core(_rID, _pID, msg.value, _affID, _team, _eventData_); - - // if round is not active - } else { - // check to see if end round needs to be ran - if (_now > round_[_rID].end && round_[_rID].ended == false) - { - // end the round (distributes pot) & start new round - round_[_rID].ended = true; - _eventData_ = endRound(_eventData_); - - // build event data - _eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID; - - // fire buy and distribute event - emit F3Devents.onBuyAndDistribute - ( - msg.sender, - plyr_[_pID].name, - msg.value, - _eventData_.compressedData, - _eventData_.compressedIDs, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount - ); - } - - // put eth in players vault - plyr_[_pID].gen = plyr_[_pID].gen.add(msg.value); - } - } - - /** - * @dev logic runs whenever a reload order is executed. determines how to handle - * incoming eth depending on if we are in an active round or not - */ - function reLoadCore(uint256 _pID, uint256 _affID, uint256 _team, uint256 _eth, F3Ddatasets.EventReturns memory _eventData_) - private - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - // if round is active - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - { - // get earnings from all vaults and return unused to gen vault - // because we use a custom safemath library. this will throw if player - // tried to spend more eth than they have. - plyr_[_pID].gen = withdrawEarnings(_pID).sub(_eth); - - // call core - core(_rID, _pID, _eth, _affID, _team, _eventData_); - - // if round is not active and end round needs to be ran - } else if (_now > round_[_rID].end && round_[_rID].ended == false) { - // end the round (distributes pot) & start new round - round_[_rID].ended = true; - _eventData_ = endRound(_eventData_); - - // build event data - _eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID; - - // fire buy and distribute event - emit F3Devents.onReLoadAndDistribute - ( - msg.sender, - plyr_[_pID].name, - _eventData_.compressedData, - _eventData_.compressedIDs, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount - ); - } - } - - /** - * @dev this is the core logic for any buy/reload that happens while a round - * is live. - */ - function core(uint256 _rID, uint256 _pID, uint256 _eth, uint256 _affID, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) - private - { - // if player is new to round - if (plyrRnds_[_pID][_rID].keys == 0) - _eventData_ = managePlayer(_pID, _eventData_); - - // early round eth limiter - if (round_[_rID].eth < 100000000000000000000 && plyrRnds_[_pID][_rID].eth.add(_eth) > 1000000000000000000) - { - uint256 _availableLimit = (1000000000000000000).sub(plyrRnds_[_pID][_rID].eth); - uint256 _refund = _eth.sub(_availableLimit); - plyr_[_pID].gen = plyr_[_pID].gen.add(_refund); - _eth = _availableLimit; - } - - // if eth left is greater than min eth allowed (sorry no pocket lint) - if (_eth > 1000000000) - { - - // mint the new keys - uint256 _keys = (round_[_rID].eth).keysRec(_eth); - - // if they bought at least 1 whole key - if (_keys >= 1000000000000000000) - { - updateTimer(_keys, _rID); - - // set new leaders - if (round_[_rID].plyr != _pID) - round_[_rID].plyr = _pID; - if (round_[_rID].team != _team) - round_[_rID].team = _team; - - // set the new leader bool to true - _eventData_.compressedData = _eventData_.compressedData + 100; - } - - // manage airdrops - if (_eth >= 100000000000000000) - { - airDropTracker_++; - if (airdrop() == true) - { - // gib muni - uint256 _prize; - if (_eth >= 10000000000000000000) - { - // calculate prize and give it to winner - _prize = ((airDropPot_).mul(75)) / 100; - plyr_[_pID].win = (plyr_[_pID].win).add(_prize); - - // adjust airDropPot - airDropPot_ = (airDropPot_).sub(_prize); - - // let event know a tier 3 prize was won - _eventData_.compressedData += 300000000000000000000000000000000; - } else if (_eth >= 1000000000000000000 && _eth < 10000000000000000000) { - // calculate prize and give it to winner - _prize = ((airDropPot_).mul(50)) / 100; - plyr_[_pID].win = (plyr_[_pID].win).add(_prize); - - // adjust airDropPot - airDropPot_ = (airDropPot_).sub(_prize); - - // let event know a tier 2 prize was won - _eventData_.compressedData += 200000000000000000000000000000000; - } else if (_eth >= 100000000000000000 && _eth < 1000000000000000000) { - // calculate prize and give it to winner - _prize = ((airDropPot_).mul(25)) / 100; - plyr_[_pID].win = (plyr_[_pID].win).add(_prize); - - // adjust airDropPot - airDropPot_ = (airDropPot_).sub(_prize); - - // let event know a tier 3 prize was won - _eventData_.compressedData += 300000000000000000000000000000000; - } - // set airdrop happened bool to true - _eventData_.compressedData += 10000000000000000000000000000000; - // let event know how much was won - _eventData_.compressedData += _prize * 1000000000000000000000000000000000; - - // reset air drop tracker - airDropTracker_ = 0; - } - } - - // store the air drop tracker number (number of buys since last airdrop) - _eventData_.compressedData = _eventData_.compressedData + (airDropTracker_ * 1000); - - // update player - plyrRnds_[_pID][_rID].keys = _keys.add(plyrRnds_[_pID][_rID].keys); - plyrRnds_[_pID][_rID].eth = _eth.add(plyrRnds_[_pID][_rID].eth); - - // update round - round_[_rID].keys = _keys.add(round_[_rID].keys); - round_[_rID].eth = _eth.add(round_[_rID].eth); - rndTmEth_[_rID][_team] = _eth.add(rndTmEth_[_rID][_team]); - - // distribute eth - _eventData_ = distributeExternal(_rID, _pID, _eth, _affID, _team, _eventData_); - _eventData_ = distributeInternal(_rID, _pID, _eth, _team, _keys, _eventData_); - - // call end tx function to fire end tx event. - endTx(_pID, _team, _eth, _keys, _eventData_); - } - } - //============================================================================== - // _ _ | _ | _ _|_ _ _ _ . - // (_(_||(_|_||(_| | (_)| _\ . - //============================================================================== - /** - * @dev calculates unmasked earnings (just calculates, does not update mask) - * @return earnings in wei format - */ - function calcUnMaskedEarnings(uint256 _pID, uint256 _rIDlast) - private - view - returns (uint256) - { - return ((((round_[_rIDlast].mask).mul(plyrRnds_[_pID][_rIDlast].keys)) / (1000000000000000000)).sub(plyrRnds_[_pID][_rIDlast].mask)); - } - - /** - * @dev returns the amount of keys you would get given an amount of eth. - * -functionhash- 0xce89c80c - * @param _rID round ID you want price for - * @param _eth amount of eth sent in - * @return keys received - */ - function calcKeysReceived(uint256 _rID, uint256 _eth) - public - view - returns (uint256) - { - // grab time - uint256 _now = now; - - // are we in a round? - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - return ((round_[_rID].eth).keysRec(_eth)); - else // rounds over. need keys for new round - return ((_eth).keys()); - } - - /** - * @dev returns current eth price for X keys. - * -functionhash- 0xcf808000 - * @param _keys number of keys desired (in 18 decimal format) - * @return amount of eth needed to send - */ - function iWantXKeys(uint256 _keys) - public - view - returns (uint256) - { - // setup local rID - uint256 _rID = rID_; - - // grab time - uint256 _now = now; - - // are we in a round? - if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) - return ((round_[_rID].keys.add(_keys)).ethRec(_keys)); - else // rounds over. need price for new round - return ((_keys).eth()); - } - //============================================================================== - // _|_ _ _ | _ . - // | (_)(_)|_\ . - //============================================================================== - /** - * @dev receives name/player info from names contract - */ - function receivePlayerInfo(uint256 _pID, address _addr, bytes32 _name, uint256 _laff) - external - { - require(msg.sender == address(playerBook), "your not playerNames contract... hmmm.."); - if (pIDxAddr_[_addr] != _pID) - pIDxAddr_[_addr] = _pID; - if (pIDxName_[_name] != _pID) - pIDxName_[_name] = _pID; - if (plyr_[_pID].addr != _addr) - plyr_[_pID].addr = _addr; - if (plyr_[_pID].name != _name) - plyr_[_pID].name = _name; - if (plyr_[_pID].laff != _laff) - plyr_[_pID].laff = _laff; - if (plyrNames_[_pID][_name] == false) - plyrNames_[_pID][_name] = true; - } - - /** - * @dev receives entire player name list - */ - function receivePlayerNameList(uint256 _pID, bytes32 _name) - external - { - require(msg.sender == address(playerBook), "your not playerNames contract... hmmm.."); - if (plyrNames_[_pID][_name] == false) - plyrNames_[_pID][_name] = true; - } - - /** - * @dev gets existing or registers new pID. use this when a player may be new - * @return pID - */ - function determinePID(F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns) - { - uint256 _pID = pIDxAddr_[msg.sender]; - // if player is new to this version of fomo3d - if (_pID == 0) - { - // grab their player ID, name and last aff ID, from player names contract - _pID = playerBook.getPlayerID(msg.sender); - bytes32 _name = playerBook.getPlayerName(_pID); - uint256 _laff = playerBook.getPlayerLAff(_pID); - - // set up player account - pIDxAddr_[msg.sender] = _pID; - plyr_[_pID].addr = msg.sender; - - if (_name != "") - { - pIDxName_[_name] = _pID; - plyr_[_pID].name = _name; - plyrNames_[_pID][_name] = true; - } - - if (_laff != 0 && _laff != _pID) - plyr_[_pID].laff = _laff; - - // set the new player bool to true - _eventData_.compressedData = _eventData_.compressedData + 1; - } - return (_eventData_); - } - - /** - * @dev checks to make sure user picked a valid team. if not sets team - * to default (sneks) - */ - function verifyTeam(uint256 _team) - private - pure - returns (uint256) - { - if (_team < 0 || _team > 3) - return (2); - else - return (_team); - } - - /** - * @dev decides if round end needs to be run & new round started. and if - * player unmasked earnings from previously played rounds need to be moved. - */ - function managePlayer(uint256 _pID, F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns) - { - // if player has played a previous round, move their unmasked earnings - // from that round to gen vault. - if (plyr_[_pID].lrnd != 0) - updateGenVault(_pID, plyr_[_pID].lrnd); - - // update player's last round played - plyr_[_pID].lrnd = rID_; - - // set the joined round bool to true - _eventData_.compressedData = _eventData_.compressedData + 10; - - return (_eventData_); - } - - /** - * @dev ends the round. manages paying out winner/splitting up pot - */ - function endRound(F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns) - { - // setup local rID - uint256 _rID = rID_; - - // grab our winning player and team id's - uint256 _winPID = round_[_rID].plyr; - uint256 _winTID = round_[_rID].team; - - // grab our pot amount - uint256 _pot = round_[_rID].pot; - - // calculate our winner share, community rewards, gen share, - // p3d share, and amount reserved for next pot - uint256 _win = (_pot.mul(48)) / 100; - uint256 _com = (_pot / 50); - uint256 _gen = (_pot.mul(potSplit_[_winTID].gen)) / 100; - uint256 _p3d = (_pot.mul(potSplit_[_winTID].p3d)) / 100; - uint256 _res = (((_pot.sub(_win)).sub(_com)).sub(_gen)).sub(_p3d); - - // calculate ppt for round mask - uint256 _ppt = (_gen.mul(1000000000000000000)) / (round_[_rID].keys); - uint256 _dust = _gen.sub((_ppt.mul(round_[_rID].keys)) / 1000000000000000000); - if (_dust > 0) - { - _gen = _gen.sub(_dust); - _res = _res.add(_dust); - } - - // pay our winner - plyr_[_winPID].win = _win.add(plyr_[_winPID].win); - - // community rewards - if (!address(Jekyll_Island_Inc).send(_com)) - { - // This ensures Team Just cannot influence the outcome of FoMo3D with - // bank migrations by breaking outgoing transactions. - // Something we would never do. But that's not the point. - // We spent 2000$ in eth re-deploying just to patch this, we hold the - // highest belief that everything we create should be trustless. - // Team JUST, The name you shouldn't have to trust. - _p3d = _p3d.add(_com); - _com = 0; - } - - // distribute gen portion to key holders - round_[_rID].mask = _ppt.add(round_[_rID].mask); - - // send share for p3d to divies - if (_p3d > 0) - Divies.transfer(_p3d); - - // prepare event data - _eventData_.compressedData = _eventData_.compressedData + (round_[_rID].end * 1000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + (_winPID * 100000000000000000000000000) + (_winTID * 100000000000000000); - _eventData_.winnerAddr = plyr_[_winPID].addr; - _eventData_.winnerName = plyr_[_winPID].name; - _eventData_.amountWon = _win; - _eventData_.genAmount = _gen; - _eventData_.P3DAmount = _p3d; - _eventData_.newPot = _res; - - // start next round - rID_++; - _rID++; - round_[_rID].strt = now; - round_[_rID].end = now.add(rndInit_).add(rndGap_); - round_[_rID].pot = _res; - - return (_eventData_); - } - - /** - * @dev moves any unmasked earnings to gen vault. updates earnings mask - */ - function updateGenVault(uint256 _pID, uint256 _rIDlast) - private - { - uint256 _earnings = calcUnMaskedEarnings(_pID, _rIDlast); - if (_earnings > 0) - { - // put in gen vault - plyr_[_pID].gen = _earnings.add(plyr_[_pID].gen); - // zero out their earnings by updating mask - plyrRnds_[_pID][_rIDlast].mask = _earnings.add(plyrRnds_[_pID][_rIDlast].mask); - } - } - - /** - * @dev updates round timer based on number of whole keys bought. - */ - function updateTimer(uint256 _keys, uint256 _rID) - private - { - // grab time - uint256 _now = now; - - // calculate time based on number of keys bought - uint256 _newTime; - if (_now > round_[_rID].end && round_[_rID].plyr == 0) - _newTime = (((_keys) / (1000000000000000000)).mul(rndInc_)).add(_now); - else - _newTime = (((_keys) / (1000000000000000000)).mul(rndInc_)).add(round_[_rID].end); - - // compare to max and set new end time - if (_newTime < (rndMax_).add(_now)) - round_[_rID].end = _newTime; - else - round_[_rID].end = rndMax_.add(_now); - } - - /** - * @dev generates a random number between 0-99 and checks to see if thats - * resulted in an airdrop win - * @return do we have a winner? - */ - function airdrop() - private - view - returns (bool) - { - uint256 seed = uint256(keccak256(abi.encodePacked( - - (block.timestamp).add - (block.difficulty).add - ((uint256(keccak256(abi.encodePacked(block.coinbase)))) / (now)).add - (block.gaslimit).add - ((uint256(keccak256(abi.encodePacked(msg.sender)))) / (now)).add - (block.number) - - ))); - if ((seed - ((seed / 1000) * 1000)) < airDropTracker_) - return (true); - else - return (false); - } - - /** - * @dev distributes eth based on fees to com, aff, and p3d - */ - function distributeExternal(uint256 _rID, uint256 _pID, uint256 _eth, uint256 _affID, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns) - { - // pay 2% out to community rewards - uint256 _com = _eth / 50; - uint256 _p3d; - if (!address(Jekyll_Island_Inc).send(_com)) - { - // This ensures Team Just cannot influence the outcome of FoMo3D with - // bank migrations by breaking outgoing transactions. - // Something we would never do. But that's not the point. - // We spent 2000$ in eth re-deploying just to patch this, we hold the - // highest belief that everything we create should be trustless. - // Team JUST, The name you shouldn't have to trust. - _p3d = _com; - _com = 0; - } - - // pay 1% out to FoMo3D short - uint256 _long = _eth / 100; - otherF3D_.transfer(_long); - - // distribute share to affiliate - uint256 _aff = _eth / 10; - - // decide what to do with affiliate share of fees - // affiliate must not be self, and must have a name registered - if (_affID != _pID && plyr_[_affID].name != '') { - plyr_[_affID].aff = _aff.add(plyr_[_affID].aff); - emit F3Devents.onAffiliatePayout(_affID, plyr_[_affID].addr, plyr_[_affID].name, _rID, _pID, _aff, now); - } else { - _p3d = _aff; - } - - // pay out p3d - _p3d = _p3d.add((_eth.mul(fees_[_team].p3d)) / (100)); - if (_p3d > 0) - { - // deposit to divies contract - Divies.transfer(_p3d); - - // set up event data - _eventData_.P3DAmount = _p3d.add(_eventData_.P3DAmount); - } - - return (_eventData_); - } - - function potSwap() - external - payable - { - // setup local rID - uint256 _rID = rID_ + 1; - - round_[_rID].pot = round_[_rID].pot.add(msg.value); - emit F3Devents.onPotSwapDeposit(_rID, msg.value); - } - - /** - * @dev distributes eth based on fees to gen and pot - */ - function distributeInternal(uint256 _rID, uint256 _pID, uint256 _eth, uint256 _team, uint256 _keys, F3Ddatasets.EventReturns memory _eventData_) - private - returns (F3Ddatasets.EventReturns) - { - // calculate gen share - uint256 _gen = (_eth.mul(fees_[_team].gen)) / 100; - - // toss 1% into airdrop pot - uint256 _air = (_eth / 100); - airDropPot_ = airDropPot_.add(_air); - - // update eth balance (eth = eth - (com share + pot swap share + aff share + p3d share + airdrop pot share)) - _eth = _eth.sub(((_eth.mul(14)) / 100).add((_eth.mul(fees_[_team].p3d)) / 100)); - - // calculate pot - uint256 _pot = _eth.sub(_gen); - - // distribute gen share (thats what updateMasks() does) and adjust - // balances for dust. - uint256 _dust = updateMasks(_rID, _pID, _gen, _keys); - if (_dust > 0) - _gen = _gen.sub(_dust); - - // add eth to pot - round_[_rID].pot = _pot.add(_dust).add(round_[_rID].pot); - - // set up event data - _eventData_.genAmount = _gen.add(_eventData_.genAmount); - _eventData_.potAmount = _pot; - - return (_eventData_); - } - - /** - * @dev updates masks for round and player when keys are bought - * @return dust left over - */ - function updateMasks(uint256 _rID, uint256 _pID, uint256 _gen, uint256 _keys) - private - returns (uint256) - { - /* MASKING NOTES - earnings masks are a tricky thing for people to wrap their minds around. - the basic thing to understand here. is were going to have a global - tracker based on profit per share for each round, that increases in - relevant proportion to the increase in share supply. - - the player will have an additional mask that basically says "based - on the rounds mask, my shares, and how much i've already withdrawn, - how much is still owed to me?" - */ - - // calc profit per key & round mask based on this buy: (dust goes to pot) - uint256 _ppt = (_gen.mul(1000000000000000000)) / (round_[_rID].keys); - round_[_rID].mask = _ppt.add(round_[_rID].mask); - - // calculate player earning from their own buy (only based on the keys - // they just bought). & update player earnings mask - uint256 _pearn = (_ppt.mul(_keys)) / (1000000000000000000); - plyrRnds_[_pID][_rID].mask = (((round_[_rID].mask.mul(_keys)) / (1000000000000000000)).sub(_pearn)).add(plyrRnds_[_pID][_rID].mask); - - // calculate & return dust - return (_gen.sub((_ppt.mul(round_[_rID].keys)) / (1000000000000000000))); - } - - /** - * @dev adds up unmasked earnings, & vault earnings, sets them all to 0 - * @return earnings in wei format - */ - function withdrawEarnings(uint256 _pID) - private - returns (uint256) - { - // update gen vault - updateGenVault(_pID, plyr_[_pID].lrnd); - - // from vaults - uint256 _earnings = (plyr_[_pID].win).add(plyr_[_pID].gen).add(plyr_[_pID].aff); - if (_earnings > 0) - { - plyr_[_pID].win = 0; - plyr_[_pID].gen = 0; - plyr_[_pID].aff = 0; - } - - return (_earnings); - } - - /** - * @dev prepares compression data and fires event for buy or reload tx's - */ - function endTx(uint256 _pID, uint256 _team, uint256 _eth, uint256 _keys, F3Ddatasets.EventReturns memory _eventData_) - private - { - _eventData_.compressedData = _eventData_.compressedData + (now * 1000000000000000000) + (_team * 100000000000000000000000000000); - _eventData_.compressedIDs = _eventData_.compressedIDs + _pID + (rID_ * 10000000000000000000000000000000000000000000000000000); - - emit F3Devents.onEndTx - ( - _eventData_.compressedData, - _eventData_.compressedIDs, - plyr_[_pID].name, - msg.sender, - _eth, - _keys, - _eventData_.winnerAddr, - _eventData_.winnerName, - _eventData_.amountWon, - _eventData_.newPot, - _eventData_.P3DAmount, - _eventData_.genAmount, - _eventData_.potAmount, - airDropPot_ - ); - } - //============================================================================== - // (~ _ _ _._|_ . - // _)(/_(_|_|| | | \/ . - //====================/========================================================= - /** upon contract deploy, it will be deactivated. this is a one time - * use function that will activate the contract. we do this so devs - * have time to set things up on the web end **/ - bool public activated_ = false; - - function activate() - public - onlyDevs - { - - // can only be ran once - require(activated_ == false, "fomo3d already activated"); - - // activate the contract - activated_ = true; - - otherF3D_ = msg.sender; - Divies = msg.sender; - Jekyll_Island_Inc = msg.sender; - - // lets start first round - rID_ = 1; - round_[1].strt = now + rndExtra_ - rndGap_; - round_[1].end = now + rndInit_ + rndExtra_; - } - - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario007.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractScenario007.sol deleted file mode 100644 index 44aae1a5e32..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario007.sol +++ /dev/null @@ -1,1433 +0,0 @@ -//pragma solidity 0.4.24; - -/** - * @title ERC165 - * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md - */ -interface ERC165 { - - /** - * @notice Query if a contract implements an interface - * @param _interfaceId The interface identifier, as specified in ERC-165 - * @dev Interface identification is specified in ERC-165. This function - * uses less than 30,000 gas. - */ - function supportsInterface(bytes4 _interfaceId) external view returns (bool); - -} - -contract ERC721Basic is ERC165 { - - event Transfer( - address indexed _from, - address indexed _to, - uint256 indexed _tokenId - ); - event Approval( - address indexed _owner, - address indexed _approved, - uint256 indexed _tokenId - ); - event ApprovalForAll( - address indexed _owner, - address indexed _operator, - bool _approved - ); - - function balanceOf(address _owner) public view returns (uint256 _balance); - function ownerOf(uint256 _tokenId) public view returns (address _owner); - function exists(uint256 _tokenId) public view returns (bool _exists); - - function approve(address _to, uint256 _tokenId) public; - function getApproved(uint256 _tokenId) - public view returns (address _operator); - - function setApprovalForAll(address _operator, bool _approved) public; - function isApprovedForAll(address _owner, address _operator) - public view returns (bool); - - function transferFrom(address _from, address _to, uint256 _tokenId) public; - function safeTransferFrom(address _from, address _to, uint256 _tokenId) - public; - - function safeTransferFrom( - address _from, - address _to, - uint256 _tokenId, - bytes memory _data - ) - public; -} - - -/** - * @title SupportsInterfaceWithLookup - * @author Matt Condon (@shrugs) - * @dev Implements ERC165 using a lookup table. - */ -contract SupportsInterfaceWithLookup is ERC165 { - bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7; - /** - * 0x01ffc9a7 === - * bytes4(keccak256('supportsInterface(bytes4)')) - */ - - /** - * @dev a mapping of interface id to whether or not it's supported - */ - mapping(bytes4 => bool) internal supportedInterfaces; - - /** - * @dev A contract implementing SupportsInterfaceWithLookup - * implement ERC165 itself - */ - constructor() public { - _registerInterface(InterfaceId_ERC165); - } - - /** - * @dev implement supportsInterface(bytes4) using a lookup table - */ - function supportsInterface(bytes4 _interfaceId) external view returns (bool) { - return supportedInterfaces[_interfaceId]; - } - - /** - * @dev private method for registering an interface - */ - function _registerInterface(bytes4 _interfaceId) internal { - require(_interfaceId != 0xffffffff); - supportedInterfaces[_interfaceId] = true; - } -} - -contract Governable { - - event Pause(); - event Unpause(); - - address public governor; - bool public paused = false; - - constructor() public { - governor = msg.sender; - } - - function setGovernor(address _gov) public onlyGovernor { - governor = _gov; - } - - modifier onlyGovernor { - require(msg.sender == governor); - _; - } - - /** - * @dev Modifier to make a function callable only when the contract is not paused. - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev Modifier to make a function callable only when the contract is paused. - */ - modifier whenPaused() { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyGovernor whenNotPaused public { - paused = true; - emit Pause(); - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyGovernor whenPaused public { - paused = false; - emit Unpause(); - } - -} - -contract CardBase is Governable { - - struct Card { - uint16 proto; - uint16 purity; - } - - function getCard(uint id) public view returns (uint16 proto, uint16 purity) { - Card memory card = cards[id]; - return (card.proto, card.purity); - } - - function getShine(uint16 purity) public pure returns (uint8) { - return uint8(purity / 1000); - } - - Card[] public cards; - -} - -contract CardProto is CardBase { - - event NewProtoCard( - uint16 id, uint8 season, uint8 god, - Rarity rarity, uint8 mana, uint8 attack, - uint8 health, uint8 cardType, uint8 tribe, bool packable - ); - - struct Limit { - uint64 limit; - bool exists; - } - - // limits for mythic cards - mapping(uint16 => Limit) public limits; - - // can only set limits once - function setLimit(uint16 id, uint64 limit) public onlyGovernor { - Limit memory l = limits[id]; - require(!l.exists); - limits[id] = Limit({ - limit: limit, - exists: true - }); - } - - function getLimit(uint16 id) public view returns (uint64 limit, bool set) { - Limit memory l = limits[id]; - return (l.limit, l.exists); - } - - // could make these arrays to save gas - // not really necessary - will be update a very limited no of times - mapping(uint8 => bool) public seasonTradable; - mapping(uint8 => bool) public seasonTradabilityLocked; - uint8 public currentSeason; - - function makeTradable(uint8 season) public onlyGovernor { - seasonTradable[season] = true; - } - - function makeUntradable(uint8 season) public onlyGovernor { - require(!seasonTradabilityLocked[season]); - seasonTradable[season] = false; - } - - function makePermanantlyTradable(uint8 season) public onlyGovernor { - require(seasonTradable[season]); - seasonTradabilityLocked[season] = true; - } - - function isTradable(uint16 proto) public view returns (bool) { - return seasonTradable[protos[proto].season]; - } - - function nextSeason() public onlyGovernor { - //Seasons shouldn't go to 0 if there is more than the uint8 should hold, the governor should know this ¯\_(ツ)_/¯ -M - require(currentSeason <= 255); - - currentSeason++; - mythic.length = 0; - legendary.length = 0; - epic.length = 0; - rare.length = 0; - common.length = 0; - } - - enum Rarity { - Common, - Rare, - Epic, - Legendary, - Mythic - } - - uint8 constant SPELL = 1; - uint8 constant MINION = 2; - uint8 constant WEAPON = 3; - uint8 constant HERO = 4; - - struct ProtoCard { - bool exists; - uint8 god; - uint8 season; - uint8 cardType; - Rarity rarity; - uint8 mana; - uint8 attack; - uint8 health; - uint8 tribe; - } - - // there is a particular design decision driving this: - // need to be able to iterate over mythics only for card generation - // don't store 5 different arrays: have to use 2 ids - // better to bear this cost (2 bytes per proto card) - // rather than 1 byte per instance - - uint16 public protoCount; - - mapping(uint16 => ProtoCard) protos; - - uint16[] public mythic; - uint16[] public legendary; - uint16[] public epic; - uint16[] public rare; - uint16[] public common; - - function addProtos( - uint16[] memory externalIDs, uint8[] memory gods, Rarity[] memory rarities, uint8[] memory manas, uint8[] memory attacks, - uint8[] memory healths, uint8[] memory cardTypes, uint8[] memory tribes, bool[] memory packable - ) public onlyGovernor returns(uint16) { - - for (uint i = 0; i < externalIDs.length; i++) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: gods[i], - season: currentSeason, - cardType: cardTypes[i], - rarity: rarities[i], - mana: manas[i], - attack: attacks[i], - health: healths[i], - tribe: tribes[i] - }); - - _addProto(externalIDs[i], card, packable[i]); - } - - } - - function addProto( - uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 cardType, uint8 tribe, bool packable - ) public onlyGovernor returns(uint16) { - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: cardType, - rarity: rarity, - mana: mana, - attack: attack, - health: health, - tribe: tribe - }); - - _addProto(externalID, card, packable); - } - - function addWeapon( - uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 durability, bool packable - ) public onlyGovernor returns(uint16) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: WEAPON, - rarity: rarity, - mana: mana, - attack: attack, - health: durability, - tribe: 0 - }); - - _addProto(externalID, card, packable); - } - - function addSpell(uint16 externalID, uint8 god, Rarity rarity, uint8 mana, bool packable) public onlyGovernor returns(uint16) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: SPELL, - rarity: rarity, - mana: mana, - attack: 0, - health: 0, - tribe: 0 - }); - - _addProto(externalID, card, packable); - } - - function addMinion( - uint16 externalID, uint8 god, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 tribe, bool packable - ) public onlyGovernor returns(uint16) { - - ProtoCard memory card = ProtoCard({ - exists: true, - god: god, - season: currentSeason, - cardType: MINION, - rarity: rarity, - mana: mana, - attack: attack, - health: health, - tribe: tribe - }); - - _addProto(externalID, card, packable); - } - - function _addProto(uint16 externalID, ProtoCard memory card, bool packable) internal { - - require(!protos[externalID].exists); - - card.exists = true; - - protos[externalID] = card; - - protoCount++; - - emit NewProtoCard( - externalID, currentSeason, card.god, - card.rarity, card.mana, card.attack, - card.health, card.cardType, card.tribe, packable - ); - - if (packable) { - Rarity rarity = card.rarity; - if (rarity == Rarity.Common) { - common.push(externalID); - } else if (rarity == Rarity.Rare) { - rare.push(externalID); - } else if (rarity == Rarity.Epic) { - epic.push(externalID); - } else if (rarity == Rarity.Legendary) { - legendary.push(externalID); - } else if (rarity == Rarity.Mythic) { - mythic.push(externalID); - } else { - require(false); - } - } - } - - function getProto(uint16 id) public view returns( - bool exists, uint8 god, uint8 season, uint8 cardType, Rarity rarity, uint8 mana, uint8 attack, uint8 health, uint8 tribe - ) { - ProtoCard memory proto = protos[id]; - return ( - proto.exists, - proto.god, - proto.season, - proto.cardType, - proto.rarity, - proto.mana, - proto.attack, - proto.health, - proto.tribe - ); - } - - function getRandomCard(Rarity rarity, uint16 random) public view returns (uint16) { - // modulo bias is fine - creates rarity tiers etc - // will obviously revert is there are no cards of that type: this is expected - should never happen - if (rarity == Rarity.Common) { - return common[random % common.length]; - } else if (rarity == Rarity.Rare) { - return rare[random % rare.length]; - } else if (rarity == Rarity.Epic) { - return epic[random % epic.length]; - } else if (rarity == Rarity.Legendary) { - return legendary[random % legendary.length]; - } else if (rarity == Rarity.Mythic) { - // make sure a mythic is available - uint16 id; - uint64 limit; - bool set; - for (uint i = 0; i < mythic.length; i++) { - id = mythic[(random + i) % mythic.length]; - (limit, set) = getLimit(id); - if (set && limit > 0){ - return id; - } - } - // if not, they get a legendary :( - return legendary[random % legendary.length]; - } - require(false); - return 0; - } - - // can never adjust tradable cards - // each season gets a 'balancing beta' - // totally immutable: season, rarity - function replaceProto( - uint16 index, uint8 god, uint8 cardType, uint8 mana, uint8 attack, uint8 health, uint8 tribe - ) public onlyGovernor { - ProtoCard memory pc = protos[index]; - require(!seasonTradable[pc.season]); - protos[index] = ProtoCard({ - exists: true, - god: god, - season: pc.season, - cardType: cardType, - rarity: pc.rarity, - mana: mana, - attack: attack, - health: health, - tribe: tribe - }); - } - -} - -contract ERC721Receiver { - /** - * @dev Magic value to be returned upon successful reception of an NFT - * Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`, - * which can be also obtained as `ERC721Receiver(0).onERC721Received.selector` - */ - bytes4 internal constant ERC721_RECEIVED = 0x150b7a02; - - /** - * @notice Handle the receipt of an NFT - * @dev The ERC721 smart contract calls this function on the recipient - * after a `safetransfer`. This function MAY throw to revert and reject the - * transfer. Return of other than the magic value MUST result in the - * transaction being reverted. - * Note: the contract address is always the message sender. - * @param _operator The address which called `safeTransferFrom` function - * @param _from The address which previously owned the token - * @param _tokenId The NFT identifier which is being transfered - * @param _data Additional data with no specified format - * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` - */ - function onERC721Received( - address _operator, - address _from, - uint256 _tokenId, - bytes memory _data - ) - public - returns(bytes4); -} - -library AddressUtils { - - /** - * Returns whether the target address is a contract - * @dev This function will return false if invoked during the constructor of a contract, - * as the code is not actually created until after the constructor finishes. - * @param addr address to check - * @return whether the target address is a contract - */ - function isContract(address addr) internal view returns (bool) { - uint256 size; - // XXX Currently there is no better way to check if there is a contract in an address - // than to check the size of the code at that address. - // See https://ethereum.stackexchange.com/a/14016/36603 - // for more details about how this works. - // TODO Check this again before the Serenity release, because all addresses will be - // contracts then. - // solium-disable-next-line security/no-inline-assembly - assembly { size := extcodesize(addr) } - return size > 0; - } - -} - -library SafeMath { - - /** - * @dev Multiplies two numbers, throws on overflow. - */ - function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { - // Gas optimization: this is cheaper than asserting 'a' not being zero, but the - // benefit is lost if 'b' is also tested. - // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 - if (a == 0) { - return 0; - } - - c = a * b; - assert(c / a == b); - return c; - } - - /** - * @dev Integer division of two numbers, truncating the quotient. - */ - function div(uint256 a, uint256 b) internal pure returns (uint256) { - // assert(b > 0); // Solidity automatically throws when dividing by 0 - // uint256 c = a / b; - // assert(a == b * c + a % b); // There is no case in which this doesn't hold - return a / b; - } - - /** - * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). - */ - function sub(uint256 a, uint256 b) internal pure returns (uint256) { - assert(b <= a); - return a - b; - } - - /** - * @dev Adds two numbers, throws on overflow. - */ - function add(uint256 a, uint256 b) internal pure returns (uint256 c) { - c = a + b; - assert(c >= a); - return c; - } -} - -contract ERC721BasicToken is CardProto, SupportsInterfaceWithLookup, ERC721Basic { - - bytes4 private constant InterfaceId_ERC721 = 0x80ac58cd; - /* - * 0x80ac58cd === - * bytes4(keccak256('balanceOf(address)')) ^ - * bytes4(keccak256('ownerOf(uint256)')) ^ - * bytes4(keccak256('approve(address,uint256)')) ^ - * bytes4(keccak256('getApproved(uint256)')) ^ - * bytes4(keccak256('setApprovalForAll(address,bool)')) ^ - * bytes4(keccak256('isApprovedForAll(address,address)')) ^ - * bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^ - * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) - */ - - bytes4 private constant InterfaceId_ERC721Exists = 0x4f558e79; - /* - * 0x4f558e79 === - * bytes4(keccak256('exists(uint256)')) - */ - - using SafeMath for uint256; - using AddressUtils for address; - - // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` - // which can be also obtained as `ERC721Receiver(0).onERC721Received.selector` - bytes4 private constant ERC721_RECEIVED = 0x150b7a02; - - // Mapping from token ID to owner - mapping (uint256 => address) internal tokenOwner; - - // Mapping from token ID to approved address - mapping (uint256 => address) internal tokenApprovals; - - // Mapping from owner to number of owned token - // mapping (address => uint256) internal ownedTokensCount; - - // Mapping from owner to operator approvals - mapping (address => mapping (address => bool)) internal operatorApprovals; - - /** - * @dev Guarantees msg.sender is owner of the given token - * @param _tokenId uint256 ID of the token to validate its ownership belongs to msg.sender - */ - modifier onlyOwnerOf(uint256 _tokenId) { - require(ownerOf(_tokenId) == msg.sender); - _; - } - - /** - * @dev Checks msg.sender can transfer a token, by being owner, approved, or operator - * @param _tokenId uint256 ID of the token to validate - */ - modifier canTransfer(uint256 _tokenId) { - require(isApprovedOrOwner(msg.sender, _tokenId)); - _; - } - - constructor() - public - { - // register the supported interfaces to conform to ERC721 via ERC165 - _registerInterface(InterfaceId_ERC721); - _registerInterface(InterfaceId_ERC721Exists); - } - - /** - * @dev Gets the balance of the specified address - * @param _owner address to query the balance of - * @return uint256 representing the amount owned by the passed address - */ - function balanceOf(address _owner) public view returns (uint256); - - /** - * @dev Gets the owner of the specified token ID - * @param _tokenId uint256 ID of the token to query the owner of - * @return owner address currently marked as the owner of the given token ID - */ - function ownerOf(uint256 _tokenId) public view returns (address) { - address owner = tokenOwner[_tokenId]; - require(owner != address(0)); - return owner; - } - - /** - * @dev Returns whether the specified token exists - * @param _tokenId uint256 ID of the token to query the existence of - * @return whether the token exists - */ - function exists(uint256 _tokenId) public view returns (bool) { - address owner = tokenOwner[_tokenId]; - return owner != address(0); - } - - /** - * @dev Approves another address to transfer the given token ID - * The zero address indicates there is no approved address. - * There can only be one approved address per token at a given time. - * Can only be called by the token owner or an approved operator. - * @param _to address to be approved for the given token ID - * @param _tokenId uint256 ID of the token to be approved - */ - function approve(address _to, uint256 _tokenId) public { - address owner = ownerOf(_tokenId); - require(_to != owner); - require(msg.sender == owner || isApprovedForAll(owner, msg.sender)); - - tokenApprovals[_tokenId] = _to; - emit Approval(owner, _to, _tokenId); - } - - /** - * @dev Gets the approved address for a token ID, or zero if no address set - * @param _tokenId uint256 ID of the token to query the approval of - * @return address currently approved for the given token ID - */ - function getApproved(uint256 _tokenId) public view returns (address) { - return tokenApprovals[_tokenId]; - } - - /** - * @dev Sets or unsets the approval of a given operator - * An operator is allowed to transfer all tokens of the sender on their behalf - * @param _to operator address to set the approval - * @param _approved representing the status of the approval to be set - */ - function setApprovalForAll(address _to, bool _approved) public { - require(_to != msg.sender); - operatorApprovals[msg.sender][_to] = _approved; - emit ApprovalForAll(msg.sender, _to, _approved); - } - - /** - * @dev Tells whether an operator is approved by a given owner - * @param _owner owner address which you want to query the approval of - * @param _operator operator address which you want to query the approval of - * @return bool whether the given operator is approved by the given owner - */ - function isApprovedForAll( - address _owner, - address _operator - ) - public - view - returns (bool) - { - return operatorApprovals[_owner][_operator]; - } - - /** - * @dev Transfers the ownership of a given token ID to another address - * Usage of this method is discouraged, use `safeTransferFrom` whenever possible - * Requires the msg sender to be the owner, approved, or operator - * @param _from current owner of the token - * @param _to address to receive the ownership of the given token ID - * @param _tokenId uint256 ID of the token to be transferred - */ - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - public - canTransfer(_tokenId) - { - require(_from != address(0)); - require(_to != address(0)); - - clearApproval(_from, _tokenId); - removeTokenFrom(_from, _tokenId); - addTokenTo(_to, _tokenId); - - emit Transfer(_from, _to, _tokenId); - } - - /** - * @dev Safely transfers the ownership of a given token ID to another address - * If the target address is a contract, it must implement `onERC721Received`, - * which is called upon a safe transfer, and return the magic value - * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, - * the transfer is reverted. - * - * Requires the msg sender to be the owner, approved, or operator - * @param _from current owner of the token - * @param _to address to receive the ownership of the given token ID - * @param _tokenId uint256 ID of the token to be transferred - */ - function safeTransferFrom( - address _from, - address _to, - uint256 _tokenId - ) - public - canTransfer(_tokenId) - { - // solium-disable-next-line arg-overflow - safeTransferFrom(_from, _to, _tokenId, ""); - } - - /** - * @dev Safely transfers the ownership of a given token ID to another address - * If the target address is a contract, it must implement `onERC721Received`, - * which is called upon a safe transfer, and return the magic value - * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, - * the transfer is reverted. - * Requires the msg sender to be the owner, approved, or operator - * @param _from current owner of the token - * @param _to address to receive the ownership of the given token ID - * @param _tokenId uint256 ID of the token to be transferred - * @param _data bytes data to send along with a safe transfer check - */ - function safeTransferFrom( - address _from, - address _to, - uint256 _tokenId, - bytes memory _data - ) - public - canTransfer(_tokenId) - { - transferFrom(_from, _to, _tokenId); - // solium-disable-next-line arg-overflow - require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data)); - } - - /** - * @dev Returns whether the given spender can transfer a given token ID - * @param _spender address of the spender to query - * @param _tokenId uint256 ID of the token to be transferred - * @return bool whether the msg.sender is approved for the given token ID, - * is an operator of the owner, or is the owner of the token - */ - function isApprovedOrOwner( - address _spender, - uint256 _tokenId - ) - internal - view - returns (bool) - { - address owner = ownerOf(_tokenId); - // Disable solium check because of - // https://github.com/duaraghav8/Solium/issues/175 - // solium-disable-next-line operator-whitespace - return ( - _spender == owner || - getApproved(_tokenId) == _spender || - isApprovedForAll(owner, _spender) - ); - } - - /** - * @dev Internal function to clear current approval of a given token ID - * Reverts if the given address is not indeed the owner of the token - * @param _owner owner of the token - * @param _tokenId uint256 ID of the token to be transferred - */ - function clearApproval(address _owner, uint256 _tokenId) internal { - require(ownerOf(_tokenId) == _owner); - if (tokenApprovals[_tokenId] != address(0)) { - tokenApprovals[_tokenId] = address(0); - } - } - - /** - * @dev Internal function to mint a new token - * Reverts if the given token ID already exists - * @param _to The address that will own the minted token - * @param _tokenId uint256 ID of the token to be minted by the msg.sender - */ - function _mint(address _to, uint256 _tokenId) internal { - require(_to != address(0)); - addNewTokenTo(_to, _tokenId); - emit Transfer(address(0), _to, _tokenId); - } - - - /** - * @dev Internal function to burn a specific token - * Reverts if the token does not exist - * @param _tokenId uint256 ID of the token being burned by the msg.sender - */ - function _burn(address _owner, uint256 _tokenId) internal { - clearApproval(_owner, _tokenId); - removeTokenFrom(_owner, _tokenId); - emit Transfer(_owner, address(0), _tokenId); - } - - function addNewTokenTo(address _to, uint256 _tokenId) internal { - require(tokenOwner[_tokenId] == address(0)); - tokenOwner[_tokenId] = _to; - } - - /** - * @dev Internal function to add a token ID to the list of a given address - * @param _to address representing the new owner of the given token ID - * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address - */ - function addTokenTo(address _to, uint256 _tokenId) internal { - require(tokenOwner[_tokenId] == address(0)); - tokenOwner[_tokenId] = _to; - // ownedTokensCount[_to] = ownedTokensCount[_to].add(1); - } - - /** - * @dev Internal function to remove a token ID from the list of a given address - * @param _from address representing the previous owner of the given token ID - * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address - */ - function removeTokenFrom(address _from, uint256 _tokenId) internal { - require(ownerOf(_tokenId) == _from); - // ownedTokensCount[_from] = ownedTokensCount[_from].sub(1); - tokenOwner[_tokenId] = address(0); - } - - /** - * @dev Internal function to invoke `onERC721Received` on a target address - * The call is not executed if the target address is not a contract - * @param _from address representing the previous owner of the given token ID - * @param _to target address that will receive the tokens - * @param _tokenId uint256 ID of the token to be transferred - * @param _data bytes optional data to send along with the call - * @return whether the call correctly returned the expected magic value - */ - function checkAndCallSafeTransfer( - address _from, - address _to, - uint256 _tokenId, - bytes memory _data - ) - internal - returns (bool) - { - if (!_to.isContract()) { - return true; - } - bytes4 retval = ERC721Receiver(_to).onERC721Received( - msg.sender, _from, _tokenId, _data); - return (retval == ERC721_RECEIVED); - } - -} - - - -contract ERC721Enumerable is ERC721Basic { - function totalSupply() public view returns (uint256); - function tokenOfOwnerByIndex( - address _owner, - uint256 _index - ) - public - view - returns (uint256 _tokenId); - - function tokenByIndex(uint256 _index) public view returns (uint256); -} - -contract ERC721Metadata is ERC721Basic { - function name() external view returns (string memory _name); - function symbol() external view returns (string memory _symbol); - function tokenURI(uint256 _tokenId) public view returns (string memory); -} - -contract ERC721 is ERC721Basic, ERC721Enumerable, ERC721Metadata { - -} - - - - -library Strings { - - // via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol - function strConcat(string memory _a, string memory _b, string memory _c, string memory _d, string memory _e) internal pure returns (string memory ) { - bytes memory _ba = bytes(_a); - bytes memory _bb = bytes(_b); - bytes memory _bc = bytes(_c); - bytes memory _bd = bytes(_d); - bytes memory _be = bytes(_e); - string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length); - bytes memory babcde = bytes(abcde); - uint k = 0; - for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i]; - for ( i = 0; i < _bb.length; i++) babcde[k++] = _bb[i]; - for ( i = 0; i < _bc.length; i++) babcde[k++] = _bc[i]; - for ( i = 0; i < _bd.length; i++) babcde[k++] = _bd[i]; - for ( i = 0; i < _be.length; i++) babcde[k++] = _be[i]; - return string(babcde); - } - - function strConcat(string memory _a, string memory _b, string memory _c, string memory _d) internal pure returns (string memory ) { - return strConcat(_a, _b, _c, _d, ""); - } - - function strConcat(string memory _a, string memory _b, string memory _c) internal pure returns (string memory ) { - return strConcat(_a, _b, _c, "", ""); - } - - function strConcat(string memory _a, string memory _b) internal pure returns (string memory ) { - return strConcat(_a, _b, "", "", ""); - } - - function uint2str(uint i) internal pure returns (string memory ) { - if (i == 0) return "0"; - uint j = i; - uint len; - while (j != 0){ - len++; - j /= 10; - } - bytes memory bstr = new bytes(len); - uint k = len - 1; - while (i != 0){ - bstr[k--] = byte(uint8(48 + i % 10)); - i /= 10; - } - return string(bstr); - } -} - -contract ERC721Token is SupportsInterfaceWithLookup, ERC721BasicToken, ERC721 { - - using Strings for string; - - bytes4 private constant InterfaceId_ERC721Enumerable = 0x780e9d63; - /** - * 0x780e9d63 === - * bytes4(keccak256('totalSupply()')) ^ - * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^ - * bytes4(keccak256('tokenByIndex(uint256)')) - */ - - bytes4 private constant InterfaceId_ERC721Metadata = 0x5b5e139f; - /** - * 0x5b5e139f === - * bytes4(keccak256('name()')) ^ - * bytes4(keccak256('symbol()')) ^ - * bytes4(keccak256('tokenURI(uint256)')) - */ - - /*** Constants ***/ - // Configure these for your own deployment - string public constant NAME = "Gods Unchained"; - string public constant SYMBOL = "GODS"; - string public tokenMetadataBaseURI = "https://api.godsunchained.com/card/"; - - // Mapping from owner to list of owned token IDs - // EDITED: limit to 2^40 (around 1T) - mapping(address => uint40[]) internal ownedTokens; - - uint32[] ownedTokensIndex; - - /** - * @dev Constructor function - */ - constructor() public { - - // register the supported interfaces to conform to ERC721 via ERC165 - _registerInterface(InterfaceId_ERC721Enumerable); - _registerInterface(InterfaceId_ERC721Metadata); - } - - /** - * @dev Gets the token name - * @return string representing the token name - */ - function name() external view returns (string memory) { - return NAME; - } - - /** - * @dev Gets the token symbol - * @return string representing the token symbol - */ - function symbol() external view returns (string memory) { - return SYMBOL; - } - - /** - * @dev Returns an URI for a given token ID - * Throws if the token ID does not exist. May return an empty string. - * @param _tokenId uint256 ID of the token to query - */ - function tokenURI(uint256 _tokenId) public view returns (string memory) { - return Strings.strConcat( - tokenMetadataBaseURI, - Strings.uint2str(_tokenId) - ); - } - - /** - * @dev Gets the token ID at a given index of the tokens list of the requested owner - * @param _owner address owning the tokens list to be accessed - * @param _index uint256 representing the index to be accessed of the requested tokens list - * @return uint256 token ID at the given index of the tokens list owned by the requested address - */ - function tokenOfOwnerByIndex( - address _owner, - uint256 _index - ) - public - view - returns (uint256) - { - require(_index < balanceOf(_owner)); - return ownedTokens[_owner][_index]; - } - - /** - * @dev Gets the total amount of tokens stored by the contract - * @return uint256 representing the total amount of tokens - */ - function totalSupply() public view returns (uint256) { - return cards.length; - } - - /** - * @dev Gets the token ID at a given index of all the tokens in this contract - * Reverts if the index is greater or equal to the total number of tokens - * @param _index uint256 representing the index to be accessed of the tokens list - * @return uint256 token ID at the given index of the tokens list - */ - function tokenByIndex(uint256 _index) public view returns (uint256) { - require(_index < totalSupply()); - return _index; - } - - /** - * @dev Internal function to add a token ID to the list of a given address - * @param _to address representing the new owner of the given token ID - * @param _tokenId uint256 ID of the token to be added to the tokens list of the given address - */ - function addTokenTo(address _to, uint256 _tokenId) internal { - super.addTokenTo(_to, _tokenId); - uint256 length = ownedTokens[_to].length; - // EDITED: prevent overflow - require(length == uint32(length)); - ownedTokens[_to].push(uint40(_tokenId)); - - ownedTokensIndex[_tokenId] = uint32(length); - } - - // EDITED - // have to have in order to use array rather than mapping - function addNewTokenTo(address _to, uint256 _tokenId) internal { - super.addNewTokenTo(_to, _tokenId); - uint256 length = ownedTokens[_to].length; - // EDITED: prevent overflow - require(length == uint32(length)); - ownedTokens[_to].push(uint40(_tokenId)); - ownedTokensIndex.push(uint32(length)); - } - - /** - * @dev Internal function to remove a token ID from the list of a given address - * @param _from address representing the previous owner of the given token ID - * @param _tokenId uint256 ID of the token to be removed from the tokens list of the given address - */ - function removeTokenFrom(address _from, uint256 _tokenId) internal { - super.removeTokenFrom(_from, _tokenId); - - uint32 tokenIndex = ownedTokensIndex[_tokenId]; - uint256 lastTokenIndex = ownedTokens[_from].length.sub(1); - uint40 lastToken = ownedTokens[_from][lastTokenIndex]; - - ownedTokens[_from][tokenIndex] = lastToken; - ownedTokens[_from][lastTokenIndex] = 0; - // Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to - // be zero. Then we can make sure that we will remove _tokenId from the ownedTokens list since we are first swapping - // the lastToken to the first position, and then dropping the element placed in the last position of the list - - ownedTokens[_from].length--; - ownedTokensIndex[_tokenId] = 0; - ownedTokensIndex[lastToken] = tokenIndex; - } - - /** - * @dev Gets the balance of the specified address - overrriden from previous to save gas - * @param _owner address to query the balance of - * @return uint256 representing the amount owned by the passed address - */ - function balanceOf(address _owner) public view returns (uint256) { - return ownedTokens[_owner].length; - } - -} - -contract CardOwnershipTwo is ERC721Token { - - uint public burnCount; - - function getActiveCards() public view returns (uint) { - return totalSupply() - burnCount; - } - - /** - * @param to : the address to which the card will be transferred - * @param id : the id of the card to be transferred - */ - function transfer(address to, uint id) public payable onlyOwnerOf(id) { - require(isTradable(cards[id].proto)); - require(to != address(0)); - - _transfer(msg.sender, to, id); - } - - function _transfer(address from, address to, uint id) internal { - - clearApproval(from, id); - - removeTokenFrom(from, id); - - addTokenTo(to, id); - - emit Transfer(from, to, id); - } - - /** - * @param to : the address to which the cards will be transferred - * @param ids : the ids of the cards to be transferred - */ - function transferAll(address to, uint[] memory ids) public payable { - for (uint i = 0; i < ids.length; i++) { - transfer(to, ids[i]); - } - } - - /** - * @param proposed : the claimed owner of the cards - * @param ids : the ids of the cards to check - * @return whether proposed owns all of the cards - */ - function ownsAll(address proposed, uint[] memory ids) public view returns (bool) { - require(ids.length > 0); - for (uint i = 0; i < ids.length; i++) { - if (!owns(proposed, ids[i])) { - return false; - } - } - return true; - } - - /** - * @param proposed : the claimed owner of the card - * @param id : the id of the card to check - * @return whether proposed owns the card - */ - function owns(address proposed, uint id) public view returns (bool) { - return ownerOf(id) == proposed; - } - - function burn(uint id) public onlyOwnerOf(id) { - burnCount++; - _burn(msg.sender, id); - } - - /** - * @param ids : the indices of the tokens to burn - */ - function burnAll(uint[] memory ids) public { - for (uint i = 0; i < ids.length; i++){ - burn(ids[i]); - } - } - - /** - * @param to : the address to approve for transfer - * @param id : the index of the card to be approved - */ - function approve(address to, uint id) public { - require(isTradable(cards[id].proto)); - super.approve(to, id); - } - - /** - * @param to : the address to approve for transfer - * @param ids : the indices of the cards to be approved - */ - function approveAll(address to, uint[] memory ids) public { - for (uint i = 0; i < ids.length; i++) { - approve(to, ids[i]); - } - } - - /** - * @param to : the address to which the token should be transferred - * @param id : the index of the token to transfer - */ - function transferFrom(address from, address to, uint id) public { - require(isTradable(cards[id].proto)); - super.transferFrom(from, to, id); - } - - /** - * @param to : the address to which the tokens should be transferred - * @param ids : the indices of the tokens to transfer - */ - function transferAllFrom(address from, address to, uint[] memory ids) public { - for (uint i = 0; i < ids.length; i++) { - transferFrom(from, to, ids[i]); - } - } - - /** - * @return the number of cards which have been burned - */ - function getBurnCount() public view returns (uint) { - return burnCount; - } - -} - -contract CardIntegrationTwo is CardOwnershipTwo { - - address[] public packs; - - event CardCreated(uint indexed id, uint16 proto, uint16 purity, address owner); - - function addPack(address approved) public onlyGovernor { - packs.push(approved); - } - - modifier onlyApprovedPacks { - require(_isApprovedPack()); - _; - } - - function _isApprovedPack() private view returns (bool) { - for (uint i = 0; i < packs.length; i++) { - if (msg.sender == address(packs[i])) { - return true; - } - } - return false; - } - - function createCard(address owner, uint16 proto, uint16 purity) public whenNotPaused onlyApprovedPacks returns (uint) { - ProtoCard memory card = protos[proto]; - require(card.season == currentSeason); - if (card.rarity == Rarity.Mythic) { - uint64 limit; - bool exists; - (limit, exists) = getLimit(proto); - require(!exists || limit > 0); - limits[proto].limit--; - } - return _createCard(owner, proto, purity); - } - - function _createCard(address owner, uint16 proto, uint16 purity) internal returns (uint) { - Card memory card = Card({ - proto: proto, - purity: purity - }); - - uint id = cards.push(card) - 1; - - _mint(owner, id); - - emit CardCreated(id, proto, purity, owner); - - return id; - } - - /*function combineCards(uint[] ids) public whenNotPaused { - require(ids.length == 5); - require(ownsAll(msg.sender, ids)); - Card memory first = cards[ids[0]]; - uint16 proto = first.proto; - uint8 shine = _getShine(first.purity); - require(shine < shineLimit); - uint16 puritySum = first.purity - (shine * 1000); - burn(ids[0]); - for (uint i = 1; i < ids.length; i++) { - Card memory next = cards[ids[i]]; - require(next.proto == proto); - require(_getShine(next.purity) == shine); - puritySum += (next.purity - (shine * 1000)); - burn(ids[i]); - } - uint16 newPurity = uint16(((shine + 1) * 1000) + (puritySum / ids.length)); - _createCard(msg.sender, proto, newPurity); - }*/ - - - // PURITY NOTES - // currently, we only - // however, to protect rarity, you'll never be abl - // this is enforced by the restriction in the create-card function - // no cards above this point can be found in packs - - - -} - -contract PreviousInterface { - - function ownerOf(uint id) public view returns (address); - - function getCard(uint id) public view returns (uint16, uint16); - - function totalSupply() public view returns (uint); - - function burnCount() public view returns (uint); - -} - -contract CardMigration is CardIntegrationTwo { - - constructor(PreviousInterface previous) public { - old = previous; - } - - // use interface to lower deployment cost - PreviousInterface old; - - mapping(uint => bool) public migrated; - - function migrate(uint id) public { - - require(!migrated[id]); - - migrated[id] = true; - - address owner = old.ownerOf(id); - - uint16 proto; - uint16 purity; - - (proto, purity) = old.getCard(id); - - _createCard(owner, proto, purity); - } - - function migrateAll(uint[] memory ids) public { - - for (uint i = 0; i < ids.length; i++){ - migrate(ids[i]); - } - - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario008.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractScenario008.sol deleted file mode 100644 index 7336976e2b6..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario008.sol +++ /dev/null @@ -1,2016 +0,0 @@ -//pragma solidity ^0.4.11; - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - function Ownable() { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -contract ERC721 { - // Required methods - function totalSupply() public view returns (uint256 total); - function balanceOf(address _owner) public view returns (uint256 balance); - function ownerOf(uint256 _tokenId) external view returns (address owner); - function approve(address _to, uint256 _tokenId) external; - function transfer(address _to, uint256 _tokenId) external; - function transferFrom(address _from, address _to, uint256 _tokenId) external; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) external view returns (bool); -} - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - - function isGeneScience() public pure returns (bool){ - return true; - } - - /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor - /// @param genes1 genes of mom - /// @param genes2 genes of sire - /// @return the genes that are supposed to be passed down the child - function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - - return (genes1+genes2+targetBlock)/2; - - -} -} - - - - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() public onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - Transfer(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(now), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - uint256 newKittenId = kitties.push(_kitty) - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(0, _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { - /// @dev Given a token Id, returns a byte array that is supposed to be converted into string. - function getMetadata(uint256 _tokenId, string) public view returns (bytes32[4] buffer, uint256 count) { - if (_tokenId == 1) { - buffer[0] = "Hello World! :D"; - count = 15; - } else if (_tokenId == 2) { - buffer[0] = "I would definitely choose a medi"; - buffer[1] = "um length string."; - count = 49; - } else if (_tokenId == 3) { - buffer[0] = "Lorem ipsum dolor sit amet, mi e"; - buffer[1] = "st accumsan dapibus augue lorem,"; - buffer[2] = " tristique vestibulum id, libero"; - buffer[3] = " suscipit varius sapien aliquam."; - count = 128; - } - } -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is KittyBase, ERC721 { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public view returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() public view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - external - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] _rawBytes, uint256 _stringLength) private view returns (string) { - var outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string _preferredTransport) external view returns (string infoUrl) { - require(erc721Metadata != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2 sun; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.send(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - - // Represents an auction on an NFT - struct Auction { - // Current owner of NFT - address seller; - // Price (in wei) at beginning of auction - uint128 startingPrice; - // Price (in wei) at end of auction - uint128 endingPrice; - // Duration (in seconds) of auction - uint64 duration; - // Time when auction started - // NOTE: 0 if this auction has been concluded - uint64 startedAt; - } - - // Reference to contract tracking NFT ownership - ERC721 public nonFungibleContract; - - // Cut owner takes on each auction, measured in basis points (1/100 of a percent). - // Values 0-10,000 map to 0%-100% - uint256 public ownerCut; - - // Map from token ID to their corresponding auction. - mapping (uint256 => Auction) tokenIdToAuction; - - event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); - event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); - event AuctionCancelled(uint256 tokenId); - - /// @dev Returns true if the claimant owns the token. - /// @param _claimant - Address claiming to own the token. - /// @param _tokenId - ID of token whose ownership to verify. - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return (nonFungibleContract.ownerOf(_tokenId) == _claimant); - } - - /// @dev Escrows the NFT, assigning ownership to this contract. - /// Throws if the escrow fails. - /// @param _owner - Current owner address of token to escrow. - /// @param _tokenId - ID of token whose approval to verify. - function _escrow(address _owner, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transferFrom(_owner, this, _tokenId); - } - - /// @dev Transfers an NFT owned by this contract to another address. - /// Returns true if the transfer succeeds. - /// @param _receiver - Address to transfer NFT to. - /// @param _tokenId - ID of token to transfer. - function _transfer(address _receiver, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transfer(_receiver, _tokenId); - } - - /// @dev Adds an auction to the list of open auctions. Also fires the - /// AuctionCreated event. - /// @param _tokenId The ID of the token to be put on auction. - /// @param _auction Auction to add. - function _addAuction(uint256 _tokenId, Auction _auction) internal { - // Require that all auctions have a duration of - // at least one minute. (Keeps our math from getting hairy!) - require(_auction.duration >= 1 minutes); - - tokenIdToAuction[_tokenId] = _auction; - - AuctionCreated( - uint256(_tokenId), - uint256(_auction.startingPrice), - uint256(_auction.endingPrice), - uint256(_auction.duration) - ); - } - - /// @dev Cancels an auction unconditionally. - function _cancelAuction(uint256 _tokenId, address _seller) internal { - _removeAuction(_tokenId); - _transfer(_seller, _tokenId); - AuctionCancelled(_tokenId); - } - - /// @dev Computes the price and transfers winnings. - /// Does NOT transfer ownership of token. - function _bid(uint256 _tokenId, uint256 _bidAmount) - internal - returns (uint256) - { - // Get a reference to the auction struct - Auction storage auction = tokenIdToAuction[_tokenId]; - - // Explicitly check that this auction is currently live. - // (Because of how Ethereum mappings work, we can't just count - // on the lookup above failing. An invalid _tokenId will just - // return an auction object that is all zeros.) - require(_isOnAuction(auction)); - - // Check that the bid is greater than or equal to the current price - uint256 price = _currentPrice(auction); - require(_bidAmount >= price); - - // Grab a reference to the seller before the auction struct - // gets deleted. - address seller = auction.seller; - - // The bid is good! Remove the auction before sending the fees - // to the sender so we can't have a reentrancy attack. - _removeAuction(_tokenId); - - // Transfer proceeds to seller (if there are any!) - if (price > 0) { - // Calculate the auctioneer's cut. - // (NOTE: _computeCut() is guaranteed to return a - // value <= price, so this subtraction can't go negative.) - uint256 auctioneerCut = _computeCut(price); - uint256 sellerProceeds = price - auctioneerCut; - - // NOTE: Doing a transfer() in the middle of a complex - // method like this is generally discouraged because of - // reentrancy attacks and DoS attacks if the seller is - // a contract with an invalid fallback function. We explicitly - // guard against reentrancy attacks by removing the auction - // before calling transfer(), and the only thing the seller - // can DoS is the sale of their own asset! (And if it's an - // accident, they can call cancelAuction(). ) - seller.transfer(sellerProceeds); - } - - // Calculate any excess funds included with the bid. If the excess - // is anything worth worrying about, transfer it back to bidder. - // NOTE: We checked above that the bid amount is greater than or - // equal to the price so this cannot underflow. - uint256 bidExcess = _bidAmount - price; - - // Return the funds. Similar to the previous transfer, this is - // not susceptible to a re-entry attack because the auction is - // removed before any transfers occur. - msg.sender.transfer(bidExcess); - - // Tell the world! - AuctionSuccessful(_tokenId, price, msg.sender); - - return price; - } - - /// @dev Removes an auction from the list of open auctions. - /// @param _tokenId - ID of NFT on auction. - function _removeAuction(uint256 _tokenId) internal { - delete tokenIdToAuction[_tokenId]; - } - - /// @dev Returns true if the NFT is on auction. - /// @param _auction - Auction to check. - function _isOnAuction(Auction storage _auction) internal view returns (bool) { - return (_auction.startedAt > 0); - } - - /// @dev Returns current price of an NFT on auction. Broken into two - /// functions (this one, that computes the duration from the auction - /// structure, and the other that does the price computation) so we - /// can easily test that the price computation works correctly. - function _currentPrice(Auction storage _auction) - internal - view - returns (uint256) - { - uint256 secondsPassed = 0; - - // A bit of insurance against negative values (or wraparound). - // Probably not necessary (since Ethereum guarnatees that the - // now variable doesn't ever go backwards). - if (now > _auction.startedAt) { - secondsPassed = now - _auction.startedAt; - } - - return _computeCurrentPrice( - _auction.startingPrice, - _auction.endingPrice, - _auction.duration, - secondsPassed - ); - } - - /// @dev Computes the current price of an auction. Factored out - /// from _currentPrice so we can run extensive unit tests. - /// When testing, make this function public and turn on - /// `Current price computation` test suite. - function _computeCurrentPrice( - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - uint256 _secondsPassed - ) - internal - pure - returns (uint256) - { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our public functions carefully cap the maximum values for - // time (at 64-bits) and currency (at 128-bits). _duration is - // also known to be non-zero (see the require() statement in - // _addAuction()) - if (_secondsPassed >= _duration) { - // We've reached the end of the dynamic pricing portion - // of the auction, just return the end price. - return _endingPrice; - } else { - // Starting price can be higher than ending price (and often is!), so - // this delta can be negative. - int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - - // This multiplication can't overflow, _secondsPassed will easily fit within - // 64-bits, and totalPriceChange will easily fit within 128-bits, their product - // will always fit within 256-bits. - int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - - // currentPriceChange can be negative, but if so, will have a magnitude - // less that _startingPrice. Thus, this result will always end up positive. - int256 currentPrice = int256(_startingPrice) + currentPriceChange; - - return uint256(currentPrice); - } - } - - /// @dev Computes owner's cut of a sale. - /// @param _price - Sale price of NFT. - function _computeCut(uint256 _price) internal view returns (uint256) { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our entry functions carefully cap the maximum values for - // currency (at 128-bits), and ownerCut <= 10000 (see the require() - // statement in the ClockAuction constructor). The result of this - // function is always guaranteed to be <= _price. - return _price * ownerCut / 10000; - } - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { - event Pause(); - event Unpause(); - - bool public paused = false; - - - /** - * @dev modifier to allow actions only when the contract IS paused - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev modifier to allow actions only when the contract IS NOT paused - */ - modifier whenPaused { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyOwner whenNotPaused returns (bool) { - paused = true; - Pause(); - return true; - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyOwner whenPaused returns (bool) { - paused = false; - Unpause(); - return true; - } -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - - /// @dev The ERC-165 interface signature for ERC-721. - /// Ref: https://github.com/ethereum/EIPs/issues/165 - /// Ref: https://github.com/ethereum/EIPs/issues/721 - bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - - /// @dev Constructor creates a reference to the NFT ownership contract - /// and verifies the owner cut is in the valid range. - /// @param _nftAddress - address of a deployed contract implementing - /// the Nonfungible Interface. - /// @param _cut - percent cut the owner takes on each auction, must be - /// between 0-10,000. - function ClockAuction(address _nftAddress, uint256 _cut) public { - require(_cut <= 10000); - ownerCut = _cut; - - ERC721 candidateContract = ERC721(_nftAddress); - require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); - nonFungibleContract = candidateContract; - } - - /// @dev Remove all Ether from the contract, which is the owner's cuts - /// as well as any Ether sent directly to the contract address. - /// Always transfers to the NFT contract, but can be called either by - /// the owner or the NFT contract. - function withdrawBalance() external { - address nftAddress = address(nonFungibleContract); - - require( - msg.sender == owner || - msg.sender == nftAddress - ); - // We are using this boolean method to make sure that even if one fails it will still work - bool res = nftAddress.send(this.balance); - } - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of time to move between starting - /// price and ending price (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address _seller - ) - external - whenNotPaused - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(_owns(msg.sender, _tokenId)); - _escrow(msg.sender, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Bids on an open auction, completing the auction and transferring - /// ownership of the NFT if enough Ether is supplied. - /// @param _tokenId - ID of token to bid on. - function bid(uint256 _tokenId) - external - payable - whenNotPaused - { - // _bid will throw if the bid or funds transfer fails - _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - } - - /// @dev Cancels an auction that hasn't been won yet. - /// Returns the NFT to original owner. - /// @notice This is a state-modifying function that can - /// be called while the contract is paused. - /// @param _tokenId - ID of token on auction - function cancelAuction(uint256 _tokenId) - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - address seller = auction.seller; - require(msg.sender == seller); - _cancelAuction(_tokenId, seller); - } - - /// @dev Cancels an auction when the contract is paused. - /// Only the owner may do this, and NFTs are returned to - /// the seller. This should only be used in emergencies. - /// @param _tokenId - ID of the NFT on auction to cancel. - function cancelAuctionWhenPaused(uint256 _tokenId) - whenPaused - onlyOwner - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - _cancelAuction(_tokenId, auction.seller); - } - - /// @dev Returns auction info for an NFT on auction. - /// @param _tokenId - ID of NFT on auction. - function getAuction(uint256 _tokenId) - external - view - returns - ( - address seller, - uint256 startingPrice, - uint256 endingPrice, - uint256 duration, - uint256 startedAt - ) { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return ( - auction.seller, - auction.startingPrice, - auction.endingPrice, - auction.duration, - auction.startedAt - ); - } - - /// @dev Returns the current price of an auction. - /// @param _tokenId - ID of the token price we are checking. - function getCurrentPrice(uint256 _tokenId) - external - view - returns (uint256) - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return _currentPrice(auction); - } - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSiringAuctionAddress() call. - bool public isSiringClockAuction = true; - - // Delegate constructor - function SiringClockAuction(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. Since this function is wrapped, - /// require sender to be KittyCore contract. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Places a bid for siring. Requires the sender - /// is the KittyCore contract because all bid methods - /// should be wrapped. Also returns the kitty to the - /// seller rather than the winner. - function bid(uint256 _tokenId) - external - payable - { - require(msg.sender == address(nonFungibleContract)); - address seller = tokenIdToAuction[_tokenId].seller; - // _bid checks that token ID is valid and will throw if bid fails - _bid(_tokenId, msg.value); - // We transfer the kitty back to the seller, the winner will get - // the offspring - _transfer(seller, _tokenId); - } - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSaleAuctionAddress() call. - bool public isSaleClockAuction = true; - - // Tracks last 5 sale price of gen0 kitty sales - uint256 public gen0SaleCount; - uint256[5] public lastGen0SalePrices; - - // Delegate constructor - function SaleClockAuction(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Updates lastSalePrice if seller is the nft contract - /// Otherwise, works the same as default bid method. - function bid(uint256 _tokenId) - external - payable - { - // _bid verifies token ID size - address seller = tokenIdToAuction[_tokenId].seller; - uint256 price = _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - - // If not a gen0 auction, exit - if (seller == address(nonFungibleContract)) { - // Track gen0 sale prices - lastGen0SalePrices[gen0SaleCount % 5] = price; - gen0SaleCount++; - } - } - - function averageGen0SalePrice() external view returns (uint256) { - uint256 sum = 0; - for (uint256 i = 0; i < 5; i++) { - sum += lastGen0SalePrices[i]; - } - return sum / 5; - } - -} - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, saleAuction); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, siringAuction); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid.value(msg.value - autoBirthFee)(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10 sun; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, saleAuction); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(this) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - function KittyCore() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - ContractUpgrade(_v2Address); - } - - /// @notice No tipping! - /// @dev Reject all Ether from being sent here, unless it's from one of the - /// two auction contracts. (Hopefully, we can prevent user accidents.) - function() external payable { - require( - msg.sender == address(saleAuction) || - msg.sender == address(siringAuction) - ); - } - - /// @notice Returns all the relevant information about a specific kitty. - /// @param _id The ID of the kitty of interest. - function getKitty(uint256 _id) - external - view - returns ( - bool isGestating, - bool isReady, - uint256 cooldownIndex, - uint256 nextActionAt, - uint256 siringWithId, - uint256 birthTime, - uint256 matronId, - uint256 sireId, - uint256 generation, - uint256 genes - ) { - Kitty storage kit = kitties[_id]; - - // if this variable is 0 then it's not gestating - isGestating = (kit.siringWithId != 0); - isReady = (kit.cooldownEndBlock <= block.number); - cooldownIndex = uint256(kit.cooldownIndex); - nextActionAt = uint256(kit.cooldownEndBlock); - siringWithId = uint256(kit.siringWithId); - birthTime = uint256(kit.birthTime); - matronId = uint256(kit.matronId); - sireId = uint256(kit.sireId); - generation = uint256(kit.generation); - genes = kit.genes; - } - - /// @dev Override unpause so it requires all external contract addresses - /// to be set before contract can be unpaused. Also, we can't have - /// newContractAddress set either, because then the contract was upgraded. - /// @notice This is public rather than external so we can call super.unpause - /// without using an expensive CALL. - function unpause() public onlyCEO whenPaused { - require(saleAuction != address(0)); - require(siringAuction != address(0)); - require(geneScience != address(0)); - require(newContractAddress == address(0)); - - // Actually unpause the contract. - super.unpause(); - } - - // @dev Allows the CFO to capture the balance available to the contract. - function withdrawBalance() external onlyCFO { - uint256 balance = this.balance; - // Subtract all the currently pregnant kittens we have, plus 1 of margin. - uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - - if (balance > subtractFees) { - cfoAddress.send(balance - subtractFees); - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario009.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractScenario009.sol deleted file mode 100644 index 215c671848e..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario009.sol +++ /dev/null @@ -1,51 +0,0 @@ -//pragma solidity ^0.4.0; - -library Set { - // We define a new struct datatype that will be used to - // hold its data in the calling contract. - struct Data { mapping(uint => bool) flags; } - - // Note that the first parameter is of type "storage - // reference" and thus only its storage address and not - // its contents is passed as part of the call. This is a - // special feature of library functions. It is idiomatic - // to call the first parameter 'self', if the function can - // be seen as a method of that object. - function insert(Data storage self, uint value) - returns (bool) - { - if (self.flags[value]) - return false; // already there - self.flags[value] = true; - return true; - } - - function remove(Data storage self, uint value) - returns (bool) - { - if (!self.flags[value]) - return false; // not there - self.flags[value] = false; - return true; - } - - function contains(Data storage self, uint value) - returns (bool) - { - return self.flags[value]; - } -} - - -contract C { - Set.Data knownValues; - - function register(uint value) { - // The library functions can be called without a - // specific instance of the library, since the - // "instance" will be the current contract. - if (!Set.insert(knownValues, value)) - throw; - } - // In this contract, we can also directly access knownValues.flags, if we want. -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario010.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractScenario010.sol deleted file mode 100644 index f665ea9686e..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario010.sol +++ /dev/null @@ -1,107 +0,0 @@ -//pragma solidity ^0.4.11; - -contract TRON_ERC721 { - //name - function name() view public returns (string memory name){ - return "Tron ERC721 Token"; - } - //symbol - function symbol() view public returns (string memory symbol){ - return "T721T"; - } - - //totalSupply - - function totalSupply() view public returns (uint256 supply){ - uint256 totalSupply = 1000000000000; - return totalSupply; - } - - mapping(address => uint) private balances; - function balanceOf(address _owner) view public returns (uint balance) - { - return balances[_owner]; - } - - - mapping(uint256 => address) private tokenOwners; - mapping(uint256 => bool) private tokenExists; - function ownerOf(uint256 _tokenId) view public returns (address owner) { - require(tokenExists[_tokenId]); - return tokenOwners[_tokenId]; - } - - - mapping(address => mapping (address => uint256)) allowed; - function approve(address _to, uint256 _tokenId) public{ - require(msg.sender == ownerOf(_tokenId)); - require(msg.sender != _to); - allowed[msg.sender][_to] = _tokenId; - emit Approval(msg.sender, _to, _tokenId); - } - - - function takeOwnership(uint256 _tokenId) public { - require(tokenExists[_tokenId]); - address oldOwner = ownerOf(_tokenId); - address newOwner = msg.sender; - require(newOwner != oldOwner); - require(allowed[oldOwner][newOwner] == _tokenId); - balances[oldOwner] -= 1; - tokenOwners[_tokenId] = newOwner; - balances[newOwner] += 1; - emit Transfer(oldOwner, newOwner, _tokenId); - } - - - mapping(address => mapping(uint256 => uint256)) private ownerTokens; - function removeFromTokenList(address owner, uint256 _tokenId) private { - for(uint256 i = 0;ownerTokens[owner][i] != _tokenId;i++){ - ownerTokens[owner][i] = 0; - } - } - - function transfer(address _to, uint256 _tokenId) public{ - address currentOwner = msg.sender; - address newOwner = _to; - require(tokenExists[_tokenId]); - require(currentOwner == ownerOf(_tokenId)); - require(currentOwner != newOwner); - require(newOwner != address(0)); - address oldOwner =currentOwner; - removeFromTokenList(oldOwner,_tokenId); - balances[oldOwner] -= 1; - tokenOwners[_tokenId] = newOwner; - balances[newOwner] += 1; - emit Transfer(oldOwner, newOwner, _tokenId); - } - - function transferFrom(address _from,address _to, uint256 _tokenId) public{ - address currentOwner = _from; - address newOwner = _to; - require(tokenExists[_tokenId]); - require(currentOwner == ownerOf(_tokenId)); - require(currentOwner != newOwner); - require(newOwner != address(0)); - address oldOwner =currentOwner; - removeFromTokenList(oldOwner,_tokenId); - balances[oldOwner] -= 1; - tokenOwners[_tokenId] = newOwner; - balances[newOwner] += 1; - emit Transfer(oldOwner, newOwner, _tokenId); - } - - - function tokenOfOwnerByIndex(address _owner, uint256 _index) view public returns (uint tokenId){ - return ownerTokens[_owner][_index]; - } - - - mapping(uint256 => string) tokenLinks; - function tokenMetadata(uint256 _tokenId) view public returns (string memory infoUrl) { - return tokenLinks[_tokenId]; - } - // Events - event Transfer(address indexed _from, address indexed _to, uint256 _tokenId); - event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId); -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario011.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractScenario011.sol deleted file mode 100644 index 4d1e9c1ba12..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario011.sol +++ /dev/null @@ -1,2050 +0,0 @@ -//pragma solidity ^0.4.11; - - -/** - * @title Ownable - * @dev The Ownable contract has an owner address, and provides basic authorization control - * functions, this simplifies the implementation of "user permissions". - */ -contract Ownable { - address public owner; - - - /** - * @dev The Ownable constructor sets the original `owner` of the contract to the sender - * account. - */ - constructor() public { - owner = msg.sender; - } - - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - - /** - * @dev Allows the current owner to transfer control of the contract to a newOwner. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) public onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } - -} - - - - -/// @title A facet of KittyCore that manages special access privileges. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyAccessControl { - // This facet controls access control for CryptoKitties. There are four roles managed here: - // - // - The CEO: The CEO can reassign other roles and change the addresses of our dependent smart - // contracts. It is also the only role that can unpause the smart contract. It is initially - // set to the address that created the smart contract in the KittyCore constructor. - // - // - The CFO: The CFO can withdraw funds from KittyCore and its auction contracts. - // - // - The COO: The COO can release gen0 kitties to auction, and mint promo cats. - // - // It should be noted that these roles are distinct without overlap in their access abilities, the - // abilities listed for each role above are exhaustive. In particular, while the CEO can assign any - // address to any role, the CEO address itself doesn't have the ability to act in those roles. This - // restriction is intentional so that we aren't tempted to use the CEO address frequently out of - // convenience. The less we use an address, the less likely it is that we somehow compromise the - // account. - - /// @dev Emited when contract is upgraded - See README.md for updgrade plan - event ContractUpgrade(address newContract); - - // The addresses of the accounts (or contracts) that can execute actions within each roles. - address public ceoAddress; - address public cfoAddress; - address public cooAddress; - - // @dev Keeps track whether the contract is paused. When that is true, most actions are blocked - bool public paused = false; - - /// @dev Access modifier for CEO-only functionality - modifier onlyCEO() { - require(msg.sender == ceoAddress); - _; - } - - /// @dev Access modifier for CFO-only functionality - modifier onlyCFO() { - require(msg.sender == cfoAddress); - _; - } - - /// @dev Access modifier for COO-only functionality - modifier onlyCOO() { - require(msg.sender == cooAddress); - _; - } - - modifier onlyCLevel() { - require( - msg.sender == cooAddress || - msg.sender == ceoAddress || - msg.sender == cfoAddress - ); - _; - } - - /// @dev Assigns a new address to act as the CEO. Only available to the current CEO. - /// @param _newCEO The address of the new CEO - function setCEO(address _newCEO) external onlyCEO { - require(_newCEO != address(0)); - - ceoAddress = _newCEO; - } - - /// @dev Assigns a new address to act as the CFO. Only available to the current CEO. - /// @param _newCFO The address of the new CFO - function setCFO(address _newCFO) external onlyCEO { - require(_newCFO != address(0)); - - cfoAddress = _newCFO; - } - - /// @dev Assigns a new address to act as the COO. Only available to the current CEO. - /// @param _newCOO The address of the new COO - function setCOO(address _newCOO) external onlyCEO { - require(_newCOO != address(0)); - - cooAddress = _newCOO; - } - - /*** Pausable functionality adapted from OpenZeppelin ***/ - - /// @dev Modifier to allow actions only when the contract IS NOT paused - modifier whenNotPaused() { - require(!paused); - _; - } - - /// @dev Modifier to allow actions only when the contract IS paused - modifier whenPaused { - require(paused); - _; - } - - /// @dev Called by any "C-level" role to pause the contract. Used only when - /// a bug or exploit is detected and we need to limit damage. - function pause() external onlyCLevel whenNotPaused { - paused = true; - } - - /// @dev Unpauses the smart contract. Can only be called by the CEO, since - /// one reason we may pause the contract is when CFO or COO accounts are - /// compromised. - /// @notice This is public rather than external so it can be called by - /// derived contracts. - function unpause() public onlyCEO whenPaused { - // can't unpause if contract was upgraded - paused = false; - } -} - - - - -/// @title Base contract for CryptoKitties. Holds all common structs, events and base variables. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBase is KittyAccessControl { - /*** EVENTS ***/ - - /// @dev The Birth event is fired whenever a new kitten comes into existence. This obviously - /// includes any time a cat is created through the giveBirth method, but it is also called - /// when a new gen0 cat is created. - event Birth(address owner, uint256 kittyId, uint256 matronId, uint256 sireId, uint256 genes); - - /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a kitten - /// ownership is assigned, including births. - event Transfer(address from, address to, uint256 tokenId); - - /*** DATA TYPES ***/ - - /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy - /// of this structure, so great care was taken to ensure that it fits neatly into - /// exactly two 256-bit words. Note that the order of the members in this structure - /// is important because of the byte-packing rules used by Ethereum. - /// Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html - struct Kitty { - // The Kitty's genetic code is packed into these 256-bits, the format is - // sooper-sekret! A cat's genes never change. - uint256 genes; - - // The timestamp from the block when this cat came into existence. - uint64 birthTime; - - // The minimum timestamp after which this cat can engage in breeding - // activities again. This same timestamp is used for the pregnancy - // timer (for matrons) as well as the siring cooldown. - uint64 cooldownEndBlock; - - // The ID of the parents of this kitty, set to 0 for gen0 cats. - // Note that using 32-bit unsigned integers limits us to a "mere" - // 4 billion cats. This number might seem small until you realize - // that Ethereum currently has a limit of about 500 million - // transactions per year! So, this definitely won't be a problem - // for several years (even as Ethereum learns to scale). - uint32 matronId; - uint32 sireId; - - // Set to the ID of the sire cat for matrons that are pregnant, - // zero otherwise. A non-zero value here is how we know a cat - // is pregnant. Used to retrieve the genetic material for the new - // kitten when the birth transpires. - uint32 siringWithId; - - // Set to the index in the cooldown array (see below) that represents - // the current cooldown duration for this Kitty. This starts at zero - // for gen0 cats, and is initialized to floor(generation/2) for others. - // Incremented by one for each successful breeding action, regardless - // of whether this cat is acting as matron or sire. - uint16 cooldownIndex; - - // The "generation number" of this cat. Cats minted by the CK contract - // for sale are called "gen0" and have a generation number of 0. The - // generation number of all other cats is the larger of the two generation - // numbers of their parents, plus one. - // (i.e. max(matron.generation, sire.generation) + 1) - uint16 generation; - } - - /*** CONSTANTS ***/ - - /// @dev A lookup table indicating the cooldown duration after any successful - /// breeding action, called "pregnancy time" for matrons and "siring cooldown" - /// for sires. Designed such that the cooldown roughly doubles each time a cat - /// is bred, encouraging owners not to just keep breeding the same cat over - /// and over again. Caps out at one week (a cat can breed an unbounded number - /// of times, and the maximum cooldown is always seven days). - uint32[14] public cooldowns = [ - uint32(1 minutes), - uint32(2 minutes), - uint32(5 minutes), - uint32(10 minutes), - uint32(30 minutes), - uint32(1 hours), - uint32(2 hours), - uint32(4 hours), - uint32(8 hours), - uint32(16 hours), - uint32(1 days), - uint32(2 days), - uint32(4 days), - uint32(7 days) - ]; - - // An approximation of currently how many seconds are in between blocks. - uint256 public secondsPerBlock = 15; - - /*** STORAGE ***/ - - /// @dev An array containing the Kitty struct for all Kitties in existence. The ID - /// of each cat is actually an index into this array. Note that ID 0 is a negacat, - /// the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre - /// creature that is both matron and sire... to itself! Has an invalid genetic code. - /// In other words, cat ID 0 is invalid... ;-) - Kitty[] kitties; - - /// @dev A mapping from cat IDs to the address that owns them. All cats have - /// some valid owner address, even gen0 cats are created with a non-zero owner. - mapping (uint256 => address) public kittyIndexToOwner; - - // @dev A mapping from owner address to count of tokens that address owns. - // Used internally inside balanceOf() to resolve ownership count. - mapping (address => uint256) ownershipTokenCount; - - /// @dev A mapping from KittyIDs to an address that has been approved to call - /// transferFrom(). Each Kitty can only have one approved address for transfer - /// at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public kittyIndexToApproved; - - /// @dev A mapping from KittyIDs to an address that has been approved to use - /// this Kitty for siring via breedWith(). Each Kitty can only have one approved - /// address for siring at any time. A zero value means no approval is outstanding. - mapping (uint256 => address) public sireAllowedToAddress; - - /// @dev The address of the ClockAuction contract that handles sales of Kitties. This - /// same contract handles both peer-to-peer sales as well as the gen0 sales which are - /// initiated every 15 minutes. - SaleClockAuction public saleAuction; - - /// @dev The address of a custom ClockAuction subclassed contract that handles siring - /// auctions. Needs to be separate from saleAuction because the actions taken on success - /// after a sales and siring auction are quite different. - SiringClockAuction public siringAuction; - - /// @dev Assigns ownership of a specific Kitty to an address. - function _transfer(address _from, address _to, uint256 _tokenId) internal { - // Since the number of kittens is capped to 2^32 we can't overflow this - ownershipTokenCount[_to]++; - // transfer ownership - kittyIndexToOwner[_tokenId] = _to; - // When creating new kittens _from is 0x0, but we can't account that address. - if (_from != address(0)) { - ownershipTokenCount[_from]--; - // once the kitten is transferred also clear sire allowances - delete sireAllowedToAddress[_tokenId]; - // clear any previously approved ownership exchange - delete kittyIndexToApproved[_tokenId]; - } - // Emit the transfer event. - emit Transfer(_from, _to, _tokenId); - } - - /// @dev An internal method that creates a new kitty and stores it. This - /// method doesn't do any checking and should only be called when the - /// input data is known to be valid. Will generate both a Birth event - /// and a Transfer event. - /// @param _matronId The kitty ID of the matron of this cat (zero for gen0) - /// @param _sireId The kitty ID of the sire of this cat (zero for gen0) - /// @param _generation The generation number of this cat, must be computed by caller. - /// @param _genes The kitty's genetic code. - /// @param _owner The inital owner of this cat, must be non-zero (except for the unKitty, ID 0) - function _createKitty( - uint256 _matronId, - uint256 _sireId, - uint256 _generation, - uint256 _genes, - address _owner - ) - internal - returns (uint) - { - // These requires are not strictly necessary, our calling code should make - // sure that these conditions are never broken. However! _createKitty() is already - // an expensive call (for storage), and it doesn't hurt to be especially careful - // to ensure our data structures are always valid. - require(_matronId == uint256(uint32(_matronId))); - require(_sireId == uint256(uint32(_sireId))); - require(_generation == uint256(uint16(_generation))); - - // New kitty starts with the same cooldown as parent gen/2 - uint16 cooldownIndex = uint16(_generation / 2); - if (cooldownIndex > 13) { - cooldownIndex = 13; - } - - Kitty memory _kitty = Kitty({ - genes: _genes, - birthTime: uint64(now), - cooldownEndBlock: 0, - matronId: uint32(_matronId), - sireId: uint32(_sireId), - siringWithId: 0, - cooldownIndex: cooldownIndex, - generation: uint16(_generation) - }); - uint256 newKittenId = kitties.push(_kitty) - 1; - - // It's probably never going to happen, 4 billion cats is A LOT, but - // let's just be 100% sure we never let this happen. - require(newKittenId == uint256(uint32(newKittenId))); - - // emit the birth event - emit Birth( - _owner, - newKittenId, - uint256(_kitty.matronId), - uint256(_kitty.sireId), - _kitty.genes - ); - - // This will assign ownership, and also emit the Transfer event as - // per ERC721 draft - _transfer(address(0), _owner, newKittenId); - - return newKittenId; - } - - // Any C-level can fix how many seconds per blocks are currently observed. - function setSecondsPerBlock(uint256 secs) external onlyCLevel { - require(secs < cooldowns[0]); - secondsPerBlock = secs; - } -} - - -/// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens -/// @author Dieter Shirley (https://github.com/dete) -contract ERC721 { - // Required methods - function totalSupply() public view returns (uint256 total); - function balanceOf(address _owner) public view returns (uint256 balance); - function ownerOf(uint256 _tokenId) external view returns (address owner); - function approve(address _to, uint256 _tokenId) external; - function transfer(address _to, uint256 _tokenId) external; - function transferFrom(address _from, address _to, uint256 _tokenId) external; - - // Events - event Transfer(address from, address to, uint256 tokenId); - event Approval(address owner, address approved, uint256 tokenId); - - // Optional - // function name() public view returns (string name); - // function symbol() public view returns (string symbol); - // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds); - // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl); - - // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165) - function supportsInterface(bytes4 _interfaceID) external view returns (bool); -} - - -/// @title The facet of the CryptoKitties core contract that manages ownership, ERC-721 (draft) compliant. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev Ref: https://github.com/ethereum/EIPs/issues/721 -/// See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyOwnership is ERC721, KittyBase { - - /// @notice Name and symbol of the non fungible token, as defined in ERC721. - string public constant name = "CryptoKitties"; - string public constant symbol = "CK"; - - // The contract that will return kitty metadata - ERC721Metadata public erc721Metadata; - - bytes4 constant InterfaceSignature_ERC165 = - bytes4(keccak256('supportsInterface(bytes4)')); - - bytes4 constant InterfaceSignature_ERC721 = - bytes4(keccak256('name()')) ^ - bytes4(keccak256('symbol()')) ^ - bytes4(keccak256('totalSupply()')) ^ - bytes4(keccak256('balanceOf(address)')) ^ - bytes4(keccak256('ownerOf(uint256)')) ^ - bytes4(keccak256('approve(address,uint256)')) ^ - bytes4(keccak256('transfer(address,uint256)')) ^ - bytes4(keccak256('transferFrom(address,address,uint256)')) ^ - bytes4(keccak256('tokensOfOwner(address)')) ^ - bytes4(keccak256('tokenMetadata(uint256,string)')); - - /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). - /// Returns true for any standardized interfaces implemented by this contract. We implement - /// ERC-165 (obviously!) and ERC-721. - function supportsInterface(bytes4 _interfaceID) external view returns (bool) - { - // DEBUG ONLY - //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); - - return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); - } - - /// @dev Set the address of the sibling contract that tracks metadata. - /// CEO only. - function setMetadataAddress(address _contractAddress) public onlyCEO { - erc721Metadata = ERC721Metadata(_contractAddress); - } - - // Internal utility functions: These functions all assume that their input arguments - // are valid. We leave it to public methods to sanitize their inputs and follow - // the required logic. - - /// @dev Checks if a given address is the current owner of a particular Kitty. - /// @param _claimant the address we are validating against. - /// @param _tokenId kitten id, only valid when > 0 - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToOwner[_tokenId] == _claimant; - } - - /// @dev Checks if a given address currently has transferApproval for a particular Kitty. - /// @param _claimant the address we are confirming kitten is approved for. - /// @param _tokenId kitten id, only valid when > 0 - function _approvedFor(address _claimant, uint256 _tokenId) internal view returns (bool) { - return kittyIndexToApproved[_tokenId] == _claimant; - } - - /// @dev Marks an address as being approved for transferFrom(), overwriting any previous - /// approval. Setting _approved to address(0) clears all transfer approval. - /// NOTE: _approve() does NOT send the Approval event. This is intentional because - /// _approve() and transferFrom() are used together for putting Kitties on auction, and - /// there is no value in spamming the log with Approval events in that case. - function _approve(uint256 _tokenId, address _approved) internal { - kittyIndexToApproved[_tokenId] = _approved; - } - - /// @notice Returns the number of Kitties owned by a specific address. - /// @param _owner The owner address to check. - /// @dev Required for ERC-721 compliance - function balanceOf(address _owner) public view returns (uint256 count) { - return ownershipTokenCount[_owner]; - } - - /// @notice Transfers a Kitty to another address. If transferring to a smart - /// contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or - /// CryptoKitties specifically) or your Kitty may be lost forever. Seriously. - /// @param _to The address of the recipient, can be a user or contract. - /// @param _tokenId The ID of the Kitty to transfer. - /// @dev Required for ERC-721 compliance. - function transfer( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Disallow transfers to the auction contracts to prevent accidental - // misuse. Auction contracts should only take ownership of kitties - // through the allow + transferFrom flow. - require(_to != address(saleAuction)); - require(_to != address(siringAuction)); - - // You can only send your own cat. - require(_owns(msg.sender, _tokenId)); - - // Reassign ownership, clear pending approvals, emit Transfer event. - _transfer(msg.sender, _to, _tokenId); - } - - /// @notice Grant another address the right to transfer a specific Kitty via - /// transferFrom(). This is the preferred flow for transfering NFTs to contracts. - /// @param _to The address to be granted transfer approval. Pass address(0) to - /// clear all approvals. - /// @param _tokenId The ID of the Kitty that can be transferred if this call succeeds. - /// @dev Required for ERC-721 compliance. - function approve( - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Only an owner can grant transfer approval. - require(_owns(msg.sender, _tokenId)); - - // Register the approval (replacing any previous approval). - _approve(_tokenId, _to); - - // Emit approval event. - emit Approval(msg.sender, _to, _tokenId); - } - - /// @notice Transfer a Kitty owned by another address, for which the calling address - /// has previously been granted transfer approval by the owner. - /// @param _from The address that owns the Kitty to be transfered. - /// @param _to The address that should take ownership of the Kitty. Can be any address, - /// including the caller. - /// @param _tokenId The ID of the Kitty to be transferred. - /// @dev Required for ERC-721 compliance. - function transferFrom( - address _from, - address _to, - uint256 _tokenId - ) - external - whenNotPaused - { - // Safety check to prevent against an unexpected 0x0 default. - require(_to != address(0)); - // Disallow transfers to this contract to prevent accidental misuse. - // The contract should never own any kitties (except very briefly - // after a gen0 cat is created and before it goes on auction). - require(_to != address(this)); - // Check for approval and valid ownership - require(_approvedFor(msg.sender, _tokenId)); - require(_owns(_from, _tokenId)); - - // Reassign ownership (also clears pending approvals and emits Transfer event). - _transfer(_from, _to, _tokenId); - } - - /// @notice Returns the total number of Kitties currently in existence. - /// @dev Required for ERC-721 compliance. - function totalSupply() public view returns (uint) { - return kitties.length - 1; - } - - /// @notice Returns the address currently assigned ownership of a given Kitty. - /// @dev Required for ERC-721 compliance. - function ownerOf(uint256 _tokenId) - external - view - returns (address owner) - { - owner = kittyIndexToOwner[_tokenId]; - - require(owner != address(0)); - } - - /// @notice Returns a list of all Kitty IDs assigned to an address. - /// @param _owner The owner whose Kitties we are interested in. - /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly - /// expensive (it walks the entire Kitty array looking for cats belonging to owner), - /// but it also returns a dynamic array, which is only supported for web3 calls, and - /// not contract-to-contract calls. - function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { - uint256 tokenCount = balanceOf(_owner); - - if (tokenCount == 0) { - // Return an empty array - return new uint256[](0); - } else { - uint256[] memory result = new uint256[](tokenCount); - uint256 totalCats = totalSupply(); - uint256 resultIndex = 0; - - // We count on the fact that all cats have IDs starting at 1 and increasing - // sequentially up to the totalCat count. - uint256 catId; - - for (catId = 1; catId <= totalCats; catId++) { - if (kittyIndexToOwner[catId] == _owner) { - result[resultIndex] = catId; - resultIndex++; - } - } - - return result; - } - } - - /// @dev Adapted from memcpy() by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _memcpy(uint _dest, uint _src, uint _len) private view { - // Copy word-length chunks while possible - for(; _len >= 32; _len -= 32) { - assembly { - mstore(_dest, mload(_src)) - } - _dest += 32; - _src += 32; - } - - // Copy remaining bytes - uint256 mask = 256 ** (32 - _len) - 1; - assembly { - let srcpart := and(mload(_src), not(mask)) - let destpart := and(mload(_dest), mask) - mstore(_dest, or(destpart, srcpart)) - } - } - - /// @dev Adapted from toString(slice) by @arachnid (Nick Johnson ) - /// This method is licenced under the Apache License. - /// Ref: https://github.com/Arachnid/solidity-stringutils/blob/2f6ca9accb48ae14c66f1437ec50ed19a0616f78/strings.sol - function _toString(bytes32[4] memory _rawBytes, uint256 _stringLength) private view returns (string memory) { - string memory outputString = new string(_stringLength); - uint256 outputPtr; - uint256 bytesPtr; - - assembly { - outputPtr := add(outputString, 32) - bytesPtr := _rawBytes - } - - _memcpy(outputPtr, bytesPtr, _stringLength); - - return outputString; - } - - /// @notice Returns a URI pointing to a metadata package for this token conforming to - /// ERC-721 (https://github.com/ethereum/EIPs/issues/721) - /// @param _tokenId The ID number of the Kitty whose metadata should be returned. - function tokenMetadata(uint256 _tokenId, string _preferredTransport) external view returns (string infoUrl) { - require( address(erc721Metadata) != address(0)); - bytes32[4] memory buffer; - uint256 count; - (buffer, count) = erc721Metadata.getMetadata(_tokenId, _preferredTransport); - - return _toString(buffer, count); - } -} - - - - -/// @title A facet of KittyCore that manages Kitty siring, gestation, and birth. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev See the KittyCore contract documentation to understand how the various contract facets are arranged. -contract KittyBreeding is KittyOwnership { - - /// @dev The Pregnant event is fired when two cats successfully breed and the pregnancy - /// timer begins for the matron. - event Pregnant(address owner, uint256 matronId, uint256 sireId, uint256 cooldownEndBlock); - - /// @notice The minimum payment required to use breedWithAuto(). This fee goes towards - /// the gas cost paid by whatever calls giveBirth(), and can be dynamically updated by - /// the COO role as the gas price changes. - uint256 public autoBirthFee = 2 sun; - - // Keeps track of number of pregnant kitties. - uint256 public pregnantKitties; - - /// @dev The address of the sibling contract that is used to implement the sooper-sekret - /// genetic combination algorithm. - GeneScienceInterface public geneScience; - - /// @dev Update the address of the genetic contract, can only be called by the CEO. - /// @param _address An address of a GeneScience contract instance to be used from this point forward. - function setGeneScienceAddress(address _address) external onlyCEO { - GeneScienceInterface candidateContract = GeneScienceInterface(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isGeneScience()); - - // Set the new contract address - geneScience = candidateContract; - } - - /// @dev Checks that a given kitten is able to breed. Requires that the - /// current cooldown is finished (for sires) and also checks that there is - /// no pending pregnancy. - function _isReadyToBreed(Kitty memory _kit) internal view returns (bool) { - // In addition to checking the cooldownEndBlock, we also need to check to see if - // the cat has a pending birth; there can be some period of time between the end - // of the pregnacy timer and the birth event. - return (_kit.siringWithId == 0) && (_kit.cooldownEndBlock <= uint64(block.number)); - } - - /// @dev Check if a sire has authorized breeding with this matron. True if both sire - /// and matron have the same owner, or if the sire has given siring permission to - /// the matron's owner (via approveSiring()). - function _isSiringPermitted(uint256 _sireId, uint256 _matronId) internal view returns (bool) { - address matronOwner = kittyIndexToOwner[_matronId]; - address sireOwner = kittyIndexToOwner[_sireId]; - - // Siring is okay if they have same owner, or if the matron's owner was given - // permission to breed with this sire. - return (matronOwner == sireOwner || sireAllowedToAddress[_sireId] == matronOwner); - } - - /// @dev Set the cooldownEndTime for the given Kitty, based on its current cooldownIndex. - /// Also increments the cooldownIndex (unless it has hit the cap). - /// @param _kitten A reference to the Kitty in storage which needs its timer started. - function _triggerCooldown(Kitty storage _kitten) internal { - // Compute an estimation of the cooldown time in blocks (based on current cooldownIndex). - _kitten.cooldownEndBlock = uint64((cooldowns[_kitten.cooldownIndex]/secondsPerBlock) + block.number); - - // Increment the breeding count, clamping it at 13, which is the length of the - // cooldowns array. We could check the array size dynamically, but hard-coding - // this as a constant saves gas. Yay, Solidity! - if (_kitten.cooldownIndex < 13) { - _kitten.cooldownIndex += 1; - } - } - - /// @notice Grants approval to another user to sire with one of your Kitties. - /// @param _addr The address that will be able to sire with your Kitty. Set to - /// address(0) to clear all siring approvals for this Kitty. - /// @param _sireId A Kitty that you own that _addr will now be able to sire with. - function approveSiring(address _addr, uint256 _sireId) - external - whenNotPaused - { - require(_owns(msg.sender, _sireId)); - sireAllowedToAddress[_sireId] = _addr; - } - - /// @dev Updates the minimum payment required for calling giveBirthAuto(). Can only - /// be called by the COO address. (This fee is used to offset the gas cost incurred - /// by the autobirth daemon). - function setAutoBirthFee(uint256 val) external onlyCOO { - autoBirthFee = val; - } - - /// @dev Checks to see if a given Kitty is pregnant and (if so) if the gestation - /// period has passed. - function _isReadyToGiveBirth(Kitty memory _matron) private view returns (bool) { - return (_matron.siringWithId != 0) && (_matron.cooldownEndBlock <= uint64(block.number)); - } - - /// @notice Checks that a given kitten is able to breed (i.e. it is not pregnant or - /// in the middle of a siring cooldown). - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isReadyToBreed(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - Kitty storage kit = kitties[_kittyId]; - return _isReadyToBreed(kit); - } - - /// @dev Checks whether a kitty is currently pregnant. - /// @param _kittyId reference the id of the kitten, any user can inquire about it - function isPregnant(uint256 _kittyId) - public - view - returns (bool) - { - require(_kittyId > 0); - // A kitty is pregnant if and only if this field is set - return kitties[_kittyId].siringWithId != 0; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair. DOES NOT - /// check ownership permissions (that is up to the caller). - /// @param _matron A reference to the Kitty struct of the potential matron. - /// @param _matronId The matron's ID. - /// @param _sire A reference to the Kitty struct of the potential sire. - /// @param _sireId The sire's ID - function _isValidMatingPair( - Kitty storage _matron, - uint256 _matronId, - Kitty storage _sire, - uint256 _sireId - ) - private - view - returns(bool) - { - // A Kitty can't breed with itself! - if (_matronId == _sireId) { - return false; - } - - // Kitties can't breed with their parents. - if (_matron.matronId == _sireId || _matron.sireId == _sireId) { - return false; - } - if (_sire.matronId == _matronId || _sire.sireId == _matronId) { - return false; - } - - // We can short circuit the sibling check (below) if either cat is - // gen zero (has a matron ID of zero). - if (_sire.matronId == 0 || _matron.matronId == 0) { - return true; - } - - // Kitties can't breed with full or half siblings. - if (_sire.matronId == _matron.matronId || _sire.matronId == _matron.sireId) { - return false; - } - if (_sire.sireId == _matron.matronId || _sire.sireId == _matron.sireId) { - return false; - } - - // Everything seems cool! Let's get DTF. - return true; - } - - /// @dev Internal check to see if a given sire and matron are a valid mating pair for - /// breeding via auction (i.e. skips ownership and siring approval checks). - function _canBreedWithViaAuction(uint256 _matronId, uint256 _sireId) - internal - view - returns (bool) - { - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId); - } - - /// @notice Checks to see if two cats can breed together, including checks for - /// ownership and siring approvals. Does NOT check that both cats are ready for - /// breeding (i.e. breedWith could still fail until the cooldowns are finished). - /// TODO: Shouldn't this check pregnancy and cooldowns?!? - /// @param _matronId The ID of the proposed matron. - /// @param _sireId The ID of the proposed sire. - function canBreedWith(uint256 _matronId, uint256 _sireId) - external - view - returns(bool) - { - require(_matronId > 0); - require(_sireId > 0); - Kitty storage matron = kitties[_matronId]; - Kitty storage sire = kitties[_sireId]; - return _isValidMatingPair(matron, _matronId, sire, _sireId) && - _isSiringPermitted(_sireId, _matronId); - } - - /// @dev Internal utility function to initiate breeding, assumes that all breeding - /// requirements have been checked. - function _breedWith(uint256 _matronId, uint256 _sireId) internal { - // Grab a reference to the Kitties from storage. - Kitty storage sire = kitties[_sireId]; - Kitty storage matron = kitties[_matronId]; - - // Mark the matron as pregnant, keeping track of who the sire is. - matron.siringWithId = uint32(_sireId); - - // Trigger the cooldown for both parents. - _triggerCooldown(sire); - _triggerCooldown(matron); - - // Clear siring permission for both parents. This may not be strictly necessary - // but it's likely to avoid confusion! - delete sireAllowedToAddress[_matronId]; - delete sireAllowedToAddress[_sireId]; - - // Every time a kitty gets pregnant, counter is incremented. - pregnantKitties++; - - // Emit the pregnancy event. - emit Pregnant(kittyIndexToOwner[_matronId], _matronId, _sireId, matron.cooldownEndBlock); - } - - /// @notice Breed a Kitty you own (as matron) with a sire that you own, or for which you - /// have previously been given Siring approval. Will either make your cat pregnant, or will - /// fail entirely. Requires a pre-payment of the fee given out to the first caller of giveBirth() - /// @param _matronId The ID of the Kitty acting as matron (will end up pregnant if successful) - /// @param _sireId The ID of the Kitty acting as sire (will begin its siring cooldown if successful) - function breedWithAuto(uint256 _matronId, uint256 _sireId) - external - payable - whenNotPaused - { - // Checks for payment. - require(msg.value >= autoBirthFee); - - // Caller must own the matron. - require(_owns(msg.sender, _matronId)); - - // Neither sire nor matron are allowed to be on auction during a normal - // breeding operation, but we don't need to check that explicitly. - // For matron: The caller of this function can't be the owner of the matron - // because the owner of a Kitty on auction is the auction house, and the - // auction house will never call breedWith(). - // For sire: Similarly, a sire on auction will be owned by the auction house - // and the act of transferring ownership will have cleared any oustanding - // siring approval. - // Thus we don't need to spend gas explicitly checking to see if either cat - // is on auction. - - // Check that matron and sire are both owned by caller, or that the sire - // has given siring permission to caller (i.e. matron's owner). - // Will fail for _sireId = 0 - require(_isSiringPermitted(_sireId, _matronId)); - - // Grab a reference to the potential matron - Kitty storage matron = kitties[_matronId]; - - // Make sure matron isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(matron)); - - // Grab a reference to the potential sire - Kitty storage sire = kitties[_sireId]; - - // Make sure sire isn't pregnant, or in the middle of a siring cooldown - require(_isReadyToBreed(sire)); - - // Test that these cats are a valid mating pair. - require(_isValidMatingPair( - matron, - _matronId, - sire, - _sireId - )); - - // All checks passed, kitty gets pregnant! - _breedWith(_matronId, _sireId); - } - - /// @notice Have a pregnant Kitty give birth! - /// @param _matronId A Kitty ready to give birth. - /// @return The Kitty ID of the new kitten. - /// @dev Looks at a given Kitty and, if pregnant and if the gestation period has passed, - /// combines the genes of the two parents to create a new kitten. The new Kitty is assigned - /// to the current owner of the matron. Upon successful completion, both the matron and the - /// new kitten will be ready to breed again. Note that anyone can call this function (if they - /// are willing to pay the gas!), but the new kitten always goes to the mother's owner. - function giveBirth(uint256 _matronId) - external - whenNotPaused - returns(uint256) - { - // Grab a reference to the matron in storage. - Kitty storage matron = kitties[_matronId]; - - // Check that the matron is a valid cat. - require(matron.birthTime != 0); - - // Check that the matron is pregnant, and that its time has come! - require(_isReadyToGiveBirth(matron)); - - // Grab a reference to the sire in storage. - uint256 sireId = matron.siringWithId; - Kitty storage sire = kitties[sireId]; - - // Determine the higher generation number of the two parents - uint16 parentGen = matron.generation; - if (sire.generation > matron.generation) { - parentGen = sire.generation; - } - - // Call the sooper-sekret gene mixing operation. - uint256 childGenes = geneScience.mixGenes(matron.genes, sire.genes, matron.cooldownEndBlock - 1); - - // Make the new kitten! - address owner = kittyIndexToOwner[_matronId]; - uint256 kittenId = _createKitty(_matronId, matron.siringWithId, parentGen + 1, childGenes, owner); - - // Clear the reference to sire from the matron (REQUIRED! Having siringWithId - // set is what marks a matron as being pregnant.) - delete matron.siringWithId; - - // Every time a kitty gives birth counter is decremented. - pregnantKitties--; - - // Send the balance fee to the person who made birth happen. - msg.sender.transfer(autoBirthFee); - - // return the new kitten's ID - return kittenId; - } -} - - - -/// @title Handles creating auctions for sale and siring of kitties. -/// This wrapper of ReverseAuction exists only so that users can create -/// auctions with only one transaction. -contract KittyAuction is KittyBreeding { - - // @notice The auction contract variables are defined in KittyBase to allow - // us to refer to them in KittyOwnership to prevent accidental transfers. - // `saleAuction` refers to the auction for gen0 and p2p sale of kitties. - // `siringAuction` refers to the auction for siring rights of kitties. - - /// @dev Sets the reference to the sale auction. - /// @param _address - Address of sale contract. - function setSaleAuctionAddress(address _address) external onlyCEO { - SaleClockAuction candidateContract = SaleClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSaleClockAuction()); - - // Set the new contract address - saleAuction = candidateContract; - } - - /// @dev Sets the reference to the siring auction. - /// @param _address - Address of siring contract. - function setSiringAuctionAddress(address _address) external onlyCEO { - SiringClockAuction candidateContract = SiringClockAuction(_address); - - // NOTE: verify that a contract is what we expect - https://github.com/Lunyr/crowdsale-contracts/blob/cfadd15986c30521d8ba7d5b6f57b4fefcc7ac38/contracts/LunyrToken.sol#L117 - require(candidateContract.isSiringClockAuction()); - - // Set the new contract address - siringAuction = candidateContract; - } - - /// @dev Put a kitty up for auction. - /// Does some ownership trickery to create auctions in one tx. - function createSaleAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - // Ensure the kitty is not pregnant to prevent the auction - // contract accidentally receiving ownership of the child. - // NOTE: the kitty IS allowed to be in a cooldown. - require(!isPregnant(_kittyId)); - _approve(_kittyId, address(saleAuction)); - // Sale auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - saleAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Put a kitty up for auction to be sire. - /// Performs checks to ensure the kitty can be sired, then - /// delegates to reverse auction. - function createSiringAuction( - uint256 _kittyId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration - ) - external - whenNotPaused - { - // Auction contract checks input sizes - // If kitty is already on any auction, this will throw - // because it will be owned by the auction contract. - require(_owns(msg.sender, _kittyId)); - require(isReadyToBreed(_kittyId)); - _approve(_kittyId, address(siringAuction)); - // Siring auction throws if inputs are invalid and clears - // transfer and sire approval after escrowing the kitty. - siringAuction.createAuction( - _kittyId, - _startingPrice, - _endingPrice, - _duration, - msg.sender - ); - } - - /// @dev Completes a siring auction by bidding. - /// Immediately breeds the winning matron with the sire on auction. - /// @param _sireId - ID of the sire on auction. - /// @param _matronId - ID of the matron owned by the bidder. - function bidOnSiringAuction( - uint256 _sireId, - uint256 _matronId - ) - external - payable - whenNotPaused - { - // Auction contract checks input sizes - require(_owns(msg.sender, _matronId)); - require(isReadyToBreed(_matronId)); - require(_canBreedWithViaAuction(_matronId, _sireId)); - - // Define the current price of the auction. - uint256 currentPrice = siringAuction.getCurrentPrice(_sireId); - require(msg.value >= currentPrice + autoBirthFee); - - // Siring auction will throw if the bid fails. - siringAuction.bid.value(msg.value - autoBirthFee)(_sireId); - _breedWith(uint32(_matronId), uint32(_sireId)); - } - - /// @dev Transfers the balance of the sale auction contract - /// to the KittyCore contract. We use two-step withdrawal to - /// prevent two transfer calls in the auction bid function. - function withdrawAuctionBalances() external onlyCLevel { - saleAuction.withdrawBalance(); - siringAuction.withdrawBalance(); - } -} - - -/// @title all functions related to creating kittens -contract KittyMinting is KittyAuction { - - // Limits the number of cats the contract owner can ever create. - uint256 public constant PROMO_CREATION_LIMIT = 5000; - uint256 public constant GEN0_CREATION_LIMIT = 45000; - - // Constants for gen0 auctions. - uint256 public constant GEN0_STARTING_PRICE = 10 sun; - uint256 public constant GEN0_AUCTION_DURATION = 1 days; - - // Counts the number of cats the contract owner has created. - uint256 public promoCreatedCount; - uint256 public gen0CreatedCount; - - /// @dev we can create promo kittens, up to a limit. Only callable by COO - /// @param _genes the encoded genes of the kitten to be created, any value is accepted - /// @param _owner the future owner of the created kittens. Default to contract COO - function createPromoKitty(uint256 _genes, address _owner) external onlyCOO { - address kittyOwner = _owner; - if (kittyOwner == address(0)) { - kittyOwner = cooAddress; - } - require(promoCreatedCount < PROMO_CREATION_LIMIT); - - promoCreatedCount++; - _createKitty(0, 0, 0, _genes, kittyOwner); - } - - /// @dev Creates a new gen0 kitty with the given genes and - /// creates an auction for it. - function createGen0Auction(uint256 _genes) external onlyCOO { - require(gen0CreatedCount < GEN0_CREATION_LIMIT); - - uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this)); - _approve(kittyId, address(saleAuction)); - - saleAuction.createAuction( - kittyId, - _computeNextGen0Price(), - 0, - GEN0_AUCTION_DURATION, - address(uint160(address(this))) - ); - - gen0CreatedCount++; - } - - /// @dev Computes the next gen0 auction starting price, given - /// the average of the past 5 prices + 50%. - function _computeNextGen0Price() internal view returns (uint256) { - uint256 avePrice = saleAuction.averageGen0SalePrice(); - - // Sanity check to ensure we don't overflow arithmetic - require(avePrice == uint256(uint128(avePrice))); - - uint256 nextPrice = avePrice + (avePrice / 2); - - // We never auction for less than starting price - if (nextPrice < GEN0_STARTING_PRICE) { - nextPrice = GEN0_STARTING_PRICE; - } - - return nextPrice; - } -} - - - -/// @title CryptoKitties: Collectible, breedable, and oh-so-adorable cats on the Ethereum blockchain. -/// @author Axiom Zen (https://www.axiomzen.co) -/// @dev The main CryptoKitties contract, keeps track of kittens so they don't wander around and get lost. -contract KittyCore is KittyMinting { - - // This is the main CryptoKitties contract. In order to keep our code seperated into logical sections, - // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts - // that handle auctions and our super-top-secret genetic combination algorithm. The auctions are - // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping - // them in their own contracts, we can upgrade them without disrupting the main contract that tracks - // kitty ownership. The genetic combination algorithm is kept seperate so we can open-source all of - // the rest of our code without making it _too_ easy for folks to figure out how the genetics work. - // Don't worry, I'm sure someone will reverse engineer it soon enough! - // - // Secondly, we break the core contract into multiple files using inheritence, one for each major - // facet of functionality of CK. This allows us to keep related code bundled together while still - // avoiding a single giant file with everything in it. The breakdown is as follows: - // - // - KittyBase: This is where we define the most fundamental code shared throughout the core - // functionality. This includes our main data storage, constants and data types, plus - // internal functions for managing these items. - // - // - KittyAccessControl: This contract manages the various addresses and constraints for operations - // that can be executed only by specific roles. Namely CEO, CFO and COO. - // - // - KittyOwnership: This provides the methods required for basic non-fungible token - // transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721). - // - // - KittyBreeding: This file contains the methods necessary to breed cats together, including - // keeping track of siring offers, and relies on an external genetic combination contract. - // - // - KittyAuctions: Here we have the public methods for auctioning or bidding on cats or siring - // services. The actual auction functionality is handled in two sibling contracts (one - // for sales and one for siring), while auction creation and bidding is mostly mediated - // through this facet of the core contract. - // - // - KittyMinting: This final facet contains the functionality we use for creating new gen0 cats. - // We can make up to 5000 "promo" cats that can be given away (especially important when - // the community is new), and all others can only be created and then immediately put up - // for auction via an algorithmically determined starting price. Regardless of how they - // are created, there is a hard limit of 50k gen0 cats. After that, it's all up to the - // community to breed, breed, breed! - - // Set in case the core contract is broken and an upgrade is required - address public newContractAddress; - - /// @notice Creates the main CryptoKitties smart contract instance. - constructor() public { - // Starts paused. - paused = true; - - // the creator of the contract is the initial CEO - ceoAddress = msg.sender; - - // the creator of the contract is also the initial COO - cooAddress = msg.sender; - - // start with the mythical kitten 0 - so we don't have generation-0 parent issues - _createKitty(0, 0, 0, uint256(-1), address(0)); - } - - /// @dev Used to mark the smart contract as upgraded, in case there is a serious - /// breaking bug. This method does nothing but keep track of the new contract and - /// emit a message indicating that the new address is set. It's up to clients of this - /// contract to update to the new contract address in that case. (This contract will - /// be paused indefinitely if such an upgrade takes place.) - /// @param _v2Address new address - function setNewAddress(address _v2Address) external onlyCEO whenPaused { - // See README.md for updgrade plan - newContractAddress = _v2Address; - emit ContractUpgrade(_v2Address); - } - - /// @notice No tipping! - /// @dev Reject all Ether from being sent here, unless it's from one of the - /// two auction contracts. (Hopefully, we can prevent user accidents.) - function() external payable { - require( - msg.sender == address(saleAuction) || - msg.sender == address(siringAuction) - ); - } - - /// @notice Returns all the relevant information about a specific kitty. - /// @param _id The ID of the kitty of interest. - function getKitty(uint256 _id) - external - view - returns ( - bool isGestating, - bool isReady, - uint256 cooldownIndex, - uint256 nextActionAt, - uint256 siringWithId, - uint256 birthTime, - uint256 matronId, - uint256 sireId, - uint256 generation, - uint256 genes - ) { - Kitty storage kit = kitties[_id]; - - // if this variable is 0 then it's not gestating - isGestating = (kit.siringWithId != 0); - isReady = (kit.cooldownEndBlock <= block.number); - cooldownIndex = uint256(kit.cooldownIndex); - nextActionAt = uint256(kit.cooldownEndBlock); - siringWithId = uint256(kit.siringWithId); - birthTime = uint256(kit.birthTime); - matronId = uint256(kit.matronId); - sireId = uint256(kit.sireId); - generation = uint256(kit.generation); - genes = kit.genes; - } - - /// @dev Override unpause so it requires all external contract addresses - /// to be set before contract can be unpaused. Also, we can't have - /// newContractAddress set either, because then the contract was upgraded. - /// @notice This is public rather than external so we can call super.unpause - /// without using an expensive CALL. - - function unpause() public onlyCEO whenPaused { - require(address(saleAuction) != address(0)); - require(address(siringAuction) != address(0)); - require(address(geneScience) != address(0)); - require(newContractAddress == address(0)); - - // Actually unpause the contract. - super.unpause(); - } - - // @dev Allows the CFO to capture the balance available to the contract. - function withdrawBalance() external onlyCFO { - uint256 balance = address(this).balance; - // Subtract all the currently pregnant kittens we have, plus 1 of margin. - uint256 subtractFees = (pregnantKitties + 1) * autoBirthFee; - - if (balance > subtractFees) { - cfoAddress.transfer(balance - subtractFees); - } - } -} - - - - - - - - - - - - - -// // Auction wrapper functions - - -// Auction wrapper functions - - - - - - - -/// @title SEKRETOOOO -contract GeneScienceInterface { - - function isGeneScience() public pure returns (bool){ - return true; - } - - /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor - /// @param genes1 genes of mom - /// @param genes2 genes of sire - /// @return the genes that are supposed to be passed down the child - function mixGenes(uint256 genes1, uint256 genes2, uint256 targetBlock) public pure returns (uint256){ - - return (genes1+genes2+targetBlock)/2; - - -} -} - - - - - - - - - - - - - - - - -/// @title The external contract that is responsible for generating metadata for the kitties, -/// it has one function that will return the data as bytes. -contract ERC721Metadata { - /// @dev Given a token Id, returns a byte array that is supposed to be converted into string. - function getMetadata(uint256 _tokenId, string memory) public view returns (bytes32[4] memory buffer, uint256 count) { - if (_tokenId == 1) { - buffer[0] = "Hello World! :D"; - count = 15; - } else if (_tokenId == 2) { - buffer[0] = "I would definitely choose a medi"; - buffer[1] = "um length string."; - count = 49; - } else if (_tokenId == 3) { - buffer[0] = "Lorem ipsum dolor sit amet, mi e"; - buffer[1] = "st accumsan dapibus augue lorem,"; - buffer[2] = " tristique vestibulum id, libero"; - buffer[3] = " suscipit varius sapien aliquam."; - count = 128; - } - } -} - - - - - - - - - - - - - - - -/// @title Auction Core -/// @dev Contains models, variables, and internal methods for the auction. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuctionBase { - - // Represents an auction on an NFT - struct Auction { - // Current owner of NFT - address seller; - // Price (in wei) at beginning of auction - uint128 startingPrice; - // Price (in wei) at end of auction - uint128 endingPrice; - // Duration (in seconds) of auction - uint64 duration; - // Time when auction started - // NOTE: 0 if this auction has been concluded - uint64 startedAt; - } - - // Reference to contract tracking NFT ownership - ERC721 public nonFungibleContract; - - // Cut owner takes on each auction, measured in basis points (1/100 of a percent). - // Values 0-10,000 map to 0%-100% - uint256 public ownerCut; - - // Map from token ID to their corresponding auction. - mapping (uint256 => Auction) tokenIdToAuction; - - event AuctionCreated(uint256 tokenId, uint256 startingPrice, uint256 endingPrice, uint256 duration); - event AuctionSuccessful(uint256 tokenId, uint256 totalPrice, address winner); - event AuctionCancelled(uint256 tokenId); - - /// @dev Returns true if the claimant owns the token. - /// @param _claimant - Address claiming to own the token. - /// @param _tokenId - ID of token whose ownership to verify. - function _owns(address _claimant, uint256 _tokenId) internal view returns (bool) { - return (nonFungibleContract.ownerOf(_tokenId) == _claimant); - } - - /// @dev Escrows the NFT, assigning ownership to this contract. - /// Throws if the escrow fails. - /// @param _owner - Current owner address of token to escrow. - /// @param _tokenId - ID of token whose approval to verify. - function _escrow(address _owner, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transferFrom(_owner, address(this), _tokenId); - } - - /// @dev Transfers an NFT owned by this contract to another address. - /// Returns true if the transfer succeeds. - /// @param _receiver - Address to transfer NFT to. - /// @param _tokenId - ID of token to transfer. - function _transfer(address _receiver, uint256 _tokenId) internal { - // it will throw if transfer fails - nonFungibleContract.transfer(_receiver, _tokenId); - } - - /// @dev Adds an auction to the list of open auctions. Also fires the - /// AuctionCreated event. - /// @param _tokenId The ID of the token to be put on auction. - /// @param _auction Auction to add. - function _addAuction(uint256 _tokenId, Auction memory _auction) internal { - // Require that all auctions have a duration of - // at least one minute. (Keeps our math from getting hairy!) - require(_auction.duration >= 1 minutes); - - tokenIdToAuction[_tokenId] = _auction; - - emit AuctionCreated( - uint256(_tokenId), - uint256(_auction.startingPrice), - uint256(_auction.endingPrice), - uint256(_auction.duration) - ); - } - - /// @dev Cancels an auction unconditionally. - function _cancelAuction(uint256 _tokenId, address _seller) internal { - _removeAuction(_tokenId); - _transfer(_seller, _tokenId); - emit AuctionCancelled(_tokenId); - } - - /// @dev Computes the price and transfers winnings. - /// Does NOT transfer ownership of token. - function _bid(uint256 _tokenId, uint256 _bidAmount) - internal - returns (uint256) - { - // Get a reference to the auction struct - Auction storage auction = tokenIdToAuction[_tokenId]; - - // Explicitly check that this auction is currently live. - // (Because of how Ethereum mappings work, we can't just count - // on the lookup above failing. An invalid _tokenId will just - // return an auction object that is all zeros.) - require(_isOnAuction(auction)); - - // Check that the bid is greater than or equal to the current price - uint256 price = _currentPrice(auction); - require(_bidAmount >= price); - - // Grab a reference to the seller before the auction struct - // gets deleted. - address seller = auction.seller; - - // The bid is good! Remove the auction before sending the fees - // to the sender so we can't have a reentrancy attack. - _removeAuction(_tokenId); - - // Transfer proceeds to seller (if there are any!) - if (price > 0) { - // Calculate the auctioneer's cut. - // (NOTE: _computeCut() is guaranteed to return a - // value <= price, so this subtraction can't go negative.) - uint256 auctioneerCut = _computeCut(price); - uint256 sellerProceeds = price - auctioneerCut; - - // NOTE: Doing a transfer() in the middle of a complex - // method like this is generally discouraged because of - // reentrancy attacks and DoS attacks if the seller is - // a contract with an invalid fallback function. We explicitly - // guard against reentrancy attacks by removing the auction - // before calling transfer(), and the only thing the seller - // can DoS is the sale of their own asset! (And if it's an - // accident, they can call cancelAuction(). ) - seller.transfer(sellerProceeds); - } - - // Calculate any excess funds included with the bid. If the excess - // is anything worth worrying about, transfer it back to bidder. - // NOTE: We checked above that the bid amount is greater than or - // equal to the price so this cannot underflow. - uint256 bidExcess = _bidAmount - price; - - // Return the funds. Similar to the previous transfer, this is - // not susceptible to a re-entry attack because the auction is - // removed before any transfers occur. - msg.sender.transfer(bidExcess); - - // Tell the world! - emit AuctionSuccessful(_tokenId, price, msg.sender); - - return price; - } - - /// @dev Removes an auction from the list of open auctions. - /// @param _tokenId - ID of NFT on auction. - function _removeAuction(uint256 _tokenId) internal { - delete tokenIdToAuction[_tokenId]; - } - - /// @dev Returns true if the NFT is on auction. - /// @param _auction - Auction to check. - function _isOnAuction(Auction storage _auction) internal view returns (bool) { - return (_auction.startedAt > 0); - } - - /// @dev Returns current price of an NFT on auction. Broken into two - /// functions (this one, that computes the duration from the auction - /// structure, and the other that does the price computation) so we - /// can easily test that the price computation works correctly. - function _currentPrice(Auction storage _auction) - internal - view - returns (uint256) - { - uint256 secondsPassed = 0; - - // A bit of insurance against negative values (or wraparound). - // Probably not necessary (since Ethereum guarnatees that the - // now variable doesn't ever go backwards). - if (now > _auction.startedAt) { - secondsPassed = now - _auction.startedAt; - } - - return _computeCurrentPrice( - _auction.startingPrice, - _auction.endingPrice, - _auction.duration, - secondsPassed - ); - } - - /// @dev Computes the current price of an auction. Factored out - /// from _currentPrice so we can run extensive unit tests. - /// When testing, make this function public and turn on - /// `Current price computation` test suite. - function _computeCurrentPrice( - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - uint256 _secondsPassed - ) - internal - pure - returns (uint256) - { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our public functions carefully cap the maximum values for - // time (at 64-bits) and currency (at 128-bits). _duration is - // also known to be non-zero (see the require() statement in - // _addAuction()) - if (_secondsPassed >= _duration) { - // We've reached the end of the dynamic pricing portion - // of the auction, just return the end price. - return _endingPrice; - } else { - // Starting price can be higher than ending price (and often is!), so - // this delta can be negative. - int256 totalPriceChange = int256(_endingPrice) - int256(_startingPrice); - - // This multiplication can't overflow, _secondsPassed will easily fit within - // 64-bits, and totalPriceChange will easily fit within 128-bits, their product - // will always fit within 256-bits. - int256 currentPriceChange = totalPriceChange * int256(_secondsPassed) / int256(_duration); - - // currentPriceChange can be negative, but if so, will have a magnitude - // less that _startingPrice. Thus, this result will always end up positive. - int256 currentPrice = int256(_startingPrice) + currentPriceChange; - - return uint256(currentPrice); - } - } - - /// @dev Computes owner's cut of a sale. - /// @param _price - Sale price of NFT. - function _computeCut(uint256 _price) internal view returns (uint256) { - // NOTE: We don't use SafeMath (or similar) in this function because - // all of our entry functions carefully cap the maximum values for - // currency (at 128-bits), and ownerCut <= 10000 (see the require() - // statement in the ClockAuction constructor). The result of this - // function is always guaranteed to be <= _price. - return _price * ownerCut / 10000; - } - -} - - - - - - - -/** - * @title Pausable - * @dev Base contract which allows children to implement an emergency stop mechanism. - */ -contract Pausable is Ownable { - event Pause(); - event Unpause(); - - bool public paused = false; - - - /** - * @dev modifier to allow actions only when the contract IS paused - */ - modifier whenNotPaused() { - require(!paused); - _; - } - - /** - * @dev modifier to allow actions only when the contract IS NOT paused - */ - modifier whenPaused { - require(paused); - _; - } - - /** - * @dev called by the owner to pause, triggers stopped state - */ - function pause() onlyOwner whenNotPaused public returns (bool) { - paused = true; - emit Pause(); - return true; - } - - /** - * @dev called by the owner to unpause, returns to normal state - */ - function unpause() onlyOwner whenPaused public returns (bool) { - paused = false; - emit Unpause(); - return true; - } -} - - -/// @title Clock auction for non-fungible tokens. -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract ClockAuction is Pausable, ClockAuctionBase { - - /// @dev The ERC-165 interface signature for ERC-721. - /// Ref: https://github.com/ethereum/EIPs/issues/165 - /// Ref: https://github.com/ethereum/EIPs/issues/721 - bytes4 constant InterfaceSignature_ERC721 = bytes4(0x9a20483d); - - /// @dev Constructor creates a reference to the NFT ownership contract - /// and verifies the owner cut is in the valid range. - /// @param _nftAddress - address of a deployed contract implementing - /// the Nonfungible Interface. - /// @param _cut - percent cut the owner takes on each auction, must be - /// between 0-10,000. - constructor(address _nftAddress, uint256 _cut) public { - require(_cut <= 10000); - ownerCut = _cut; - - ERC721 candidateContract = ERC721(_nftAddress); - require(candidateContract.supportsInterface(InterfaceSignature_ERC721)); - nonFungibleContract = candidateContract; - } - - /// @dev Remove all Ether from the contract, which is the owner's cuts - /// as well as any Ether sent directly to the contract address. - /// Always transfers to the NFT contract, but can be called either by - /// the owner or the NFT contract. - function withdrawBalance() external { - address nftAddress = address(uint160(address(nonFungibleContract))); - - require( - msg.sender == owner || - msg.sender == nftAddress - ); - // We are using this boolean method to make sure that even if one fails it will still work - bool res = nftAddress.send(address(this).balance); - } - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of time to move between starting - /// price and ending price (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address _seller - ) - external - whenNotPaused - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(_owns(msg.sender, _tokenId)); - _escrow(msg.sender, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Bids on an open auction, completing the auction and transferring - /// ownership of the NFT if enough Ether is supplied. - /// @param _tokenId - ID of token to bid on. - function bid(uint256 _tokenId) - external - payable - whenNotPaused - { - // _bid will throw if the bid or funds transfer fails - _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - } - - /// @dev Cancels an auction that hasn't been won yet. - /// Returns the NFT to original owner. - /// @notice This is a state-modifying function that can - /// be called while the contract is paused. - /// @param _tokenId - ID of token on auction - function cancelAuction(uint256 _tokenId) - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - address seller = auction.seller; - require(msg.sender == seller); - _cancelAuction(_tokenId, seller); - } - - /// @dev Cancels an auction when the contract is paused. - /// Only the owner may do this, and NFTs are returned to - /// the seller. This should only be used in emergencies. - /// @param _tokenId - ID of the NFT on auction to cancel. - function cancelAuctionWhenPaused(uint256 _tokenId) - whenPaused - onlyOwner - external - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - _cancelAuction(_tokenId, auction.seller); - } - - /// @dev Returns auction info for an NFT on auction. - /// @param _tokenId - ID of NFT on auction. - function getAuction(uint256 _tokenId) - external - view - returns - ( - address seller, - uint256 startingPrice, - uint256 endingPrice, - uint256 duration, - uint256 startedAt - ) { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return ( - auction.seller, - auction.startingPrice, - auction.endingPrice, - auction.duration, - auction.startedAt - ); - } - - /// @dev Returns the current price of an auction. - /// @param _tokenId - ID of the token price we are checking. - function getCurrentPrice(uint256 _tokenId) - external - view - returns (uint256) - { - Auction storage auction = tokenIdToAuction[_tokenId]; - require(_isOnAuction(auction)); - return _currentPrice(auction); - } - -} - - -/// @title Reverse auction modified for siring -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SiringClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSiringAuctionAddress() call. - bool public isSiringClockAuction = true; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. Since this function is wrapped, - /// require sender to be KittyCore contract. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Places a bid for siring. Requires the sender - /// is the KittyCore contract because all bid methods - /// should be wrapped. Also returns the kitty to the - /// seller rather than the winner. - function bid(uint256 _tokenId) - external - payable - { - require(msg.sender == address(nonFungibleContract)); - address seller = tokenIdToAuction[_tokenId].seller; - // _bid checks that token ID is valid and will throw if bid fails - _bid(_tokenId, msg.value); - // We transfer the kitty back to the seller, the winner will get - // the offspring - _transfer(seller, _tokenId); - } - -} - - - - - -/// @title Clock auction modified for sale of kitties -/// @notice We omit a fallback function to prevent accidental sends to this contract. -contract SaleClockAuction is ClockAuction { - - // @dev Sanity check that allows us to ensure that we are pointing to the - // right auction in our setSaleAuctionAddress() call. - bool public isSaleClockAuction = true; - - // Tracks last 5 sale price of gen0 kitty sales - uint256 public gen0SaleCount; - uint256[5] public lastGen0SalePrices; - - // Delegate constructor - constructor(address _nftAddr, uint256 _cut) public - ClockAuction(_nftAddr, _cut) {} - - /// @dev Creates and begins a new auction. - /// @param _tokenId - ID of token to auction, sender must be owner. - /// @param _startingPrice - Price of item (in wei) at beginning of auction. - /// @param _endingPrice - Price of item (in wei) at end of auction. - /// @param _duration - Length of auction (in seconds). - /// @param _seller - Seller, if not the message sender - function createAuction( - uint256 _tokenId, - uint256 _startingPrice, - uint256 _endingPrice, - uint256 _duration, - address _seller - ) - external - { - // Sanity check that no inputs overflow how many bits we've allocated - // to store them in the auction struct. - require(_startingPrice == uint256(uint128(_startingPrice))); - require(_endingPrice == uint256(uint128(_endingPrice))); - require(_duration == uint256(uint64(_duration))); - - require(msg.sender == address(nonFungibleContract)); - _escrow(_seller, _tokenId); - Auction memory auction = Auction( - _seller, - uint128(_startingPrice), - uint128(_endingPrice), - uint64(_duration), - uint64(now) - ); - _addAuction(_tokenId, auction); - } - - /// @dev Updates lastSalePrice if seller is the nft contract - /// Otherwise, works the same as default bid method. - function bid(uint256 _tokenId) - external - payable - { - // _bid verifies token ID size - address seller = tokenIdToAuction[_tokenId].seller; - uint256 price = _bid(_tokenId, msg.value); - _transfer(msg.sender, _tokenId); - - // If not a gen0 auction, exit - if (seller == address(nonFungibleContract)) { - // Track gen0 sale prices - lastGen0SalePrices[gen0SaleCount % 5] = price; - gen0SaleCount++; - } - } - - function averageGen0SalePrice() external view returns (uint256) { - uint256 sum = 0; - for (uint256 i = 0; i < 5; i++) { - sum += lastGen0SalePrices[i]; - } - return sum / 5; - } - -} - - - - - - - diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario012.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractScenario012.sol deleted file mode 100644 index 81f64134298..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario012.sol +++ /dev/null @@ -1,57 +0,0 @@ -//pragma solidity ^0.4.0; -contract PayTest { - -uint256 public n; -constructor() payable public{ -n = 0; -} - -function nPlusOne() public{ -n = n+1; -} - -//get current contract balance -function getBalance() payable public returns (uint) { -return address(this).balance; -} - -function getSenderBalance() public view returns(address, uint) { -return (msg.sender, msg.sender.balance); -} - -address public user; - -//deposit 1 coin to msg.sender -function depositOneCoin() payable public returns(bool success){ -return msg.sender.send(1); -} - -// function transferOneCoin() payable public returns(){ -// address(msg.sender).transfer(1); -// } - -// function depositOneCoin() payable public returns(address addr, uint amount, bool success){ -// return (msg.sender, msg.value, msg.sender.send(1)); -// } - -//deposit coin to msg.sender -function deposit(uint256 money) payable public returns(bool success){ -return msg.sender.send(money); -} -// function deposit(uint money) payable public returns(address addr, uint amount, bool success){ -// return (msg.sender, msg.value, msg.sender.send(money)); -// } - -// function () payable { -// msg.sender.send(1); -// } - -function sendToAddress(address _receiver) payable public{ -_receiver.transfer(msg.value); -} - -function sendToAddress2(address _receiver) payable public{ -_receiver.transfer(5); -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario013.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractScenario013.sol deleted file mode 100644 index b91085d018e..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario013.sol +++ /dev/null @@ -1,8 +0,0 @@ -//pragma solidity ^0.4.0; -contract timetest { - -function time() public{ -require(1 trx == 1000000 sun); - -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario014.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractScenario014.sol deleted file mode 100644 index 0e00a8f7f9b..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractScenario014.sol +++ /dev/null @@ -1,34 +0,0 @@ -//pragma solidity ^0.4.0; -contract Contract1 { - constructor() public payable{} - function send5SunToReceiver(address _receiver) payable public{ - _receiver.transfer(5); - } -} -contract contract2 { - address public payContract; - - constructor(address _add) payable public{ - payContract = _add; - } - - function triggerContract1(address _receiver) payable public{ - payContract.call(abi.encodeWithSignature("send5SunToReceiver(address)",_receiver)); - } - - function triggerContract1ButRevert(address _receiver) payable public{ - payContract.call(abi.encodeWithSignature("send5SunToReceiver(address)",_receiver)); - require(1 == 2); - } - -} -contract contract3 { - address public payContract; - constructor(address _add) payable public{ - payContract = _add; - } - - function triggerContract2(address _receiver) payable public{ - payContract.call(abi.encodeWithSignature("triggerContract1(address)",_receiver)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTest.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTest.sol deleted file mode 100644 index d6c5f34af2d..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTest.sol +++ /dev/null @@ -1,19 +0,0 @@ -//pragma solidity ^0.4.4; - -contract Test{ - -function a() returns (uint){ - -uint256 count = 0; - -for (uint256 i = 1; i > 0; i++) { - -count++; - -} - -return count; - -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractToMathedFeed.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractToMathedFeed.sol deleted file mode 100644 index 7cbfddfc657..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractToMathedFeed.sol +++ /dev/null @@ -1,19 +0,0 @@ -//pragma solidity ^0.4.0; - -contract ToMathedFeed { - uint public i=1; - function ToMathed(uint value) { - i=value; - } -} - -contract ToMathedUseINContract { - function ToMathedIUseNR(address a,uint256 n) returns(bool){ - address payContract=a; - return payContract.call(bytes4(keccak256("ToMathedNot(uint256)")),n); - } - function ToMathedIUseNRE(address a,uint256 value) returns(bool){ - address payContract=a; - return payContract.call(bytes4(keccak256("ToMathed(uint256)")),value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken001.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken001.sol deleted file mode 100644 index a7649149263..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken001.sol +++ /dev/null @@ -1,30 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken002.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken002.sol deleted file mode 100644 index a7649149263..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken002.sol +++ /dev/null @@ -1,30 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken003.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken003.sol deleted file mode 100644 index 924513518ea..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken003.sol +++ /dev/null @@ -1,16 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken005.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken005.sol deleted file mode 100644 index 924513518ea..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken005.sol +++ /dev/null @@ -1,16 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken011.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken011.sol deleted file mode 100644 index eee0510ccc3..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken011.sol +++ /dev/null @@ -1,35 +0,0 @@ -//pragma solidity ^0.4.24; -contract transferTokenContract { - constructor() payable public{} - function() payable public{} - function transferTokenTest(address toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - function() payable public{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken012.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken012.sol deleted file mode 100644 index 99bb82c48f2..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken012.sol +++ /dev/null @@ -1,26 +0,0 @@ -//pragma solidity ^0.4.24; -contract transferTokenContract { - constructor() payable public{} - function() payable public{} - function transferTokenTest(address toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken014.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken014.sol deleted file mode 100644 index ada9432a02e..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken014.sol +++ /dev/null @@ -1,34 +0,0 @@ -//pragma solidity ^0.4.24; -contract transferTokenContract { - constructor() payable public{} - function() payable public{} - function transferTokenTest(address toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - function() payable external{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken018.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken018.sol deleted file mode 100644 index 99bb82c48f2..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken018.sol +++ /dev/null @@ -1,26 +0,0 @@ -//pragma solidity ^0.4.24; -contract transferTokenContract { - constructor() payable public{} - function() payable public{} - function transferTokenTest(address toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken023.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken023.sol deleted file mode 100644 index 16551e2f177..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken023.sol +++ /dev/null @@ -1,26 +0,0 @@ -pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - function TransferTokenTo(address toAddress, trcToken id,uint256 amount) public payable{ - toAddress.transferToken(amount,id); - } - } - -contract B{ - uint256 public flag = 0; - constructor() public payable {} - function() public payable { - flag = 1; -} - -} -pragma solidity ^0.4.24; -contract C{ - uint256 public flag = 0; - constructor() public payable {} - function() public payable { - //flag = 1; -} - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken026.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken026.sol deleted file mode 100644 index a45d885bbb4..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken026.sol +++ /dev/null @@ -1,30 +0,0 @@ -pragma solidity ^0.4.24; - -contract token{ - constructor() payable public{} - function() payable public{} - function testInCall(address callBAddress,address callCAddress, address toAddress ,uint256 amount,trcToken id) payable public{ - callBAddress.call(bytes4(keccak256("transC(address,address,uint256,trcToken)")),callCAddress,toAddress,amount,id); - } - function testIndelegateCall(address callBddress,address callAddressC, address toAddress,uint256 amount, trcToken id) payable public{ - callBddress.delegatecall(bytes4(keccak256("transC(address,address,uint256,trcToken)")),callAddressC,toAddress,amount,id); - } - } - - - -contract B{ - constructor() public payable{} - function() public payable{} - function transC(address callCAddress,address toAddress,uint256 amount, trcToken id) payable public{ - callCAddress.call(bytes4(keccak256("trans(address,uint256,trcToken)")),toAddress,amount,id); - } -} -contract C{ - constructor() payable public{} - function() payable public{} - function trans(address toAddress,uint256 amount, trcToken id) payable public{ - toAddress.transferToken(amount,id); - } - -} diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken027.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken027.sol deleted file mode 100644 index a45d885bbb4..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken027.sol +++ /dev/null @@ -1,30 +0,0 @@ -pragma solidity ^0.4.24; - -contract token{ - constructor() payable public{} - function() payable public{} - function testInCall(address callBAddress,address callCAddress, address toAddress ,uint256 amount,trcToken id) payable public{ - callBAddress.call(bytes4(keccak256("transC(address,address,uint256,trcToken)")),callCAddress,toAddress,amount,id); - } - function testIndelegateCall(address callBddress,address callAddressC, address toAddress,uint256 amount, trcToken id) payable public{ - callBddress.delegatecall(bytes4(keccak256("transC(address,address,uint256,trcToken)")),callAddressC,toAddress,amount,id); - } - } - - - -contract B{ - constructor() public payable{} - function() public payable{} - function transC(address callCAddress,address toAddress,uint256 amount, trcToken id) payable public{ - callCAddress.call(bytes4(keccak256("trans(address,uint256,trcToken)")),toAddress,amount,id); - } -} -contract C{ - constructor() payable public{} - function() payable public{} - function trans(address toAddress,uint256 amount, trcToken id) payable public{ - toAddress.transferToken(amount,id); - } - -} diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken028.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken028.sol deleted file mode 100644 index 36dad7847a2..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken028.sol +++ /dev/null @@ -1,25 +0,0 @@ -pragma solidity ^0.4.24; - -contract token{ - uint256 public a=1; - constructor() public payable{} - function tokenBalanceWithSameName(trcToken id) public payable{ - B b= new B(); - a= b.tokenBalance(id); - } - function getA() public returns(uint256){ - return a; - } -} - - -contract B{ - uint256 public flag =0; - constructor() public payable{} - function() public payable{} - function tokenBalance(trcToken id) payable public returns(uint256){ - flag =9; - return flag; - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken029.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken029.sol deleted file mode 100644 index 93a79a6f774..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken029.sol +++ /dev/null @@ -1,24 +0,0 @@ -pragma solidity ^0.4.24; - -contract token{ - address public a; - constructor() public payable{} - function transferTokenWithSameName(trcToken id,uint256 amount) public payable{ - B b= new B(); - b.transferToken(amount,id); - a= address(b); - } -} - - -contract B{ - uint256 public flag =0; - constructor() public payable{} - function() public payable{} - function transferToken(uint256 amount, trcToken id) payable public returns(bool){ - flag =9; - } - function getFlag() public view returns (uint256){ - return flag; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken030.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken030.sol deleted file mode 100644 index d82c6ab6928..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken030.sol +++ /dev/null @@ -1,18 +0,0 @@ -pragma solidity ^0.4.24; - - contract token{ - constructor() public payable{} - - // 4)suicide也会转移token - // 所有token,trx均被转移到toAddress, - // 若toAddress为合约地址本身,则所有token,trx均被烧掉进黑洞 - function kill(address toAddress) payable public{ - selfdestruct(toAddress); - } - - } - -contract B{ - constructor() public payable {} - function() public payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken031.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken031.sol deleted file mode 100644 index d82c6ab6928..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken031.sol +++ /dev/null @@ -1,18 +0,0 @@ -pragma solidity ^0.4.24; - - contract token{ - constructor() public payable{} - - // 4)suicide也会转移token - // 所有token,trx均被转移到toAddress, - // 若toAddress为合约地址本身,则所有token,trx均被烧掉进黑洞 - function kill(address toAddress) payable public{ - selfdestruct(toAddress); - } - - } - -contract B{ - constructor() public payable {} - function() public payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken034.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken034.sol deleted file mode 100644 index 03afab38850..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken034.sol +++ /dev/null @@ -1,23 +0,0 @@ -pragma solidity ^0.4.24; - - contract token{ - - // 2. 异常测试 - // 1)revert, 金额回退 - function failTransferTokenRevert(address toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - require(1==2); - } - - // 2)Error, 金额回退, fee limit 扣光 - function failTransferTokenError(address toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - assert(1==2); - } - - } - contract B{ - uint256 public flag = 0; - constructor() public payable {} - function() public payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken035.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken035.sol deleted file mode 100644 index 03afab38850..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken035.sol +++ /dev/null @@ -1,23 +0,0 @@ -pragma solidity ^0.4.24; - - contract token{ - - // 2. 异常测试 - // 1)revert, 金额回退 - function failTransferTokenRevert(address toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - require(1==2); - } - - // 2)Error, 金额回退, fee limit 扣光 - function failTransferTokenError(address toAddress,uint256 amount, trcToken id) public payable{ - toAddress.transferToken(amount,id); - assert(1==2); - } - - } - contract B{ - uint256 public flag = 0; - constructor() public payable {} - function() public payable {} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken036.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken036.sol deleted file mode 100644 index b9c81f8cd59..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken036.sol +++ /dev/null @@ -1,65 +0,0 @@ -pragma solidity ^0.4.24; -contract IllegalDecorate { -constructor() payable public{} -function() payable public{} -event log(uint256); -function transferTokenWithPure(address toAddress, uint256 tokenValue) public payable { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate1 { -constructor() payable public{} -function() payable public{} -event log(uint256); -function transferTokenWithConstant(address toAddress, uint256 tokenValue) public constant { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate2 { -constructor() payable public{} -function() payable public{} -event log(uint256); -function transferTokenWithView(address toAddress, uint256 tokenValue) public view { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate3 { -event log(uint256); -constructor() payable public{} -function() payable public{} -function transferTokenWithOutPayable(address toAddress, uint256 tokenValue) public { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} - -contract IllegalDecorate4 { -constructor() payable public{} -function() payable public{} -event log(uint256); -function transferTokenWithPure(address toAddress, uint256 tokenValue) public pure { -emit log(msg.value); -emit log(msg.tokenvalue); -emit log(msg.tokenid); -toAddress.transferToken(msg.tokenvalue, msg.tokenid); -toAddress.transfer(msg.value); -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken037.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken037.sol deleted file mode 100644 index ad19db9a3a6..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken037.sol +++ /dev/null @@ -1,23 +0,0 @@ -pragma solidity ^0.4.24; - -contract transferTrc10 { - function receive(address rec) public payable { - uint256 aamount=address(this).tokenBalance(msg.tokenid); - uint256 bamount=rec.tokenBalance(msg.tokenid); - require(msg.tokenvalue==aamount); - require(aamount==msg.tokenvalue); - rec.transferToken(aamount,msg.tokenid); - require(0==address(this).tokenBalance(msg.tokenid)); - require(bamount+aamount==rec.tokenBalance(msg.tokenid)); - require(rec.call(bytes4(keccak256("checkTrc10(uint256,trcToken,uint256)")),bamount+aamount,msg.tokenid,0)); - } -} - -contract receiveTrc10 { - function() public payable { - } - function checkTrc10(uint256 amount,trcToken tid,uint256 meamount) public{ - require(amount==address(this).tokenBalance(tid)); - require(meamount==msg.sender.tokenBalance(tid)); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken038.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken038.sol deleted file mode 100644 index 5b1a0babe8b..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken038.sol +++ /dev/null @@ -1,22 +0,0 @@ -pragma solidity ^0.4.24; - -contract transferTrc10 { - function receive(address rec) public payable { - uint256 aamount=address(this).tokenBalance(msg.tokenid); - uint256 bamount=rec.tokenBalance(msg.tokenid); - require(msg.tokenvalue==aamount); - require(aamount==msg.tokenvalue); - rec.transferToken(aamount,msg.tokenid); - require(rec.call(bytes4(keccak256("AssertError()")))); - require(aamount==address(this).tokenBalance(msg.tokenid)); - require(bamount==rec.tokenBalance(msg.tokenid)); - } -} - -contract receiveTrc10 { - function() public payable { - } - function AssertError() public{ - assert(1==2); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken039.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken039.sol deleted file mode 100644 index 7229e3aaa9a..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken039.sol +++ /dev/null @@ -1,44 +0,0 @@ -pragma solidity ^0.4.24; -/* - * 1. caller账户issue一个token - * 2. caller部署proxy, 传入1000 token,1000 trx - * 3. caller部署A - * 4. caller部署B - * 5. caller调用proxy中upgradetTo函数,传入A的地址 - * 6. caller调用proxy中不存在的trans(uint256,address,trcToken)函数,注意这时trcToken是无意义的,但也带上tokenid。address是任意另外某账户的地址 - * 7. 可以看到目标地址trx增长5,caller账户trx减少5 - * 8. caller调用proxy中upgradeTo函数,传入B的地址 - * 9. caller调用proxy中不存在的trans(uint256,address,trcToken)函数。 - * 10. 可以看到目标地址token增长5,caller账户token减少5 -*/ -contract Proxy { - constructor() payable public{} - address public implementation; - function upgradeTo(address _address) public { - implementation = _address; - } - function() payable public{ - address addr = implementation; - require(addr != address(0)); - assembly { - let freememstart := mload(0x40) - calldatacopy(freememstart, 0, calldatasize()) - let success := delegatecall(not(0), addr, freememstart, calldatasize(), freememstart, 0) - returndatacopy(freememstart, 0, returndatasize()) - switch success - case 0 { revert(freememstart, returndatasize()) } - default { return(freememstart, returndatasize()) } - } - } -} - -contract A { - function trans(uint256 amount, address toAddress, trcToken id) payable public { - toAddress.transfer(amount); - } -} -contract B{ - function trans(uint256 amount, address toAddress, trcToken id) payable public { - toAddress.transferToken(amount,id); - } -} diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken041.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken041.sol deleted file mode 100644 index f70ab112afe..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken041.sol +++ /dev/null @@ -1,20 +0,0 @@ -pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } - -contract B{ - uint256 public flag = 0; - constructor() public payable {} - function() public payable {} - - function setFlag() public payable{ - flag = 1; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken043.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken043.sol deleted file mode 100644 index eee0510ccc3..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken043.sol +++ /dev/null @@ -1,35 +0,0 @@ -//pragma solidity ^0.4.24; -contract transferTokenContract { - constructor() payable public{} - function() payable public{} - function transferTokenTest(address toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - function() payable public{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken048.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken048.sol deleted file mode 100644 index de2844608c0..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken048.sol +++ /dev/null @@ -1,14 +0,0 @@ -//pragma solidity ^0.4.24; - - contract Test { - event log(uint256); - function testMsgTokenValue() payable public returns(uint256 value) { - emit log(msg.tokenvalue); - return msg.tokenvalue; - } - - function testMsgValue() payable public returns(uint256 value) { - emit log(msg.value); - return msg.value; - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken049.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken049.sol deleted file mode 100644 index 25b31a4ffd6..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken049.sol +++ /dev/null @@ -1,10 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken050.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken050.sol deleted file mode 100644 index 25b31a4ffd6..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken050.sol +++ /dev/null @@ -1,10 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken051.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken051.sol deleted file mode 100644 index 25b31a4ffd6..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken051.sol +++ /dev/null @@ -1,10 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken052.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken052.sol deleted file mode 100644 index 25b31a4ffd6..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken052.sol +++ /dev/null @@ -1,10 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken054.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken054.sol deleted file mode 100644 index 924513518ea..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken054.sol +++ /dev/null @@ -1,16 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken055.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken055.sol deleted file mode 100644 index 924513518ea..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken055.sol +++ /dev/null @@ -1,16 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken060.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken060.sol deleted file mode 100644 index a7649149263..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken060.sol +++ /dev/null @@ -1,30 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken061.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken061.sol deleted file mode 100644 index a7649149263..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken061.sol +++ /dev/null @@ -1,30 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken064.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken064.sol deleted file mode 100644 index 0378fd90cc1..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken064.sol +++ /dev/null @@ -1,49 +0,0 @@ -//pragma solidity ^0.4.24; -contract transferTokenContract { - constructor() payable public{} - function() payable public{} - function transferTokenTest(address toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } - function transferTokenTestValueMaxBigInteger(address toAddress) payable public { - toAddress.transferToken(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0); - } - function transferTokenTestValueOverBigInteger(address toAddress) payable public { - toAddress.transferToken(9223372036854775808, 1000001); - } - function transferTokenTestValueMaxLong(address toAddress) payable public { - toAddress.transferToken(9223372036854775807, 1000001); - } - function transferTokenTestValue0IdBigInteger(address toAddress) payable public { - toAddress.transferToken(0, 9223372036854775809); - } -} - - - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - function() payable public{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken066.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken066.sol deleted file mode 100644 index eee0510ccc3..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken066.sol +++ /dev/null @@ -1,35 +0,0 @@ -//pragma solidity ^0.4.24; -contract transferTokenContract { - constructor() payable public{} - function() payable public{} - function transferTokenTest(address toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - function() payable public{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken067.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken067.sol deleted file mode 100644 index eee0510ccc3..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken067.sol +++ /dev/null @@ -1,35 +0,0 @@ -//pragma solidity ^0.4.24; -contract transferTokenContract { - constructor() payable public{} - function() payable public{} - function transferTokenTest(address toAddress, uint256 tokenValue, trcToken id) payable public { - toAddress.transferToken(tokenValue, id); - } - function transferTokenTestIDOverBigInteger(address toAddress) payable public { - toAddress.transferToken(1, 9223372036854775809); - } - function transferTokenTestValueRandomIdBigInteger(address toAddress) payable public { - toAddress.transferToken(1, 36893488147420103233); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256){ - trcToken id = msg.tokenid; - uint256 value = msg.tokenvalue; - return (id, value); - } - function getTokenBalanceTest(address accountAddress) payable public returns (uint256){ - trcToken id = 1000001; - return accountAddress.tokenBalance(id); - } - function getTokenBalnce(address toAddress, trcToken tokenId) public payable returns(uint256){ - return toAddress.tokenBalance(tokenId); - } -} - - -contract Result { - event log(uint256,uint256,uint256); - constructor() payable public{} - function() payable public{ - emit log(msg.tokenid,msg.tokenvalue,msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken073.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken073.sol deleted file mode 100644 index b5b6d149565..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken073.sol +++ /dev/null @@ -1,17 +0,0 @@ -//pragma solidity ^0.4.0; - -contract Dest { - event logFallback(uint256 indexed, uint256 indexed, uint256 indexed); - event logGetToken(uint256 indexed, uint256 indexed, uint256 indexed, uint256); - - - function Dest() payable public {} - - function getToken(trcToken tokenId) payable { - logGetToken(msg.sender.tokenBalance(tokenId), msg.tokenid, msg.tokenvalue, msg.value); - } - - function () payable { - logFallback(msg.tokenid, msg.tokenvalue, msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken075.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken075.sol deleted file mode 100644 index dfcaf8c2a52..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken075.sol +++ /dev/null @@ -1,26 +0,0 @@ -//pragma solidity ^0.4.0; - -contract Dest { - event logFallback(uint256 indexed, uint256 indexed, uint256 indexed); - event logGetToken(uint256 indexed, uint256 indexed, uint256 indexed, uint256); - - function Dest() payable public {} - - function getToken(trcToken tokenId) payable { - logGetToken(msg.sender.tokenBalance(tokenId), msg.tokenid, msg.tokenvalue, msg.value); - } - - function getTokenLongMin() payable { - // long.min - 1000020 - logGetToken(msg.sender.tokenBalance(trcToken(-9223372036855775828)), msg.tokenid, msg.tokenvalue, msg.value); - } - - function getTokenLongMax() payable { - // long.max + 1000020 - logGetToken(msg.sender.tokenBalance(trcToken(9223372036855775827)), msg.tokenid, msg.tokenvalue, msg.value); - } - - function () payable { - logFallback(msg.tokenid, msg.tokenvalue, msg.value); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken076.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken076.sol deleted file mode 100644 index 9de79a327c3..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken076.sol +++ /dev/null @@ -1,19 +0,0 @@ -//pragma solidity ^0.4.24; -contract Test { - address public origin; - address public sender; - bool public result1; - bool public result2; - function test() external { - origin = tx.origin; - sender = msg.sender; - result1 = msg.sender == tx.origin; // true - result2 = origin == sender; // true - } -function getResult1() public returns(bool){ - return result1; -} -function getResult2() public returns(bool){ - return result2; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken077.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken077.sol deleted file mode 100644 index e110f24e2fc..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken077.sol +++ /dev/null @@ -1,11 +0,0 @@ -//pragma solidity ^0.4.24; - -contract trcToken077 { -function addressTest() public returns(bytes32 addressValue) { - assembly{ - let x := mload(0x40) //Find empty storage location using "free memory pointer" - mstore(x,address) //Place current contract address - addressValue := mload(x) - } - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken078.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken078.sol deleted file mode 100644 index 4d51a365e14..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken078.sol +++ /dev/null @@ -1,35 +0,0 @@ -//pragma solidity ^0.4.24; -contract callerContract { - constructor() payable{} - function() payable{} - function sendToB(address called_address,address c) public payable{ - called_address.delegatecall(bytes4(keccak256("transferTo(address)")),c); - } - function sendToB2(address called_address,address c) public payable{ - called_address.call(bytes4(keccak256("transferTo(address)")),c); - } - function sendToB3(address called_address,address c) public payable{ - called_address.callcode(bytes4(keccak256("transferTo(address)")),c); - } -} - contract calledContract { - function() payable{} - constructor() payable {} - function transferTo(address toAddress)public payable{ - toAddress.transfer(5); - } - - function setIinC(address c) public payable{ - c.call.value(5)(bytes4(keccak256("setI()"))); - } - - } - contract c{ - address public origin; - address public sender; - constructor() public payable{} - event log(address,address); - function() payable public{ - emit log(tx.origin,msg.sender); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken079.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken079.sol deleted file mode 100644 index 924513518ea..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken079.sol +++ /dev/null @@ -1,16 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - constructor() public payable{} - // positive case - function TransferTokenTo(address toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken080.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken080.sol deleted file mode 100644 index a7649149263..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcToken080.sol +++ /dev/null @@ -1,30 +0,0 @@ -//pragma solidity ^0.4.24; - - contract tokenTest{ - trcToken idCon = 0; - uint256 tokenValueCon=0; - uint256 callValueCon = 0; - - // positive case - function TransferTokenTo(address toAddress, trcToken id,uint256 amount) public payable{ - //trcToken id = 0x74657374546f6b656e; - toAddress.transferToken(amount,id); - } - - function msgTokenValueAndTokenIdTest() public payable returns(trcToken, uint256, uint256){ - trcToken id = msg.tokenid; - uint256 tokenValue = msg.tokenvalue; - uint256 callValue = msg.value; - return (id, tokenValue, callValue); - } - - constructor() public payable { - idCon = msg.tokenid; - tokenValueCon = msg.tokenvalue; - callValueCon = msg.value; - } - - function getResultInCon() public payable returns(trcToken, uint256, uint256) { - return (idCon, tokenValueCon, callValueCon); - } - } \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcTokenToOther.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractTrcTokenToOther.sol deleted file mode 100644 index e9ebd0ae865..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractTrcTokenToOther.sol +++ /dev/null @@ -1,44 +0,0 @@ -//pragma solidity ^0.4.24; - -contract ConvertType { - -constructor() payable public{} - -function() payable public{} - -// function trcTokenOnStorage(trcToken storage token) internal { // ERROR Storage location can only be given for array or struct types -// } - -function trcTokenToString(trcToken token) public constant returns(string r){ -// string s = token; // ERROR -// string s2 = string(token); // ERROR -} - -function trcTokenToUint256(trcToken token) public constant returns(uint256 r){ -uint256 u = token; // OK -uint256 u2 = uint256(token); // OK -r = u2; -} - -function trcTokenToAddress(trcToken token) public constant returns(address r){ -// address a = token; // ERROR -token = 0x1234567812345678123456781234567812345678123456781234567812345678; -address a2 = address(token); // OK -r = a2; -} - -function trcTokenToBytes(trcToken token) public constant returns(bytes r){ -// bytes b = token; // ERROR -// bytes b2 = bytes(token); // ERROR -} - -function trcTokenToBytes32(trcToken token) public constant returns(bytes32 r){ -// bytes32 b = token; // ERROR -bytes32 b2 = bytes32(token); // OK -r = b2; -} - -function trcTokenToArray(trcToken token) public constant returns(uint[] r){ -// uint[] a = token; // ERROR -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/contractUnknownException.sol b/framework/src/test/resources/soliditycode_v0.4.25/contractUnknownException.sol deleted file mode 100644 index be8af8f7451..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/contractUnknownException.sol +++ /dev/null @@ -1,65 +0,0 @@ - pragma solidity ^0.4.24; - -contract testA { - constructor() public payable { - A a = (new A).value(10)(); - a.fun(); - } -} - -contract testB { - constructor() public payable { - B b = (new B).value(10)(); - b.fun(); - } -} - - -contract testC { - constructor() public payable{ - C c = (new C).value(10)(); - c.fun(); - } -} - -contract testD { - constructor() public payable{ - D d = (new D).value(10)(); - d.fun(); - } -} - - -contract A { - constructor() public payable{ - selfdestruct(msg.sender); - } - function fun() { - } - -} - -contract B { - constructor() public payable { - revert(); - } - function fun() { - } -} - - -contract C { - constructor() public payable { - assert(1==2); - } - function fun() { - } -} - -contract D { - constructor() public payable { - require(1==2); - } - function fun() { - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest1TestRequireContract.sol b/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest1TestRequireContract.sol deleted file mode 100644 index a7c874ebd92..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest1TestRequireContract.sol +++ /dev/null @@ -1,15 +0,0 @@ -pragma solidity ^0.4.0; -contract TestThrowsContract{ - function testAssert(){ - assert(1==2); - } - function testRequire(){ - require(2==1); - } - function testRevert(){ - revert(); - } - function testThrow(){ - throw; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest2TestThrowsContract.sol b/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest2TestThrowsContract.sol deleted file mode 100644 index a7c874ebd92..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest2TestThrowsContract.sol +++ /dev/null @@ -1,15 +0,0 @@ -pragma solidity ^0.4.0; -contract TestThrowsContract{ - function testAssert(){ - assert(1==2); - } - function testRequire(){ - require(2==1); - } - function testRevert(){ - revert(); - } - function testThrow(){ - throw; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest3TestRevertContract.sol b/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest3TestRevertContract.sol deleted file mode 100644 index a7c874ebd92..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest3TestRevertContract.sol +++ /dev/null @@ -1,15 +0,0 @@ -pragma solidity ^0.4.0; -contract TestThrowsContract{ - function testAssert(){ - assert(1==2); - } - function testRequire(){ - require(2==1); - } - function testRevert(){ - revert(); - } - function testThrow(){ - throw; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest4noPayableContract.sol b/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest4noPayableContract.sol deleted file mode 100644 index 59c15a1b1ab..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest4noPayableContract.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma solidity ^0.4.0; - -contract noPayableContract { - -function noPayable() public returns (uint){ -return msg.value; -} -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest5noPayableConstructor.sol b/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest5noPayableConstructor.sol deleted file mode 100644 index c1138704b8b..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest5noPayableConstructor.sol +++ /dev/null @@ -1,10 +0,0 @@ -pragma solidity ^0.4.0; - -contract MyContract { - uint money; - - function MyContract(uint _money) { - require(msg.value >= _money); - money = _money; - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest6transferTestContract.sol b/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest6transferTestContract.sol deleted file mode 100644 index b0d93d238cf..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest6transferTestContract.sol +++ /dev/null @@ -1,8 +0,0 @@ -pragma solidity ^0.4.0; - -contract transferTestContract { - function tranferTest(address addr) public payable{ - addr.transfer(10); - - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest7payableFallbakContract.sol b/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest7payableFallbakContract.sol deleted file mode 100644 index af290a06804..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest7payableFallbakContract.sol +++ /dev/null @@ -1,13 +0,0 @@ -pragma solidity ^0.4.0; - -contract Test { - function() { x = 1; } - uint x; -} - - -contract Caller { - function callTest(Test test) { - test.call(0xabcdef01); // hash does not exist - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest8newContractGasNoenough.sol b/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest8newContractGasNoenough.sol deleted file mode 100644 index 79066c2bfc8..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest8newContractGasNoenough.sol +++ /dev/null @@ -1,18 +0,0 @@ -pragma solidity ^0.4.0; - -contract Account{ - uint256 public accId; - - function Account(uint accountId) payable{ - accId = accountId; - } -} - -contract Initialize{ - // Account public account = new Account(10); - - function newAccount(){ - Account account = new Account(1); - } - -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest9MessageUsedErrorFeed.sol b/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest9MessageUsedErrorFeed.sol deleted file mode 100644 index f6187a6c3d1..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontest9MessageUsedErrorFeed.sol +++ /dev/null @@ -1,18 +0,0 @@ -pragma solidity ^0.4.0; - -contract MathedFeed { - - function divideMathed() public returns (uint ret) { - uint x=1; - uint y=0; - return x/y; - } -} - - -contract MathedUseContract { - - function MathedUse(address addr) public returns (uint) { - return MathedFeed(addr).divideMathed(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontestFunctionUsedErrorFeed.sol b/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontestFunctionUsedErrorFeed.sol deleted file mode 100644 index cc1e8c88306..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/requireExceptiontestFunctionUsedErrorFeed.sol +++ /dev/null @@ -1,17 +0,0 @@ -pragma solidity ^0.4.0; - -contract MessageFeed { - - function mValue() payable returns (uint ret) { - return msg.value; - } -} - -contract MessageUseContract { - function inputValue() payable returns (uint){ - return msg.value; - } - function messageUse(address addr) payable returns (uint) { - return MessageFeed(addr).mValue.value(1)(); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/soliditycode_v0.4.25/walletTestMutiSign004.sol b/framework/src/test/resources/soliditycode_v0.4.25/walletTestMutiSign004.sol deleted file mode 100644 index 7de52e9f155..00000000000 --- a/framework/src/test/resources/soliditycode_v0.4.25/walletTestMutiSign004.sol +++ /dev/null @@ -1,52 +0,0 @@ -//pragma solidity ^0.4.0; - -contract timeoutTest { - string public iarray1; - // cpu - function oneCpu() { - require(1==1); - } - - function storage8Char() { - iarray1 = "12345678"; - - } - - function testUseCpu(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - } - return count; - } - - - uint256[] public iarray; - uint public calculatedFibNumber; - mapping(address=>mapping(address=>uint256)) public m; - - function testUseStorage(uint256 a) public returns (uint256){ - uint256 count = 0; - for (uint256 i = 0; i < a; i++) { - count++; - iarray.push(i); - } - return count; - } - - // stack - uint n = 0; - function test() { - n += 1; - test(); - } - - function setFibonacci(uint n) public returns (uint256){ - calculatedFibNumber = fibonacci(n); - return calculatedFibNumber; - } - - function fibonacci(uint n) internal returns (uint) { - return fibonacci(n - 1) + fibonacci(n - 2); - } -} \ No newline at end of file diff --git a/framework/src/test/resources/testng.xml b/framework/src/test/resources/testng.xml deleted file mode 100644 index 6856338d3b8..00000000000 --- a/framework/src/test/resources/testng.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/plugins/README.md b/plugins/README.md index 17f3f81f04d..da371b2533b 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -90,7 +90,7 @@ DB lite provides lite database, parameters are compatible with previous `LiteFul #split and get a history dataset java -jar Toolkit.jar db lite -o split -t history --fn-data-path output-directory/database --dataset-path /tmp #merge history dataset and snapshot dataset - java -jar Toolkit.jar db lite -o split -t history --fn-data-path /tmp/snapshot --dataset-path /tmp/history + java -jar Toolkit.jar db lite -o merge --fn-data-path /tmp/snapshot --dataset-path /tmp/history ``` ## DB Move diff --git a/plugins/build.gradle b/plugins/build.gradle index c769f7b163f..98ebed70809 100644 --- a/plugins/build.gradle +++ b/plugins/build.gradle @@ -29,7 +29,8 @@ dependencies { testCompile group: 'junit', name: 'junit', version: '4.13.2' testCompile group: 'org.mockito', name: 'mockito-core', version: '2.13.0' testCompile group: 'org.hamcrest', name: 'hamcrest-junit', version: '1.0.0.1' - testCompile group: 'org.testng', name: 'testng', version: '6.14.3' + testCompile project(":framework") + testCompile project(":framework").sourceSets.test.output compile group: 'info.picocli', name: 'picocli', version: '4.6.3' compile group: 'com.typesafe', name: 'config', version: '1.3.2' compile group: 'me.tongfei', name: 'progressbar', version: '0.9.3' @@ -77,8 +78,9 @@ test { testLogging { exceptionFormat = 'full' } + maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 jacoco { - destinationFile = file("$buildDir/jacoco/jacocoTest.exec") + destinationFile = file("../framework/build/jacoco/jacocoTest1.exec") classDumpDir = file("$buildDir/jacoco/classpathdumps") } } @@ -89,7 +91,7 @@ jacocoTestReport { csv.enabled false html.destination file("${buildDir}/jacocoHtml") } - executionData.from = 'build/jacoco/jacocoTest.exec' + getExecutionData().setFrom(fileTree('../framework/build/jacoco').include("**.exec")) } def binaryRelease(taskName, jarName, mainClass) { diff --git a/plugins/src/main/java/org/tron/plugins/DbLite.java b/plugins/src/main/java/org/tron/plugins/DbLite.java index 7a11b186976..6a01d86aec3 100644 --- a/plugins/src/main/java/org/tron/plugins/DbLite.java +++ b/plugins/src/main/java/org/tron/plugins/DbLite.java @@ -355,15 +355,7 @@ private void generateInfoProperties(String propertyfile, long num) public long getLatestBlockHeaderNum(String databaseDir) throws IOException, RocksDBException { // query latest_block_header_number from checkpoint first final String latestBlockHeaderNumber = "latest_block_header_number"; - List cpList = getCheckpointV2List(databaseDir); - DBInterface checkpointDb; - if (cpList.size() > 0) { - String lastestCp = cpList.get(cpList.size() - 1); - checkpointDb = DbTool.getDB( - databaseDir + "/" + DBUtils.CHECKPOINT_DB_V2, lastestCp); - } else { - checkpointDb = DbTool.getDB(databaseDir, CHECKPOINT_DB); - } + DBInterface checkpointDb = getCheckpointDb(databaseDir); Long blockNumber = getLatestBlockHeaderNumFromCP(checkpointDb, latestBlockHeaderNumber.getBytes()); if (blockNumber != null) { @@ -594,7 +586,7 @@ private void mergeBak2Database(String liteDir, BlockNumInfo blockNumInfo) throws private byte[] getDataFromSourceDB(String sourceDir, String dbName, byte[] key) throws IOException, RocksDBException { DBInterface sourceDb = DbTool.getDB(sourceDir, dbName); - DBInterface checkpointDb = DbTool.getDB(sourceDir, CHECKPOINT_DB); + DBInterface checkpointDb = getCheckpointDb(sourceDir); // get data from tmp first. byte[] valueFromTmp = checkpointDb.get(Bytes.concat(simpleEncode(dbName), key)); byte[] value; @@ -672,6 +664,19 @@ public long getSecondBlock(String databaseDir) throws RocksDBException, IOExcept return num; } + private DBInterface getCheckpointDb(String sourceDir) throws IOException, RocksDBException { + List cpList = getCheckpointV2List(sourceDir); + DBInterface checkpointDb; + if (cpList.size() > 0) { + String latestCp = cpList.get(cpList.size() - 1); + checkpointDb = DbTool.getDB( + sourceDir + "/" + DBUtils.CHECKPOINT_DB_V2, latestCp); + } else { + checkpointDb = DbTool.getDB(sourceDir, CHECKPOINT_DB); + } + return checkpointDb; + } + @VisibleForTesting public static void setRecentBlks(long recentBlks) { RECENT_BLKS = recentBlks; diff --git a/plugins/src/test/java/org/tron/plugins/DbConvertTest.java b/plugins/src/test/java/org/tron/plugins/DbConvertTest.java index 91996815c01..150e47c9f65 100644 --- a/plugins/src/test/java/org/tron/plugins/DbConvertTest.java +++ b/plugins/src/test/java/org/tron/plugins/DbConvertTest.java @@ -1,85 +1,24 @@ package org.tron.plugins; -import java.io.File; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.util.UUID; -import org.iq80.leveldb.DB; -import org.junit.AfterClass; import org.junit.Assert; -import org.junit.BeforeClass; import org.junit.Test; -import org.tron.plugins.utils.ByteArray; -import org.tron.plugins.utils.DBUtils; -import org.tron.plugins.utils.FileUtils; -import org.tron.plugins.utils.MarketUtils; import picocli.CommandLine; -public class DbConvertTest { +public class DbConvertTest extends DbTest { - - private static final String INPUT_DIRECTORY = "output-directory/convert-database/"; - private static final String OUTPUT_DIRECTORY = "output-directory/convert-database-dest/"; - private static final String ACCOUNT = "account"; - private static final String MARKET = DBUtils.MARKET_PAIR_PRICE_TO_ORDER; - CommandLine cli = new CommandLine(new Toolkit()); - - - @BeforeClass - public static void init() throws IOException { - if (new File(INPUT_DIRECTORY).mkdirs()) { - initDB(new File(INPUT_DIRECTORY,ACCOUNT)); - initDB(new File(INPUT_DIRECTORY,MARKET)); - } - } - - private static void initDB(File file) throws IOException { - try (DB db = DBUtils.newLevelDb(file.toPath())) { - if (MARKET.equalsIgnoreCase(file.getName())) { - byte[] sellTokenID1 = ByteArray.fromString("100"); - byte[] buyTokenID1 = ByteArray.fromString("200"); - byte[] pairPriceKey1 = MarketUtils.createPairPriceKey( - sellTokenID1, - buyTokenID1, - 1000L, - 2001L - ); - byte[] pairPriceKey2 = MarketUtils.createPairPriceKey( - sellTokenID1, - buyTokenID1, - 1000L, - 2002L - ); - byte[] pairPriceKey3 = MarketUtils.createPairPriceKey( - sellTokenID1, - buyTokenID1, - 1000L, - 2003L - ); - - - //Use out-of-order insertion,key in store should be 1,2,3 - db.put(pairPriceKey1, "1".getBytes(StandardCharsets.UTF_8)); - db.put(pairPriceKey2, "2".getBytes(StandardCharsets.UTF_8)); - db.put(pairPriceKey3, "3".getBytes(StandardCharsets.UTF_8)); - } else { - for (int i = 0; i < 100; i++) { - byte[] bytes = UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8); - db.put(bytes, bytes); - } - } - } - } - - @AfterClass - public static void destroy() { - FileUtils.deleteDir(new File(INPUT_DIRECTORY)); - FileUtils.deleteDir(new File(OUTPUT_DIRECTORY)); + @Test + public void testRun() throws IOException { + String[] args = new String[] { "db", "convert", INPUT_DIRECTORY, + temporaryFolder.newFolder().toString() }; + Assert.assertEquals(0, cli.execute(args)); } @Test - public void testRun() { - String[] args = new String[] { "db", "convert", INPUT_DIRECTORY, OUTPUT_DIRECTORY }; + public void testRunWithSafe() throws IOException { + String[] args = new String[] { "db", "convert", INPUT_DIRECTORY, + temporaryFolder.newFolder().toString(),"--safe" }; Assert.assertEquals(0, cli.execute(args)); } @@ -92,18 +31,15 @@ public void testHelp() { @Test public void testNotExist() { - String[] args = new String[] {"db", "convert", - OUTPUT_DIRECTORY + File.separator + UUID.randomUUID(), - OUTPUT_DIRECTORY}; + String[] args = new String[] {"db", "convert", UUID.randomUUID().toString(), + UUID.randomUUID().toString()}; Assert.assertEquals(404, cli.execute(args)); } @Test - public void testEmpty() { - File file = new File(OUTPUT_DIRECTORY + File.separator + UUID.randomUUID()); - file.mkdirs(); - file.deleteOnExit(); - String[] args = new String[] {"db", "convert", file.toString(), OUTPUT_DIRECTORY}; + public void testEmpty() throws IOException { + String[] args = new String[] {"db", "convert", temporaryFolder.newFolder().toString(), + temporaryFolder.newFolder().toString()}; Assert.assertEquals(0, cli.execute(args)); } diff --git a/plugins/src/test/java/org/tron/plugins/DbCopyTest.java b/plugins/src/test/java/org/tron/plugins/DbCopyTest.java new file mode 100644 index 00000000000..c5cc8f2bb31 --- /dev/null +++ b/plugins/src/test/java/org/tron/plugins/DbCopyTest.java @@ -0,0 +1,53 @@ +package org.tron.plugins; + +import java.io.IOException; +import java.util.UUID; +import org.junit.Assert; +import org.junit.Test; +import picocli.CommandLine; + +public class DbCopyTest extends DbTest { + + @Test + public void testRun() { + String[] args = new String[] { "db", "cp", INPUT_DIRECTORY, + tmpDir + UUID.randomUUID()}; + Assert.assertEquals(0, cli.execute(args)); + } + + @Test + public void testHelp() { + String[] args = new String[] {"db", "cp", "-h"}; + CommandLine cli = new CommandLine(new Toolkit()); + Assert.assertEquals(0, cli.execute(args)); + } + + @Test + public void testNotExist() { + String[] args = new String[] {"db", "cp", UUID.randomUUID().toString(), + UUID.randomUUID().toString()}; + Assert.assertEquals(404, cli.execute(args)); + } + + @Test + public void testEmpty() throws IOException { + String[] args = new String[] {"db", "cp", temporaryFolder.newFolder().toString(), + tmpDir + UUID.randomUUID()}; + Assert.assertEquals(0, cli.execute(args)); + } + + @Test + public void testDestIsExist() throws IOException { + String[] args = new String[] {"db", "cp", temporaryFolder.newFile().toString(), + temporaryFolder.newFolder().toString()}; + Assert.assertEquals(402, cli.execute(args)); + } + + @Test + public void testSrcIsFile() throws IOException { + String[] args = new String[] {"db", "cp", temporaryFolder.newFile().toString(), + tmpDir + UUID.randomUUID()}; + Assert.assertEquals(403, cli.execute(args)); + } + +} diff --git a/plugins/src/test/java/org/tron/plugins/DbLiteLevelDbTest.java b/plugins/src/test/java/org/tron/plugins/DbLiteLevelDbTest.java new file mode 100644 index 00000000000..792f93ad197 --- /dev/null +++ b/plugins/src/test/java/org/tron/plugins/DbLiteLevelDbTest.java @@ -0,0 +1,13 @@ +package org.tron.plugins; + +import java.io.IOException; +import org.junit.Test; + + +public class DbLiteLevelDbTest extends DbLiteTest { + + @Test + public void testToolsWithLevelDB() throws InterruptedException, IOException { + testTools("LEVELDB", 1); + } +} diff --git a/plugins/src/test/java/org/tron/plugins/DbLiteLevelDbV2Test.java b/plugins/src/test/java/org/tron/plugins/DbLiteLevelDbV2Test.java new file mode 100644 index 00000000000..ae48e1d66e9 --- /dev/null +++ b/plugins/src/test/java/org/tron/plugins/DbLiteLevelDbV2Test.java @@ -0,0 +1,12 @@ +package org.tron.plugins; + +import java.io.IOException; +import org.junit.Test; + +public class DbLiteLevelDbV2Test extends DbLiteTest { + + @Test + public void testToolsWithLevelDBV2() throws InterruptedException, IOException { + testTools("LEVELDB", 2); + } +} diff --git a/plugins/src/test/java/org/tron/plugins/DbLiteRocksDbTest.java b/plugins/src/test/java/org/tron/plugins/DbLiteRocksDbTest.java new file mode 100644 index 00000000000..e6910b1103a --- /dev/null +++ b/plugins/src/test/java/org/tron/plugins/DbLiteRocksDbTest.java @@ -0,0 +1,12 @@ +package org.tron.plugins; + +import java.io.IOException; +import org.junit.Test; + +public class DbLiteRocksDbTest extends DbLiteTest { + + @Test + public void testToolsWithRocksDB() throws InterruptedException, IOException { + testTools("ROCKSDB", 1); + } +} diff --git a/plugins/src/test/java/org/tron/plugins/DbLiteTest.java b/plugins/src/test/java/org/tron/plugins/DbLiteTest.java new file mode 100644 index 00000000000..8baf48b0b48 --- /dev/null +++ b/plugins/src/test/java/org/tron/plugins/DbLiteTest.java @@ -0,0 +1,176 @@ +package org.tron.plugins; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import org.junit.After; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.rules.TemporaryFolder; +import org.tron.api.WalletGrpc; +import org.tron.common.application.Application; +import org.tron.common.application.ApplicationFactory; +import org.tron.common.application.TronApplicationContext; +import org.tron.common.config.DbBackupConfig; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.FileUtil; +import org.tron.common.utils.PublicMethod; +import org.tron.common.utils.Utils; +import org.tron.core.config.DefaultConfig; +import org.tron.core.config.args.Args; +import org.tron.core.services.RpcApiService; +import org.tron.core.services.interfaceOnSolidity.RpcApiServiceOnSolidity; +import picocli.CommandLine; + +@Slf4j +public class DbLiteTest { + + private TronApplicationContext context; + private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private ManagedChannel channelFull; + private Application appTest; + private String databaseDir; + + @Rule + public final TemporaryFolder folder = new TemporaryFolder(); + + private String dbPath; + CommandLine cli = new CommandLine(new DbLite()); + + /** + * init logic. + */ + public void startApp() { + context = new TronApplicationContext(DefaultConfig.class); + appTest = ApplicationFactory.create(context); + appTest.addService(context.getBean(RpcApiService.class)); + appTest.addService(context.getBean(RpcApiServiceOnSolidity.class)); + appTest.startup(); + + String fullNode = String.format("%s:%d", "127.0.0.1", + Args.getInstance().getRpcPort()); + channelFull = ManagedChannelBuilder.forTarget(fullNode) + .usePlaintext() + .build(); + blockingStubFull = WalletGrpc.newBlockingStub(channelFull); + } + + /** + * shutdown the fullNode. + */ + public void shutdown() throws InterruptedException { + if (channelFull != null) { + channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + context.close(); + } + + public void init() throws IOException { + dbPath = folder.newFolder().toString(); + Args.setParam(new String[]{"-d", dbPath, "-w", "--p2p-disable", "true"}, + "config-localtest.conf"); + // allow account root + Args.getInstance().setAllowAccountStateRoot(1); + Args.getInstance().setRpcPort(PublicMethod.chooseRandomPort()); + databaseDir = Args.getInstance().getStorage().getDbDirectory(); + // init dbBackupConfig to avoid NPE + Args.getInstance().dbBackupConfig = DbBackupConfig.getInstance(); + } + + @After + public void clear() { + Args.clearParam(); + } + + void testTools(String dbType, int checkpointVersion) + throws InterruptedException, IOException { + logger.info("dbType {}, checkpointVersion {}", dbType, checkpointVersion); + dbPath = String.format("%s_%s_%d", dbPath, dbType, System.currentTimeMillis()); + init(); + final String[] argsForSnapshot = + new String[]{"-o", "split", "-t", "snapshot", "--fn-data-path", + dbPath + File.separator + databaseDir, "--dataset-path", + dbPath}; + final String[] argsForHistory = + new String[]{"-o", "split", "-t", "history", "--fn-data-path", + dbPath + File.separator + databaseDir, "--dataset-path", + dbPath}; + final String[] argsForMerge = + new String[]{"-o", "merge", "--fn-data-path", dbPath + File.separator + databaseDir, + "--dataset-path", dbPath + File.separator + "history"}; + Args.getInstance().getStorage().setDbEngine(dbType); + Args.getInstance().getStorage().setCheckpointVersion(checkpointVersion); + DbLite.setRecentBlks(3); + // start fullNode + startApp(); + // produce transactions for 18 seconds + generateSomeTransactions(18); + // stop the node + shutdown(); + // delete tran-cache + FileUtil.deleteDir(Paths.get(dbPath, databaseDir, "trans-cache").toFile()); + // generate snapshot + cli.execute(argsForSnapshot); + // start fullNode + startApp(); + // produce transactions for 6 seconds + generateSomeTransactions(6); + // stop the node + shutdown(); + // generate history + cli.execute(argsForHistory); + // backup original database to database_bak + File database = new File(Paths.get(dbPath, databaseDir).toString()); + if (!database.renameTo(new File(Paths.get(dbPath, databaseDir + "_bak").toString()))) { + throw new RuntimeException( + String.format("rename %s to %s failed", database.getPath(), + Paths.get(dbPath, databaseDir))); + } + // change snapshot to the new database + File snapshot = new File(Paths.get(dbPath, "snapshot").toString()); + if (!snapshot.renameTo(new File(Paths.get(dbPath, databaseDir).toString()))) { + throw new RuntimeException( + String.format("rename snapshot to %s failed", + Paths.get(dbPath, databaseDir))); + } + // start and validate the snapshot + startApp(); + generateSomeTransactions(6); + // stop the node + shutdown(); + // merge history + cli.execute(argsForMerge); + // start and validate + startApp(); + generateSomeTransactions(6); + shutdown(); + DbLite.reSetRecentBlks(); + } + + private void generateSomeTransactions(int during) { + during *= 1000; // ms + int runTime = 0; + int sleepOnce = 100; + while (true) { + ECKey ecKey2 = new ECKey(Utils.getRandom()); + byte[] address = ecKey2.getAddress(); + + String sunPri = "cba92a516ea09f620a16ff7ee95ce0df1d56550a8babe9964981a7144c8a784a"; + byte[] sunAddress = PublicMethod.getFinalAddress(sunPri); + PublicMethod.sendcoin(address, 1L, + sunAddress, sunPri, blockingStubFull); + try { + Thread.sleep(sleepOnce); + } catch (InterruptedException e) { + e.printStackTrace(); + } + if ((runTime += sleepOnce) > during) { + return; + } + } + } +} diff --git a/plugins/src/test/java/org/tron/plugins/DbTest.java b/plugins/src/test/java/org/tron/plugins/DbTest.java new file mode 100644 index 00000000000..8a5f9de4a67 --- /dev/null +++ b/plugins/src/test/java/org/tron/plugins/DbTest.java @@ -0,0 +1,89 @@ +package org.tron.plugins; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Paths; +import java.util.UUID; +import org.iq80.leveldb.DB; +import org.junit.Before; +import org.junit.Rule; +import org.junit.rules.TemporaryFolder; +import org.tron.plugins.utils.ByteArray; +import org.tron.plugins.utils.DBUtils; +import org.tron.plugins.utils.MarketUtils; +import picocli.CommandLine; + +public class DbTest { + + String INPUT_DIRECTORY; + private static final String ACCOUNT = "account"; + private static final String MARKET = DBUtils.MARKET_PAIR_PRICE_TO_ORDER; + CommandLine cli = new CommandLine(new Toolkit()); + String tmpDir = System.getProperty("java.io.tmpdir"); + + @Rule + public final TemporaryFolder temporaryFolder = new TemporaryFolder(); + + + @Before + public void init() throws IOException { + INPUT_DIRECTORY = temporaryFolder.newFolder().toString(); + initDB(new File(INPUT_DIRECTORY, ACCOUNT)); + initDB(new File(INPUT_DIRECTORY, MARKET)); + initDB(new File(INPUT_DIRECTORY, DBUtils.CHECKPOINT_DB_V2)); + } + + private static void initDB(File file) throws IOException { + if (DBUtils.CHECKPOINT_DB_V2.equalsIgnoreCase(file.getName())) { + File dbFile = new File(file, DBUtils.CHECKPOINT_DB_V2); + if (dbFile.mkdirs()) { + for (int i = 0; i < 3; i++) { + try (DB db = DBUtils.newLevelDb(Paths.get(dbFile.getPath(), + System.currentTimeMillis() + ""))) { + for (int j = 0; j < 100; j++) { + byte[] bytes = UUID.randomUUID().toString().getBytes(); + db.put(bytes, bytes); + } + } + } + } + return; + } + try (DB db = DBUtils.newLevelDb(file.toPath())) { + if (MARKET.equalsIgnoreCase(file.getName())) { + byte[] sellTokenID1 = ByteArray.fromString("100"); + byte[] buyTokenID1 = ByteArray.fromString("200"); + byte[] pairPriceKey1 = MarketUtils.createPairPriceKey( + sellTokenID1, + buyTokenID1, + 1000L, + 2001L + ); + byte[] pairPriceKey2 = MarketUtils.createPairPriceKey( + sellTokenID1, + buyTokenID1, + 1000L, + 2002L + ); + byte[] pairPriceKey3 = MarketUtils.createPairPriceKey( + sellTokenID1, + buyTokenID1, + 1000L, + 2003L + ); + + + //Use out-of-order insertion,key in store should be 1,2,3 + db.put(pairPriceKey1, "1".getBytes(StandardCharsets.UTF_8)); + db.put(pairPriceKey2, "2".getBytes(StandardCharsets.UTF_8)); + db.put(pairPriceKey3, "3".getBytes(StandardCharsets.UTF_8)); + } else { + for (int i = 0; i < 100; i++) { + byte[] bytes = UUID.randomUUID().toString().getBytes(); + db.put(bytes, bytes); + } + } + } + } +} diff --git a/protocol/build.gradle b/protocol/build.gradle index acdb7f15187..e790e480fa0 100644 --- a/protocol/build.gradle +++ b/protocol/build.gradle @@ -1,8 +1,7 @@ apply plugin: 'com.google.protobuf' -def protobufVersion = "3.19.2" - -def grpcVersion = "1.14.0" +def protobufVersion = '3.21.12' +def grpcVersion = '1.52.1' dependencies { compile group: 'com.google.protobuf', name: 'protobuf-java', version: protobufVersion @@ -16,7 +15,7 @@ dependencies { compile group: 'io.grpc', name: 'grpc-stub', version: grpcVersion // end google grpc - compile group: 'com.google.api.grpc', name: 'googleapis-common-protos', version: '0.0.3' + compile group: 'com.google.api.grpc', name: 'proto-google-common-protos', version: '2.15.0' } tasks.matching { it instanceof Test }.all { @@ -39,12 +38,12 @@ sourceSets { protobuf { generatedFilesBaseDir = "$projectDir/src/" protoc { - artifact = "com.google.protobuf:protoc:3.5.1-1" + artifact = "com.google.protobuf:protoc:${protobufVersion}" } plugins { grpc { - artifact = 'io.grpc:protoc-gen-grpc-java:1.9.0' + artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" } } generateProtoTasks { diff --git a/protocol/src/main/protos/api/api.proto b/protocol/src/main/protos/api/api.proto index d23d6e01729..9a7534cf6ce 100644 --- a/protocol/src/main/protos/api/api.proto +++ b/protocol/src/main/protos/api/api.proto @@ -767,6 +767,15 @@ service Wallet { rpc GetBlock (BlockReq) returns (BlockExtention) { } + + rpc GetBandwidthPrices (EmptyMessage) returns (PricesResponseMessage) { + } + + rpc GetEnergyPrices (EmptyMessage) returns (PricesResponseMessage) { + } + + rpc GetMemoFee (EmptyMessage) returns (PricesResponseMessage) { + } }; service WalletSolidity { @@ -963,6 +972,11 @@ service WalletSolidity { } rpc GetBlock (BlockReq) returns (BlockExtention) { } + rpc GetBandwidthPrices (EmptyMessage) returns (PricesResponseMessage) { + } + + rpc GetEnergyPrices (EmptyMessage) returns (PricesResponseMessage) { + } }; service WalletExtension { @@ -1107,6 +1121,10 @@ message CanWithdrawUnfreezeAmountResponseMessage { int64 amount = 1; } +message PricesResponseMessage { + string prices = 1; +} + // Gossip node list message NodeList { repeated Node nodes = 1; diff --git a/protocol/src/main/protos/core/Tron.proto b/protocol/src/main/protos/core/Tron.proto index 365080b903b..1c2301fc5f3 100644 --- a/protocol/src/main/protos/core/Tron.proto +++ b/protocol/src/main/protos/core/Tron.proto @@ -602,6 +602,8 @@ enum ReasonCode { TOO_MANY_PEERS_WITH_SAME_IP = 0x22; LIGHT_NODE_SYNC_FAIL = 0x23; BELOW_THAN_ME = 0X24; + NOT_WITNESS = 0x25; + NO_SUCH_MESSAGE = 0x26; UNKNOWN = 0xFF; } diff --git a/start.sh b/start.sh index 6c579a97478..89f13cf25a7 100644 --- a/start.sh +++ b/start.sh @@ -22,7 +22,7 @@ FULL_NODE_DIR="FullNode" FULL_NODE_CONFIG_DIR="config" # config file FULL_NODE_CONFIG_MAIN_NET="main_net_config.conf" -FULL_NODE_CONFIG_TEST_NET="test_net_config.conf.conf" +FULL_NODE_CONFIG_TEST_NET="test_net_config.conf" FULL_NODE_CONFIG_PRIVATE_NET="private_net_config.conf" DEFAULT_FULL_NODE_CONFIG='config.conf' JAR_NAME="FullNode.jar" From 612944f576db55b37a4c2a3d6f7bcf94468c7ae6 Mon Sep 17 00:00:00 2001 From: halibobo1205 <82020050+halibobo1205@users.noreply.github.com> Date: Mon, 1 Apr 2024 15:12:05 +0800 Subject: [PATCH 30/34] feat(trie): merge 4.7.4 (#19) --- README.md | 141 ++-- Tron protobuf protocol document.md | 16 +- actuator/build.gradle | 16 - .../org/tron/core/utils/ProposalUtil.java | 23 +- build.gradle | 23 +- chainbase/build.gradle | 34 +- .../org/tron/common/utils/ForkController.java | 2 +- .../tron/core/capsule/TransactionCapsule.java | 4 +- .../tron/core/capsule/utils/MerkleTree.java | 2 + .../core/db/common/iterator/DBIterator.java | 64 +- .../db/common/iterator/RockStoreIterator.java | 64 +- .../db/common/iterator/StoreIterator.java | 61 +- .../org/tron/core/db2/common/TxCacheDB.java | 3 - .../tron/core/service/MortgageService.java | 45 +- .../tron/core/service/RewardViCalService.java | 286 ++++++++ .../tron/core/state/WorldStateCallBack.java | 5 + .../core/store/DynamicPropertiesStore.java | 17 + .../org/tron/core/store/RewardViStore.java | 43 ++ common/build.gradle | 9 +- .../common/parameter/CommonParameter.java | 17 +- .../org/tron/common/utils/MerkleRoot.java | 68 ++ .../src/main/java/org/tron/core/Constant.java | 9 +- .../java/org/tron/core/config/Parameter.java | 5 +- .../org/tron/core/config/args/Storage.java | 18 + config/checkstyle/checkStyle.xml | 2 +- config/checkstyle/checkStyleAll.xml | 2 +- consensus/build.gradle | 13 - .../consensus/pbft/PbftMessageHandle.java | 4 +- crypto/build.gradle | 2 - docs/implement-a-customized-actuator-en.md | 2 +- docs/implement-a-customized-actuator-zh.md | 2 +- framework/build.gradle | 33 +- framework/config/checkstyle/checkStyle.xml | 2 +- framework/config/checkstyle/checkStyleAll.xml | 2 +- .../common/application/ApplicationImpl.java | 4 +- .../tron/common/cache/CacheManagerTest.java | 14 - .../nativequeue/NativeMessageQueue.java | 6 +- .../src/main/java/org/tron/core/Wallet.java | 15 + .../java/org/tron/core/config/args/Args.java | 58 +- .../tron/core/consensus/ProposalService.java | 4 + .../main/java/org/tron/core/db/Manager.java | 13 +- .../db/common/iterator/AbstractIterator.java | 41 -- .../common/iterator/AssetIssueIterator.java | 17 - .../core/db/common/iterator/DBIterator.java | 9 - .../common/iterator/TransactionIterator.java | 22 - .../db/common/iterator/WitnessIterator.java | 17 - .../org/tron/core/net/TronNetDelegate.java | 17 +- .../net/message/handshake/HelloMessage.java | 29 +- .../net/messagehandler/BlockMsgHandler.java | 16 +- .../messagehandler/InventoryMsgHandler.java | 7 + .../messagehandler/PbftDataSyncHandler.java | 18 +- .../net/messagehandler/PbftMsgHandler.java | 3 + .../tron/core/net/peer/PeerConnection.java | 1 - .../service/handshake/HandshakeService.java | 15 +- .../tron/core/services/NodeInfoService.java | 2 +- .../org/tron/core/services/RpcApiService.java | 18 +- .../org/tron/core/services/http/Util.java | 2 +- .../interfaceOnPBFT/RpcApiServiceOnPBFT.java | 5 + .../RpcApiServiceOnSolidity.java | 5 + .../jsonrpc/FullNodeJsonRpcHttpService.java | 2 - .../main/java/org/tron/program/Version.java | 6 +- .../org/tron/tool/litefullnode/DbTool.java | 199 ------ .../tool/litefullnode/LiteFullNodeTool.java | 637 ------------------ .../java/org/tron/tool/litefullnode/README.md | 109 --- .../java/org/tron/tool/litefullnode/Util.java | 62 -- .../tool/litefullnode/db/DBInterface.java | 21 - .../tool/litefullnode/db/LevelDBImpl.java | 46 -- .../tool/litefullnode/db/RocksDBImpl.java | 66 -- .../litefullnode/iterator/DBIterator.java | 18 - .../iterator/LevelDBIterator.java | 47 -- .../litefullnode/iterator/RockDBIterator.java | 48 -- .../src/main/resources/config-backup.conf | 1 - framework/src/main/resources/config-beta.conf | 1 - .../src/main/resources/config-localtest.conf | 4 +- .../src/main/resources/config-test-net.conf | 1 - framework/src/main/resources/config.conf | 15 +- .../org/tron/common/config/args/ArgsTest.java | 1 + .../tron/common/jetty/JettyServerTest.java | 63 ++ .../core/actuator/ActuatorFactoryTest.java | 71 ++ .../core/actuator/utils/ProposalUtilTest.java | 57 +- .../actuator/utils/TransactionUtilTest.java | 19 + .../core/capsule/utils/DecodeResultTest.java | 28 + .../core/capsule/utils/MerkleTreeTest.java | 35 +- .../tron/core/capsule/utils/RLPListTest.java | 81 +++ .../org/tron/core/config/args/ArgsTest.java | 32 +- .../tron/core/db/AccountTraceStoreTest.java | 13 + .../org/tron/core/db/BlockIndexStoreTest.java | 64 ++ .../java/org/tron/core/db/BlockStoreTest.java | 69 ++ .../java/org/tron/core/db/DBIteratorTest.java | 110 ++- .../core/db/DelegatedResourceStoreTest.java | 15 + .../org/tron/core/db/DelegationStoreTest.java | 17 + .../org/tron/core/db/ExchangeStoreTest.java | 25 + .../org/tron/core/db/ExchangeV2StoreTest.java | 26 + .../java/org/tron/core/db/ManagerTest.java | 48 +- .../tron/core/db/MarketAccountStoreTest.java | 16 + .../tron/core/db/MarketOrderStoreTest.java | 17 + .../tron/core/db/RecentBlockStoreTest.java | 81 +++ .../core/db/RecentTransactionStoreTest.java | 72 ++ .../tron/core/db/TransactionHistoryTest.java | 7 + .../tron/core/db/TransactionStoreTest.java | 2 +- .../org/tron/core/db/ZKProofStoreTest.java | 58 ++ .../tron/core/net/TronNetDelegateTest.java | 52 ++ .../InventoryMsgHandlerTest.java | 22 +- .../PbftDataSyncHandlerTest.java | 7 +- .../messagehandler/PbftMsgHandlerTest.java | 9 + .../net/services/HandShakeServiceTest.java | 45 ++ .../net/services/TronStatsManagerTest.java | 27 + .../java/org/tron/core/pbft/PbftTest.java | 1 + .../tron/core/services/ComputeRewardTest.java | 307 +++++++++ .../core/services/RpcApiServicesTest.java | 6 +- .../LiteFnQueryGrpcInterceptorTest.java | 6 +- .../filter/RpcApiAccessInterceptorTest.java | 6 +- .../services/http/ClearABIServletTest.java | 92 +++ .../http/CreateAccountServletTest.java | 75 +++ .../http/CreateAssetIssueServletTest.java | 90 +++ .../http/CreateSpendAuthSigServletTest.java | 60 ++ .../http/CreateWitnessServletTest.java | 88 +++ .../http/GetAccountByIdServletTest.java | 47 ++ .../http/GetBlockByIdServletTest.java | 51 ++ .../http/GetBlockByNumServletTest.java | 69 ++ ...tTransactionInfoByBlockNumServletTest.java | 79 +++ .../GetTransactionInfoByIdServletTest.java | 126 ++++ ...TransactionListFromPendingServletTest.java | 38 ++ .../http/UpdateAccountServletTest.java | 77 +++ .../services/jsonrpc/BlockResultTest.java | 46 ++ .../services/jsonrpc/BuildArgumentsTest.java | 73 ++ .../services/jsonrpc/CallArgumentsTest.java | 47 ++ .../jsonrpc/TransactionReceiptTest.java | 66 ++ .../jsonrpc/TransactionResultTest.java | 59 ++ .../tron/core/zksnark/NoteEncDecryTest.java | 2 - .../core/zksnark/ShieldedReceiveTest.java | 5 +- .../tron/program/LiteFullNodeToolTest.java | 202 ------ framework/src/test/resources/args-test.conf | 224 ++++++ .../src/test/resources/config-localtest.conf | 14 +- .../test/resources/config-test-dbbackup.conf | 1 - .../src/test/resources/config-test-index.conf | 1 - .../test/resources/config-test-mainnet.conf | 1 - .../resources/config-test-storagetest.conf | 3 +- framework/src/test/resources/config-test.conf | 12 +- plugins/README.md | 12 +- plugins/build.gradle | 3 - .../src/main/java/org/tron/plugins/Db.java | 1 + .../main/java/org/tron/plugins/DbRoot.java | 121 ++++ .../org/tron/plugins/utils/MerkleRoot.java | 68 ++ .../org/tron/plugins/utils/Sha256Hash.java | 10 +- .../tron/plugins/utils/db/DBInterface.java | 2 + .../org/tron/plugins/utils/db/DbTool.java | 18 +- .../tron/plugins/utils/db/LevelDBImpl.java | 7 +- .../tron/plugins/utils/db/RocksDBImpl.java | 7 +- .../java/org/tron/plugins/DbLiteTest.java | 6 +- .../java/org/tron/plugins/DbRootTest.java | 82 +++ protocol/build.gradle | 2 + protocol/src/main/protos/api/api.proto | 2 + protocol/src/main/protos/core/Tron.proto | 1 + quickstart.md | 20 - run.md | 10 +- script/checkStyle.sh | 26 - script/codecov.sh | 5 - script/querySonar.sh | 41 -- script/sonar.sh | 89 --- 160 files changed, 4194 insertions(+), 2182 deletions(-) create mode 100644 chainbase/src/main/java/org/tron/core/service/RewardViCalService.java create mode 100755 chainbase/src/main/java/org/tron/core/store/RewardViStore.java create mode 100644 common/src/main/java/org/tron/common/utils/MerkleRoot.java delete mode 100644 framework/src/main/java/org/tron/common/cache/CacheManagerTest.java delete mode 100644 framework/src/main/java/org/tron/core/db/common/iterator/AbstractIterator.java delete mode 100644 framework/src/main/java/org/tron/core/db/common/iterator/AssetIssueIterator.java delete mode 100755 framework/src/main/java/org/tron/core/db/common/iterator/DBIterator.java delete mode 100644 framework/src/main/java/org/tron/core/db/common/iterator/TransactionIterator.java delete mode 100644 framework/src/main/java/org/tron/core/db/common/iterator/WitnessIterator.java delete mode 100644 framework/src/main/java/org/tron/tool/litefullnode/DbTool.java delete mode 100644 framework/src/main/java/org/tron/tool/litefullnode/LiteFullNodeTool.java delete mode 100644 framework/src/main/java/org/tron/tool/litefullnode/README.md delete mode 100644 framework/src/main/java/org/tron/tool/litefullnode/Util.java delete mode 100644 framework/src/main/java/org/tron/tool/litefullnode/db/DBInterface.java delete mode 100644 framework/src/main/java/org/tron/tool/litefullnode/db/LevelDBImpl.java delete mode 100644 framework/src/main/java/org/tron/tool/litefullnode/db/RocksDBImpl.java delete mode 100644 framework/src/main/java/org/tron/tool/litefullnode/iterator/DBIterator.java delete mode 100644 framework/src/main/java/org/tron/tool/litefullnode/iterator/LevelDBIterator.java delete mode 100644 framework/src/main/java/org/tron/tool/litefullnode/iterator/RockDBIterator.java create mode 100644 framework/src/test/java/org/tron/common/jetty/JettyServerTest.java create mode 100644 framework/src/test/java/org/tron/core/actuator/ActuatorFactoryTest.java create mode 100644 framework/src/test/java/org/tron/core/capsule/utils/DecodeResultTest.java create mode 100644 framework/src/test/java/org/tron/core/capsule/utils/RLPListTest.java create mode 100644 framework/src/test/java/org/tron/core/db/BlockIndexStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/RecentBlockStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/RecentTransactionStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/db/ZKProofStoreTest.java create mode 100644 framework/src/test/java/org/tron/core/net/TronNetDelegateTest.java create mode 100644 framework/src/test/java/org/tron/core/net/services/TronStatsManagerTest.java create mode 100644 framework/src/test/java/org/tron/core/services/ComputeRewardTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/ClearABIServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/CreateAccountServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/CreateAssetIssueServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/CreateSpendAuthSigServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/CreateWitnessServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/GetAccountByIdServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/GetBlockByIdServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/GetBlockByNumServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/GetTransactionInfoByBlockNumServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/GetTransactionInfoByIdServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/GetTransactionListFromPendingServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/http/UpdateAccountServletTest.java create mode 100644 framework/src/test/java/org/tron/core/services/jsonrpc/BlockResultTest.java create mode 100644 framework/src/test/java/org/tron/core/services/jsonrpc/BuildArgumentsTest.java create mode 100644 framework/src/test/java/org/tron/core/services/jsonrpc/CallArgumentsTest.java create mode 100644 framework/src/test/java/org/tron/core/services/jsonrpc/TransactionReceiptTest.java create mode 100644 framework/src/test/java/org/tron/core/services/jsonrpc/TransactionResultTest.java delete mode 100644 framework/src/test/java/org/tron/program/LiteFullNodeToolTest.java create mode 100644 framework/src/test/resources/args-test.conf create mode 100644 plugins/src/main/java/org/tron/plugins/DbRoot.java create mode 100644 plugins/src/main/java/org/tron/plugins/utils/MerkleRoot.java create mode 100644 plugins/src/test/java/org/tron/plugins/DbRootTest.java delete mode 100644 script/checkStyle.sh delete mode 100644 script/codecov.sh delete mode 100644 script/querySonar.sh delete mode 100644 script/sonar.sh diff --git a/README.md b/README.md index 4d1d7b0b3b6..89101bbc4d1 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,6 @@ Java implementation of the Tron Protocol -

@@ -42,6 +41,7 @@

## Table of Contents + - [What’s TRON?](#whats-tron) - [Building the Source Code](#building-the-source) - [Running java-tron](#running-java-tron) @@ -55,94 +55,109 @@ TRON is a project dedicated to building the infrastructure for a truly decentralized Internet. -* Tron Protocol, one of the largest blockchain-based operating systems in the world, offers scalable, high-availability and high-throughput support that underlies all the decentralized applications in the TRON ecosystem. +- Tron Protocol, one of the largest blockchain-based operating systems in the world, offers scalable, high-availability and high-throughput support that underlies all the decentralized applications in the TRON ecosystem. -* Tron Virtual Machine (TVM) allows anyone to develop decentralized applications (DAPPs) for themselves or their communities with smart contracts thereby making decentralized crowdfunding and token issuance easier than ever. +- Tron Virtual Machine (TVM) allows anyone to develop decentralized applications (DAPPs) for themselves or their communities with smart contracts thereby making decentralized crowdfunding and token issuance easier than ever. TRON enables large-scale development and engagement. With over 2000 transactions per second (TPS), high concurrency, low latency, and massive data transmission. It is ideal for building decentralized entertainment applications. Free features and incentive systems allow developers to create premium app experiences for users. # Building the source + Building java-tron requires `git` and 64-bit version of `Oracle JDK 1.8` to be installed, other JDK versions are not supported yet. Make sure you operate on `Linux` and `MacOS` operating systems. Clone the repo and switch to the `master` branch - ```bash - $ git clone https://github.com/tronprotocol/java-tron.git - $ cd java-tron - $ git checkout -t origin/master - ``` +```bash +$ git clone https://github.com/tronprotocol/java-tron.git +$ cd java-tron +$ git checkout -t origin/master +``` + then run the following command to build java-tron, the `FullNode.jar` file can be found in `java-tron/build/libs/` after build successful. + ```bash $ ./gradlew clean build -x test ``` - # Running java-tron + Running java-tron requires 64-bit version of `Oracle JDK 1.8` to be installed, other JDK versions are not supported yet. Make sure you operate on `Linux` and `MacOS` operating systems. -Get the mainnet configuration file: [main_net_config.conf](https://github.com/tronprotocol/tron-deployment/blob/master/main_net_config.conf), other network configuration files can be find [here](https://github.com/tronprotocol/tron-deployment). +Get the mainnet configuration file: [main_net_config.conf](https://github.com/tronprotocol/tron-deployment/blob/master/main_net_config.conf), other network configuration files can be found [here](https://github.com/tronprotocol/tron-deployment). + ## Hardware Requirements + Minimum: -* CPU with 8 cores -* 16GB RAM -* 2TB free storage space to sync the Mainnet + +- CPU with 8 cores +- 16GB RAM +- 2TB free storage space to sync the Mainnet Recommended: -* CPU with 16+ cores(32+ cores for a super representative) -* 32GB+ RAM(64GB+ for a super representative) -* High Performance SSD with at least 2.5TB free space -* 100+ MB/s download Internet service +- CPU with 16+ cores(32+ cores for a super representative) +- 32GB+ RAM(64GB+ for a super representative) +- High Performance SSD with at least 2.5TB free space +- 100+ MB/s download Internet service ## Running a full node for mainnet -Full node has full historical data, it is the entry point into the TRON network , it can be used by other processes as a gateway into the TRON network via HTTP and GRPC endpoints. You can interact with the TRON network through full node:transfer assets, deploy contracts, interact with contracts and so on. `-c ` parameter specifies a configuration file to run a full node: - ```bash - $ nohup java -Xms9G -Xmx9G -XX:ReservedCodeCacheSize=256m \ - -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m \ - -XX:MaxDirectMemorySize=1G -XX:+PrintGCDetails \ - -XX:+PrintGCDateStamps -Xloggc:gc.log \ - -XX:+UseConcMarkSweepGC -XX:NewRatio=2 \ - -XX:+CMSScavengeBeforeRemark -XX:+ParallelRefProcEnabled \ - -XX:+HeapDumpOnOutOfMemoryError \ - -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 \ - -jar FullNode.jar -c main_net_config.conf >> start.log 2>&1 & - ``` + +Full node has full historical data, it is the entry point into the TRON network , it can be used by other processes as a gateway into the TRON network via HTTP and GRPC endpoints. You can interact with the TRON network through full node:transfer assets, deploy contracts, interact with contracts and so on. `-c` parameter specifies a configuration file to run a full node: + +```bash +$ nohup java -Xms9G -Xmx9G -XX:ReservedCodeCacheSize=256m \ + -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m \ + -XX:MaxDirectMemorySize=1G -XX:+PrintGCDetails \ + -XX:+PrintGCDateStamps -Xloggc:gc.log \ + -XX:+UseConcMarkSweepGC -XX:NewRatio=2 \ + -XX:+CMSScavengeBeforeRemark -XX:+ParallelRefProcEnabled \ + -XX:+HeapDumpOnOutOfMemoryError \ + -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 \ + -jar FullNode.jar -c main_net_config.conf >> start.log 2>&1 & +``` + ## Running a super representative node for mainnet -Adding the `--witness` parameter to the startup command, full node will run as a super representative node. The super representative node supports all the functions of the full node and also supports block production. Before running, make sure you have a super representative account and get votes from others,once the number of obtained votes ranks in the top 27, your super representative node will participate in block production. -Fill in the private key of super representative address into the `localwitness` list in the `main_net_config.conf`, here is an example: - ``` - localwitness = [ - 650950B193DDDDB35B6E48912DD28F7AB0E7140C1BFDEFD493348F02295BD812 - ] - ``` +Adding the `--witness` parameter to the startup command, full node will run as a super representative node. The super representative node supports all the functions of the full node and also supports block production. Before running, make sure you have a super representative account and get votes from others. Once the number of obtained votes ranks in the top 27, your super representative node will participate in block production. + +Fill in the private key of super representative address into the `localwitness` list in the `main_net_config.conf`. Here is an example: + +``` + localwitness = [ + + ] +``` then run the following command to start the node: - ```bash - $ nohup java -Xms9G -Xmx9G -XX:ReservedCodeCacheSize=256m \ - -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m \ - -XX:MaxDirectMemorySize=1G -XX:+PrintGCDetails \ - -XX:+PrintGCDateStamps -Xloggc:gc.log \ - -XX:+UseConcMarkSweepGC -XX:NewRatio=2 \ - -XX:+CMSScavengeBeforeRemark -XX:+ParallelRefProcEnabled \ - -XX:+HeapDumpOnOutOfMemoryError \ - -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 \ - -jar FullNode.jar --witness -c main_net_config.conf >> start.log 2>&1 & - ``` + +```bash +$ nohup java -Xms9G -Xmx9G -XX:ReservedCodeCacheSize=256m \ + -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m \ + -XX:MaxDirectMemorySize=1G -XX:+PrintGCDetails \ + -XX:+PrintGCDateStamps -Xloggc:gc.log \ + -XX:+UseConcMarkSweepGC -XX:NewRatio=2 \ + -XX:+CMSScavengeBeforeRemark -XX:+ParallelRefProcEnabled \ + -XX:+HeapDumpOnOutOfMemoryError \ + -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 \ + -jar FullNode.jar --witness -c main_net_config.conf >> start.log 2>&1 & +``` ## Quick Start Tool -An easier way to build and run java-tron is to use `start.sh`, `start.sh` is a quick start script written in shell language, you can use it to build and run java-tron quickly and easily. + +An easier way to build and run java-tron is to use `start.sh`. `start.sh` is a quick start script written in the Shell language. You can use it to build and run java-tron quickly and easily. Here are some common use cases of the scripting tool -* Use `start.sh` to start a full node with the downloaded `FullNode.jar` -* Use `start.sh` to download the latest `FullNode.jar` and start a full node. -* Use `start.sh` to download the latest source code and compile a `FullNode.jar` and then start a full node. + +- Use `start.sh` to start a full node with the downloaded `FullNode.jar` +- Use `start.sh` to download the latest `FullNode.jar` and start a full node. +- Use `start.sh` to download the latest source code and compile a `FullNode.jar` and then start a full node. For more details, please refer to the tool [guide](./shell.md). ## Run inside Docker container One of the quickest ways to get `java-tron` up and running on your machine is by using Docker: + ```shell $ docker run -d --name="java-tron" \ -v /your_path/output-directory:/java-tron/output-directory \ @@ -155,6 +170,7 @@ $ docker run -d --name="java-tron" \ This will mount the `output-directory` and `logs` directories on the host, the docker.sh tool can also be used to simplify the use of docker, see more [here](docker/docker.md). # Community + [Tron Developers & SRs](https://discord.gg/hqKvyAM) is Tron's official Discord channel. Feel free to join this channel if you have any questions. [Core Devs Community](https://t.me/troncoredevscommunity) is the Telegram channel for java-tron community developers. If you want to contribute to java-tron, please join this channel. @@ -162,22 +178,27 @@ This will mount the `output-directory` and `logs` directories on the host, the d [tronprotocol/allcoredev](https://gitter.im/tronprotocol/allcoredev) is the official Gitter channel for developers. # Contribution -Thank you for considering to help out with the source code! If you'd like to contribute to java-tron, please see the [Contribution Guide](./CONTRIBUTING.md) for more details. +Thank you for considering to help out with the source code! If you'd like to contribute to java-tron, please see the [Contribution Guide](./CONTRIBUTING.md) for more details. # Resources -* [Medium](https://medium.com/@coredevs) java-tron's official technical articles are published there. -* [Documentation](https://tronprotocol.github.io/documentation-en/introduction/) java-tron's official technical documentation website. -* [Test network](http://nileex.io/) A stable test network of TRON contributed by TRON community. -* [Tronscan](https://tronscan.org/#/) TRON network blockchain browser. -* [Wallet-cli](https://github.com/tronprotocol/wallet-cli) TRON network wallet using command line. -* [TIP](https://github.com/tronprotocol/tips) TRON Improvement Proposal (TIP) describes standards for the TRON network. -* [TP](https://github.com/tronprotocol/tips/tree/master/tp) TRON Protocol (TP) describes standards already implemented in TRON network but not published as a TIP. + +- [Medium](https://medium.com/@coredevs) java-tron's official technical articles are published there. +- [Documentation](https://tronprotocol.github.io/documentation-en/introduction/) java-tron's official technical documentation website. +- [Test network](http://nileex.io/) A stable test network of TRON contributed by TRON community. +- [Tronscan](https://tronscan.org/#/) TRON network blockchain browser. +- [Wallet-cli](https://github.com/tronprotocol/wallet-cli) TRON network wallet using command line. +- [TIP](https://github.com/tronprotocol/tips) TRON Improvement Proposal (TIP) describes standards for the TRON network. +- [TP](https://github.com/tronprotocol/tips/tree/master/tp) TRON Protocol (TP) describes standards already implemented in TRON network but not published as a TIP. + # Integrity Check -* After January 3, 2023, releases are signed the gpg key: + +- After January 3, 2023, the release files will be signed using a GPG key pair, and the correctness of the signature will be verified using the following public key: ``` pub: 1254 F859 D2B1 BD9F 66E7 107D F859 BCB4 4A28 290B uid: build@tron.network ``` + # License + java-tron is released under the [LGPLv3 license](https://github.com/tronprotocol/java-tron/blob/master/LICENSE). diff --git a/Tron protobuf protocol document.md b/Tron protobuf protocol document.md index 852ff313797..2ba2c3113a3 100644 --- a/Tron protobuf protocol document.md +++ b/Tron protobuf protocol document.md @@ -546,11 +546,11 @@ Transaction and transaction-related messages. message `raw` - `ref_block_bytes`: Deprecated. + `ref_block_bytes`: intercepted part of the now block bytes in transaction head. - `ref_block_num`: now block number in transaction head. + `ref_block_num`: Deprecated. - `ref_block_hash`: now block hash in transaction head. + `ref_block_hash`:intercepted part of the now block hash in transaction head.. `expiration`: the expiration time in transaction head. @@ -565,15 +565,15 @@ Transaction and transaction-related messages. ```java message raw { bytes ref_block_bytes = 1; - int64 ref_block_num = 3; + int64 ref_block_num = 3; bytes ref_block_hash = 4; - int64 expiration = 8; + int64 expiration = 8; repeated authority auths = 9; - bytes data = 10; + bytes data = 10; repeated Contract contract = 11; - bytes scripts = 12; + bytes scripts = 12; int64 timestamp = 14; - int64 fee_limit = 18; + int64 fee_limit = 18; } ``` diff --git a/actuator/build.gradle b/actuator/build.gradle index a0ce72b0ee6..9b200064fb0 100644 --- a/actuator/build.gradle +++ b/actuator/build.gradle @@ -1,25 +1,9 @@ description = "actuator – a series of transactions for blockchain." -// Dependency versions -// --------------------------------------- - -def junitVersion = "4.13.2" -def mockitoVersion = "2.1.0" -def testNgVersion = "6.11" -def slf4jVersion = "1.7.25" -// -------------------------------------- - dependencies { compile project(":chainbase") compile project(":protocol") compile project(":crypto") - testImplementation "junit:junit:$junitVersion" - testImplementation "org.mockito:mockito-core:$mockitoVersion" - - compile "org.slf4j:jcl-over-slf4j:$slf4jVersion" - compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.69' - compile group: 'commons-codec', name: 'commons-codec', version: '1.11' - compile 'org.reflections:reflections:0.9.11' } test { diff --git a/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java b/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java index 0f55bbae9b7..cfec5b09d96 100644 --- a/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java +++ b/actuator/src/main/java/org/tron/core/utils/ProposalUtil.java @@ -728,6 +728,26 @@ public static void validator(DynamicPropertiesStore dynamicPropertiesStore, } break; } + case ALLOW_OLD_REWARD_OPT: { + if (!forkController.pass(ForkBlockVersionEnum.VERSION_4_7_4)) { + throw new ContractValidateException( + "Bad chain parameter id [ALLOW_OLD_REWARD_OPT]"); + } + if (dynamicPropertiesStore.allowOldRewardOpt()) { + throw new ContractValidateException( + "[ALLOW_OLD_REWARD_OPT] has been valid, no need to propose again"); + } + if (value != 1) { + throw new ContractValidateException( + "This value[ALLOW_OLD_REWARD_OPT] is only allowed to be 1"); + } + if (!dynamicPropertiesStore.useNewRewardAlgorithm()) { + throw new ContractValidateException( + "[ALLOW_NEW_REWARD] or [ALLOW_TVM_VOTE] proposal must be approved " + + "before [ALLOW_OLD_REWARD_OPT] can be proposed"); + } + break; + } default: break; } @@ -803,7 +823,8 @@ public enum ProposalType { // current value, value range DYNAMIC_ENERGY_MAX_FACTOR(75), // 0, [0, 100_000] ALLOW_TVM_SHANGHAI(76), // 0, 1 ALLOW_CANCEL_ALL_UNFREEZE_V2(77), // 0, 1 - MAX_DELEGATE_LOCK_PERIOD(78); // (86400, 10512000] + MAX_DELEGATE_LOCK_PERIOD(78), // (86400, 10512000] + ALLOW_OLD_REWARD_OPT(79); // 0, 1 private long code; diff --git a/build.gradle b/build.gradle index 2e1803fad4b..aba239d6785 100644 --- a/build.gradle +++ b/build.gradle @@ -38,12 +38,7 @@ subprojects { dependencies { compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25' compile group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.7.25' - compile "org.slf4j:jcl-over-slf4j:1.7.25" compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.9' - compileOnly 'org.projectlombok:lombok:1.18.12' - annotationProcessor 'org.projectlombok:lombok:1.18.12' - testCompileOnly 'org.projectlombok:lombok:1.18.12' - testAnnotationProcessor 'org.projectlombok:lombok:1.18.12' compile group: 'com.google.guava', name: 'guava', version: '30.1-jre' compile "com.google.code.findbugs:jsr305:3.0.0" compile group: 'org.springframework', name: 'spring-context', version: '5.3.18' @@ -54,7 +49,15 @@ subprojects { compile group: 'org.apache.commons', name: 'commons-math', version: '2.2' compile "org.apache.commons:commons-collections4:4.1" compile group: 'joda-time', name: 'joda-time', version: '2.3' + compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.69' + compileOnly 'org.projectlombok:lombok:1.18.12' + annotationProcessor 'org.projectlombok:lombok:1.18.12' + testCompileOnly 'org.projectlombok:lombok:1.18.12' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.12' + + testImplementation group: 'junit', name: 'junit', version: '4.13.2' + testImplementation "org.mockito:mockito-core:2.13.0" } task sourcesJar(type: Jar, dependsOn: classes) { @@ -69,14 +72,8 @@ subprojects { } configurations.all { - resolutionStrategy.eachDependency { details -> - if (details.requested.group == 'com.google.guava' && details.requested.name == 'guava') { - details.useVersion "30.1-jre" - } - // TODO if update grpc remove - if(details.requested.group == 'io.netty') { - details.useVersion "4.1.27.Final" - } + resolutionStrategy { + force group: 'com.google.guava', name: 'guava', version: '30.1-jre' } } } diff --git a/chainbase/build.gradle b/chainbase/build.gradle index f2f37cc4ec1..51cbd580be7 100644 --- a/chainbase/build.gradle +++ b/chainbase/build.gradle @@ -2,47 +2,17 @@ description = "chainbase – a decentralized database for blockchain." // Dependency versions // --------------------------------------- - -def junitVersion = "4.13.2" -def mockitoVersion = "2.1.0" -def testNgVersion = "6.11" def jacocoVersion = "0.8.0" -def leveldbVersion = "1.8" def jansiVersion = "1.16" // -------------------------------------- -static def isWindows() { - return org.gradle.internal.os.OperatingSystem.current().isWindows() -} - -if (isWindows()) { - ext { - leveldbGroup = "org.ethereum" - leveldbName = "leveldbjni-all" - leveldbVersion = "1.18.3" - } -} else { - ext { - leveldbGroup = "org.fusesource.leveldbjni" - leveldbName = "leveldbjni-all" - leveldbVersion = "1.8" - } -} - dependencies { - testImplementation "junit:junit:$junitVersion" - testImplementation "org.mockito:mockito-core:$mockitoVersion" - - compile group: leveldbGroup, name: leveldbName, version: leveldbVersion - compile "org.fusesource.jansi:jansi:$jansiVersion" - compile group: 'org.rocksdb', name: 'rocksdbjni', version: '7.7.3' - compile group: 'com.typesafe', name: 'config', version: '1.3.2' - compile 'io.github.tronprotocol:zksnark-java-sdk:1.0.0' - compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.8.5' compile project(":protocol") compile project(":common") compile project(":crypto") compile project(":state-trie-jdk8") + compile "org.fusesource.jansi:jansi:$jansiVersion" + compile 'io.github.tronprotocol:zksnark-java-sdk:1.0.0' compile 'org.reflections:reflections:0.9.11' } diff --git a/chainbase/src/main/java/org/tron/common/utils/ForkController.java b/chainbase/src/main/java/org/tron/common/utils/ForkController.java index c3db883a011..7cbac28e781 100644 --- a/chainbase/src/main/java/org/tron/common/utils/ForkController.java +++ b/chainbase/src/main/java/org/tron/common/utils/ForkController.java @@ -78,7 +78,7 @@ private boolean passOld(int version) { private boolean passNew(int version) { ForkBlockVersionEnum versionEnum = ForkBlockVersionEnum.getForkBlockVersionEnum(version); if (versionEnum == null) { - logger.error("Not exist block version: {}.", version); + logger.warn("Not exist block version: {}.", version); return false; } long latestBlockTime = manager.getDynamicPropertiesStore().getLatestBlockHeaderTimestamp(); diff --git a/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java b/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java index 9598fd99a6b..a588b28c748 100755 --- a/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java +++ b/chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java @@ -102,7 +102,6 @@ public class TransactionCapsule implements ProtoCapsule { @Setter private TransactionTrace trxTrace; - private StringBuilder toStringBuff = new StringBuilder(); @Getter @Setter private long time; @@ -738,8 +737,7 @@ public Transaction getInstance() { @Override public String toString() { - - toStringBuff.setLength(0); + StringBuilder toStringBuff = new StringBuilder(); toStringBuff.append("TransactionCapsule \n[ "); toStringBuff.append("hash=").append(getTransactionId()).append("\n"); diff --git a/chainbase/src/main/java/org/tron/core/capsule/utils/MerkleTree.java b/chainbase/src/main/java/org/tron/core/capsule/utils/MerkleTree.java index 47ac45c9fb8..94d22f4b474 100644 --- a/chainbase/src/main/java/org/tron/core/capsule/utils/MerkleTree.java +++ b/chainbase/src/main/java/org/tron/core/capsule/utils/MerkleTree.java @@ -5,10 +5,12 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; import lombok.Getter; +import net.jcip.annotations.NotThreadSafe; import org.tron.common.parameter.CommonParameter; import org.tron.common.utils.Sha256Hash; @Getter +@NotThreadSafe public class MerkleTree { private static volatile MerkleTree instance; diff --git a/chainbase/src/main/java/org/tron/core/db/common/iterator/DBIterator.java b/chainbase/src/main/java/org/tron/core/db/common/iterator/DBIterator.java index f706623693f..afbacac35db 100755 --- a/chainbase/src/main/java/org/tron/core/db/common/iterator/DBIterator.java +++ b/chainbase/src/main/java/org/tron/core/db/common/iterator/DBIterator.java @@ -1,9 +1,71 @@ package org.tron.core.db.common.iterator; +import com.google.common.collect.Iterators; +import com.google.common.collect.UnmodifiableIterator; +import com.google.common.primitives.Bytes; import java.io.Closeable; import java.util.Iterator; import java.util.Map.Entry; +import java.util.NoSuchElementException; -public interface DBIterator extends Iterator>, Closeable { +public interface DBIterator extends Iterator>, AutoCloseable, Closeable { + void seek(byte[] key); + + void seekToFirst(); + + void seekToLast(); + + /** + * An iterator is either positioned at a key/value pair, or + * not valid. This method returns true iff the iterator is valid. + * + * REQUIRES: iterator not closed + * + * @throws IllegalStateException if the iterator is closed. + * @return an iterator is either positioned at a key/value pair + */ + boolean valid(); + + /** + * The underlying storage for + * the returned slice is valid only until the next modification of + * the iterator. + * + * REQUIRES: valid() && !closed + * + * @throws IllegalStateException if the iterator is closed. + * @throws NoSuchElementException if the iterator is not valid. + * + * @return the key for the current entry + */ + byte[] getKey(); + + /** + * The underlying storage for + * the returned slice is valid only until the next modification of + * the iterator. + * + * REQUIRES: valid() && !closed + * + * @throws IllegalStateException if the iterator is closed. + * @throws NoSuchElementException if the iterator is not valid. + * + * @return the value for the current entry + */ + byte[] getValue(); + + /** + * @throws IllegalStateException if the iterator is closed. + */ + void checkState(); + + /** + * @throws NoSuchElementException if the iterator is not valid. + */ + default void checkValid() { + if (!valid()) { + throw new NoSuchElementException(); + } + } } diff --git a/chainbase/src/main/java/org/tron/core/db/common/iterator/RockStoreIterator.java b/chainbase/src/main/java/org/tron/core/db/common/iterator/RockStoreIterator.java index a8c4cff2066..541f71348af 100644 --- a/chainbase/src/main/java/org/tron/core/db/common/iterator/RockStoreIterator.java +++ b/chainbase/src/main/java/org/tron/core/db/common/iterator/RockStoreIterator.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.util.Map.Entry; import java.util.NoSuchElementException; +import java.util.concurrent.atomic.AtomicBoolean; import lombok.extern.slf4j.Slf4j; import org.rocksdb.RocksIterator; @@ -13,7 +14,7 @@ public final class RockStoreIterator implements DBIterator { private final RocksIterator dbIterator; private boolean first = true; - private boolean valid = true; + private final AtomicBoolean close = new AtomicBoolean(false); public RockStoreIterator(RocksIterator dbIterator) { this.dbIterator = dbIterator; @@ -21,12 +22,14 @@ public RockStoreIterator(RocksIterator dbIterator) { @Override public void close() throws IOException { - dbIterator.close(); + if (close.compareAndSet(false, true)) { + dbIterator.close(); + } } @Override public boolean hasNext() { - if (!valid) { + if (close.get()) { return false; } boolean hasNext = false; @@ -37,13 +40,12 @@ public boolean hasNext() { first = false; } if (!(hasNext = dbIterator.isValid())) { // false is last item - dbIterator.close(); - valid = false; + close(); } } catch (Exception e) { logger.error(e.getMessage(), e); try { - dbIterator.close(); + close(); } catch (Exception e1) { logger.error(e.getMessage(), e); } @@ -53,7 +55,7 @@ public boolean hasNext() { @Override public Entry next() { - if (!valid) { + if (close.get()) { throw new NoSuchElementException(); } byte[] key = dbIterator.key(); @@ -76,4 +78,50 @@ public byte[] setValue(byte[] value) { } }; } -} \ No newline at end of file + + @Override + public void seek(byte[] key) { + checkState(); + dbIterator.seek(key); + this.first = false; + } + + @Override + public void seekToFirst() { + checkState(); + dbIterator.seekToFirst(); + this.first = false; + } + + @Override + public void seekToLast() { + checkState(); + dbIterator.seekToLast(); + this.first = false; + } + + @Override + public boolean valid() { + checkState(); + return dbIterator.isValid(); + } + + @Override + public byte[] getKey() { + checkValid(); + return dbIterator.key(); + } + + @Override + public byte[] getValue() { + checkValid(); + return dbIterator.value(); + } + + @Override + public void checkState() { + if (close.get()) { + throw new IllegalStateException("iterator has been closed"); + } + } +} diff --git a/chainbase/src/main/java/org/tron/core/db/common/iterator/StoreIterator.java b/chainbase/src/main/java/org/tron/core/db/common/iterator/StoreIterator.java index 292bb421e54..d771716a7e8 100755 --- a/chainbase/src/main/java/org/tron/core/db/common/iterator/StoreIterator.java +++ b/chainbase/src/main/java/org/tron/core/db/common/iterator/StoreIterator.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.util.Map.Entry; import java.util.NoSuchElementException; +import java.util.concurrent.atomic.AtomicBoolean; import lombok.extern.slf4j.Slf4j; import org.iq80.leveldb.DBIterator; @@ -13,7 +14,7 @@ public final class StoreIterator implements org.tron.core.db.common.iterator.DBI private final DBIterator dbIterator; private boolean first = true; - private boolean valid = true; + private final AtomicBoolean close = new AtomicBoolean(false); public StoreIterator(DBIterator dbIterator) { this.dbIterator = dbIterator; @@ -21,12 +22,14 @@ public StoreIterator(DBIterator dbIterator) { @Override public void close() throws IOException { - dbIterator.close(); + if (close.compareAndSet(false, true)) { + dbIterator.close(); + } } @Override public boolean hasNext() { - if (!valid) { + if (close.get()) { return false; } @@ -39,8 +42,7 @@ public boolean hasNext() { } if (!(hasNext = dbIterator.hasNext())) { // false is last item - dbIterator.close(); - valid = false; + close(); } } catch (Exception e) { logger.error(e.getMessage(), e); @@ -51,7 +53,7 @@ public boolean hasNext() { @Override public Entry next() { - if (!valid) { + if (close.get()) { throw new NoSuchElementException(); } return dbIterator.next(); @@ -61,4 +63,51 @@ public Entry next() { public void remove() { throw new UnsupportedOperationException(); } + + @Override + public void seek(byte[] key) { + checkState(); + dbIterator.seek(key); + this.first = false; + } + + @Override + public void seekToFirst() { + checkState(); + dbIterator.seekToFirst(); + this.first = false; + } + + @Override + public void seekToLast() { + checkState(); + dbIterator.seekToLast(); + this.first = false; + } + + @Override + public boolean valid() { + checkState(); + return dbIterator.hasNext(); + } + + @Override + public byte[] getKey() { + checkValid(); + return dbIterator.peekNext().getKey(); + } + + @Override + public byte[] getValue() { + checkValid(); + return dbIterator.peekNext().getValue(); + } + + @Override + public void checkState() { + if (close.get()) { + throw new IllegalStateException("iterator has been closed"); + } + } } + diff --git a/chainbase/src/main/java/org/tron/core/db2/common/TxCacheDB.java b/chainbase/src/main/java/org/tron/core/db2/common/TxCacheDB.java index 5d605a7fa90..9d2409685c9 100644 --- a/chainbase/src/main/java/org/tron/core/db2/common/TxCacheDB.java +++ b/chainbase/src/main/java/org/tron/core/db2/common/TxCacheDB.java @@ -156,9 +156,6 @@ private void initCache() { } public void init() { - if (CommonParameter.getInstance().isP2pDisable()) { - return; - } if (recovery()) { isValid.set(true); setAlive(true); diff --git a/chainbase/src/main/java/org/tron/core/service/MortgageService.java b/chainbase/src/main/java/org/tron/core/service/MortgageService.java index e9b00a38201..805245d53f2 100644 --- a/chainbase/src/main/java/org/tron/core/service/MortgageService.java +++ b/chainbase/src/main/java/org/tron/core/service/MortgageService.java @@ -4,12 +4,15 @@ import java.math.BigInteger; import java.util.Comparator; import java.util.List; +import java.util.stream.Collectors; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.bouncycastle.util.encoders.Hex; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.common.utils.Pair; import org.tron.common.utils.StringUtil; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.WitnessCapsule; @@ -18,7 +21,6 @@ import org.tron.core.store.DelegationStore; import org.tron.core.store.DynamicPropertiesStore; import org.tron.core.store.WitnessStore; -import org.tron.protos.Protocol.Vote; @Slf4j(topic = "mortgage") @Component @@ -37,6 +39,9 @@ public class MortgageService { @Setter private AccountStore accountStore; + @Autowired + private RewardViCalService rewardViCalService; + public void initStore(WitnessStore witnessStore, DelegationStore delegationStore, DynamicPropertiesStore dynamicPropertiesStore, AccountStore accountStore) { this.witnessStore = witnessStore; @@ -162,21 +167,21 @@ public long queryReward(byte[] address) { return reward + accountCapsule.getAllowance(); } - private long computeReward(long cycle, AccountCapsule accountCapsule) { + private long computeReward(long cycle, List> votes) { long reward = 0; - for (Vote vote : accountCapsule.getVotesList()) { - byte[] srAddress = vote.getVoteAddress().toByteArray(); + for (Pair vote : votes) { + byte[] srAddress = vote.getKey(); long totalReward = delegationStore.getReward(cycle, srAddress); + if (totalReward <= 0) { + continue; + } long totalVote = delegationStore.getWitnessVote(cycle, srAddress); if (totalVote == DelegationStore.REMARK || totalVote == 0) { continue; } - long userVote = vote.getVoteCount(); + long userVote = vote.getValue(); double voteRate = (double) userVote / totalVote; reward += voteRate * totalReward; - logger.debug("ComputeReward {}, {}, {}, {}, {}, {}, {}.", cycle, - Hex.toHexString(accountCapsule.getAddress().toByteArray()), Hex.toHexString(srAddress), - userVote, totalVote, totalReward, reward); } return reward; } @@ -197,23 +202,24 @@ private long computeReward(long beginCycle, long endCycle, AccountCapsule accoun long reward = 0; long newAlgorithmCycle = dynamicPropertiesStore.getNewRewardAlgorithmEffectiveCycle(); + List> srAddresses = accountCapsule.getVotesList().stream() + .map(vote -> new Pair<>(vote.getVoteAddress().toByteArray(), vote.getVoteCount())) + .collect(Collectors.toList()); if (beginCycle < newAlgorithmCycle) { long oldEndCycle = Math.min(endCycle, newAlgorithmCycle); - for (long cycle = beginCycle; cycle < oldEndCycle; cycle++) { - reward += computeReward(cycle, accountCapsule); - } + reward = getOldReward(beginCycle, oldEndCycle, srAddresses); beginCycle = oldEndCycle; } if (beginCycle < endCycle) { - for (Vote vote : accountCapsule.getVotesList()) { - byte[] srAddress = vote.getVoteAddress().toByteArray(); + for (Pair vote : srAddresses) { + byte[] srAddress = vote.getKey(); BigInteger beginVi = delegationStore.getWitnessVi(beginCycle - 1, srAddress); BigInteger endVi = delegationStore.getWitnessVi(endCycle - 1, srAddress); BigInteger deltaVi = endVi.subtract(beginVi); if (deltaVi.signum() <= 0) { continue; } - long userVote = vote.getVoteCount(); + long userVote = vote.getValue(); reward += deltaVi.multiply(BigInteger.valueOf(userVote)) .divide(DelegationStore.DECIMAL_OF_VI_REWARD).longValue(); } @@ -257,4 +263,15 @@ private void sortWitness(List list) { list.sort(Comparator.comparingLong((ByteString b) -> getWitnessByAddress(b).getVoteCount()) .reversed().thenComparing(Comparator.comparingInt(ByteString::hashCode).reversed())); } + + private long getOldReward(long begin, long end, List> votes) { + if (dynamicPropertiesStore.allowOldRewardOpt()) { + return rewardViCalService.getNewRewardAlgorithmReward(begin, end, votes); + } + long reward = 0; + for (long cycle = begin; cycle < end; cycle++) { + reward += computeReward(cycle, votes); + } + return reward; + } } diff --git a/chainbase/src/main/java/org/tron/core/service/RewardViCalService.java b/chainbase/src/main/java/org/tron/core/service/RewardViCalService.java new file mode 100644 index 00000000000..e27990f0403 --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/service/RewardViCalService.java @@ -0,0 +1,286 @@ +package org.tron.core.service; + +import static org.tron.core.store.DelegationStore.DECIMAL_OF_VI_REWARD; +import static org.tron.core.store.DelegationStore.REMARK; + +import com.google.common.collect.Streams; +import com.google.common.primitives.Bytes; +import com.google.protobuf.ByteString; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.LongStream; +import javax.annotation.PreDestroy; +import lombok.extern.slf4j.Slf4j; +import org.bouncycastle.util.encoders.Hex; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.tron.common.error.TronDBException; +import org.tron.common.es.ExecutorServiceManager; +import org.tron.common.parameter.CommonParameter; +import org.tron.common.utils.ByteArray; +import org.tron.common.utils.MerkleRoot; +import org.tron.common.utils.Pair; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.db.common.iterator.DBIterator; +import org.tron.core.db2.common.DB; +import org.tron.core.store.DelegationStore; +import org.tron.core.store.DynamicPropertiesStore; +import org.tron.core.store.RewardViStore; +import org.tron.core.store.WitnessStore; + +@Component +@Slf4j(topic = "rewardViCalService") +public class RewardViCalService { + + private final DB propertiesStore; + private final DB delegationStore; + private final DB witnessStore; + + @Autowired + private RewardViStore rewardViStore; + + private static final byte[] IS_DONE_KEY = new byte[]{0x00}; + private static final byte[] IS_DONE_VALUE = new byte[]{0x01}; + + private long newRewardCalStartCycle = Long.MAX_VALUE; + + private volatile long lastBlockNumber = -1; + + private static final String MAIN_NET_ROOT_HEX = + "9debcb9924055500aaae98cdee10501c5c39d4daa75800a996f4bdda73dbccd8"; + + private final Sha256Hash rewardViRoot = CommonParameter.getInstance().getStorage().getDbRoot( + "reward-vi", Sha256Hash.wrap(ByteString.fromHex(MAIN_NET_ROOT_HEX))); + + private final CountDownLatch lock = new CountDownLatch(1); + + private final ScheduledExecutorService es = ExecutorServiceManager + .newSingleThreadScheduledExecutor("rewardViCalService"); + + + @Autowired + public RewardViCalService(@Autowired DynamicPropertiesStore propertiesStore, + @Autowired DelegationStore delegationStore, @Autowired WitnessStore witnessStore) { + this.propertiesStore = propertiesStore.getDb(); + this.delegationStore = delegationStore.getDb(); + this.witnessStore = witnessStore.getDb(); + } + + public void init() { + // after init, we can get the latest block header number from db + this.newRewardCalStartCycle = this.getNewRewardAlgorithmEffectiveCycle(); + boolean ret = this.newRewardCalStartCycle != Long.MAX_VALUE; + if (ret) { + // checkpoint is flushed to db, we can start rewardViCalService immediately + lastBlockNumber = Long.MAX_VALUE; + } + es.scheduleWithFixedDelay(this::maybeRun, 0, 3, TimeUnit.SECONDS); + } + + private boolean enableNewRewardAlgorithm() { + this.newRewardCalStartCycle = this.getNewRewardAlgorithmEffectiveCycle(); + boolean ret = this.newRewardCalStartCycle != Long.MAX_VALUE; + if (ret && lastBlockNumber == -1) { + lastBlockNumber = this.getLatestBlockHeaderNumber(); + } + return ret; + } + + private boolean isDone() { + return rewardViStore.has(IS_DONE_KEY); + } + + private void maybeRun() { + try { + if (enableNewRewardAlgorithm()) { + if (this.newRewardCalStartCycle > 1) { + if (isDone()) { + this.clearUp(true); + logger.info("rewardViCalService is already done"); + } else { + if (lastBlockNumber == Long.MAX_VALUE // start rewardViCalService immediately + || this.getLatestBlockHeaderNumber() > lastBlockNumber) { + // checkpoint is flushed to db, so we can start rewardViCalService + startRewardCal(); + clearUp(true); + } else { + logger.info("startRewardCal will run after checkpoint is flushed to db"); + } + } + } else { + clearUp(false); + logger.info("rewardViCalService is no need to run"); + } + } + } catch (Exception e) { + logger.error(" Find fatal error, program will be exited soon.", e); + System.exit(1); + } + } + + private void clearUp(boolean isDone) { + lock.countDown(); + if (isDone) { + calcMerkleRoot(); + } + es.shutdown(); + } + + @PreDestroy + private void destroy() { + es.shutdownNow(); + } + + + public long getNewRewardAlgorithmReward(long beginCycle, long endCycle, + List> votes) { + if (!isDone()) { + logger.warn("rewardViCalService is not done, wait for it"); + try { + lock.await(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new TronDBException(e); + } + } + + long reward = 0; + if (beginCycle < endCycle) { + for (Pair vote : votes) { + byte[] srAddress = vote.getKey(); + BigInteger beginVi = getWitnessVi(beginCycle - 1, srAddress); + BigInteger endVi = getWitnessVi(endCycle - 1, srAddress); + BigInteger deltaVi = endVi.subtract(beginVi); + if (deltaVi.signum() <= 0) { + continue; + } + long userVote = vote.getValue(); + reward += deltaVi.multiply(BigInteger.valueOf(userVote)) + .divide(DelegationStore.DECIMAL_OF_VI_REWARD).longValue(); + } + } + return reward; + + } + + private void calcMerkleRoot() { + logger.info("calcMerkleRoot start"); + DBIterator iterator = rewardViStore.iterator(); + iterator.seekToFirst(); + ArrayList ids = Streams.stream(iterator) + .map(this::getHash) + .collect(Collectors.toCollection(ArrayList::new)); + + Sha256Hash rewardViRootLocal = MerkleRoot.root(ids); + if (!Objects.equals(rewardViRoot, rewardViRootLocal)) { + logger.warn("Merkle root mismatch, expect: {}, actual: {}." + + " If you are quite sure that there is no miscalculation (not on the main network)" + + ", please configure 'storage.merkleRoot.reward-vi = {}'" + + "(for a specific network such as Nile, etc.) in config.conf to fix the hints", + rewardViRoot, rewardViRootLocal, rewardViRootLocal); + } + logger.info("calcMerkleRoot: {}", rewardViRootLocal); + } + + private Sha256Hash getHash(Map.Entry entry) { + return Sha256Hash.of(CommonParameter.getInstance().isECKeyCryptoEngine(), + Bytes.concat(entry.getKey(), entry.getValue())); + } + + private void startRewardCal() { + logger.info("rewardViCalService start"); + rewardViStore.reset(); + DBIterator iterator = (DBIterator) witnessStore.iterator(); + iterator.seekToFirst(); + iterator.forEachRemaining(e -> accumulateWitnessReward(e.getKey())); + rewardViStore.put(IS_DONE_KEY, IS_DONE_VALUE); + logger.info("rewardViCalService is done"); + + } + + private void accumulateWitnessReward(byte[] witness) { + long startCycle = 1; + LongStream.range(startCycle, newRewardCalStartCycle) + .forEach(cycle -> accumulateWitnessVi(cycle, witness)); + } + + private void accumulateWitnessVi(long cycle, byte[] address) { + BigInteger preVi = getWitnessVi(cycle - 1, address); + long voteCount = getWitnessVote(cycle, address); + long reward = getReward(cycle, address); + if (reward == 0 || voteCount == 0) { // Just forward pre vi + if (!BigInteger.ZERO.equals(preVi)) { // Zero vi will not be record + setWitnessVi(cycle, address, preVi); + } + } else { // Accumulate delta vi + BigInteger deltaVi = BigInteger.valueOf(reward) + .multiply(DECIMAL_OF_VI_REWARD) + .divide(BigInteger.valueOf(voteCount)); + setWitnessVi(cycle, address, preVi.add(deltaVi)); + } + } + + private void setWitnessVi(long cycle, byte[] address, BigInteger value) { + byte[] k = buildViKey(cycle, address); + byte[] v = value.toByteArray(); + rewardViStore.put(k, v); + } + + private BigInteger getWitnessVi(long cycle, byte[] address) { + + byte[] v = rewardViStore.get(buildViKey(cycle, address)); + if (v == null) { + return BigInteger.ZERO; + } else { + return new BigInteger(v); + } + } + + private byte[] buildViKey(long cycle, byte[] address) { + return generateKey(cycle, address, "vi"); + } + + private long getReward(long cycle, byte[] address) { + byte[] value = this.delegationStore.get(generateKey(cycle, address, "reward")); + return value == null ? 0 : ByteArray.toLong(value); + } + + private long getWitnessVote(long cycle, byte[] address) { + byte[] value = this.delegationStore.get(generateKey(cycle, address, "vote")); + return value == null ? REMARK : ByteArray.toLong(value); + } + + private byte[] generateKey(long cycle, byte[] address, String suffix) { + return generateKey(cycle + "", address, suffix); + } + + private byte[] generateKey(String prefix, byte[] address, String suffix) { + StringBuilder sb = new StringBuilder(); + if (prefix != null) { + sb.append(prefix).append("-"); + } + sb.append(Hex.toHexString(address)); + if (suffix != null) { + sb.append("-").append(suffix); + } + return sb.toString().getBytes(); + } + + private long getNewRewardAlgorithmEffectiveCycle() { + byte[] value = this.propertiesStore.get("NEW_REWARD_ALGORITHM_EFFECTIVE_CYCLE".getBytes()); + return value == null ? Long.MAX_VALUE : ByteArray.toLong(value); + } + + private long getLatestBlockHeaderNumber() { + byte[] value = this.propertiesStore.get("latest_block_header_number".getBytes()); + return value == null ? 1 : ByteArray.toLong(value); + } +} + diff --git a/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java b/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java index 34ebeb7a9d3..1b860715ddc 100644 --- a/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java +++ b/chainbase/src/main/java/org/tron/core/state/WorldStateCallBack.java @@ -159,11 +159,16 @@ public void executePushFinish() { if (!exe()) { return; } + logger.trace("block num: {}, before root: {}", blockCapsule.getNum(), trie.getRootHashByte32()); + trieEntryList.forEach((key, value) -> + logger.trace("StateType: {}, key: {}, value: {}", + StateType.decodeType(key).getName(), key, value)); clear(); trie.commit(); trie.flush(); Bytes32 newRoot = trie.getRootHashByte32(); blockCapsule.setArchiveRoot(newRoot.toArray()); + logger.trace("block num: {}, after root: {}", blockCapsule.getNum(), trie.getRootHashByte32()); execute = false; } diff --git a/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java b/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java index 99b868d3a26..230eab8de64 100644 --- a/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java +++ b/chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java @@ -218,6 +218,8 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking private static final byte[] MAX_DELEGATE_LOCK_PERIOD = "MAX_DELEGATE_LOCK_PERIOD".getBytes(); + private static final byte[] ALLOW_OLD_REWARD_OPT = "ALLOW_OLD_REWARD_OPT".getBytes(); + @Autowired private DynamicPropertiesStore(@Value("properties") String dbName, @Autowired WorldStateCallBack worldStateCallBack) { @@ -2840,6 +2842,21 @@ public boolean supportMaxDelegateLockPeriod() { getUnfreezeDelayDays() > 0; } + public void saveAllowOldRewardOpt(long allowOldRewardOpt) { + this.put(ALLOW_OLD_REWARD_OPT, new BytesCapsule(ByteArray.fromLong(allowOldRewardOpt))); + } + + public boolean allowOldRewardOpt() { + return getAllowOldRewardOpt() == 1L; + } + + public long getAllowOldRewardOpt() { + return Optional.ofNullable(getUnchecked(ALLOW_OLD_REWARD_OPT)) + .map(BytesCapsule::getData) + .map(ByteArray::toLong) + .orElse(CommonParameter.getInstance().getAllowOldRewardOpt()); + } + private static class DynamicResourceProperties { private static final byte[] ONE_DAY_NET_LIMIT = "ONE_DAY_NET_LIMIT".getBytes(); diff --git a/chainbase/src/main/java/org/tron/core/store/RewardViStore.java b/chainbase/src/main/java/org/tron/core/store/RewardViStore.java new file mode 100755 index 00000000000..f173cecc00f --- /dev/null +++ b/chainbase/src/main/java/org/tron/core/store/RewardViStore.java @@ -0,0 +1,43 @@ +package org.tron.core.store; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.tron.core.db.TronDatabase; +import org.tron.core.db.common.iterator.DBIterator; + +@Slf4j(topic = "DB") +@Component +public class RewardViStore extends TronDatabase { + + @Autowired + private RewardViStore(@Value("reward-vi") String dbName) { + super(dbName); + } + + @Override + public byte[] get(byte[] key) { + return dbSource.getData(key); + } + + @Override + public void put(byte[] key, byte[] item) { + dbSource.putData(key, item); + } + + @Override + public void delete(byte[] key) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean has(byte[] key) { + return dbSource.getData(key) != null; + } + + @Override + public DBIterator iterator() { + return ((DBIterator) dbSource.iterator()); + } +} diff --git a/common/build.gradle b/common/build.gradle index 3949b47edb5..6b1848ed18c 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -8,7 +8,6 @@ sourceCompatibility = 1.8 // Dependency versions // --------------------------------------- - def leveldbVersion = "1.8" // -------------------------------------- @@ -30,13 +29,7 @@ if (isWindows()) { } } -repositories { - mavenCentral() -} - dependencies { - testCompile group: 'junit', name: 'junit', version: '4.13.2' - compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.69' compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.13.4.1' compile "com.cedarsoftware:java-util:1.8.0" compile group: 'org.apache.httpcomponents', name: 'httpasyncclient', version: '4.1.1' @@ -53,7 +46,7 @@ dependencies { compile 'org.aspectj:aspectjrt:1.8.13' compile 'org.aspectj:aspectjweaver:1.8.13' compile 'org.aspectj:aspectjtools:1.8.13' - compile group: 'io.github.tronprotocol', name: 'libp2p', version: '2.1.0',{ + compile group: 'io.github.tronprotocol', name: 'libp2p', version: '2.2.1',{ exclude group: 'io.grpc', module: 'grpc-context' exclude group: 'io.grpc', module: 'grpc-core' exclude group: 'io.grpc', module: 'grpc-netty' diff --git a/common/src/main/java/org/tron/common/parameter/CommonParameter.java b/common/src/main/java/org/tron/common/parameter/CommonParameter.java index ce4f3681372..a1d5aa6f666 100644 --- a/common/src/main/java/org/tron/common/parameter/CommonParameter.java +++ b/common/src/main/java/org/tron/common/parameter/CommonParameter.java @@ -176,7 +176,7 @@ public class CommonParameter { public int nodeListenPort; @Getter @Setter - public String nodeDiscoveryBindIp; + public String nodeLanIp; @Getter @Setter public String nodeExternalIp; @@ -255,6 +255,9 @@ public class CommonParameter { public int maxHeaderListSize; @Getter @Setter + public boolean isRpcReflectionServiceEnable; + @Getter + @Setter @Parameter(names = {"--validate-sign-thread"}, description = "Num of validate thread") public int validateSignThreadNum; @Getter @@ -663,6 +666,18 @@ public class CommonParameter { @Setter public long allowCancelAllUnfreezeV2; + @Getter + @Setter + public boolean unsolidifiedBlockCheck; + + @Getter + @Setter + public int maxUnsolidifiedBlocks; + + @Getter + @Setter + public long allowOldRewardOpt; + private static double calcMaxTimeRatio() { //return max(2.0, min(5.0, 5 * 4.0 / max(Runtime.getRuntime().availableProcessors(), 1))); return 5.0; diff --git a/common/src/main/java/org/tron/common/utils/MerkleRoot.java b/common/src/main/java/org/tron/common/utils/MerkleRoot.java new file mode 100644 index 00000000000..ccd8905b6c5 --- /dev/null +++ b/common/src/main/java/org/tron/common/utils/MerkleRoot.java @@ -0,0 +1,68 @@ +package org.tron.common.utils; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import lombok.Getter; + +public class MerkleRoot { + + private MerkleRoot() { + + } + + public static Sha256Hash root(List hashList) { + List leaves = createLeaves(hashList); + while (leaves.size() > 1) { + leaves = createParentLeaves(leaves); + } + return leaves.isEmpty() ? Sha256Hash.ZERO_HASH : leaves.get(0).hash; + } + + private static List createParentLeaves(List leaves) { + int step = 2; + int len = leaves.size(); + return IntStream.iterate(0, i -> i + step) + .limit(len) + .filter(i -> i < len) + .mapToObj(i -> { + Leaf right = i + 1 < len ? leaves.get(i + 1) : null; + return createLeaf(leaves.get(i), right); + }).collect(Collectors.toList()); + } + + private static List createLeaves(List hashList) { + int step = 2; + int len = hashList.size(); + return IntStream.iterate(0, i -> i + step) + .limit(len) + .filter(i -> i < len) + .mapToObj(i -> { + Leaf right = i + 1 < len ? createLeaf(hashList.get(i + 1)) : null; + return createLeaf(createLeaf(hashList.get(i)), right); + }).collect(Collectors.toList()); + } + + private static Leaf createLeaf(Leaf left, Leaf right) { + Leaf leaf = new Leaf(); + leaf.hash = right == null ? left.hash : computeHash(left.hash, right.hash); + return leaf; + } + + private static Leaf createLeaf(Sha256Hash hash) { + Leaf leaf = new Leaf(); + leaf.hash = hash; + return leaf; + } + + private static Sha256Hash computeHash(Sha256Hash leftHash, Sha256Hash rightHash) { + return Sha256Hash.of(true, + leftHash.getByteString().concat(rightHash.getByteString()).toByteArray()); + } + + @Getter + private static class Leaf { + + private Sha256Hash hash; + } +} diff --git a/common/src/main/java/org/tron/core/Constant.java b/common/src/main/java/org/tron/core/Constant.java index 56135c495cf..fce6dd36d68 100644 --- a/common/src/main/java/org/tron/core/Constant.java +++ b/common/src/main/java/org/tron/core/Constant.java @@ -155,6 +155,8 @@ public class Constant { public static final String NODE_RPC_MAX_HEADER_LIST_SIZE = "node.rpc.maxHeaderListSize"; + public static final String NODE_RPC_REFLECTION_SERVICE = "node.rpc.reflectionService"; + public static final String NODE_OPEN_HISTORY_QUERY_WHEN_LITEFN = "node.openHistoryQueryWhenLiteFN"; public static final String BLOCK_MAINTENANCE_TIME_INTERVAL = "block.maintenanceTimeInterval"; @@ -283,8 +285,6 @@ public class Constant { public static final String EVENT_SUBSCRIBE_CONTRACT_ADDRESS = "event.subscribe.filter.contractAddress"; public static final String EVENT_SUBSCRIBE_CONTRACT_TOPIC = "event.subscribe.filter.contractTopic"; - public static final String NODE_DISCOVERY_BIND_IP = "node.discovery.bind.ip"; - public static final String NODE_DISCOVERY_EXTERNAL_IP = "node.discovery.external.ip"; public static final String NODE_BACKUP_PRIORITY = "node.backup.priority"; @@ -376,5 +376,10 @@ public class Constant { public static final String COMMITTEE_ALLOW_TVM_SHANGHAI = "committee.allowTvmShangHai"; + public static final String UNSOLIDIFIED_BLOCK_CHECK = "node.unsolidifiedBlockCheck"; + + public static final String MAX_UNSOLIDIFIED_BLOCKS = "node.maxUnsolidifiedBlocks"; + public static final String COMMITTEE_ALLOW_OLD_REWARD_OPT = "committee.allowOldRewardOpt"; + public static final long TOKEN_NUM_START = 1000000L; } diff --git a/common/src/main/java/org/tron/core/config/Parameter.java b/common/src/main/java/org/tron/core/config/Parameter.java index b1a948e9fdf..247826af77a 100644 --- a/common/src/main/java/org/tron/core/config/Parameter.java +++ b/common/src/main/java/org/tron/core/config/Parameter.java @@ -22,7 +22,8 @@ public enum ForkBlockVersionEnum { VERSION_4_6(25, 1596780000000L, 80), VERSION_4_7(26, 1596780000000L, 80), VERSION_4_7_1(27, 1596780000000L, 80), - VERSION_4_7_2(28, 1596780000000L, 80); + VERSION_4_7_2(28, 1596780000000L, 80), + VERSION_4_7_4(29, 1596780000000L, 80); // if add a version, modify BLOCK_VERSION simultaneously @Getter @@ -71,7 +72,7 @@ public class ChainConstant { public static final int SINGLE_REPEAT = 1; public static final int BLOCK_FILLED_SLOTS_NUMBER = 128; public static final int MAX_FROZEN_NUMBER = 1; - public static final int BLOCK_VERSION = 28; + public static final int BLOCK_VERSION = 29; public static final long FROZEN_PERIOD = 86_400_000L; public static final long DELEGATE_PERIOD = 3 * 86_400_000L; public static final long TRX_PRECISION = 1000_000L; diff --git a/common/src/main/java/org/tron/core/config/args/Storage.java b/common/src/main/java/org/tron/core/config/args/Storage.java index b7459a2ac83..b9f5962bcf3 100644 --- a/common/src/main/java/org/tron/core/config/args/Storage.java +++ b/common/src/main/java/org/tron/core/config/args/Storage.java @@ -16,6 +16,7 @@ package org.tron.core.config.args; import com.google.common.collect.Maps; +import com.google.protobuf.ByteString; import com.typesafe.config.Config; import com.typesafe.config.ConfigObject; import java.io.File; @@ -33,6 +34,7 @@ import org.tron.common.utils.DbOptionalsUtils; import org.tron.common.utils.FileUtil; import org.tron.common.utils.Property; +import org.tron.common.utils.Sha256Hash; /** * Custom storage configurations @@ -80,6 +82,7 @@ public class Storage { private static final String CACHE_STRATEGIES = "storage.cache.strategies"; public static final String TX_CACHE_INIT_OPTIMIZATION = "storage.txCache.initOptimization"; + private static final String MERKLE_ROOT = "storage.merkleRoot"; private static final String STATE_ROOT_SWITCH_KEY = "storage.stateRoot.switch"; private static final String STATE_DB_MAX_OPEN_FILES_KEY = "storage.stateRoot.db.maxOpenFiles"; private static final String STATE_DB_WRITE_BUFFER_SIZE_KEY = @@ -184,6 +187,9 @@ public class Storage { @Getter private Map propertyMap; + // db root + private final Map dbRoots = Maps.newConcurrentMap(); + public static String getDbEngineFromConfig(final Config config) { return config.hasPath(DB_ENGINE_CONFIG_KEY) ? config.getString(DB_ENGINE_CONFIG_KEY) : DEFAULT_DB_ENGINE; @@ -279,6 +285,18 @@ public String getCacheStrategy(CacheType dbName) { return this.cacheStrategies.getOrDefault(dbName, CacheStrategies.getCacheStrategy(dbName)); } + public Sha256Hash getDbRoot(String dbName, Sha256Hash defaultV) { + return this.dbRoots.getOrDefault(dbName, defaultV); + } + + public void setDbRoots(Config config) { + if (config.hasPath(MERKLE_ROOT)) { + config.getConfig(MERKLE_ROOT).resolve().entrySet().forEach(c -> + this.dbRoots.put(c.getKey(), Sha256Hash.wrap( + ByteString.fromHex(c.getValue().unwrapped().toString())))); + } + } + public void setStateConfig(final Config config) { if (config.hasPath(STATE_ROOT_SWITCH_KEY)) { this.allowStateRoot = config.getBoolean(STATE_ROOT_SWITCH_KEY); diff --git a/config/checkstyle/checkStyle.xml b/config/checkstyle/checkStyle.xml index 16fda0fdc4f..9d09ca11bee 100644 --- a/config/checkstyle/checkStyle.xml +++ b/config/checkstyle/checkStyle.xml @@ -1,7 +1,7 @@ + "https://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd"> - ``` [PM2] Spawning PM2 daemon with pm2_home=/root/.pm2 [PM2] PM2 Successfully daemonized @@ -166,25 +165,6 @@ If everything goes well, your terminal console output will look like following : (8) TYjQd4xrLZQGYMdLJqsTCuXVGapPqUp9ZX (10000 TRX) (9) THCw6hPZpFcLCWDcsZg3W77rXZ9rJQPncD (10000 TRX) - Private Keys - ================== - - (0) 2b2bddbeea87cecedcaf51eef55877b65725f709d2c0fcdfea0cb52d80acd52b - (1) f08759925316dc6344af538ebe3a619aeab836a0c254adca903cc764f87b0ee9 - (2) 1afc9f033cf9c6058db366b78a9f1b9c909b1b83397c9aed795afa05e9017511 - (3) f8f5bc70e91fc177eefea43b68c97b66536ac317a9300639e9d32a9db2f18a1f - (4) 031015272915917056c117d3cc2a03491a8f22ef450af83f6783efddf7064c59 - (5) 5eb25e2c1144f216aa99bbe2139d84bb6dedfb2c1ed72f3df6684a4c6d2cd96b - (6) f0b781da23992e6a3f536cb60917c3eb6a9c5434fcf441fcb8d7c58c01d6b70e - (7) 158f60a4379688a77d4a420e2f2a3e014ebf9ed0a1a093d7dc01ba23ebc5c970 - (8) e9342bb9108f46573804890a5301530c2834dce3703cd51ab77fba6161afec00 - (9) 2e9f0c507d2ea98dc4005a1afb1b743c629f7c145ccb55f38f75ae73cf8f605c - - HD Wallet - ================== - Mnemonic: border pulse twenty cruise grief shy need raw clean possible begin climb - Base HD Path: m/44'/60'/0'/0/{account_index} - ``` diff --git a/run.md b/run.md index 112478a4db5..c0ecbe4d91f 100644 --- a/run.md +++ b/run.md @@ -14,9 +14,9 @@ Use the [Testnet Config](https://github.com/tronprotocol/TronDeployment/blob/mas **Use the executable JAR(Recommended way):** ```bash -java -jar FullNode.jar -p your private key --witness -c your config.conf(Example:/data/java-tron/config.conf) +java -jar FullNode.jar -p --witness -c your config.conf(Example:/data/java-tron/config.conf) Example: -java -jar FullNode.jar -p 650950B193DDDDB35B6E48912DD28F7AB0E7140C1BFDEFD493348F02295BD812 --witness -c /data/java-tron/config.conf +java -jar FullNode.jar -p --witness -c /data/java-tron/config.conf ``` @@ -65,9 +65,9 @@ Then observe whether block synchronization success,If synchronization successf ```bash cd build/libs -java -jar FullNode.jar -p your private key --witness -c your config.conf (Example:/data/java-tron/config.conf) +java -jar FullNode.jar -p --witness -c your config.conf (Example:/data/java-tron/config.conf) Example: -java -jar FullNode.jar -p 650950B193DDDDB35B6E48912DD28F7AB0E7140C1BFDEFD493348F02295BD812 --witness -c /data/java-tron/config.conf +java -jar FullNode.jar -p --witness -c /data/java-tron/config.conf ``` @@ -81,7 +81,7 @@ java -jar FullNode.jar -p 650950B193DDDDB35B6E48912DD28F7AB0E7140C1BFDEFD493348F Using TaskInputs.file() with something that doesn't resolve to a File object has been deprecated and is scheduled to be removed in Gradle 5.0. Use TaskInputs.files() instead. > Task :run -20:39:22.749 INFO [o.t.c.c.a.Args] private.key = 63e62a71ed39e30bac7223097a173924aad5855959de517ff2987b0e0ec89f1a +20:39:22.749 INFO [o.t.c.c.a.Args] private.key = 63e62a71ed3... 20:39:22.816 WARN [o.t.c.c.a.Args] localwitness size must be one, get the first one 20:39:22.832 INFO [o.t.p.FullNode] Here is the help message.output-directory/ 三月 22, 2018 8:39:23 下午 org.tron.core.services.RpcApiService start diff --git a/script/checkStyle.sh b/script/checkStyle.sh deleted file mode 100644 index af3d5e7df1f..00000000000 --- a/script/checkStyle.sh +++ /dev/null @@ -1,26 +0,0 @@ -./gradlew clean build -x test > build.log 2>&1 -if [ $? != 0 ];then - echo "run ./gradlew build fail, Please check you code, Or just retry this test" - exit 1 -fi -echo "------------------------------ checkStyle check ------------------------------" -#echo $BUILDKITE_PULL_REQUEST_BASE_BRANCH -#if [[ x"$BUILDKITE_PULL_REQUEST_BASE_BRANCH" != x'develop' && x"$BUILDKITE_PULL_REQUEST_BASE_BRANCH" != x'master' ]];then -# echo "BUILDKITE_PULL_REQUEST_BASE_BRANCH isnot develop or master, SKIPED" -# exit 0 -#fi - -grep -v ":checkstyleMain\|:checkstyleTest\|:lint" build.log |grep "ant:checkstyle" > checkStyle.log 2>&1 -checkNum=`cat checkStyle.log | wc -l` -if [ ${checkNum} -gt 0 ];then - echo "please fix checkStyle problem," - echo "run [ ./gradlew clean build -x test ], and you can find checkStyle report in framework/build/reports/checkstyle/" - echo "!!!!! checkStyle Num ${checkNum} !!!!!" - cat checkStyle.log - - echo "checkStyle Failed, please fix checkStyle problem" - touch checkFailTag -else - echo "checkStyle problem zero" -fi -exit 0 diff --git a/script/codecov.sh b/script/codecov.sh deleted file mode 100644 index ba83a5a8ee2..00000000000 --- a/script/codecov.sh +++ /dev/null @@ -1,5 +0,0 @@ -bash <(curl -s https://codecov.io/bash) -t ee5ed39e-1cc4-49d1-bcf9-12bce10e5b3b -s ./common/build/reports/jacoco/test/ -s ./consensus/build/reports/jacoco/test/ -s ./chainbase/build/reports/jacoco/test/ -s ./actuator/build/reports/jacoco/test/ -s ./framework/build/reports/jacoco/test/ - -#bash <(curl -s https://codecov.io/bash) -t ee5ed39e-1cc4-49d1-bcf9-12bce10e5b3b -s ./common/build/reports/jacoco/test/jacocoTestReport.xml -s ./consensus/build/reports/jacoco/test/jacocoTestReport.xml -s ./chainbase/build/reports/jacoco/test/jacocoTestReport.xml -s ./actuator/build/reports/jacoco/test/jacocoTestReport.xml -s ./framework/build/reports/jacoco/test/jacocoTestReport.xml - -#bash <(curl -s https://codecov.io/bash) -t c2f718cbe2e84c62970a892cef614689 diff --git a/script/querySonar.sh b/script/querySonar.sh deleted file mode 100644 index 8c558634304..00000000000 --- a/script/querySonar.sh +++ /dev/null @@ -1,41 +0,0 @@ -echo "current branch is : "$BUILDKITE_BRANCH -if [ $BUILDKITE_PULL_REQUEST = "false" ]; then - SonarStatus_Url="https://sonarcloud.io/api/qualitygates/project_status?projectKey=java-tron&branch="$BUILDKITE_BRANCH - Status=`curl -s $SonarStatus_Url | jq '.projectStatus.status'` - echo "current branch sonarcloud status is : "$Status - if [ $Status = null ]; then - echo "wait for check finish, 5m ....." - sleep 300 - SonarStatus_Url="https://sonarcloud.io/api/qualitygates/project_status?projectKey=java-tron&branch="$BUILDKITE_BRANCH - Status=`curl -s $SonarStatus_Url | jq '.projectStatus.status'` - fi - - if [ x"$Status" = x'"OK"' ];then - echo "Sonar Check Pass" - exit 0 - else - echo "Sonar Check Failed" - echo "Please visit https://sonarcloud.io/dashboard?branch="$BUILDKITE_BRANCH"&id=java-tron for more details" - exit 1 - fi -else - echo "current PR number is : "$BUILDKITE_PULL_REQUEST - SonarStatus_Url="https://sonarcloud.io/api/qualitygates/project_status?projectKey=java-tron&pullRequest="$BUILDKITE_PULL_REQUEST - Status=`curl -s $SonarStatus_Url | jq '.projectStatus.status'` - if [ $Status = null ]; then - echo "wait for check finish, 5m ....." - sleep 300 - SonarStatus_Url="https://sonarcloud.io/api/qualitygates/project_status?projectKey=java-tron&pullRequest="$BUILDKITE_PULL_REQUEST - Status=`curl -s $SonarStatus_Url | jq '.projectStatus.status'` - fi - - echo "current pullRequest sonarcloud status is : "$Status - if [ x"$Status" = x'"OK"' ];then - echo "Sonar Check Pass" - exit 0 - else - echo "Sonar Check Failed" - echo "Please visit https://sonarcloud.io/dashboard?id=java-tron&pullRequest="$BUILDKITE_PULL_REQUEST" for more details" - exit 1 - fi -fi \ No newline at end of file diff --git a/script/sonar.sh b/script/sonar.sh deleted file mode 100644 index b3e2b5ccf28..00000000000 --- a/script/sonar.sh +++ /dev/null @@ -1,89 +0,0 @@ -echo "------------------------------ sonar check ------------------------------" -export SONAR_SCANNER_VERSION=4.2.0.1873 -export SONAR_SCANNER_HOME=/home/java-tron/sonar-scanner-4.1.0.1829-linux -export PATH=$SONAR_SCANNER_HOME/bin:$PATH -export SONAR_SCANNER_OPTS="-server" -#export PATH=$PATH:/home/java-tron/sonar-scanner-4.1.0.1829-linux/bin - -#BUILDKITE_BRANCH="MiraculousWang:develop" - -echo "current branch is : "$BUILDKITE_BRANCH -if [ $BUILDKITE_PULL_REQUEST = "false" ]; then - - sonar-scanner \ - -Dsonar.projectKey=java-tron \ - -Dsonar.organization=tron-zhaohong \ - -Dsonar.sources=./actuator/src,./framework/src/main,./consensus/src,./chainbase/src,./common/src,./crypto/src,./protocol/src \ - -Dsonar.java.binaries=./actuator/build/classes,./framework/build/classes,./consensus/build/classes,./chainbase/build/classes,./common/build/classes,./crypto/build/classes,./protocol/build/classes \ - -Dsonar.host.url=https://sonarcloud.io \ - -Dsonar.links.homepage=https://github.com/tronprotocol/java-tron \ - -Dsonar.links.scm=https://github.com/tronprotocol/java-tron \ - -Dsoanr.links.issue=https://github.com/tronprotocol/java-tron/issues \ - -Dsonar.branch.name=$BUILDKITE_BRANCH \ - -Dsonar.coverage.jacoco.xmlReportPaths=./common/build/reports/jacoco/test/jacocoTestReport.xml,./consensus/build/reports/jacoco/test/jacocoTestReport.xml,./chainbase/build/reports/jacoco/test/jacocoTestReport.xml,./actuator/build/reports/jacoco/test/jacocoTestReport.xml,./framework/build/reports/jacoco/test/jacocoTestReport.xml \ - -Dsonar.login=1717c3c748ec2e0ea61e501b05458de243c4abcc > /data/checkStyle/sonar.log - - sleep 100 - - - SonarStatus_Url="https://sonarcloud.io/api/qualitygates/project_status?projectKey=java-tron&branch="$BUILDKITE_BRANCH - Status=`curl -s $SonarStatus_Url | jq '.projectStatus.status'` - echo "current branch sonarcloud status is : "$Status - if [ $Status = null ]; then - echo "wait for check finish, 5m ....." - sleep 300 - SonarStatus_Url="https://sonarcloud.io/api/qualitygates/project_status?projectKey=java-tron&branch="$BUILDKITE_BRANCH - Status=`curl -s $SonarStatus_Url | jq '.projectStatus.status'` - fi - - if [ x"$Status" = x'"OK"' ];then - echo "Sonar Check Pass" - exit 0 - else - echo ">>>>>>>>>>>>>>>>>>>>>>>>>> Sonar Check Failed <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" - echo ">>>>>>>>>>>> Please visit https://sonarcloud.io/dashboard?branch="$BUILDKITE_BRANCH"&id=java-tron for more details <<<<<<<<<<<<<<<<<<" - touch checkFailTag - exit 0 - fi -else - echo "current PR number is : "$BUILDKITE_PULL_REQUEST - - sonar-scanner \ - -Dsonar.projectKey=java-tron \ - -Dsonar.organization=tron-zhaohong \ - -Dsonar.sources=./actuator/src,./framework/src/main,./consensus/src,./chainbase/src,./common/src,./crypto/src,./protocol/src \ - -Dsonar.java.binaries=./actuator/build/classes,./framework/build/classes,./consensus/build/classes,./chainbase/build/classes,./common/build/classes,./crypto/build/classes,./protocol/build/classes \ - -Dsonar.host.url=https://sonarcloud.io \ - -Dsonar.links.homepage=https://github.com/tronprotocol/java-tron \ - -Dsonar.links.scm=https://github.com/tronprotocol/java-tron \ - -Dsoanr.links.issue=https://github.com/tronprotocol/java-tron/issues \ - -Dsonar.pullrequest.key=$BUILDKITE_PULL_REQUEST \ - -Dsonar.pullrequest.branch=$BUILDKITE_BRANCH \ - -Dsonar.pullrequest.base=$BUILDKITE_PULL_REQUEST_BASE_BRANCH \ - -Dsonar.coverage.jacoco.xmlReportPaths=./common/build/reports/jacoco/test/jacocoTestReport.xml,./consensus/build/reports/jacoco/test/jacocoTestReport.xml,./chainbase/build/reports/jacoco/test/jacocoTestReport.xml,./actuator/build/reports/jacoco/test/jacocoTestReport.xml,./framework/build/reports/jacoco/test/jacocoTestReport.xml \ - -Dsonar.login=1717c3c748ec2e0ea61e501b05458de243c4abcc > /data/checkStyle/sonar.log - - sleep 100 - - SonarStatus_Url="https://sonarcloud.io/api/qualitygates/project_status?projectKey=java-tron&pullRequest="$BUILDKITE_PULL_REQUEST - Status=`curl -s $SonarStatus_Url | jq '.projectStatus.status'` - if [ $Status = null ]; then - echo "wait for check finish, 5m ....." - sleep 300 - SonarStatus_Url="https://sonarcloud.io/api/qualitygates/project_status?projectKey=java-tron&pullRequest="$BUILDKITE_PULL_REQUEST - Status=`curl -s $SonarStatus_Url | jq '.projectStatus.status'` - fi - - echo "current pullRequest sonarcloud status is : "$Status - if [ x"$Status" = x'"OK"' ];then - echo "Sonar Check Pass" - exit 0 - else - echo " -------------------------------- sonar check Failed ---------------------------------" - echo ">>>>>>>>>>>>>>> Please visit https://sonarcloud.io/dashboard?id=java-tron&pullRequest="$BUILDKITE_PULL_REQUEST" for more details <<<<<<<<<<<<<<<<<<" - echo "If this Sonar problem is not caused by your modification,Make sure you local branch is newest, And merge the newest tronprotocol/java-tron" - echo ">>>>>>>>>>>>>>>>>>>>>>>>>> Sonar Check Failed <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< " - touch checkFailTag - exit 0 - fi -fi From 20e198386f96bc970e0f6df702aed602c525ece9 Mon Sep 17 00:00:00 2001 From: halibobo1205 <82020050+halibobo1205@users.noreply.github.com> Date: Mon, 1 Apr 2024 16:03:53 +0800 Subject: [PATCH 31/34] merge master (#20) --- framework/src/main/java/org/tron/core/db/Manager.java | 1 + framework/src/main/resources/config.conf | 5 +---- framework/src/test/resources/config-test.conf | 5 ++--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/framework/src/main/java/org/tron/core/db/Manager.java b/framework/src/main/java/org/tron/core/db/Manager.java index 46bc51a57fe..8eefe2d17de 100644 --- a/framework/src/main/java/org/tron/core/db/Manager.java +++ b/framework/src/main/java/org/tron/core/db/Manager.java @@ -542,6 +542,7 @@ public void init() { // init liteFullNode initLiteNode(); + long headNum = chainBaseManager.getDynamicPropertiesStore().getLatestBlockHeaderNumber(); logger.info("Current headNum is: {}.", headNum); boolean isLite = chainBaseManager.isLiteNode(); diff --git a/framework/src/main/resources/config.conf b/framework/src/main/resources/config.conf index 50adbb3ddff..174e077b0cd 100644 --- a/framework/src/main/resources/config.conf +++ b/framework/src/main/resources/config.conf @@ -101,12 +101,9 @@ storage { # data root setting, for check data, currently, only reward-vi is used. # merkleRoot = { - # reward-vi = 9debcb9924055500aaae98cdee10501c5c39d4daa75800a996f4bdda73dbccd8 // main-net, Sha256Hash, hexString + # reward-vi = 9debcb9924055500aaae98cdee10501c5c39d4daa75800a996f4bdda73dbccd8 // main-net, Sha256Hash, hexString # } - # if true, transaction cache initialization will be faster. default false - # txCache.initOptimization = true - # world state # stateRoot.switch = false # stateGenesis.directory = "state-genesis" diff --git a/framework/src/test/resources/config-test.conf b/framework/src/test/resources/config-test.conf index 81e1d9d5ea3..43ed0000cce 100644 --- a/framework/src/test/resources/config-test.conf +++ b/framework/src/test/resources/config-test.conf @@ -73,9 +73,8 @@ storage { merkleRoot = { reward-vi = e0ebe2f3243391ed674dff816a07f589a3279420d6d88bc823b6a9d5778337ce - } - # if true, transaction cache initialization will be faster. default false - txCache.initOptimization = true + } + stateRoot.switch = true stateGenesis.directory = "state-genesis" stateRoot.db = { From 9e8475a5eaa64892422cb13cb83bd10a40b93877 Mon Sep 17 00:00:00 2001 From: halibobo1205 <82020050+halibobo1205@users.noreply.github.com> Date: Tue, 9 Apr 2024 15:10:19 +0800 Subject: [PATCH 32/34] feat(state-trie): add eth_getAccounts (#5795) --- .../src/main/java/org/tron/core/Wallet.java | 56 +++++++++++++++++++ .../core/services/jsonrpc/TronJsonRpc.java | 8 +++ .../services/jsonrpc/TronJsonRpcImpl.java | 43 ++++++++++++++ .../DelegateResourceActuatorTest.java | 2 +- .../tron/core/state/WorldStateQueryTest.java | 37 +++++++++++- 5 files changed, 142 insertions(+), 4 deletions(-) diff --git a/framework/src/main/java/org/tron/core/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java index 404e146dd95..4fb9af6961a 100755 --- a/framework/src/main/java/org/tron/core/Wallet.java +++ b/framework/src/main/java/org/tron/core/Wallet.java @@ -52,6 +52,7 @@ import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ArrayUtils; @@ -187,10 +188,14 @@ import org.tron.core.net.TronNetService; import org.tron.core.net.message.adv.TransactionMessage; import org.tron.core.state.WorldStateQueryInstance; +import org.tron.core.state.store.AccountStateStore; +import org.tron.core.state.store.AssetIssueV2StateStore; +import org.tron.core.state.store.DynamicPropertiesStateStore; import org.tron.core.state.store.StorageRowStateStore; import org.tron.core.store.AccountIdIndexStore; import org.tron.core.store.AccountStore; import org.tron.core.store.AccountTraceStore; +import org.tron.core.store.AssetIssueV2Store; import org.tron.core.store.BalanceTraceStore; import org.tron.core.store.ContractStore; import org.tron.core.store.DynamicPropertiesStore; @@ -361,6 +366,57 @@ public Account getAccount(byte[] address, long blockNumber) { return accountCapsule.getInstance(); } + public List getAccounts(List addressList) { + AccountStore accountStore = chainBaseManager.getAccountStore(); + BandwidthProcessor processor = new BandwidthProcessor(chainBaseManager); + EnergyProcessor energyProcessor = new EnergyProcessor( + chainBaseManager.getDynamicPropertiesStore(), + chainBaseManager.getAccountStore()); + return addressList.stream().map(address -> { + AccountCapsule accountCapsule = accountStore.get(address); + if (accountCapsule == null) { + return Account.getDefaultInstance(); + } + return enrichAccount(accountCapsule, processor, energyProcessor).getInstance(); + }).collect(Collectors.toList()); + } + + public List getAccounts(List addressList, long blockNumber) { + Bytes32 rootHash = getRootHashByNumber(blockNumber); + WorldStateQueryInstance worldStateQueryInstance = initWorldStateQueryInstance(rootHash); + DynamicPropertiesStore propertiesStore = + new DynamicPropertiesStateStore(worldStateQueryInstance); + AccountStore accountStore = new AccountStateStore(worldStateQueryInstance); + AssetIssueV2Store assetIssueV2Store = new AssetIssueV2StateStore(worldStateQueryInstance); + final BandwidthProcessor processor = new BandwidthProcessor(propertiesStore, accountStore, + assetIssueV2Store, assetIssueV2Store); + final EnergyProcessor energyProcessor = new EnergyProcessor(propertiesStore, accountStore); + return addressList.stream().map(address -> { + AccountCapsule accountCapsule = worldStateQueryInstance.getAccount(address); + if (accountCapsule == null) { + return Account.getDefaultInstance(); + } + return enrichAccount(accountCapsule, processor, energyProcessor).getInstance(); + }).collect(Collectors.toList()); + } + + private AccountCapsule enrichAccount(AccountCapsule accountCapsule, + BandwidthProcessor processor, EnergyProcessor energyProcessor) { + accountCapsule.importAllAsset(); + processor.updateUsage(accountCapsule); + energyProcessor.updateUsage(accountCapsule); + + long genesisTimeStamp = chainBaseManager.getGenesisBlock().getTimeStamp(); + accountCapsule.setLatestConsumeTime(genesisTimeStamp + + BLOCK_PRODUCED_INTERVAL * accountCapsule.getLatestConsumeTime()); + accountCapsule.setLatestConsumeFreeTime(genesisTimeStamp + + BLOCK_PRODUCED_INTERVAL * accountCapsule.getLatestConsumeFreeTime()); + accountCapsule.setLatestConsumeTimeForEnergy(genesisTimeStamp + + BLOCK_PRODUCED_INTERVAL * accountCapsule.getLatestConsumeTimeForEnergy()); + sortFrozenV2List(accountCapsule); + return accountCapsule; + } + private void sortFrozenV2List(AccountCapsule accountCapsule) { List oldFreezeV2List = accountCapsule.getFrozenV2List(); diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java index 7e8a1679b51..4e16e7bd68e 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java @@ -202,6 +202,14 @@ String getCall(CallArguments transactionCall, Object blockNumOrTag) @JsonRpcMethod("eth_accounts") String[] getAccounts(); + @JsonRpcMethod("eth_getAccounts") + @JsonRpcErrors({ + @JsonRpcError(exception = JsonRpcInvalidParamsException.class, code = -32602, data = "{}"), + }) + List getAccounts(String[] addressList, String blockNumOrTag) + throws JsonRpcInvalidParamsException; + + @JsonRpcMethod("buildTransaction") @JsonRpcErrors({ @JsonRpcError(exception = JsonRpcInvalidRequestException.class, code = -32600, data = "{}"), diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index 1461963282d..be8f32f70c4 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -11,6 +11,7 @@ import static org.tron.core.services.jsonrpc.JsonRpcApiUtil.triggerCallContract; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.google.protobuf.ByteString; import com.google.protobuf.GeneratedMessageV3; import java.io.Closeable; @@ -19,6 +20,7 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; @@ -30,6 +32,8 @@ import java.util.concurrent.ExecutorService; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; + import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; @@ -111,6 +115,7 @@ public enum RequestSource { private static final String FILTER_NOT_FOUND = "filter not found"; public static final int EXPIRE_SECONDS = 5 * 60; + public static final int MAX_BATCH_SIZE = 100; // max batch size for getAccounts /** * for log filter in Full Json-RPC */ @@ -1032,6 +1037,44 @@ public String[] getAccounts() { return new String[0]; } + @Override + public List getAccounts(String[] addressList, String blockNumOrTag) + throws JsonRpcInvalidParamsException { + if (addressList == null || addressList.length == 0) { + return Collections.emptyList(); + } + if (addressList.length > MAX_BATCH_SIZE) { + throw new JsonRpcInvalidParamsException("The maximum number of addresses is " + + MAX_BATCH_SIZE); + } + List addressToQuery = new ArrayList<>(); + for (String address : addressList) { + byte[] addressData = addressCompatibleToByteArray(address); + addressToQuery.add(addressData); + } + List reply; + if (EARLIEST_STR.equalsIgnoreCase(blockNumOrTag) + || PENDING_STR.equalsIgnoreCase(blockNumOrTag)) { + throw new JsonRpcInvalidParamsException(TAG_NOT_SUPPORT_ERROR); + } else if (LATEST_STR.equalsIgnoreCase(blockNumOrTag)) { + reply = wallet.getAccounts(addressToQuery); + } else { + BigInteger blockNumber; + try { + blockNumber = ByteArray.hexToBigInteger(blockNumOrTag); + } catch (Exception e) { + throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR); + } + if (allowStateRoot) { + reply = wallet.getAccounts(addressToQuery, blockNumber.longValue()); + } else { + throw new JsonRpcInvalidParamsException(QUANTITY_NOT_SUPPORT_ERROR); + } + } + return reply.stream().map(Util::convertOutput).map(JSONObject::parseObject) + .collect(Collectors.toList()); + } + private TransactionJson buildCreateSmartContractTransaction(byte[] ownerAddress, BuildArguments args) throws JsonRpcInvalidParamsException, JsonRpcInvalidRequestException, JsonRpcInternalException { diff --git a/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java index 61d4ab6e2a4..1edaf6ace81 100644 --- a/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java @@ -15,8 +15,8 @@ import com.google.protobuf.Any; import com.google.protobuf.ByteString; -import lombok.extern.slf4j.Slf4j; import javax.annotation.Resource; +import lombok.extern.slf4j.Slf4j; import org.junit.After; import org.junit.Assert; import org.junit.Before; diff --git a/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java b/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java index ccc7cba3a46..fe9e9eff112 100644 --- a/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java +++ b/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java @@ -4,6 +4,7 @@ import com.google.protobuf.ByteString; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -15,6 +16,7 @@ import org.junit.ClassRule; import org.junit.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; @@ -31,6 +33,7 @@ import org.tron.common.utils.Sha256Hash; import org.tron.common.utils.WalletUtil; import org.tron.core.ChainBaseManager; +import org.tron.core.Wallet; import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.AssetIssueCapsule; import org.tron.core.capsule.BlockCapsule; @@ -45,6 +48,7 @@ import org.tron.core.exception.JsonRpcInvalidRequestException; import org.tron.core.exception.StoreException; import org.tron.core.services.jsonrpc.TronJsonRpc; +import org.tron.core.services.jsonrpc.TronJsonRpcImpl; import org.tron.core.services.jsonrpc.types.CallArguments; import org.tron.core.state.store.StorageRowStateStore; import org.tron.core.vm.program.Storage; @@ -63,6 +67,9 @@ public class WorldStateQueryTest { private static Manager manager; private static TronJsonRpc tronJsonRpc; + private static Wallet wallet; + @ClassRule + public static final ExpectedException thrown = ExpectedException.none(); private static final long TOKEN_ID1 = 1000001L; private static final long TOKEN_ID2 = 1000002L; @@ -83,8 +90,6 @@ public static void init() throws IOException { Args.setParam(new String[]{"-d", temporaryFolder.newFolder().toString()}, "config-localtest.conf"); - // disable p2p - Args.getInstance().setP2pDisable(true); // allow account root Args.getInstance().setAllowAccountStateRoot(1); // init dbBackupConfig to avoid NPE @@ -102,7 +107,7 @@ public static void init() throws IOException { worldStateCallBack.setExecute(false); manager = context.getBean(Manager.class); tronJsonRpc = context.getBean(TronJsonRpc.class); - + wallet = context.getBean(Wallet.class); Protocol.Account acc = Protocol.Account.newBuilder() .setAccountName(ByteString.copyFrom(Objects.requireNonNull(ByteArray.fromString("acc")))) .setAddress(ByteString.copyFrom(account1Prikey.getAddress())) @@ -336,6 +341,20 @@ private void checkAccount(WorldStateQueryInstance worldStateQueryInstance, long ByteArray.toJsonHex(blockNum)), tronJsonRpc.getToken10( ByteArray.toHexString(account2Prikey.getAddress()), "latest")); + List addressList = new ArrayList<>(); + addressList.add(ByteArray.toHexString(account1Prikey.getAddress())); + addressList.add(ByteArray.toHexString(account2Prikey.getAddress())); + + Assert.assertEquals(tronJsonRpc.getAccounts( + addressList.toArray(new String[0]), ByteArray.toJsonHex(blockNum)), + tronJsonRpc.getAccounts( + addressList.toArray(new String[0]), "latest")); + + Assert.assertEquals(wallet.getAccount( + Protocol.Account.newBuilder().setAddress(ByteString.copyFrom(account1Prikey.getAddress())) + .build()), + wallet.getAccounts(Collections.singletonList(account1Prikey.getAddress()), blockNum) + .get(0)); Map asset = new HashMap<>(); for (TronJsonRpc.Token10Result t : tronJsonRpc.getToken10( @@ -386,6 +405,18 @@ private void checkAccount(WorldStateQueryInstance worldStateQueryInstance, long } } + @Test + public void testGetAccounts() { + List addressList2 = new ArrayList<>(); + for (int i = 0; i < 101; i++) { + addressList2.add("0x" + i); + } + Assert.assertThrows("The maximum number of addresses is " + + TronJsonRpcImpl.MAX_BATCH_SIZE, + JsonRpcInvalidParamsException.class, () -> + tronJsonRpc.getAccounts(addressList2.toArray(new String[0]), "latest")); + } + private BlockCapsule buildTransferBlock(BlockCapsule parentBlock) { BalanceContract.TransferContract transferContract = BalanceContract .TransferContract.newBuilder() From cc1b86d7ea21f410ba8dcdfd93455e07fdacebd8 Mon Sep 17 00:00:00 2001 From: halibobo1205 <82020050+halibobo1205@users.noreply.github.com> Date: Wed, 10 Apr 2024 18:53:21 +0800 Subject: [PATCH 33/34] feat(state-trie): add tron_getAccountResources (#5796) --- .../src/main/java/org/tron/core/Wallet.java | 79 +++++++++++++++++++ .../core/services/jsonrpc/TronJsonRpc.java | 7 ++ .../services/jsonrpc/TronJsonRpcImpl.java | 41 ++++++++++ .../tron/core/state/WorldStateQueryTest.java | 10 +++ 4 files changed, 137 insertions(+) diff --git a/framework/src/main/java/org/tron/core/Wallet.java b/framework/src/main/java/org/tron/core/Wallet.java index 4fb9af6961a..57ae4a1259e 100755 --- a/framework/src/main/java/org/tron/core/Wallet.java +++ b/framework/src/main/java/org/tron/core/Wallet.java @@ -417,6 +417,85 @@ private AccountCapsule enrichAccount(AccountCapsule accountCapsule, return accountCapsule; } + public List getAccountResources(List addressList) { + AccountStore accountStore = chainBaseManager.getAccountStore(); + DynamicPropertiesStore propertiesStore = chainBaseManager.getDynamicPropertiesStore(); + BandwidthProcessor processor = new BandwidthProcessor(chainBaseManager); + EnergyProcessor energyProcessor = new EnergyProcessor(propertiesStore, accountStore); + return queryAccountResources(addressList, processor, energyProcessor, propertiesStore, + accountStore); + } + + public List getAccountResources(List addressList, + long blockNumber) { + Bytes32 rootHash = getRootHashByNumber(blockNumber); + WorldStateQueryInstance instance = initWorldStateQueryInstance(rootHash); + AccountStore accountStore = new AccountStateStore(instance); + DynamicPropertiesStore propertiesStore = new DynamicPropertiesStateStore(instance); + AssetIssueV2Store assetIssueV2Store = new AssetIssueV2StateStore(instance); + BandwidthProcessor processor = new BandwidthProcessor(propertiesStore, accountStore, + assetIssueV2Store, assetIssueV2Store); + EnergyProcessor energyProcessor = new EnergyProcessor(propertiesStore, accountStore); + return queryAccountResources(addressList, processor, energyProcessor, propertiesStore, + accountStore); + } + + private List queryAccountResources(List addressList, + BandwidthProcessor processor, + EnergyProcessor energyProcessor, + DynamicPropertiesStore propertiesStore, + AccountStore accountStore) { + return addressList.stream().map(address -> { + AccountCapsule accountCapsule = accountStore.get(address); + return buildAccountResource(accountCapsule, processor, energyProcessor, propertiesStore); + }).collect(Collectors.toList()); + } + + private AccountResourceMessage buildAccountResource(AccountCapsule accountCapsule, + BandwidthProcessor processor, + EnergyProcessor energyProcessor, + DynamicPropertiesStore propertiesStore) { + if (accountCapsule == null) { + return AccountResourceMessage.getDefaultInstance(); + } + processor.updateUsage(accountCapsule); + energyProcessor.updateUsage(accountCapsule); + long netLimit = processor.calculateGlobalNetLimit(accountCapsule); + long freeNetLimit = propertiesStore.getFreeNetLimit(); + long totalNetLimit = propertiesStore.getTotalNetLimit(); + long totalNetWeight = propertiesStore.getTotalNetWeight(); + long totalTronPowerWeight = propertiesStore.getTotalTronPowerWeight(); + long energyLimit = energyProcessor.calculateGlobalEnergyLimit(accountCapsule); + long totalEnergyLimit = propertiesStore.getTotalEnergyCurrentLimit(); + long totalEnergyWeight = propertiesStore.getTotalEnergyWeight(); + long storageLimit = accountCapsule.getAccountResource().getStorageLimit(); + long storageUsage = accountCapsule.getAccountResource().getStorageUsage(); + long allTronPowerUsage = accountCapsule.getTronPowerUsage(); + long allTronPower = accountCapsule.getAllTronPower() / TRX_PRECISION; + + Map assetNetLimitMap = new HashMap<>(); + Map allFreeAssetNetUsage = setAssetNetLimit(assetNetLimitMap, accountCapsule); + AccountResourceMessage.Builder builder = AccountResourceMessage.newBuilder(); + builder.setFreeNetUsed(accountCapsule.getFreeNetUsage()) + .setFreeNetLimit(freeNetLimit) + .setNetUsed(accountCapsule.getNetUsage()) + .setNetLimit(netLimit) + .setTotalNetLimit(totalNetLimit) + .setTotalNetWeight(totalNetWeight) + .setTotalTronPowerWeight(totalTronPowerWeight) + .setEnergyLimit(energyLimit) + .setEnergyUsed(accountCapsule.getAccountResource().getEnergyUsage()) + .setTronPowerUsed(allTronPowerUsage) + .setTronPowerLimit(allTronPower) + .setTotalEnergyLimit(totalEnergyLimit) + .setTotalEnergyWeight(totalEnergyWeight) + .setStorageLimit(storageLimit) + .setStorageUsed(storageUsage) + .putAllAssetNetUsed(allFreeAssetNetUsage) + .putAllAssetNetLimit(assetNetLimitMap); + return builder.build(); + } + private void sortFrozenV2List(AccountCapsule accountCapsule) { List oldFreezeV2List = accountCapsule.getFrozenV2List(); diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java index 4e16e7bd68e..70e40dc3ed9 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java @@ -209,6 +209,13 @@ String getCall(CallArguments transactionCall, Object blockNumOrTag) List getAccounts(String[] addressList, String blockNumOrTag) throws JsonRpcInvalidParamsException; + @JsonRpcMethod("tron_getAccountResources") + @JsonRpcErrors({ + @JsonRpcError(exception = JsonRpcInvalidParamsException.class, code = -32602, data = "{}"), + }) + List getAccountResources(String[] addressList, String blockNumOrTag) + throws JsonRpcInvalidParamsException; + @JsonRpcMethod("buildTransaction") @JsonRpcErrors({ diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index be8f32f70c4..e74ff05bc63 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -41,6 +41,7 @@ import org.bouncycastle.util.encoders.Hex; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.tron.api.GrpcAPI; import org.tron.api.GrpcAPI.BytesMessage; import org.tron.api.GrpcAPI.EstimateEnergyMessage; import org.tron.api.GrpcAPI.Return; @@ -1075,6 +1076,46 @@ public List getAccounts(String[] addressList, String blockNumOrTag) .collect(Collectors.toList()); } + @Override + public List getAccountResources(String[] addressList, String blockNumOrTag) + throws JsonRpcInvalidParamsException { + if (addressList == null || addressList.length == 0) { + return Collections.emptyList(); + } + if (addressList.length > MAX_BATCH_SIZE) { + throw new JsonRpcInvalidParamsException("The maximum number of addresses is " + + MAX_BATCH_SIZE); + } + List addressToQuery = new ArrayList<>(); + for (String address : addressList) { + byte[] addressData = addressCompatibleToByteArray(address); + addressToQuery.add(addressData); + } + List reply; + if (EARLIEST_STR.equalsIgnoreCase(blockNumOrTag) + || PENDING_STR.equalsIgnoreCase(blockNumOrTag)) { + throw new JsonRpcInvalidParamsException(TAG_NOT_SUPPORT_ERROR); + } else if (LATEST_STR.equalsIgnoreCase(blockNumOrTag)) { + reply = wallet.getAccountResources(addressToQuery); + } else { + BigInteger blockNumber; + try { + blockNumber = ByteArray.hexToBigInteger(blockNumOrTag); + } catch (Exception e) { + throw new JsonRpcInvalidParamsException(BLOCK_NUM_ERROR); + } + if (allowStateRoot) { + reply = wallet.getAccountResources(addressToQuery, blockNumber.longValue()); + } else { + throw new JsonRpcInvalidParamsException(QUANTITY_NOT_SUPPORT_ERROR); + } + } + return reply.stream() + .map(r -> JsonFormat.printToString(r, false)) + .map(JSONObject::parseObject) + .collect(Collectors.toList()); + } + private TransactionJson buildCreateSmartContractTransaction(byte[] ownerAddress, BuildArguments args) throws JsonRpcInvalidParamsException, JsonRpcInvalidRequestException, JsonRpcInternalException { diff --git a/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java b/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java index fe9e9eff112..a84721518a8 100644 --- a/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java +++ b/framework/src/test/java/org/tron/core/state/WorldStateQueryTest.java @@ -356,6 +356,16 @@ private void checkAccount(WorldStateQueryInstance worldStateQueryInstance, long wallet.getAccounts(Collections.singletonList(account1Prikey.getAddress()), blockNum) .get(0)); + Assert.assertEquals(tronJsonRpc.getAccountResources( + addressList.toArray(new String[0]), ByteArray.toJsonHex(blockNum)), + tronJsonRpc.getAccountResources( + addressList.toArray(new String[0]), "latest")); + + Assert.assertEquals(wallet.getAccountResource( + ByteString.copyFrom(account1Prikey.getAddress())), + wallet.getAccountResources(Collections.singletonList(account1Prikey.getAddress()), blockNum) + .get(0)); + Map asset = new HashMap<>(); for (TronJsonRpc.Token10Result t : tronJsonRpc.getToken10( ByteArray.toHexString(account2Prikey.getAddress()), "latest")) { From 567744da841db7e39ea7370d01c6e8d88390c676 Mon Sep 17 00:00:00 2001 From: halibobo1205 <82020050+halibobo1205@users.noreply.github.com> Date: Mon, 28 Oct 2024 14:59:40 +0800 Subject: [PATCH 34/34] feat(state-trie): add miss dependencies for guava (#6054) --- state-trie-jdk8/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/state-trie-jdk8/build.gradle b/state-trie-jdk8/build.gradle index 5ca8eafc88e..8ab58b60aac 100644 --- a/state-trie-jdk8/build.gradle +++ b/state-trie-jdk8/build.gradle @@ -29,6 +29,7 @@ dependencies { compile group: 'org.immutables', name: 'value', version: '2.9.3' compile group: 'org.immutables', name: 'value-annotations', version: '2.9.3' compile group: 'org.rocksdb', name: 'rocksdbjni', version: '7.7.3' + implementation group: 'com.google.guava', name: 'guava', version: '32.0.1-jre' testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.9.1'