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