Skip to content

Commit

Permalink
Merge pull request #4 from ghareeb-falazi/use-doc
Browse files Browse the repository at this point in the history
Use Degree-of-Confidence finality measure instead of block-confirmations
  • Loading branch information
ghareeb-falazi authored Oct 14, 2019
2 parents dc17fda + fd58c90 commit b7810e9
Show file tree
Hide file tree
Showing 13 changed files with 97 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import blockchains.iaas.uni.stuttgart.de.adaptation.BlockchainAdapterFactory;
import blockchains.iaas.uni.stuttgart.de.adaptation.adapters.AbstractAdapter;
import blockchains.iaas.uni.stuttgart.de.adaptation.utils.PoWConfidenceCalculator;
import blockchains.iaas.uni.stuttgart.de.exceptions.BlockchainNodeUnreachableException;
import blockchains.iaas.uni.stuttgart.de.exceptions.InvalidTransactionException;
import blockchains.iaas.uni.stuttgart.de.model.Block;
Expand Down Expand Up @@ -184,11 +185,12 @@ public void blockDetected(com.neemre.btcdcli4j.core.domain.Block block) {
}

@Override
public CompletableFuture<Transaction> submitTransaction(long waitFor, String receiverAddress, BigDecimal value) throws InvalidTransactionException {
public CompletableFuture<Transaction> submitTransaction(String receiverAddress, BigDecimal value, double requiredConfidence) throws InvalidTransactionException {
try {
final BigDecimal valueBitcoins = BitcoinUtils.satoshiToBitcoin(value);
final String transactionId = client.sendToAddress(receiverAddress, valueBitcoins);
CompletableFuture<Transaction> result;
long waitFor = ((PoWConfidenceCalculator) this.confidenceCalculator).getEquivalentBlockDepth(requiredConfidence);

if (waitFor > 0) {
result = subscribeForTxEvent(transactionId, waitFor, TransactionState.NOT_FOUND, TransactionState.CONFIRMED);
Expand All @@ -209,9 +211,10 @@ public CompletableFuture<Transaction> submitTransaction(long waitFor, String rec
}

@Override
public Observable<Transaction> receiveTransactions(long waitFor, String senderId) {
public Observable<Transaction> receiveTransactions(String senderId, double requiredConfidence) {

final PublishSubject<Transaction> subject = PublishSubject.create();
long waitFor = ((PoWConfidenceCalculator) this.confidenceCalculator).getEquivalentBlockDepth(requiredConfidence);
final WalletListener listener = new WalletListener() {
@Override
public void walletChanged(com.neemre.btcdcli4j.core.domain.Transaction transaction) {
Expand Down Expand Up @@ -252,7 +255,8 @@ public void walletChanged(com.neemre.btcdcli4j.core.domain.Transaction transacti
}

@Override
public CompletableFuture<TransactionState> ensureTransactionState(long waitFor, String transactionId) {
public CompletableFuture<TransactionState> ensureTransactionState(String transactionId, double requiredConfidence) {
long waitFor = ((PoWConfidenceCalculator) this.confidenceCalculator).getEquivalentBlockDepth(requiredConfidence);
return subscribeForTxEvent(transactionId, waitFor, TransactionState.NOT_FOUND, TransactionState.CONFIRMED)
.thenApply(Transaction::getState);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,15 @@ else if (e.getCause() instanceof RuntimeException)
}

@Override
public CompletableFuture<Transaction> submitTransaction(long waitFor, String receiverAddress, BigDecimal value)
public CompletableFuture<Transaction> submitTransaction(String receiverAddress, BigDecimal value, double requiredConfidence)
throws InvalidTransactionException {
if (credentials == null) {
log.error("Credentials are not set for the Ethereum user");
throw new NullPointerException("Credentials are not set for the Ethereum user");
}

try {
final long waitFor = ((PoWConfidenceCalculator)this.confidenceCalculator).getEquivalentBlockDepth(requiredConfidence);
return Transfer.sendFunds(web3j, credentials, receiverAddress, value, Convert.Unit.WEI) // 1 wei = 10^-18 Ether
.sendAsync()
// when an exception (e.g., ConnectException happens), the following is skipped
Expand All @@ -200,12 +201,13 @@ public CompletableFuture<Transaction> submitTransaction(long waitFor, String rec
}

@Override
public Observable<Transaction> receiveTransactions(long waitFor, String senderId) {
public Observable<Transaction> receiveTransactions(String senderId, double requiredConfidence) {
if (credentials == null) {
log.error("Credentials are not set for the Ethereum user");
throw new NullPointerException("Credentials are not set for the Ethereum user");
}

final long waitFor = ((PoWConfidenceCalculator)this.confidenceCalculator).getEquivalentBlockDepth(requiredConfidence);
final String myAddress = credentials.getAddress();
final PublishSubject<Transaction> result = PublishSubject.create();
final Disposable newTransactionObservable = web3j.transactionFlowable().subscribe(tx -> {
Expand All @@ -226,7 +228,8 @@ public Observable<Transaction> receiveTransactions(long waitFor, String senderId
}

@Override
public CompletableFuture<TransactionState> ensureTransactionState(long waitFor, String transactionId) {
public CompletableFuture<TransactionState> ensureTransactionState(String transactionId, double requiredConfidence) {
final long waitFor = ((PoWConfidenceCalculator)this.confidenceCalculator).getEquivalentBlockDepth(requiredConfidence);
// only monitor the transition into the CONFIRMED state or the NOT_FOUND state
return subscribeForTxEvent(transactionId, waitFor, TransactionState.CONFIRMED, TransactionState.NOT_FOUND)
.thenApply(Transaction::getState)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,21 @@ public void setConnectionProfilePath(String connectionProfilePath) {
}

@Override
public CompletableFuture<Transaction> submitTransaction(long waitFor, String receiverAddress, BigDecimal value) throws InvalidTransactionException, MethodNotSupportedException {
public CompletableFuture<Transaction> submitTransaction(String receiverAddress, BigDecimal value, double requiredConfidence



) throws InvalidTransactionException, MethodNotSupportedException {
throw new MethodNotSupportedException("Fabric does not support submitting monetary transactions!");
}

@Override
public Observable<Transaction> receiveTransactions(long waitFor, String senderId) throws MethodNotSupportedException {
public Observable<Transaction> receiveTransactions(String senderId, double requiredConfidence) throws MethodNotSupportedException {
throw new MethodNotSupportedException("Fabric does not support receiving monetary transactions!");
}

@Override
public CompletableFuture<TransactionState> ensureTransactionState(long waitFor, String transactionId) throws MethodNotSupportedException {
public CompletableFuture<TransactionState> ensureTransactionState(String transactionId, double requiredConfidence) throws MethodNotSupportedException {
throw new MethodNotSupportedException("Fabric does not support monetary transactions!");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import blockchains.iaas.uni.stuttgart.de.exceptions.InvalidTransactionException;
import blockchains.iaas.uni.stuttgart.de.model.SmartContractFunctionArgument;
import blockchains.iaas.uni.stuttgart.de.model.LinearChainTransaction;
import blockchains.iaas.uni.stuttgart.de.model.Transaction;
import blockchains.iaas.uni.stuttgart.de.model.TransactionState;
import io.reactivex.Observable;
Expand All @@ -27,9 +26,9 @@ public interface BlockchainAdapter {
/**
* submits a transaction to the blockchain that transfers an amount of the native crypto-currency to some address.
*
* @param waitFor the number of block-confirmations to receive before emitting a result
* @param receiverAddress the address of the receiver
* @param value the value to transfer measured in the most granular unit, e.g., wei, satoshi
* @param requiredConfidence the degree-of-confidence required to be achieved before sending a callback message to the invoker.
* @param receiverAddress the address of the receiver
* @param value the value to transfer measured in the most granular unit, e.g., wei, satoshi
* @return a completable future that emits a summary of the submitted transaction.
* The future should normally complete with a transaction of the state CONFIRMED if the desired number of block-confirmations were received,
* and with a transaction of the state NOT_FOUND if the transaction was committed to a block and then orphaned and invalidated.
Expand All @@ -38,27 +37,27 @@ public interface BlockchainAdapter {
* @throws InvalidTransactionException if the submitted transaction causes an immediate validation error, e.g.,
* insufficient funds, or incorrect receiverAddress (this seems to never be thrown)
*/
CompletableFuture<Transaction> submitTransaction(long waitFor, String receiverAddress, BigDecimal value) throws InvalidTransactionException, MethodNotSupportedException;
CompletableFuture<Transaction> submitTransaction(String receiverAddress, BigDecimal value, double requiredConfidence) throws InvalidTransactionException, MethodNotSupportedException;

/**
* receives transactions addressed to us (potentially from a specific sender)
*
* @param waitFor the number of block-confirmations to be detected before emitting a result
* @param senderId an optional address of the sender. If specified, only transactions from this sender are considered
* @param requiredConfidence the degree-of-confidence required to be achieved before sending a callback message to the invoker.
* @param senderId an optional address of the sender. If specified, only transactions from this sender are considered
* @return an observable that emits a summary of the received transaction whenever one is detected
*/
Observable<Transaction> receiveTransactions(long waitFor, String senderId) throws MethodNotSupportedException;
Observable<Transaction> receiveTransactions(String senderId, double requiredConfidence) throws MethodNotSupportedException;

/**
* ensures that a transaction receives enough block-confirmations
*
* @param waitFor the number of block-confirmations to be detected before considering the transaction to be confirmed
* @param transactionId the hash of the transaction we want to monitor
* @param requiredConfidence the degree-of-confidence required to be achieved before sending a callback message to the invoker.
* @param transactionId the hash of the transaction we want to monitor
* @return a completable future that emits the new state of the transaction (either COFIRMED in case the desired
* number of block-confirmations got received, or NOT_FOUND if the transaction got invalidated).
* The future should exceptionally complete with an exception of type BlockchainNodeUnreachableException if the blockchain node is not reachable
*/
CompletableFuture<TransactionState> ensureTransactionState(long waitFor, String transactionId) throws MethodNotSupportedException;
CompletableFuture<TransactionState> ensureTransactionState(String transactionId, double requiredConfidence) throws MethodNotSupportedException;

/**
* detects that the given transaction got orphaned
Expand All @@ -70,5 +69,14 @@ public interface BlockchainAdapter {
*/
CompletableFuture<TransactionState> detectOrphanedTransaction(String transactionId) throws MethodNotSupportedException;

/**
* invokes a smart contract function
*
* @param functionIdentifier the scip identifier of the function to be invoked
* @param parameters the arguments to be passed to the function being invoked
* @param requiredConfidence the degree-of-confidence required to be achieved before sending a callback message to the invoker.
* @return a completable future that emits a new transaction object holding the result of the invocation.
* @throws MethodNotSupportedException if the underlying blockchain system does not support smart contracts.
*/
CompletableFuture<Transaction> invokeSmartContract(String functionIdentifier, List<SmartContractFunctionArgument> parameters, double requiredConfidence) throws MethodNotSupportedException;
}
Loading

0 comments on commit b7810e9

Please sign in to comment.