Skip to content

Commit

Permalink
cache authority address, evmtool: do not fail if sender address is wrong
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net>
  • Loading branch information
daniellehrner committed Jul 16, 2024
1 parent 475c56e commit 0e94498
Show file tree
Hide file tree
Showing 7 changed files with 298 additions and 205 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@

import org.hyperledger.besu.crypto.SECP256K1;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.SetCodeAuthorization;
import org.hyperledger.besu.datatypes.TransactionType;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.ethereum.core.SetCodeAuthorization;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.account.Account;
Expand Down Expand Up @@ -78,7 +78,7 @@ void setUp() throws IOException {
public void shouldTransferAllEthOfAuthorizerToSponsor() throws IOException {

// 7702 transaction
final SetCodeAuthorization authorization =
final org.hyperledger.besu.datatypes.SetCodeAuthorization authorization =
SetCodeAuthorization.builder()
.chainId(BigInteger.valueOf(20211))
.address(SEND_ALL_ETH_CONTRACT_ADDRESS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,202 +14,70 @@
*/
package org.hyperledger.besu.datatypes;

import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.SECPSignature;
import org.hyperledger.besu.crypto.SignatureAlgorithm;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;

import java.math.BigInteger;
import java.util.List;
import java.util.function.Supplier;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Suppliers;
import org.apache.tuweni.bytes.Bytes;
import java.util.Optional;

/**
* An access list entry as defined in EIP-7702
*
* @param chainId can be either the current chain id or zero
* @param address the address from which the code will be set into the EOA account
* @param nonces the list of nonces
* @param signature the signature of the EOA account which will be used to set the code
* SetCodeAuthorization is a data structure that represents the authorization to set code on a EOA
* account.
*/
public record SetCodeAuthorization(
BigInteger chainId, Address address, List<Long> nonces, SECPSignature signature) {
public interface SetCodeAuthorization {
/**
* Return the chain id.
*
* @return chain id
*/
BigInteger chainId();

private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
/**
* Return the address of the account which code will be used.
*
* @return address
*/
Address address();

public static final Bytes MAGIC = Bytes.fromHexString("05");
/**
* Return the signature.
*
* @return signature
*/
SECPSignature signature();

/**
* Create access list entry.
* Return the authorizer address.
*
* @param chainId can be either the current chain id or zero
* @param address the address from which the code will be set into the EOA account
* @param nonces the list of nonces
* @param v the recovery id
* @param r the r value of the signature
* @param s the s value of the signature
* @return SetCodeTransactionEntry
* @return authorizer address of the EOA which will load the code into its account
*/
@JsonCreator
public static SetCodeAuthorization createSetCodeAuthorizationEntry(
@JsonProperty("chainId") final BigInteger chainId,
@JsonProperty("address") final Address address,
@JsonProperty("nonce") final List<Long> nonces,
@JsonProperty("v") final byte v,
@JsonProperty("r") final BigInteger r,
@JsonProperty("s") final BigInteger s) {
return new SetCodeAuthorization(
chainId, address, nonces, SIGNATURE_ALGORITHM.get().createSignature(r, s, v));
}
Optional<Address> authorizer();

/**
* Return the list of nonces
*
* @return all the nonces
*/
@Override
@JsonProperty("nonce")
public List<Long> nonces() {
return nonces;
}
List<Long> nonces();

/**
* Return the recovery id.
*
* @return byte
*/
@JsonProperty("v")
public byte v() {
return signature.getRecId();
}
byte v();

/**
* Return the r value of the signature.
*
* @return r value
*/
@JsonProperty("r")
public BigInteger r() {
return signature.getR();
}
BigInteger r();

/**
* Return the s value of the signature.
*
* @return s value
*/
@JsonProperty("s")
public BigInteger s() {
return signature.getS();
}

/**
* Create set code authorization with a builder.
*
* @return SetCodeAuthorization.Builder
*/
public static Builder builder() {
return new Builder();
}

/** Builder for SetCodeAuthorization. */
public static class Builder {
private BigInteger chainId = BigInteger.ZERO;
private Address address;
private List<Long> nonces = List.of();
private SECPSignature signature;

/** Create a new builder. */
protected Builder() {}

/**
* Set the optional chain id.
*
* @param chainId the chain id
* @return this builder
*/
public Builder chainId(final BigInteger chainId) {
this.chainId = chainId;
return this;
}

/**
* Set the address of the authorized smart contract.
*
* @param address the address
* @return this builder
*/
public Builder address(final Address address) {
this.address = address;
return this;
}

/**
* Set the list of optional nonces.
*
* @param nonces the list of nonces. Only the first nonce will be used.
* @return this builder
*/
public Builder nonces(final List<Long> nonces) {
this.nonces = nonces;
return this;
}

/**
* Set the signature of the authorizer account.
*
* @param signature the signature
* @return this builder
*/
public Builder signature(final SECPSignature signature) {
this.signature = signature;
return this;
}

/**
* Sign the authorization with the given key pair and return the authorization.
*
* @param keyPair the key pair
* @return SetCodeAuthorization
*/
public SetCodeAuthorization signAndBuild(final KeyPair keyPair) {
final BytesValueRLPOutput output = new BytesValueRLPOutput();
output.startList();
output.writeBigIntegerScalar(chainId);
output.writeBytes(address);
output.startList();
nonces.forEach(output::writeLongScalar);
output.endList();
output.endList();

signature(
SIGNATURE_ALGORITHM
.get()
.sign(Hash.hash(Bytes.concatenate(MAGIC, output.encoded())), keyPair));
return build();
}

/**
* Build the authorization.
*
* @return SetCodeAuthorization
*/
public SetCodeAuthorization build() {
if (address == null) {
throw new IllegalStateException("Address must be set");
}

if (signature == null) {
throw new IllegalStateException("Signature must be set");
}

return new SetCodeAuthorization(chainId, address, nonces, signature);
}
}
BigInteger s();
}
Loading

0 comments on commit 0e94498

Please sign in to comment.