Skip to content

Commit

Permalink
Various SELFDESTRUCT related fixes (#1661)
Browse files Browse the repository at this point in the history
  • Loading branch information
OlivierBBB authored Dec 15, 2024
1 parent cb7760d commit dfebb97
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package net.consensys.linea.zktracer.module.hub.fragment.account;

import static com.google.common.base.Preconditions.*;
import static net.consensys.linea.zktracer.module.hub.Trace.MULTIPLIER___DOM_SUB_STAMPS;
import static net.consensys.linea.zktracer.types.AddressUtils.highPart;
import static net.consensys.linea.zktracer.types.AddressUtils.isPrecompile;
import static net.consensys.linea.zktracer.types.AddressUtils.lowPart;
Expand Down Expand Up @@ -173,7 +174,8 @@ public void resolvePostTransaction(
new EphemeralAccount(oldState.address(), oldState.deploymentNumber());
if (effectiveSelfDestructMap.containsKey(ephemeralAccount)) {
final int selfDestructTime = effectiveSelfDestructMap.get(ephemeralAccount);
markedForSelfDestruct = hubStamp > selfDestructTime;
markedForSelfDestruct =
domSubStampsSubFragment.domStamp() > MULTIPLIER___DOM_SUB_STAMPS * selfDestructTime;
markedForSelfDestructNew = hubStamp >= selfDestructTime;
} else {
markedForSelfDestruct = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import net.consensys.linea.zktracer.module.hub.section.TraceSection;
import net.consensys.linea.zktracer.module.hub.signals.Exceptions;
import net.consensys.linea.zktracer.runtime.callstack.CallFrame;
import net.consensys.linea.zktracer.types.Bytecode;
import net.consensys.linea.zktracer.types.TransactionProcessingMetadata;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
Expand All @@ -52,15 +53,15 @@ public class SelfdestructSection extends TraceSection
SelfdestructScenarioFragment selfdestructScenarioFragment;

final Address addressWhichMaySelfDestruct;
AccountSnapshot selfdestructorAccountBefore;
AccountSnapshot selfdestructorAccountAfter;

final Bytes recipientAddressUntrimmed;
final Address recipientAddress;
AccountFragment selfdestructorFirstAccountFragment;
AccountFragment recipientFirstAccountFragment;
AccountSnapshot recipientAccountBefore;
AccountSnapshot recipientAccountAfter;

AccountSnapshot selfdestructor;
AccountSnapshot selfdestructorNew;
AccountSnapshot recipient;
AccountSnapshot recipientNew;
AccountSnapshot accountWiping;
AccountSnapshot accountWipingNew;

@Getter boolean selfDestructWasReverted = false;

Expand All @@ -78,7 +79,7 @@ public SelfdestructSection(Hub hub, MessageFrame frame) {

// Account
addressWhichMaySelfDestruct = frame.getRecipientAddress();
selfdestructorAccountBefore =
selfdestructor =
AccountSnapshot.canonical(hub, frame.getWorldUpdater(), addressWhichMaySelfDestruct);

// Recipient
Expand Down Expand Up @@ -108,25 +109,25 @@ public SelfdestructSection(Hub hub, MessageFrame frame) {
if (Exceptions.any(exceptions)) {
checkArgument(exceptions == OUT_OF_GAS_EXCEPTION);

recipientAccountBefore =
recipient =
selfdestructTargetsItself()
? selfdestructorAccountBefore
? selfdestructor
: AccountSnapshot.canonical(hub, frame.getWorldUpdater(), recipientAddress);

selfdestructorFirstAccountFragment =
AccountFragment selfdestructorFirstAccountFragment =
hub.factories()
.accountFragment()
.make(
selfdestructorAccountBefore,
selfdestructorAccountBefore,
selfdestructor,
selfdestructor,
DomSubStampsSubFragment.standardDomSubStamps(this.hubStamp(), 0));

recipientFirstAccountFragment =
AccountFragment recipientFirstAccountFragment =
hub.factories()
.accountFragment()
.makeWithTrm(
recipientAccountBefore,
recipientAccountBefore,
recipient,
recipient,
recipientAddressUntrimmed,
DomSubStampsSubFragment.standardDomSubStamps(this.hubStamp(), 1));

Expand All @@ -142,17 +143,15 @@ public SelfdestructSection(Hub hub, MessageFrame frame) {
hub.txStack().current().getUnexceptionalSelfDestructMap();

final EphemeralAccount ephemeralAccount =
new EphemeralAccount(
addressWhichMaySelfDestruct, selfdestructorAccountBefore.deploymentNumber());
new EphemeralAccount(addressWhichMaySelfDestruct, selfdestructor.deploymentNumber());

if (unexceptionalSelfDestructMap.containsKey(ephemeralAccount)) {
unexceptionalSelfDestructMap
.get(ephemeralAccount)
.add(new AttemptedSelfDestruct(hubStamp, hub.currentFrame()));
} else {
unexceptionalSelfDestructMap.put(
new EphemeralAccount(
addressWhichMaySelfDestruct, selfdestructorAccountBefore.deploymentNumber()),
new EphemeralAccount(addressWhichMaySelfDestruct, selfdestructor.deploymentNumber()),
new ArrayList<>(List.of(new AttemptedSelfDestruct(hubStamp, hub.currentFrame()))));
}

Expand All @@ -168,37 +167,40 @@ public SelfdestructSection(Hub hub, MessageFrame frame) {
// - The recipient address will become warm (i+3)
// * recipientFirstAccountFragment

selfdestructorAccountAfter = selfdestructorAccountBefore.deepCopy().setBalanceToZero();
selfdestructorNew = selfdestructor.deepCopy().setBalanceToZero();

final boolean isDeployment = frame.getType() == MessageFrame.Type.CONTRACT_CREATION;
checkState(isDeployment == selfdestructor.deploymentStatus());
if (isDeployment) {
selfdestructorNew = selfdestructorNew.deploymentStatus(false);
selfdestructorNew.code(Bytecode.EMPTY);
}

if (selfdestructTargetsItself()) {
recipientAccountBefore = selfdestructorAccountAfter.deepCopy();
recipientAccountAfter = recipientAccountBefore.deepCopy();
recipient = selfdestructorNew.deepCopy();
recipientNew = selfdestructorNew.deepCopy();
} else {
recipientAccountBefore =
AccountSnapshot.canonical(hub, frame.getWorldUpdater(), recipientAddress);
recipientAccountAfter =
recipientAccountBefore
.deepCopy()
.incrementBalanceBy(selfdestructorAccountBefore.balance())
.turnOnWarmth();
recipient = AccountSnapshot.canonical(hub, frame.getWorldUpdater(), recipientAddress);
recipientNew =
recipient.deepCopy().incrementBalanceBy(selfdestructor.balance()).turnOnWarmth();
}
checkArgument(recipientAccountAfter.isWarm());
checkArgument(recipientNew.isWarm());

selfdestructorFirstAccountFragment =
AccountFragment selfdestructorFirstAccountFragment =
hub.factories()
.accountFragment()
.make(
selfdestructorAccountBefore,
selfdestructorAccountAfter,
DomSubStampsSubFragment.standardDomSubStamps(hub.stamp(), 0));
recipientFirstAccountFragment =
selfdestructor,
selfdestructorNew,
DomSubStampsSubFragment.standardDomSubStamps(hubStamp, 0));
AccountFragment recipientFirstAccountFragment =
hub.factories()
.accountFragment()
.makeWithTrm(
recipientAccountBefore,
recipientAccountAfter,
recipient,
recipientNew,
recipientAddressUntrimmed,
DomSubStampsSubFragment.standardDomSubStamps(hub.stamp(), 1));
DomSubStampsSubFragment.standardDomSubStamps(hubStamp, 1));

this.addFragment(selfdestructorFirstAccountFragment);
this.addFragment(recipientFirstAccountFragment);
Expand All @@ -212,19 +214,20 @@ public void resolveUponRollback(Hub hub, MessageFrame messageFrame, CallFrame ca
hub.factories()
.accountFragment()
.make(
selfdestructorAccountAfter,
selfdestructorAccountBefore,
selfdestructorNew.deepCopy().setDeploymentNumber(hub),
selfdestructor.deepCopy().setDeploymentNumber(hub),
DomSubStampsSubFragment.revertWithCurrentDomSubStamps(
hubStamp, callFrame.revertStamp(), 2));

final AccountFragment recipientUndoingAccountFragment =
hub.factories()
.accountFragment()
.make(
recipientAccountAfter,
recipientAccountBefore,
recipientNew.deepCopy().setDeploymentNumber(hub),
recipient.deepCopy().setDeploymentNumber(hub),
DomSubStampsSubFragment.revertWithCurrentDomSubStamps(
hubStamp, callFrame.revertStamp(), 3));

this.addFragment(selfDestroyerUndoingAccountFragment);
this.addFragment(recipientUndoingAccountFragment);

Expand All @@ -247,8 +250,7 @@ public void resolvePostTransaction(
final Map<EphemeralAccount, Integer> effectiveSelfDestructMap =
transactionProcessingMetadata.getEffectiveSelfDestructMap();
final EphemeralAccount ephemeralAccount =
new EphemeralAccount(
addressWhichMaySelfDestruct, selfdestructorAccountAfter.deploymentNumber());
new EphemeralAccount(addressWhichMaySelfDestruct, selfdestructorNew.deploymentNumber());

checkArgument(effectiveSelfDestructMap.containsKey(ephemeralAccount));

Expand All @@ -257,7 +259,7 @@ public void resolvePostTransaction(

checkArgument(hubStamp >= hubStampOfTheActionableSelfDestruct);

final AccountSnapshot accountBeforeSelfDestruct =
accountWiping =
transactionProcessingMetadata.getDestructedAccountsSnapshot().stream()
.filter(
accountSnapshot -> accountSnapshot.address().equals(addressWhichMaySelfDestruct))
Expand All @@ -272,7 +274,9 @@ public void resolvePostTransaction(
hub.transients()
.conflation()
.deploymentInfo()
.deploymentUpdateForSuccessfulSelfDestruct(selfdestructorAccountBefore.address());
.deploymentUpdateForSuccessfulSelfDestruct(selfdestructor.address());

accountWipingNew = selfdestructorNew.wipe(hub.transients().conflation().deploymentInfo());

// the hub's defers.resolvePostTransaction() gets called after the
// hub's completeLineaTransaction which in turn calls
Expand All @@ -282,8 +286,8 @@ public void resolvePostTransaction(
hub.factories()
.accountFragment()
.make(
accountBeforeSelfDestruct,
selfdestructorAccountAfter.wipe(hub.transients().conflation().deploymentInfo()),
accountWiping,
accountWipingNew,
DomSubStampsSubFragment.selfdestructDomSubStamps(hub, hubStamp));

this.addFragment(accountWipingFragment);
Expand Down

0 comments on commit dfebb97

Please sign in to comment.