Skip to content

Commit

Permalink
Merge pull request #2299 from rsksmart/abi-call-refactors-integration
Browse files Browse the repository at this point in the history
Abi call refactors integration
  • Loading branch information
josedahlquist authored May 3, 2024
2 parents e97ce77 + f03f097 commit a61e908
Showing 25 changed files with 162 additions and 144 deletions.
2 changes: 1 addition & 1 deletion rskj-core/src/main/java/co/rsk/config/BridgeConstants.java
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@
import co.rsk.bitcoinj.core.BtcECKey;
import co.rsk.bitcoinj.core.Coin;
import co.rsk.bitcoinj.core.NetworkParameters;
import co.rsk.peg.AddressBasedAuthorizer;
import co.rsk.peg.vote.AddressBasedAuthorizer;
import co.rsk.peg.federation.Federation;
import java.util.List;

Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@
import co.rsk.bitcoinj.core.BtcECKey;
import co.rsk.bitcoinj.core.Coin;
import co.rsk.bitcoinj.core.NetworkParameters;
import co.rsk.peg.AddressBasedAuthorizer;
import co.rsk.peg.vote.AddressBasedAuthorizer;
import co.rsk.peg.federation.FederationArgs;
import co.rsk.peg.federation.FederationMember;
import co.rsk.peg.federation.FederationFactory;
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
import co.rsk.bitcoinj.core.BtcECKey;
import co.rsk.bitcoinj.core.Coin;
import co.rsk.bitcoinj.core.NetworkParameters;
import co.rsk.peg.AddressBasedAuthorizer;
import co.rsk.peg.vote.AddressBasedAuthorizer;
import co.rsk.peg.federation.FederationArgs;
import co.rsk.peg.federation.FederationMember;
import co.rsk.peg.federation.FederationFactory;
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@
import co.rsk.bitcoinj.core.BtcECKey;
import co.rsk.bitcoinj.core.Coin;
import co.rsk.bitcoinj.core.NetworkParameters;
import co.rsk.peg.AddressBasedAuthorizer;
import co.rsk.peg.vote.AddressBasedAuthorizer;
import co.rsk.peg.federation.FederationArgs;
import co.rsk.peg.federation.FederationMember;
import co.rsk.peg.federation.FederationFactory;
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@
import co.rsk.bitcoinj.core.BtcECKey;
import co.rsk.bitcoinj.core.Coin;
import co.rsk.bitcoinj.core.NetworkParameters;
import co.rsk.peg.AddressBasedAuthorizer;
import co.rsk.peg.vote.AddressBasedAuthorizer;
import co.rsk.peg.federation.FederationArgs;
import co.rsk.peg.federation.FederationMember;
import co.rsk.peg.federation.FederationFactory;
1 change: 1 addition & 0 deletions rskj-core/src/main/java/co/rsk/peg/Bridge.java
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@
import co.rsk.crypto.Keccak256;
import co.rsk.panic.PanicProcessor;
import co.rsk.peg.BridgeMethods.BridgeMethodExecutor;
import co.rsk.peg.vote.ABICallSpec;
import co.rsk.peg.bitcoin.MerkleBranch;
import co.rsk.peg.federation.Federation;
import co.rsk.peg.federation.FederationMember;
Original file line number Diff line number Diff line change
@@ -23,9 +23,12 @@
import co.rsk.config.BridgeConstants;
import co.rsk.core.RskAddress;
import co.rsk.crypto.Keccak256;
import co.rsk.peg.vote.ABICallElection;
import co.rsk.peg.vote.ABICallSpec;
import co.rsk.peg.bitcoin.CoinbaseInformation;
import co.rsk.peg.federation.*;
import co.rsk.peg.flyover.FlyoverFederationInformation;
import co.rsk.peg.vote.AddressBasedAuthorizer;
import co.rsk.peg.whitelist.OneOffWhiteListEntry;
import co.rsk.peg.whitelist.UnlimitedWhiteListEntry;
import org.apache.commons.lang3.tuple.Pair;
2 changes: 2 additions & 0 deletions rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java
Original file line number Diff line number Diff line change
@@ -23,10 +23,12 @@
import co.rsk.config.BridgeConstants;
import co.rsk.core.RskAddress;
import co.rsk.crypto.Keccak256;
import co.rsk.peg.vote.ABICallElection;
import co.rsk.peg.bitcoin.CoinbaseInformation;
import co.rsk.peg.federation.Federation;
import co.rsk.peg.federation.PendingFederation;
import co.rsk.peg.flyover.FlyoverFederationInformation;
import co.rsk.peg.vote.AddressBasedAuthorizer;
import co.rsk.peg.whitelist.LockWhitelist;
import co.rsk.peg.whitelist.LockWhitelistEntry;
import co.rsk.peg.whitelist.OneOffWhiteListEntry;
80 changes: 18 additions & 62 deletions rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java
Original file line number Diff line number Diff line change
@@ -20,91 +20,45 @@
import static co.rsk.peg.BridgeUtils.getRegularPegoutTxSize;
import static co.rsk.peg.ReleaseTransactionBuilder.BTC_TX_VERSION_2;
import static co.rsk.peg.pegin.RejectedPeginReason.INVALID_AMOUNT;
import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP186;
import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP219;
import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP271;
import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP293;
import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP294;
import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP377;

import co.rsk.bitcoinj.core.Address;
import co.rsk.bitcoinj.core.AddressFormatException;
import co.rsk.bitcoinj.core.BtcBlock;
import co.rsk.bitcoinj.core.BtcBlockChain;
import co.rsk.bitcoinj.core.BtcECKey;
import co.rsk.bitcoinj.core.BtcTransaction;
import co.rsk.bitcoinj.core.CheckpointManager;
import co.rsk.bitcoinj.core.Coin;
import co.rsk.bitcoinj.core.Context;
import co.rsk.bitcoinj.core.InsufficientMoneyException;
import co.rsk.bitcoinj.core.NetworkParameters;
import co.rsk.bitcoinj.core.PartialMerkleTree;
import co.rsk.bitcoinj.core.Sha256Hash;
import co.rsk.bitcoinj.core.StoredBlock;
import co.rsk.bitcoinj.core.TransactionInput;
import co.rsk.bitcoinj.core.TransactionOutput;
import co.rsk.bitcoinj.core.UTXO;
import co.rsk.bitcoinj.core.UTXOProviderException;
import co.rsk.bitcoinj.core.VerificationException;
import static org.ethereum.config.blockchain.upgrades.ConsensusRule.*;

import co.rsk.bitcoinj.core.*;
import co.rsk.bitcoinj.crypto.TransactionSignature;
import co.rsk.bitcoinj.script.FastBridgeRedeemScriptParser;
import co.rsk.bitcoinj.script.Script;
import co.rsk.bitcoinj.script.ScriptBuilder;
import co.rsk.bitcoinj.script.ScriptChunk;
import co.rsk.bitcoinj.script.*;
import co.rsk.bitcoinj.store.BlockStoreException;
import co.rsk.bitcoinj.wallet.SendRequest;
import co.rsk.bitcoinj.wallet.Wallet;
import co.rsk.config.BridgeConstants;
import co.rsk.core.RskAddress;
import co.rsk.crypto.Keccak256;
import co.rsk.panic.PanicProcessor;
import co.rsk.peg.bitcoin.BitcoinUtils;
import co.rsk.peg.bitcoin.CoinbaseInformation;
import co.rsk.peg.bitcoin.MerkleBranch;
import co.rsk.peg.bitcoin.RskAllowUnconfirmedCoinSelector;
import co.rsk.peg.bitcoin.*;
import co.rsk.peg.btcLockSender.BtcLockSender.TxSenderAddressType;
import co.rsk.peg.btcLockSender.BtcLockSenderProvider;
import co.rsk.peg.federation.*;
import co.rsk.peg.flyover.FlyoverFederationInformation;
import co.rsk.peg.flyover.FlyoverTxResponseCodes;
import co.rsk.peg.pegin.PeginEvaluationResult;
import co.rsk.peg.pegin.PeginProcessAction;
import co.rsk.peg.pegin.RejectedPeginReason;
import co.rsk.peg.pegin.*;
import co.rsk.peg.pegininstructions.PeginInstructionsException;
import co.rsk.peg.pegininstructions.PeginInstructionsProvider;
import co.rsk.peg.utils.BridgeEventLogger;
import co.rsk.peg.utils.BtcTransactionFormatUtils;
import co.rsk.peg.utils.PartialMerkleTreeFormatUtils;
import co.rsk.peg.utils.RejectedPegoutReason;
import co.rsk.peg.utils.UnrefundablePeginReason;
import co.rsk.peg.whitelist.LockWhitelist;
import co.rsk.peg.whitelist.LockWhitelistEntry;
import co.rsk.peg.whitelist.OneOffWhiteListEntry;
import co.rsk.peg.whitelist.UnlimitedWhiteListEntry;
import co.rsk.peg.utils.*;
import co.rsk.peg.vote.*;
import co.rsk.peg.whitelist.*;
import co.rsk.rpc.modules.trace.CallType;
import co.rsk.rpc.modules.trace.ProgramSubtrace;
import com.google.common.annotations.VisibleForTesting;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.Pair;
import org.bouncycastle.util.encoders.Hex;
import org.ethereum.config.blockchain.upgrades.ActivationConfig;
import org.ethereum.config.blockchain.upgrades.ConsensusRule;
import org.ethereum.core.Block;
import org.ethereum.core.Repository;
import org.ethereum.core.SignatureCache;
import org.ethereum.core.Transaction;
import org.ethereum.core.*;
import org.ethereum.crypto.ECKey;
import org.ethereum.crypto.HashUtil;
import org.ethereum.util.ByteUtil;
@@ -153,7 +107,7 @@ public class BridgeSupport {
// (6 blocks/hour, 24 hours/day, 30 days/month)
public static final Integer BTC_TRANSACTION_CONFIRMATION_MAX_DEPTH = 4320;

private static final Logger logger = LoggerFactory.getLogger("BridgeSupport");
private static final Logger logger = LoggerFactory.getLogger(BridgeSupport.class);
private static final PanicProcessor panicProcessor = new PanicProcessor();

private static final String INVALID_ADDRESS_FORMAT_MESSAGE = "invalid address format";
@@ -2298,8 +2252,9 @@ public Integer voteFederationChange(Transaction tx, ABICallSpec callSpec) throws
}

// If enough votes have been reached, then actually execute the function
ABICallSpec winnerSpec = election.getWinner();
if (winnerSpec != null) {
Optional<ABICallSpec> winnerSpecOptional = election.getWinner();
if (winnerSpecOptional.isPresent()) {
ABICallSpec winnerSpec = winnerSpecOptional.get();
try {
result = executeVoteFederationChangeFunction(false, winnerSpec);
} catch (IOException e) {
@@ -2601,12 +2556,13 @@ public Integer voteFeePerKbChange(Transaction tx, Coin feePerKb) {
return -1;
}

ABICallSpec winner = feePerKbElection.getWinner();
if (winner == null) {
Optional<ABICallSpec> winnerOptional = feePerKbElection.getWinner();
if (!winnerOptional.isPresent()) {
logger.info("Successful fee per kb vote for {}", feePerKb);
return 1;
}

ABICallSpec winner = winnerOptional.get();
Coin winnerFee;
try {
winnerFee = BridgeSerializationUtils.deserializeCoin(winner.getArguments()[0]);
1 change: 1 addition & 0 deletions rskj-core/src/main/java/co/rsk/peg/BridgeUtils.java
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@
import co.rsk.peg.federation.Federation;
import co.rsk.peg.flyover.FlyoverTxResponseCodes;
import co.rsk.peg.utils.BtcTransactionFormatUtils;
import co.rsk.peg.vote.AddressBasedAuthorizer;
import org.ethereum.config.Constants;
import org.ethereum.config.blockchain.upgrades.ActivationConfig;
import org.ethereum.config.blockchain.upgrades.ConsensusRule;
Original file line number Diff line number Diff line change
@@ -16,11 +16,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package co.rsk.peg;
package co.rsk.peg.vote;

import co.rsk.core.RskAddress;

import java.util.*;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Representation of a given state of the election
@@ -30,22 +34,28 @@
* @author Ariel Mendelzon
*/
public class ABICallElection {
private AddressBasedAuthorizer authorizer;
private static final Logger logger = LoggerFactory.getLogger(ABICallElection.class);
private final AddressBasedAuthorizer authorizer;
private Map<ABICallSpec, List<RskAddress>> votes;

public ABICallElection(AddressBasedAuthorizer authorizer) {
this.authorizer = authorizer;
this.votes = new HashMap<>();
}

public ABICallElection(AddressBasedAuthorizer authorizer, Map<ABICallSpec, List<RskAddress>> votes) {
this.authorizer = authorizer;
this.votes = votes;
this.votes = clone(votes);
validate();
}

public ABICallElection(AddressBasedAuthorizer authorizer) {
this.authorizer = authorizer;
this.votes = new HashMap<>();
private Map<ABICallSpec, List<RskAddress>> clone(Map<ABICallSpec, List<RskAddress>> originalMap) {
return originalMap.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> new ArrayList<>(e.getValue())));
}

public Map<ABICallSpec, List<RskAddress>> getVotes() {
return votes;
return clone(votes);
}

public void clear() {
@@ -59,47 +69,57 @@ public void clear() {
* @return whether the voting succeeded
*/
public boolean vote(ABICallSpec callSpec, RskAddress voter) {
logger.info("[vote] Trying to register voter's {} vote ", voter);

if (!authorizer.isAuthorized(voter)) {
logger.info("[vote] Voter is not authorized.");
return false;
}

if (!votes.containsKey(callSpec)) {
votes.put(callSpec, new ArrayList<>());
}

votes.computeIfAbsent(callSpec, k -> new ArrayList<>());
List<RskAddress> callVoters = votes.get(callSpec);

if (callVoters.contains(voter)) {
logger.info("[vote] Vote has already been registered.");
return false;
}

callVoters.add(voter);
logger.info("[vote] Vote registered successfully.");
return true;
}

/**
* Returns the election winner abi call spec, or null if there's none
* Returns the election winner abi call spec, or empty if there's none
* The vote authorizer determines the number of participants,
* whereas this class determines the number of votes that
* conforms a win
* @return the winner abi call spec
* @return the (optional) winner abi call spec
*/
public ABICallSpec getWinner() {
public Optional<ABICallSpec> getWinner() {
for (Map.Entry<ABICallSpec, List<RskAddress>> specVotes : votes.entrySet()) {
if (specVotes.getValue().size() >= authorizer.getRequiredAuthorizedKeys()) {
return specVotes.getKey();
int votesSize = specVotes.getValue().size();
if (areEnoughVotes(votesSize)) {
ABICallSpec winner = specVotes.getKey();
logger.info("[getWinner] Winner is {} ", winner);
return Optional.of(winner);
}
}

return null;
return Optional.empty();
}

private boolean areEnoughVotes(int votesSize) {
return votesSize >= authorizer.getRequiredAuthorizedKeys();
}

/**
* Removes the entry votes for the current winner of the election
*/
public void clearWinners() {
ABICallSpec winner = getWinner();
if (winner != null) {
Optional<ABICallSpec> winnerOptional = getWinner();
if (winnerOptional.isPresent()) {
ABICallSpec winner = winnerOptional.get();
votes.remove(winner);
}
}
@@ -109,7 +129,7 @@ private void validate() {
for (Map.Entry<ABICallSpec, List<RskAddress>> specVotes : votes.entrySet()) {
for (RskAddress vote : specVotes.getValue()) {
if (!authorizer.isAuthorized(vote)) {
throw new RuntimeException("Unauthorized voter");
throw new UnauthorizedVoterException("Unauthorized voter");
}
}
}
Loading

0 comments on commit a61e908

Please sign in to comment.