mirror of https://github.com/hyperledger/besu
refactor-privacy-storage (#7)
* refactor-privacy-storage Signed-off-by: Ivaylo Kirilov <iikirilov@gmail.com>pull/62/head
parent
f84bd55f2f
commit
c09145e490
@ -1,74 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.privacy; |
|
||||||
|
|
||||||
import org.hyperledger.besu.ethereum.core.Hash; |
|
||||||
import org.hyperledger.besu.plugin.services.storage.KeyValueStorage; |
|
||||||
import org.hyperledger.besu.plugin.services.storage.KeyValueStorageTransaction; |
|
||||||
import org.hyperledger.besu.util.bytes.Bytes32; |
|
||||||
import org.hyperledger.besu.util.bytes.BytesValue; |
|
||||||
|
|
||||||
import java.util.Optional; |
|
||||||
|
|
||||||
public class PrivateStateKeyValueStorage implements PrivateStateStorage { |
|
||||||
|
|
||||||
private final KeyValueStorage keyValueStorage; |
|
||||||
|
|
||||||
public PrivateStateKeyValueStorage(final KeyValueStorage keyValueStorage) { |
|
||||||
this.keyValueStorage = keyValueStorage; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Optional<Hash> getPrivateAccountState(final BytesValue privacyId) { |
|
||||||
final byte[] id = privacyId.getArrayUnsafe(); |
|
||||||
|
|
||||||
if (keyValueStorage.get(id).isPresent()) { |
|
||||||
return Optional.of(Hash.wrap(Bytes32.wrap(keyValueStorage.get(id).get()))); |
|
||||||
} else { |
|
||||||
return Optional.empty(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isWorldStateAvailable(final Bytes32 rootHash) { |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public PrivateStateStorage.Updater updater() { |
|
||||||
return new PrivateStateKeyValueStorage.Updater(keyValueStorage.startTransaction()); |
|
||||||
} |
|
||||||
|
|
||||||
public static class Updater implements PrivateStateStorage.Updater { |
|
||||||
|
|
||||||
private final KeyValueStorageTransaction transaction; |
|
||||||
|
|
||||||
private Updater(final KeyValueStorageTransaction transaction) { |
|
||||||
this.transaction = transaction; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public PrivateStateStorage.Updater putPrivateAccountState( |
|
||||||
final BytesValue privacyId, final Hash privateStateHash) { |
|
||||||
transaction.put(privacyId.getArrayUnsafe(), privateStateHash.extractArray()); |
|
||||||
return this; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void commit() { |
|
||||||
transaction.commit(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,37 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.privacy; |
|
||||||
|
|
||||||
import org.hyperledger.besu.ethereum.core.Hash; |
|
||||||
import org.hyperledger.besu.util.bytes.Bytes32; |
|
||||||
import org.hyperledger.besu.util.bytes.BytesValue; |
|
||||||
|
|
||||||
import java.util.Optional; |
|
||||||
|
|
||||||
public interface PrivateStateStorage { |
|
||||||
|
|
||||||
Optional<Hash> getPrivateAccountState(BytesValue privacyId); |
|
||||||
|
|
||||||
boolean isWorldStateAvailable(Bytes32 rootHash); |
|
||||||
|
|
||||||
PrivateStateStorage.Updater updater(); |
|
||||||
|
|
||||||
interface Updater { |
|
||||||
|
|
||||||
PrivateStateStorage.Updater putPrivateAccountState(BytesValue privacyId, Hash privateStateHash); |
|
||||||
|
|
||||||
void commit(); |
|
||||||
} |
|
||||||
} |
|
@ -1,110 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.privacy; |
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8; |
|
||||||
|
|
||||||
import org.hyperledger.besu.ethereum.core.Log; |
|
||||||
import org.hyperledger.besu.ethereum.core.LogSeries; |
|
||||||
import org.hyperledger.besu.ethereum.rlp.RLP; |
|
||||||
import org.hyperledger.besu.plugin.services.storage.KeyValueStorage; |
|
||||||
import org.hyperledger.besu.plugin.services.storage.KeyValueStorageTransaction; |
|
||||||
import org.hyperledger.besu.util.bytes.Bytes32; |
|
||||||
import org.hyperledger.besu.util.bytes.BytesValue; |
|
||||||
import org.hyperledger.besu.util.bytes.BytesValues; |
|
||||||
|
|
||||||
import java.util.List; |
|
||||||
import java.util.Optional; |
|
||||||
|
|
||||||
public class PrivateTransactionKeyValueStorage implements PrivateTransactionStorage { |
|
||||||
|
|
||||||
private final KeyValueStorage keyValueStorage; |
|
||||||
|
|
||||||
private static final BytesValue EVENTS_KEY_SUFFIX = BytesValue.of("EVENTS".getBytes(UTF_8)); |
|
||||||
private static final BytesValue OUTPUT_KEY_SUFFIX = BytesValue.of("OUTPUT".getBytes(UTF_8)); |
|
||||||
|
|
||||||
public PrivateTransactionKeyValueStorage(final KeyValueStorage keyValueStorage) { |
|
||||||
this.keyValueStorage = keyValueStorage; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Optional<List<Log>> getEvents(final Bytes32 transactionHash) { |
|
||||||
return get(transactionHash, EVENTS_KEY_SUFFIX).map(this::rlpDecodeLog); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Optional<BytesValue> getOutput(final Bytes32 transactionHash) { |
|
||||||
return get(transactionHash, OUTPUT_KEY_SUFFIX); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isPrivateStateAvailable(final Bytes32 transactionHash) { |
|
||||||
return get(transactionHash, EVENTS_KEY_SUFFIX).isPresent() |
|
||||||
|| get(transactionHash, OUTPUT_KEY_SUFFIX).isPresent(); |
|
||||||
} |
|
||||||
|
|
||||||
private List<Log> rlpDecodeLog(final BytesValue bytes) { |
|
||||||
return RLP.input(bytes).readList(Log::readFrom); |
|
||||||
} |
|
||||||
|
|
||||||
private Optional<BytesValue> get(final BytesValue key, final BytesValue keySuffix) { |
|
||||||
return keyValueStorage |
|
||||||
.get(BytesValues.concatenate(key, keySuffix).getArrayUnsafe()) |
|
||||||
.map(BytesValue::wrap); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Updater updater() { |
|
||||||
return new Updater(keyValueStorage.startTransaction()); |
|
||||||
} |
|
||||||
|
|
||||||
public static class Updater implements PrivateTransactionStorage.Updater { |
|
||||||
|
|
||||||
private final KeyValueStorageTransaction transaction; |
|
||||||
|
|
||||||
private Updater(final KeyValueStorageTransaction transaction) { |
|
||||||
this.transaction = transaction; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public PrivateTransactionStorage.Updater putTransactionLogs( |
|
||||||
final Bytes32 transactionHash, final LogSeries logs) { |
|
||||||
set(transactionHash, EVENTS_KEY_SUFFIX, RLP.encode(logs::writeTo)); |
|
||||||
return this; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public PrivateTransactionStorage.Updater putTransactionResult( |
|
||||||
final Bytes32 transactionHash, final BytesValue events) { |
|
||||||
set(transactionHash, OUTPUT_KEY_SUFFIX, events); |
|
||||||
return this; |
|
||||||
} |
|
||||||
|
|
||||||
private void set(final BytesValue key, final BytesValue keySuffix, final BytesValue value) { |
|
||||||
transaction.put( |
|
||||||
BytesValues.concatenate(key, keySuffix).getArrayUnsafe(), value.getArrayUnsafe()); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void commit() { |
|
||||||
transaction.commit(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void rollback() { |
|
||||||
transaction.rollback(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,160 @@ |
|||||||
|
/* |
||||||
|
* 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.privacy.storage; |
||||||
|
|
||||||
|
import static java.nio.charset.StandardCharsets.UTF_8; |
||||||
|
|
||||||
|
import org.hyperledger.besu.ethereum.core.Hash; |
||||||
|
import org.hyperledger.besu.ethereum.core.Log; |
||||||
|
import org.hyperledger.besu.ethereum.core.LogSeries; |
||||||
|
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput; |
||||||
|
import org.hyperledger.besu.ethereum.rlp.RLP; |
||||||
|
import org.hyperledger.besu.plugin.services.storage.KeyValueStorage; |
||||||
|
import org.hyperledger.besu.plugin.services.storage.KeyValueStorageTransaction; |
||||||
|
import org.hyperledger.besu.util.bytes.Bytes32; |
||||||
|
import org.hyperledger.besu.util.bytes.BytesValue; |
||||||
|
import org.hyperledger.besu.util.bytes.BytesValues; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.Optional; |
||||||
|
|
||||||
|
public class PrivateStateKeyValueStorage implements PrivateStateStorage { |
||||||
|
|
||||||
|
@Deprecated |
||||||
|
private static final BytesValue EVENTS_KEY_SUFFIX = BytesValue.of("EVENTS".getBytes(UTF_8)); |
||||||
|
|
||||||
|
private static final BytesValue LOGS_KEY_SUFFIX = BytesValue.of("LOGS".getBytes(UTF_8)); |
||||||
|
private static final BytesValue OUTPUT_KEY_SUFFIX = BytesValue.of("OUTPUT".getBytes(UTF_8)); |
||||||
|
private static final BytesValue METADATA_KEY_SUFFIX = BytesValue.of("METADATA".getBytes(UTF_8)); |
||||||
|
|
||||||
|
private final KeyValueStorage keyValueStorage; |
||||||
|
|
||||||
|
public PrivateStateKeyValueStorage(final KeyValueStorage keyValueStorage) { |
||||||
|
this.keyValueStorage = keyValueStorage; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Optional<Hash> getLatestStateRoot(final BytesValue privacyId) { |
||||||
|
final byte[] id = privacyId.getArrayUnsafe(); |
||||||
|
|
||||||
|
if (keyValueStorage.get(id).isPresent()) { |
||||||
|
return Optional.of(Hash.wrap(Bytes32.wrap(keyValueStorage.get(id).get()))); |
||||||
|
} else { |
||||||
|
return Optional.empty(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Optional<List<Log>> getTransactionLogs(final Bytes32 transactionHash) { |
||||||
|
final Optional<List<Log>> logs = get(transactionHash, LOGS_KEY_SUFFIX).map(this::rlpDecodeLog); |
||||||
|
if (logs.isEmpty()) { |
||||||
|
return get(transactionHash, EVENTS_KEY_SUFFIX).map(this::rlpDecodeLog); |
||||||
|
} |
||||||
|
return logs; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Optional<BytesValue> getTransactionOutput(final Bytes32 transactionHash) { |
||||||
|
return get(transactionHash, OUTPUT_KEY_SUFFIX); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Optional<PrivateTransactionMetadata> getTransactionMetadata( |
||||||
|
final Bytes32 blockHash, final Bytes32 transactionHash) { |
||||||
|
return get(BytesValues.concatenate(blockHash, transactionHash), METADATA_KEY_SUFFIX) |
||||||
|
.map( |
||||||
|
bytesValue -> |
||||||
|
PrivateTransactionMetadata.readFrom(new BytesValueRLPInput(bytesValue, false))); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isPrivateStateAvailable(final Bytes32 transactionHash) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isWorldStateAvailable(final Bytes32 rootHash) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private Optional<BytesValue> get(final BytesValue key, final BytesValue keySuffix) { |
||||||
|
return keyValueStorage |
||||||
|
.get(BytesValues.concatenate(key, keySuffix).getArrayUnsafe()) |
||||||
|
.map(BytesValue::wrap); |
||||||
|
} |
||||||
|
|
||||||
|
private List<Log> rlpDecodeLog(final BytesValue bytes) { |
||||||
|
return RLP.input(bytes).readList(Log::readFrom); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public PrivateStateStorage.Updater updater() { |
||||||
|
return new PrivateStateKeyValueStorage.Updater(keyValueStorage.startTransaction()); |
||||||
|
} |
||||||
|
|
||||||
|
public static class Updater implements PrivateStateStorage.Updater { |
||||||
|
|
||||||
|
private final KeyValueStorageTransaction transaction; |
||||||
|
|
||||||
|
private Updater(final KeyValueStorageTransaction transaction) { |
||||||
|
this.transaction = transaction; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Updater putLatestStateRoot(final BytesValue privacyId, final Hash privateStateHash) { |
||||||
|
transaction.put(privacyId.getArrayUnsafe(), privateStateHash.extractArray()); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Updater putTransactionLogs(final Bytes32 transactionHash, final LogSeries logs) { |
||||||
|
set(transactionHash, LOGS_KEY_SUFFIX, RLP.encode(logs::writeTo)); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Updater putTransactionResult(final Bytes32 transactionHash, final BytesValue events) { |
||||||
|
set(transactionHash, OUTPUT_KEY_SUFFIX, events); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Updater putTransactionMetadata( |
||||||
|
final Bytes32 blockHash, |
||||||
|
final Bytes32 transactionHash, |
||||||
|
final PrivateTransactionMetadata metadata) { |
||||||
|
set( |
||||||
|
BytesValues.concatenate(blockHash, transactionHash), |
||||||
|
METADATA_KEY_SUFFIX, |
||||||
|
RLP.encode(metadata::writeTo)); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void commit() { |
||||||
|
transaction.commit(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void rollback() { |
||||||
|
transaction.rollback(); |
||||||
|
} |
||||||
|
|
||||||
|
private void set(final BytesValue key, final BytesValue keySuffix, final BytesValue value) { |
||||||
|
transaction.put( |
||||||
|
BytesValues.concatenate(key, keySuffix).getArrayUnsafe(), value.getArrayUnsafe()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,50 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2019 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.privacy.storage; |
||||||
|
|
||||||
|
import org.hyperledger.besu.ethereum.core.Hash; |
||||||
|
import org.hyperledger.besu.ethereum.rlp.RLPInput; |
||||||
|
import org.hyperledger.besu.ethereum.rlp.RLPOutput; |
||||||
|
|
||||||
|
/** Mined private transaction metadata. */ |
||||||
|
public class PrivateTransactionMetadata { |
||||||
|
private final Hash stateRoot; |
||||||
|
|
||||||
|
public PrivateTransactionMetadata(final Hash stateRoot) { |
||||||
|
this.stateRoot = stateRoot; |
||||||
|
} |
||||||
|
|
||||||
|
public Hash getStateRoot() { |
||||||
|
return stateRoot; |
||||||
|
} |
||||||
|
|
||||||
|
public void writeTo(final RLPOutput out) { |
||||||
|
out.startList(); |
||||||
|
|
||||||
|
out.writeBytesValue(stateRoot); |
||||||
|
|
||||||
|
out.endList(); |
||||||
|
} |
||||||
|
|
||||||
|
public static PrivateTransactionMetadata readFrom(final RLPInput input) { |
||||||
|
input.enterList(); |
||||||
|
|
||||||
|
final PrivateTransactionMetadata privateTransactionMetadata = |
||||||
|
new PrivateTransactionMetadata(Hash.wrap(input.readBytes32())); |
||||||
|
|
||||||
|
input.leaveList(); |
||||||
|
return privateTransactionMetadata; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue