-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13 from ketola/admission_control_layer
Admission control layer
- Loading branch information
Showing
16 changed files
with
433 additions
and
119 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
149 changes: 149 additions & 0 deletions
149
src/main/java/dev/jlibra/admissioncontrol/AdmissionControl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
package dev.jlibra.admissioncontrol; | ||
|
||
import static java.util.stream.Collectors.toList; | ||
|
||
import java.io.IOException; | ||
import java.security.PrivateKey; | ||
import java.security.PublicKey; | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import com.google.protobuf.ByteString; | ||
|
||
import admission_control.AdmissionControlGrpc; | ||
import admission_control.AdmissionControlGrpc.AdmissionControlBlockingStub; | ||
import admission_control.AdmissionControlOuterClass.SubmitTransactionRequest; | ||
import admission_control.AdmissionControlOuterClass.SubmitTransactionResponse; | ||
import dev.jlibra.AccountState; | ||
import dev.jlibra.KeyUtils; | ||
import dev.jlibra.LibraHelper; | ||
import dev.jlibra.admissioncontrol.query.GetAccountState; | ||
import dev.jlibra.admissioncontrol.query.UpdateToLatestLedgerResult; | ||
import dev.jlibra.admissioncontrol.transaction.SubmitTransactionResult; | ||
import dev.jlibra.admissioncontrol.transaction.Transaction; | ||
import dev.jlibra.admissioncontrol.transaction.TransactionArgument.Type; | ||
import io.grpc.ManagedChannel; | ||
import io.grpc.ManagedChannelBuilder; | ||
import types.GetWithProof.GetAccountStateRequest; | ||
import types.GetWithProof.RequestItem; | ||
import types.GetWithProof.UpdateToLatestLedgerRequest; | ||
import types.GetWithProof.UpdateToLatestLedgerResponse; | ||
import types.Transaction.Program; | ||
import types.Transaction.RawTransaction; | ||
import types.Transaction.SignedTransaction; | ||
import types.Transaction.TransactionArgument; | ||
import types.Transaction.TransactionArgument.ArgType; | ||
|
||
public class AdmissionControl { | ||
|
||
private String host; | ||
|
||
private int port; | ||
|
||
public AdmissionControl(String host, int port) { | ||
this.host = host; | ||
this.port = port; | ||
} | ||
|
||
private static Map<Type, ArgType> jlibraArgumentTypeToGrpcArgumentType; | ||
|
||
static { | ||
jlibraArgumentTypeToGrpcArgumentType = new HashMap<>(); | ||
jlibraArgumentTypeToGrpcArgumentType.put(Type.ADDRESS, ArgType.ADDRESS); | ||
jlibraArgumentTypeToGrpcArgumentType.put(Type.U64, ArgType.U64); | ||
} | ||
|
||
public SubmitTransactionResult submitTransaction(PublicKey publicKey, PrivateKey privateKey, | ||
Transaction transaction) { | ||
|
||
ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port) | ||
.usePlaintext() | ||
.build(); | ||
|
||
AdmissionControlBlockingStub stub = AdmissionControlGrpc.newBlockingStub(channel); | ||
|
||
List<TransactionArgument> transactionArguments = transaction.getProgram().getArguments().stream() | ||
.map(txArgument -> TransactionArgument.newBuilder() | ||
.setType(jlibraArgumentTypeToGrpcArgumentType.get(txArgument.type())) | ||
.setData(ByteString.copyFrom(txArgument.toByteArray())) | ||
.build()) | ||
.collect(toList()); | ||
|
||
Program program = Program.newBuilder() | ||
.addAllArguments(transactionArguments) | ||
.setCode(readCodeFromStream(transaction)) | ||
.addAllModules(new ArrayList<ByteString>()) | ||
.build(); | ||
|
||
RawTransaction rawTransaction = RawTransaction.newBuilder() | ||
.setProgram(program) | ||
.setExpirationTime(transaction.getExpirationTime()) | ||
.setGasUnitPrice(transaction.getGasUnitPrice()) | ||
.setMaxGasAmount(transaction.getMaxGasAmount()) | ||
.setSenderAccount(ByteString.copyFrom(KeyUtils.toByteArrayLibraAddress(publicKey.getEncoded()))) | ||
.setSequenceNumber(transaction.getSequenceNumber()) | ||
.build(); | ||
|
||
SignedTransaction signedTransaction = SignedTransaction.newBuilder() | ||
.setRawTxnBytes(rawTransaction.toByteString()) | ||
.setSenderPublicKey(ByteString.copyFrom(KeyUtils.stripPublicKeyPrefix(publicKey.getEncoded()))) | ||
.setSenderSignature(ByteString.copyFrom(LibraHelper.signTransaction(rawTransaction, privateKey))) | ||
.build(); | ||
|
||
SubmitTransactionRequest submitTransactionRequest = SubmitTransactionRequest.newBuilder() | ||
.setSignedTxn(signedTransaction) | ||
.build(); | ||
|
||
SubmitTransactionResponse response = stub.submitTransaction(submitTransactionRequest); | ||
|
||
channel.shutdown(); | ||
|
||
return new SubmitTransactionResult(response.getAcStatus(), response.getMempoolStatus(), response.getVmStatus()); | ||
} | ||
|
||
private ByteString readCodeFromStream(Transaction transaction) { | ||
try { | ||
return ByteString.readFrom(transaction.getProgram().getCode()); | ||
} catch (IOException e) { | ||
throw new RuntimeException("Could not read move code from input stream", e); | ||
} | ||
} | ||
|
||
public UpdateToLatestLedgerResult updateToLatestLedger(List<GetAccountState> arguments) { | ||
ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port) | ||
.usePlaintext() | ||
.build(); | ||
|
||
AdmissionControlBlockingStub stub = AdmissionControlGrpc.newBlockingStub(channel); | ||
|
||
List<RequestItem> requestItems = arguments.stream().map(argument -> { | ||
GetAccountStateRequest getAccountStateRequest = GetAccountStateRequest.newBuilder() | ||
.setAddress(ByteString.copyFrom(argument.getAddress())) | ||
.build(); | ||
|
||
RequestItem requestItem = RequestItem.newBuilder() | ||
.setGetAccountStateRequest(getAccountStateRequest) | ||
.build(); | ||
return requestItem; | ||
}).collect(toList()); | ||
|
||
UpdateToLatestLedgerResponse response = stub.updateToLatestLedger(UpdateToLatestLedgerRequest.newBuilder() | ||
.addAllRequestedItems(requestItems) | ||
.build()); | ||
|
||
List<AccountState> accountStates = new ArrayList<>(); | ||
|
||
response.getResponseItemsList().forEach(responseItem -> { | ||
accountStates.addAll(LibraHelper.readAccountStates(responseItem.getGetAccountStateResponse() | ||
.getAccountStateWithProof())); | ||
}); | ||
|
||
UpdateToLatestLedgerResult result = UpdateToLatestLedgerResult.create() | ||
.withAccountStates(accountStates); | ||
|
||
return result; | ||
} | ||
|
||
} |
13 changes: 13 additions & 0 deletions
13
src/main/java/dev/jlibra/admissioncontrol/query/GetAccountState.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package dev.jlibra.admissioncontrol.query; | ||
|
||
public class GetAccountState { | ||
private byte[] address; | ||
|
||
public GetAccountState(byte[] address) { | ||
this.address = address; | ||
} | ||
|
||
public byte[] getAddress() { | ||
return address; | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/main/java/dev/jlibra/admissioncontrol/query/UpdateToLatestLedgerResult.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package dev.jlibra.admissioncontrol.query; | ||
|
||
import java.util.List; | ||
|
||
import dev.jlibra.AccountState; | ||
|
||
public class UpdateToLatestLedgerResult { | ||
|
||
private List<AccountState> accountStates; | ||
|
||
private UpdateToLatestLedgerResult() { | ||
} | ||
|
||
public static UpdateToLatestLedgerResult create() { | ||
return new UpdateToLatestLedgerResult(); | ||
} | ||
|
||
public UpdateToLatestLedgerResult withAccountStates(List<AccountState> accountStates) { | ||
this.accountStates = accountStates; | ||
return this; | ||
} | ||
|
||
public List<AccountState> getAccountStates() { | ||
return accountStates; | ||
} | ||
|
||
} |
21 changes: 21 additions & 0 deletions
21
src/main/java/dev/jlibra/admissioncontrol/transaction/AddressArgument.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package dev.jlibra.admissioncontrol.transaction; | ||
|
||
public class AddressArgument implements TransactionArgument { | ||
|
||
private byte[] address; | ||
|
||
public AddressArgument(byte[] address) { | ||
this.address = address; | ||
} | ||
|
||
@Override | ||
public byte[] toByteArray() { | ||
return address; | ||
} | ||
|
||
@Override | ||
public Type type() { | ||
return Type.ADDRESS; | ||
} | ||
|
||
} |
25 changes: 25 additions & 0 deletions
25
src/main/java/dev/jlibra/admissioncontrol/transaction/Program.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package dev.jlibra.admissioncontrol.transaction; | ||
|
||
import java.io.InputStream; | ||
import java.util.List; | ||
|
||
public class Program { | ||
|
||
private InputStream code; | ||
|
||
private List<TransactionArgument> arguments; | ||
|
||
public Program(InputStream code, List<TransactionArgument> arguments) { | ||
this.code = code; | ||
this.arguments = arguments; | ||
} | ||
|
||
public InputStream getCode() { | ||
return code; | ||
} | ||
|
||
public List<TransactionArgument> getArguments() { | ||
return arguments; | ||
} | ||
|
||
} |
38 changes: 38 additions & 0 deletions
38
src/main/java/dev/jlibra/admissioncontrol/transaction/SubmitTransactionResult.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package dev.jlibra.admissioncontrol.transaction; | ||
|
||
import admission_control.AdmissionControlOuterClass.AdmissionControlStatus; | ||
import mempool.MempoolStatus; | ||
import types.VmErrors.VMStatus; | ||
|
||
public class SubmitTransactionResult { | ||
|
||
// TODO: Create own enum types instead of putting grpc enums directly here | ||
// Could also add the description texts for clearer errors | ||
|
||
private AdmissionControlStatus admissionControlStatus; | ||
|
||
private MempoolStatus.MempoolAddTransactionStatus mempoolStatus; | ||
|
||
private VMStatus vmStatus; | ||
|
||
public SubmitTransactionResult(AdmissionControlStatus admissionControlStatus, | ||
MempoolStatus.MempoolAddTransactionStatus mempoolStatus, | ||
VMStatus vmStatus) { | ||
this.admissionControlStatus = admissionControlStatus; | ||
this.mempoolStatus = mempoolStatus; | ||
this.vmStatus = vmStatus; | ||
} | ||
|
||
public AdmissionControlStatus getAdmissionControlStatus() { | ||
return admissionControlStatus; | ||
} | ||
|
||
public MempoolStatus.MempoolAddTransactionStatus getMempoolStatus() { | ||
return mempoolStatus; | ||
} | ||
|
||
public VMStatus getVmStatus() { | ||
return vmStatus; | ||
} | ||
|
||
} |
67 changes: 67 additions & 0 deletions
67
src/main/java/dev/jlibra/admissioncontrol/transaction/Transaction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package dev.jlibra.admissioncontrol.transaction; | ||
|
||
public class Transaction { | ||
|
||
private long sequenceNumber; | ||
|
||
private Program program; | ||
|
||
private long expirationTime; | ||
|
||
private long gasUnitPrice; | ||
|
||
private long maxGasAmount; | ||
|
||
private Transaction() { | ||
} | ||
|
||
public static Transaction create() { | ||
return new Transaction(); | ||
} | ||
|
||
public Transaction withProgram(Program program) { | ||
this.program = program; | ||
return this; | ||
} | ||
|
||
public Transaction withSequenceNumber(long sequenceNumber) { | ||
this.sequenceNumber = sequenceNumber; | ||
return this; | ||
} | ||
|
||
public Transaction withExpirationTime(long expirationTime) { | ||
this.expirationTime = expirationTime; | ||
return this; | ||
} | ||
|
||
public Transaction withGasUnitPrice(long gasUnitPrice) { | ||
this.gasUnitPrice = gasUnitPrice; | ||
return this; | ||
} | ||
|
||
public Transaction withMaxGasAmount(long maxGasAmount) { | ||
this.maxGasAmount = maxGasAmount; | ||
return this; | ||
} | ||
|
||
public long getSequenceNumber() { | ||
return sequenceNumber; | ||
} | ||
|
||
public Program getProgram() { | ||
return program; | ||
} | ||
|
||
public long getExpirationTime() { | ||
return expirationTime; | ||
} | ||
|
||
public long getGasUnitPrice() { | ||
return gasUnitPrice; | ||
} | ||
|
||
public long getMaxGasAmount() { | ||
return maxGasAmount; | ||
} | ||
|
||
} |
13 changes: 13 additions & 0 deletions
13
src/main/java/dev/jlibra/admissioncontrol/transaction/TransactionArgument.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package dev.jlibra.admissioncontrol.transaction; | ||
|
||
public interface TransactionArgument { | ||
|
||
public enum Type { | ||
U64, ADDRESS | ||
} | ||
|
||
byte[] toByteArray(); | ||
|
||
Type type(); | ||
|
||
} |
Oops, something went wrong.