mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge remote-tracking branch 'upstream/develop' into evmjit
This commit is contained in:
commit
fc3ea6aa6c
@ -34,34 +34,45 @@ BOOST_AUTO_TEST_CASE(blocks)
|
||||
{
|
||||
enumerateClients([](Json::Value const& _json, dev::eth::ClientBase& _client) -> void
|
||||
{
|
||||
for (string const& name: _json["postState"].getMemberNames())
|
||||
auto compareState = [&_client](Json::Value const& _o, string const& _name, BlockNumber _blockNumber) -> void
|
||||
{
|
||||
Json::Value o = _json["postState"][name];
|
||||
Address address(name);
|
||||
Address address(_name);
|
||||
|
||||
// balanceAt
|
||||
u256 expectedBalance = u256(o["balance"].asString());
|
||||
u256 balance = _client.balanceAt(address);
|
||||
u256 expectedBalance = u256(_o["balance"].asString());
|
||||
u256 balance = _client.balanceAt(address, _blockNumber);
|
||||
ETH_CHECK_EQUAL(expectedBalance, balance);
|
||||
|
||||
// countAt
|
||||
u256 expectedCount = u256(o["nonce"].asString());
|
||||
u256 count = _client.countAt(address);
|
||||
u256 expectedCount = u256(_o["nonce"].asString());
|
||||
u256 count = _client.countAt(address, _blockNumber);
|
||||
ETH_CHECK_EQUAL(expectedCount, count);
|
||||
|
||||
// stateAt
|
||||
for (string const& pos: o["storage"].getMemberNames())
|
||||
for (string const& pos: _o["storage"].getMemberNames())
|
||||
{
|
||||
u256 expectedState = u256(o["storage"][pos].asString());
|
||||
u256 state = _client.stateAt(address, u256(pos));
|
||||
u256 expectedState = u256(_o["storage"][pos].asString());
|
||||
u256 state = _client.stateAt(address, u256(pos), _blockNumber);
|
||||
ETH_CHECK_EQUAL(expectedState, state);
|
||||
}
|
||||
|
||||
// codeAt
|
||||
bytes expectedCode = fromHex(o["code"].asString());
|
||||
bytes code = _client.codeAt(address);
|
||||
bytes expectedCode = fromHex(_o["code"].asString());
|
||||
bytes code = _client.codeAt(address, _blockNumber);
|
||||
ETH_CHECK_EQUAL_COLLECTIONS(expectedCode.begin(), expectedCode.end(),
|
||||
code.begin(), code.end());
|
||||
};
|
||||
|
||||
for (string const& name: _json["postState"].getMemberNames())
|
||||
{
|
||||
Json::Value o = _json["postState"][name];
|
||||
compareState(o, name, PendingBlock);
|
||||
}
|
||||
|
||||
for (string const& name: _json["pre"].getMemberNames())
|
||||
{
|
||||
Json::Value o = _json["pre"][name];
|
||||
compareState(o, name, 0);
|
||||
}
|
||||
|
||||
// number
|
||||
|
@ -460,7 +460,7 @@ BOOST_AUTO_TEST_CASE(function_external_types)
|
||||
uint a;
|
||||
}
|
||||
contract Test {
|
||||
function boo(uint arg2, bool arg3, bytes8 arg4, bool[2] pairs, uint[] dynamic, C carg) external returns (uint ret) {
|
||||
function boo(uint arg2, bool arg3, bytes8 arg4, bool[2] pairs, uint[] dynamic, C carg, address[] addresses) external returns (uint ret) {
|
||||
ret = 5;
|
||||
}
|
||||
})";
|
||||
@ -471,7 +471,7 @@ BOOST_AUTO_TEST_CASE(function_external_types)
|
||||
auto functions = contract->getDefinedFunctions();
|
||||
if (functions.empty())
|
||||
continue;
|
||||
BOOST_CHECK_EQUAL("boo(uint256,bool,bytes8,bool[2],uint256[],address)", functions[0]->externalSignature());
|
||||
BOOST_CHECK_EQUAL("boo(uint256,bool,bytes8,bool[2],uint256[],address,address[])", functions[0]->externalSignature());
|
||||
}
|
||||
}
|
||||
|
||||
@ -503,6 +503,16 @@ BOOST_AUTO_TEST_CASE(function_external_call_not_allowed_conversion)
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
|
||||
}
|
||||
|
||||
// todo delete when implemented
|
||||
BOOST_AUTO_TEST_CASE(arrays_in_internal_functions)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract Test {
|
||||
function foo(address[] addresses) {}
|
||||
})";
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(function_internal_allowed_conversion)
|
||||
{
|
||||
char const* text = R"(
|
||||
|
@ -303,6 +303,271 @@ BOOST_AUTO_TEST_CASE(cse_associativity2)
|
||||
checkCSE(input, {Instruction::DUP2, Instruction::DUP2, Instruction::ADD, u256(5), Instruction::ADD});
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(cse_storage)
|
||||
{
|
||||
AssemblyItems input{
|
||||
u256(0),
|
||||
Instruction::SLOAD,
|
||||
u256(0),
|
||||
Instruction::SLOAD,
|
||||
Instruction::ADD,
|
||||
u256(0),
|
||||
Instruction::SSTORE
|
||||
};
|
||||
checkCSE(input, {
|
||||
u256(0),
|
||||
Instruction::DUP1,
|
||||
Instruction::SLOAD,
|
||||
Instruction::DUP1,
|
||||
Instruction::ADD,
|
||||
Instruction::SWAP1,
|
||||
Instruction::SSTORE
|
||||
});
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(cse_noninterleaved_storage)
|
||||
{
|
||||
// two stores to the same location should be replaced by only one store, even if we
|
||||
// read in the meantime
|
||||
AssemblyItems input{
|
||||
u256(7),
|
||||
Instruction::DUP2,
|
||||
Instruction::SSTORE,
|
||||
Instruction::DUP1,
|
||||
Instruction::SLOAD,
|
||||
u256(8),
|
||||
Instruction::DUP3,
|
||||
Instruction::SSTORE
|
||||
};
|
||||
checkCSE(input, {
|
||||
u256(8),
|
||||
Instruction::DUP2,
|
||||
Instruction::SSTORE,
|
||||
u256(7)
|
||||
});
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(cse_interleaved_storage)
|
||||
{
|
||||
// stores and reads to/from two unknown locations, should not optimize away the first store
|
||||
AssemblyItems input{
|
||||
u256(7),
|
||||
Instruction::DUP2,
|
||||
Instruction::SSTORE, // store to "DUP1"
|
||||
Instruction::DUP2,
|
||||
Instruction::SLOAD, // read from "DUP2", might be equal to "DUP1"
|
||||
u256(0),
|
||||
Instruction::DUP3,
|
||||
Instruction::SSTORE // store different value to "DUP1"
|
||||
};
|
||||
checkCSE(input, input);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(cse_interleaved_storage_same_value)
|
||||
{
|
||||
// stores and reads to/from two unknown locations, should not optimize away the first store
|
||||
// but it should optimize away the second, since we already know the value will be the same
|
||||
AssemblyItems input{
|
||||
u256(7),
|
||||
Instruction::DUP2,
|
||||
Instruction::SSTORE, // store to "DUP1"
|
||||
Instruction::DUP2,
|
||||
Instruction::SLOAD, // read from "DUP2", might be equal to "DUP1"
|
||||
u256(6),
|
||||
u256(1),
|
||||
Instruction::ADD,
|
||||
Instruction::DUP3,
|
||||
Instruction::SSTORE // store same value to "DUP1"
|
||||
};
|
||||
checkCSE(input, {
|
||||
u256(7),
|
||||
Instruction::DUP2,
|
||||
Instruction::SSTORE,
|
||||
Instruction::DUP2,
|
||||
Instruction::SLOAD
|
||||
});
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(cse_interleaved_storage_at_known_location)
|
||||
{
|
||||
// stores and reads to/from two known locations, should optimize away the first store,
|
||||
// because we know that the location is different
|
||||
AssemblyItems input{
|
||||
u256(0x70),
|
||||
u256(1),
|
||||
Instruction::SSTORE, // store to 1
|
||||
u256(2),
|
||||
Instruction::SLOAD, // read from 2, is different from 1
|
||||
u256(0x90),
|
||||
u256(1),
|
||||
Instruction::SSTORE // store different value at 1
|
||||
};
|
||||
checkCSE(input, {
|
||||
u256(2),
|
||||
Instruction::SLOAD,
|
||||
u256(0x90),
|
||||
u256(1),
|
||||
Instruction::SSTORE
|
||||
});
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(cse_interleaved_storage_at_known_location_offset)
|
||||
{
|
||||
// stores and reads to/from two locations which are known to be different,
|
||||
// should optimize away the first store, because we know that the location is different
|
||||
AssemblyItems input{
|
||||
u256(0x70),
|
||||
Instruction::DUP2,
|
||||
u256(1),
|
||||
Instruction::ADD,
|
||||
Instruction::SSTORE, // store to "DUP1"+1
|
||||
Instruction::DUP1,
|
||||
u256(2),
|
||||
Instruction::ADD,
|
||||
Instruction::SLOAD, // read from "DUP1"+2, is different from "DUP1"+1
|
||||
u256(0x90),
|
||||
Instruction::DUP3,
|
||||
u256(1),
|
||||
Instruction::ADD,
|
||||
Instruction::SSTORE // store different value at "DUP1"+1
|
||||
};
|
||||
checkCSE(input, {
|
||||
u256(2),
|
||||
Instruction::DUP2,
|
||||
Instruction::ADD,
|
||||
Instruction::SLOAD,
|
||||
u256(0x90),
|
||||
u256(1),
|
||||
Instruction::DUP4,
|
||||
Instruction::ADD,
|
||||
Instruction::SSTORE
|
||||
});
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(cse_interleaved_memory_at_known_location_offset)
|
||||
{
|
||||
// stores and reads to/from two locations which are known to be different,
|
||||
// should not optimize away the first store, because the location overlaps with the load,
|
||||
// but it should optimize away the second, because we know that the location is different by 32
|
||||
AssemblyItems input{
|
||||
u256(0x50),
|
||||
Instruction::DUP2,
|
||||
u256(2),
|
||||
Instruction::ADD,
|
||||
Instruction::MSTORE, // ["DUP1"+2] = 0x50
|
||||
u256(0x60),
|
||||
Instruction::DUP2,
|
||||
u256(32),
|
||||
Instruction::ADD,
|
||||
Instruction::MSTORE, // ["DUP1"+32] = 0x60
|
||||
Instruction::DUP1,
|
||||
Instruction::MLOAD, // read from "DUP1"
|
||||
u256(0x70),
|
||||
Instruction::DUP3,
|
||||
u256(32),
|
||||
Instruction::ADD,
|
||||
Instruction::MSTORE, // ["DUP1"+32] = 0x70
|
||||
u256(0x80),
|
||||
Instruction::DUP3,
|
||||
u256(2),
|
||||
Instruction::ADD,
|
||||
Instruction::MSTORE, // ["DUP1"+2] = 0x80
|
||||
};
|
||||
// If the actual code changes too much, we could also simply check that the output contains
|
||||
// exactly 3 MSTORE and exactly 1 MLOAD instruction.
|
||||
checkCSE(input, {
|
||||
u256(0x50),
|
||||
u256(2),
|
||||
Instruction::DUP3,
|
||||
Instruction::ADD,
|
||||
Instruction::SWAP1,
|
||||
Instruction::DUP2,
|
||||
Instruction::MSTORE, // ["DUP1"+2] = 0x50
|
||||
Instruction::DUP2,
|
||||
Instruction::MLOAD, // read from "DUP1"
|
||||
u256(0x70),
|
||||
u256(32),
|
||||
Instruction::DUP5,
|
||||
Instruction::ADD,
|
||||
Instruction::MSTORE, // ["DUP1"+32] = 0x70
|
||||
u256(0x80),
|
||||
Instruction::SWAP1,
|
||||
Instruction::SWAP2,
|
||||
Instruction::MSTORE // ["DUP1"+2] = 0x80
|
||||
});
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(cse_deep_stack)
|
||||
{
|
||||
AssemblyItems input{
|
||||
Instruction::ADD,
|
||||
Instruction::SWAP1,
|
||||
Instruction::POP,
|
||||
Instruction::SWAP8,
|
||||
Instruction::POP,
|
||||
Instruction::SWAP8,
|
||||
Instruction::POP,
|
||||
Instruction::SWAP8,
|
||||
Instruction::SWAP5,
|
||||
Instruction::POP,
|
||||
Instruction::POP,
|
||||
Instruction::POP,
|
||||
Instruction::POP,
|
||||
Instruction::POP,
|
||||
};
|
||||
checkCSE(input, {
|
||||
Instruction::SWAP4,
|
||||
Instruction::SWAP12,
|
||||
Instruction::SWAP3,
|
||||
Instruction::SWAP11,
|
||||
Instruction::POP,
|
||||
Instruction::SWAP1,
|
||||
Instruction::SWAP3,
|
||||
Instruction::ADD,
|
||||
Instruction::SWAP8,
|
||||
Instruction::POP,
|
||||
Instruction::SWAP6,
|
||||
Instruction::POP,
|
||||
Instruction::POP,
|
||||
Instruction::POP,
|
||||
Instruction::POP,
|
||||
Instruction::POP,
|
||||
Instruction::POP,
|
||||
});
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(cse_jumpi_no_jump)
|
||||
{
|
||||
AssemblyItems input{
|
||||
u256(0),
|
||||
u256(1),
|
||||
Instruction::DUP2,
|
||||
AssemblyItem(PushTag, 1),
|
||||
Instruction::JUMPI
|
||||
};
|
||||
checkCSE(input, {
|
||||
u256(0),
|
||||
u256(1)
|
||||
});
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(cse_jumpi_jump)
|
||||
{
|
||||
AssemblyItems input{
|
||||
u256(1),
|
||||
u256(1),
|
||||
Instruction::DUP2,
|
||||
AssemblyItem(PushTag, 1),
|
||||
Instruction::JUMPI
|
||||
};
|
||||
checkCSE(input, {
|
||||
u256(1),
|
||||
Instruction::DUP1,
|
||||
AssemblyItem(PushTag, 1),
|
||||
Instruction::JUMP
|
||||
});
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
}
|
||||
|
@ -63,8 +63,8 @@ BOOST_AUTO_TEST_CASE(basic_test)
|
||||
|
||||
unsigned cacheSize(o["cache_size"].get_int());
|
||||
h256 cacheHash(o["cache_hash"].get_str());
|
||||
BOOST_REQUIRE_EQUAL(Ethasher::get()->cache(header).size(), cacheSize);
|
||||
BOOST_REQUIRE_EQUAL(sha3(Ethasher::get()->cache(header)), cacheHash);
|
||||
BOOST_REQUIRE_EQUAL(Ethasher::get()->params(header).cache_size, cacheSize);
|
||||
BOOST_REQUIRE_EQUAL(sha3(bytesConstRef((byte const*)Ethasher::get()->cache(header), cacheSize)), cacheHash);
|
||||
|
||||
#if TEST_FULL
|
||||
unsigned fullSize(o["full_size"].get_int());
|
||||
|
9
peer.cpp
9
peer.cpp
@ -57,6 +57,15 @@ BOOST_AUTO_TEST_CASE(host)
|
||||
g_logVerbosity = oldLogVerbosity;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(networkConfig)
|
||||
{
|
||||
Host save("Test", NetworkPreferences(false));
|
||||
bytes store(save.saveNetwork());
|
||||
|
||||
Host restore("Test", NetworkPreferences(false), bytesConstRef(&store));
|
||||
BOOST_REQUIRE(save.id() == restore.id());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(save_nodes)
|
||||
{
|
||||
std::list<Host*> hosts;
|
||||
|
@ -1461,7 +1461,7 @@
|
||||
}
|
||||
},
|
||||
|
||||
"stackLimitPush32_1024": {
|
||||
"stackLimitPush32_1023": {
|
||||
"env" : {
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
|
||||
"currentNumber" : "0",
|
||||
@ -1495,7 +1495,7 @@
|
||||
}
|
||||
},
|
||||
|
||||
"stackLimitPush32_1025": {
|
||||
"stackLimitPush32_1024": {
|
||||
"env" : {
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
|
||||
"currentNumber" : "0",
|
||||
@ -1529,7 +1529,41 @@
|
||||
}
|
||||
},
|
||||
|
||||
"stackLimitPush31_1024": {
|
||||
"stackLimitPush32_1025": {
|
||||
"env" : {
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
|
||||
"currentNumber" : "0",
|
||||
"currentGasLimit" : "42949672960",
|
||||
"currentDifficulty" : "256",
|
||||
"currentTimestamp" : "1",
|
||||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
|
||||
},
|
||||
"pre" : {
|
||||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
|
||||
"balance" : "1000000000000000000",
|
||||
"nonce" : "0",
|
||||
"code" : "(asm 1023 0x00 MSTORE JUMPDEST 0x0102030405060708090a0102030405060708090a0102030405060708090a0102 0x01 0x00 MLOAD SUB 0x00 MSTORE 0x00 MLOAD 0x06 JUMPI STOP )",
|
||||
"storage": {}
|
||||
},
|
||||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
|
||||
"balance" : "429496729600",
|
||||
"nonce" : "0",
|
||||
"code" : "",
|
||||
"storage": {}
|
||||
}
|
||||
},
|
||||
"transaction" : {
|
||||
"nonce" : "0",
|
||||
"gasPrice" : "1",
|
||||
"gasLimit" : "100000",
|
||||
"to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
|
||||
"value" : "10",
|
||||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
|
||||
"data" : ""
|
||||
}
|
||||
},
|
||||
|
||||
"stackLimitPush31_1023": {
|
||||
"env" : {
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
|
||||
"currentNumber" : "0",
|
||||
@ -1563,7 +1597,7 @@
|
||||
}
|
||||
},
|
||||
|
||||
"stackLimitPush31_1025": {
|
||||
"stackLimitPush31_1024": {
|
||||
"env" : {
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
|
||||
"currentNumber" : "0",
|
||||
@ -1597,7 +1631,41 @@
|
||||
}
|
||||
},
|
||||
|
||||
"stackLimitGas_1024": {
|
||||
"stackLimitPush31_1025": {
|
||||
"env" : {
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
|
||||
"currentNumber" : "0",
|
||||
"currentGasLimit" : "42949672960",
|
||||
"currentDifficulty" : "256",
|
||||
"currentTimestamp" : "1",
|
||||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
|
||||
},
|
||||
"pre" : {
|
||||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
|
||||
"balance" : "1000000000000000000",
|
||||
"nonce" : "0",
|
||||
"code" : "(asm 1023 0x00 MSTORE JUMPDEST 0x0102030405060708090a0102030405060708090a0102030405060708090a01 0x01 0x00 MLOAD SUB 0x00 MSTORE 0x00 MLOAD 0x06 JUMPI STOP )",
|
||||
"storage": {}
|
||||
},
|
||||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
|
||||
"balance" : "429496729600",
|
||||
"nonce" : "0",
|
||||
"code" : "",
|
||||
"storage": {}
|
||||
}
|
||||
},
|
||||
"transaction" : {
|
||||
"nonce" : "0",
|
||||
"gasPrice" : "1",
|
||||
"gasLimit" : "100000",
|
||||
"to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
|
||||
"value" : "10",
|
||||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
|
||||
"data" : ""
|
||||
}
|
||||
},
|
||||
|
||||
"stackLimitGas_1023": {
|
||||
"env" : {
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
|
||||
"currentNumber" : "0",
|
||||
@ -1631,7 +1699,7 @@
|
||||
}
|
||||
},
|
||||
|
||||
"stackLimitGas_1025": {
|
||||
"stackLimitGas_1024": {
|
||||
"env" : {
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
|
||||
"currentNumber" : "0",
|
||||
@ -1665,6 +1733,40 @@
|
||||
}
|
||||
},
|
||||
|
||||
"stackLimitGas_1025": {
|
||||
"env" : {
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
|
||||
"currentNumber" : "0",
|
||||
"currentGasLimit" : "42949672960",
|
||||
"currentDifficulty" : "256",
|
||||
"currentTimestamp" : "1",
|
||||
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"
|
||||
},
|
||||
"pre" : {
|
||||
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
|
||||
"balance" : "1000000000000000000",
|
||||
"nonce" : "0",
|
||||
"code" : "(asm 1023 0x00 MSTORE JUMPDEST GAS 0x01 0x00 MLOAD SUB 0x00 MSTORE 0x00 MLOAD 0x06 JUMPI STOP )",
|
||||
"storage": {}
|
||||
},
|
||||
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
|
||||
"balance" : "429496729600",
|
||||
"nonce" : "0",
|
||||
"code" : "",
|
||||
"storage": {}
|
||||
}
|
||||
},
|
||||
"transaction" : {
|
||||
"nonce" : "0",
|
||||
"gasPrice" : "1",
|
||||
"gasLimit" : "100000",
|
||||
"to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
|
||||
"value" : "10",
|
||||
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
|
||||
"data" : ""
|
||||
}
|
||||
},
|
||||
|
||||
"mstroe8_dejavu": {
|
||||
"env" : {
|
||||
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
|
||||
|
Loading…
Reference in New Issue
Block a user