Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addition of Transient Storage Opcodes #2778

Draft
wants to merge 21 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
729dbae
Adding the structure for transient storage opcodes
fmacleal Sep 30, 2024
d66eba6
Adding scratch from the DSL tests and contracts for tests
fmacleal Oct 1, 2024
47388c3
Some adjustments in DSL file and tests
fmacleal Oct 2, 2024
762f0df
Update test in BitcoinUtilsTest to use deterministic keys
marcos-iov Sep 27, 2024
08cd200
build: run rit check overnight; allow plus symbol in branch names
Vovchyk Sep 27, 2024
53eca95
refactor: update Bytes and BytesSlice to 'mimic' System.arraycopy and…
Vovchyk Jul 26, 2024
22b6f96
perf: improve decoding in CallTransaction
Vovchyk Jul 26, 2024
2869680
perf: improve decoding in RLP
Vovchyk Jul 26, 2024
c48edca
perf: refactor some tests
Vovchyk Aug 9, 2024
fa2eb47
Update rskj-core/src/test/java/co/rsk/core/types/bytes/BytesSliceTest…
fmacleal Aug 21, 2024
8892bf3
Merge branch 'master' into fmacleal/addition_transient_storage_opcodes
fmacleal Oct 14, 2024
264bbcd
Merge branch 'master' into fmacleal/addition_transient_storage_opcodes
fmacleal Oct 20, 2024
ce6b734
Merge branch 'master' into fmacleal/addition_transient_storage_opcodes
fmacleal Oct 21, 2024
c9b91ac
Merge branch 'master' into fmacleal/addition_transient_storage_opcodes
fmacleal Oct 22, 2024
e4a19d4
Merge branch 'master' into fmacleal/addition_transient_storage_opcodes
fmacleal Oct 25, 2024
0b5e303
Merge branch 'master' into fmacleal/addition_transient_storage_opcodes
fmacleal Nov 4, 2024
551df42
Adding transient storage maps with TLOAD/TSTORE implementation (#2801)
fmacleal Nov 4, 2024
99599fb
Fixing some sonar issues
fmacleal Nov 5, 2024
ea7d304
fmacleal/integrate tstorage in transaction execution (#2844)
fmacleal Nov 14, 2024
f3f99fa
Merge branch 'master' into fmacleal/addition_transient_storage_opcodes
fmacleal Nov 18, 2024
f7d3822
Merge branch 'master' into fmacleal/addition_transient_storage_opcodes
fmacleal Nov 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ public enum ConsensusRule {
RSKIP427("rskip427"),
RSKIP428("rskip428"),
RSKIP434("rskip434"),
RSKIP438("rskip438")
RSKIP438("rskip438"),
RSKIP446("rskip446") // Transient storage opcodes addition implementing EIP-1153
;

private final String configKey;
Expand Down
2 changes: 1 addition & 1 deletion rskj-core/src/main/java/org/ethereum/core/Repository.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

import java.math.BigInteger;

public interface Repository extends RepositorySnapshot {
public interface Repository extends RepositorySnapshot, TransientRepository {
Trie getTrie();

/**
Expand Down
40 changes: 40 additions & 0 deletions rskj-core/src/main/java/org/ethereum/core/TransientRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* This file is part of RskJ
* Copyright (C) 2024 RSK Labs Ltd.
* (derived from ethereumJ library, Copyright (c) 2016 <ether.camp>)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package org.ethereum.core;

import co.rsk.core.RskAddress;
import org.ethereum.vm.DataWord;

import javax.annotation.Nullable;

public interface TransientRepository {

void addTransientStorageRow(RskAddress addr, DataWord key, DataWord value);

void addTransientStorageBytes(RskAddress addr, DataWord key, byte[] value);

void clearTransientStorage();

@Nullable
DataWord getTransientStorageValue(RskAddress addr, DataWord key);

@Nullable
byte[] getTransientStorageBytes(RskAddress addr, DataWord key);
}
76 changes: 71 additions & 5 deletions rskj-core/src/main/java/org/ethereum/db/MutableRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,29 @@
import co.rsk.crypto.Keccak256;
import co.rsk.db.MutableTrieCache;
import co.rsk.db.MutableTrieImpl;
import co.rsk.trie.*;
import co.rsk.trie.IterationElement;
import co.rsk.trie.MutableTrie;
import co.rsk.trie.Trie;
import co.rsk.trie.TrieKeySlice;
import co.rsk.trie.TrieStore;
import co.rsk.trie.TrieStoreImpl;
import com.google.common.annotations.VisibleForTesting;
import org.ethereum.core.AccountState;
import org.ethereum.core.Repository;
import org.ethereum.crypto.HashUtil;
import org.ethereum.crypto.Keccak256Helper;
import org.ethereum.datasource.HashMapDB;
import org.ethereum.vm.DataWord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.math.BigInteger;
import java.util.*;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Optional;
import java.util.Set;

public class MutableRepository implements Repository {
private static final Logger logger = LoggerFactory.getLogger("repository");
Expand All @@ -47,21 +57,32 @@ public class MutableRepository implements Repository {

private final TrieKeyMapper trieKeyMapper;
private final MutableTrie mutableTrie;
private MutableTrie transientTrie;
private final IReadWrittenKeysTracker tracker;

public MutableRepository(TrieStore trieStore, Trie trie) {
this(new MutableTrieImpl(trieStore, trie));
this(new MutableTrieImpl(trieStore, trie), new MutableTrieImpl(new TrieStoreImpl(new HashMapDB()), new Trie()));
}

public MutableRepository(MutableTrie mutableTrie) {
this(mutableTrie, new MutableTrieImpl(new TrieStoreImpl(new HashMapDB()), new Trie()));
}

public MutableRepository(MutableTrie mutableTrie, IReadWrittenKeysTracker tracker) {
this(mutableTrie, new MutableTrieImpl(new TrieStoreImpl(new HashMapDB()), new Trie()), tracker);
}

public MutableRepository(MutableTrie mutableTrie, MutableTrie transientTrie) {
this.trieKeyMapper = new TrieKeyMapper();
this.mutableTrie = mutableTrie;
this.transientTrie = transientTrie;
this.tracker = new DummyReadWrittenKeysTracker();
}

public MutableRepository(MutableTrie mutableTrie, IReadWrittenKeysTracker tracker) {
public MutableRepository(MutableTrie mutableTrie, MutableTrie transientTrie, IReadWrittenKeysTracker tracker) {
this.trieKeyMapper = new TrieKeyMapper();
this.mutableTrie = mutableTrie;
this.transientTrie = transientTrie;
this.tracker = tracker;
}

Expand Down Expand Up @@ -327,7 +348,7 @@ public synchronized Set<RskAddress> getAccountsKeys() {
// To start tracking, a new repository is created, with a MutableTrieCache in the middle
@Override
public synchronized Repository startTracking() {
return new MutableRepository(new MutableTrieCache(mutableTrie), tracker);
return new MutableRepository(new MutableTrieCache(mutableTrie), new MutableTrieCache(transientTrie), tracker);
}

@Override
Expand All @@ -338,11 +359,13 @@ public void save() {
@Override
public synchronized void commit() {
mutableTrie.commit();
transientTrie.commit();
}

@Override
public synchronized void rollback() {
mutableTrie.rollback();
transientTrie.rollback();
}

@Override
Expand Down Expand Up @@ -406,4 +429,47 @@ private Optional<Keccak256> internalGetValueHash(byte[] key) {
tracker.addNewReadKey(new ByteArrayWrapper(key));
return mutableTrie.getValueHash(key);
}

@Override
public void addTransientStorageRow(RskAddress addr, DataWord key, DataWord value) {
addTransientStorageBytes(addr, key, value.getByteArrayForStorage());
}

@Override
public void addTransientStorageBytes(RskAddress addr, DataWord key, byte[] value) {
byte[] triekey = trieKeyMapper.getAccountStorageKey(addr, key);

// Special case: if the value is an empty vector, we pass "null" which commands the trie to remove the item.
// Note that if the call comes from addStorageRow(), this method will already have replaced 0 by null, so the
// conversion here only applies if this is called directly. If suppose this only occurs in tests, but it can
// also occur in precompiled contracts that store data directly using this method.
if (value == null || value.length == 0) {
transientTrie.put(triekey, null);
} else {
transientTrie.put(triekey, value);
}
}

@Override
public void clearTransientStorage() {
this.transientTrie = new MutableTrieImpl(new TrieStoreImpl(new HashMapDB()), new Trie());
}

@Nullable
@Override
public DataWord getTransientStorageValue(RskAddress addr, DataWord key) {
byte[] value = getTransientStorageBytes(addr, key);
if (value == null) {
return null;
}

return DataWord.valueOf(value);
}

@Nullable
@Override
public byte[] getTransientStorageBytes(RskAddress addr, DataWord key) {
byte[] triekey = trieKeyMapper.getAccountStorageKey(addr, key);
return transientTrie.get(triekey);
}
}
9 changes: 9 additions & 0 deletions rskj-core/src/main/java/org/ethereum/vm/OpCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,15 @@ public enum OpCode {
*/
JUMPDEST(0x5b, 0, 0, SPECIAL_TIER),

/**
* (0x5c) Load word from transient storage at address
*/
TLOAD(0x5c, 1, 1, SPECIAL_TIER), // Will adjust the correct inputs and outputs later

/**
* (0x5c) Store word from transient storage at address
*/
TSTORE(0x5d, 2, 0, SPECIAL_TIER), // Will adjust the correct inputs and outputs later

/* Push Operations */
/**
Expand Down
17 changes: 12 additions & 5 deletions rskj-core/src/main/java/org/ethereum/vm/OpCodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@
* Created by Sergio on 07/07/2016.
*/
public class OpCodes {

private OpCodes() {

}

/**
* Halts execution (0x00)
*/
Expand Down Expand Up @@ -325,6 +320,14 @@ private OpCodes() {
* (0x5b)
*/
static final byte OP_JUMPDEST =0x5b ;
/**
* (0x5c)
*/
public static final byte OP_TLOAD =0x5c ;
/**
* (0x5d)
*/
public static final byte OP_TSTORE =0x5d ;

/* Push Operations */
/**
Expand Down Expand Up @@ -664,4 +667,8 @@ private OpCodes() {
* later deletion
*/
static final byte OP_SUICIDE =(byte)0xff;

private OpCodes() {

}
}
Loading