Repository: iotexproject/iotex-core
Pull request #4151 (2024-02-27 00:45:07)

[evm] add transientStorage struct
# Description
add `transientStorage` struct. next PR will implement EIP1153 transient storage in EVM
refer to Ethereum's implementation: https://github.com/ethereum/go-ethereum/pull/26003/files#diff-881df080822cc037890983e168ea0f004c9ebe26a87df47867436b415e234604

Fixes #(issue)

## Type of change
Please delete options that are not relevant.
- [] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [] Code refactor or improvement
- [] Breaking change (fix or feature that would cause a new or changed behavior of existing functionality)
- [] This change requires a documentation update

# How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
- [x] make test
- [] fullsync
- [] Other test (please specify)

**Test Configuration**:
- Firmware version:
- Hardware:
- Toolchain:
- SDK:

# Checklist:
- [] My code follows the style guidelines of this project
- [] I have performed a self-review of my code
- [] I have commented my code, particularly in hard-to-understand areas
- [] I have made corresponding changes to the documentation
- [] My changes generate no new warnings
- [] I have added tests that prove my fix is effective or that my feature works
- [] New and existing unit tests pass locally with my changes
- [] Any dependent changes have been merged and published in downstream modules


sonarcloud[bot]: ## [![Quality Gate Failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-failed-20px.png 'Quality Gate Failed')](https://sonarcloud.io/dashboard?id=iotexproject_iotex-core&pullRequest=4151) **Quality Gate failed**  
Failed conditions  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/failed-16px.png '') [4.5% Duplication on New Code](https://sonarcloud.io/component_measures?id=iotexproject_iotex-core&pullRequest=4151&metric=new_duplicated_lines_density&view=list) (required ≤ 3%)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=iotexproject_iotex-core&pullRequest=4151)


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/iotexproject/iotex-core/pull/4151?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iotexproject) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 76.37%. Comparing base [(`e1f0636`)](https://app.codecov.io/gh/iotexproject/iotex-core/commit/e1f0636b27ca54fa57da8cadb3034431143833fa?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iotexproject) to head [(`9101107`)](https://app.codecov.io/gh/iotexproject/iotex-core/pull/4151?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iotexproject).
> Report is 176 commits behind head on master.


<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #4151      +/-   ##
==========================================
+ Coverage   75.38%   76.37%   +0.98%     
==========================================
  Files         303      340      +37     
  Lines       25923    28871    +2948     
==========================================
+ Hits        19541    22049    +2508     
- Misses       5360     5721     +361     
- Partials     1022     1101      +79     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/iotexproject/iotex-core/pull/4151?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iotexproject).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=iotexproject).

sonarcloud[bot]: ## [![Quality Gate Failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-failed-20px.png 'Quality Gate Failed')](https://sonarcloud.io/dashboard?id=iotexproject_iotex-core&pullRequest=4151) **Quality Gate failed**  
Failed conditions  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/failed-16px.png '') [4.5% Duplication on New Code](https://sonarcloud.io/component_measures?id=iotexproject_iotex-core&pullRequest=4151&metric=new_duplicated_lines_density&view=list) (required ≤ 3%)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=iotexproject_iotex-core&pullRequest=4151)



Patch:
diff --git a/action/protocol/execution/evm/transient_storage.go b/action/protocol/execution/evm/transient_storage.go
new file mode 100644
index 000000000..71fbbfd68
--- /dev/null
+++ b/action/protocol/execution/evm/transient_storage.go
@@ -0,0 +1,45 @@
+// Copyright (c) 2024 IoTeX Foundation
+// This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability
+// or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed.
+// This source code is governed by Apache License 2.0 that can be found in the LICENSE file.
+
+package evm
+
+import (
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/core/state"
+)
+
+// transientStorage is a representation of EIP-1153 "Transient Storage".
+type transientStorage map[common.Address]state.Storage
+
+// newTransientStorage creates a new instance of a transientStorage.
+func newTransientStorage() transientStorage {
+	return make(transientStorage)
+}
+
+// Set sets the transient-storage `value` for `key` at the given `addr`.
+func (t transientStorage) Set(addr common.Address, key, value common.Hash) {
+	if _, ok := t[addr]; !ok {
+		t[addr] = make(state.Storage)
+	}
+	t[addr][key] = value
+}
+
+// Get gets the transient storage for `key` at the given `addr`.
+func (t transientStorage) Get(addr common.Address, key common.Hash) common.Hash {
+	val, ok := t[addr]
+	if !ok {
+		return common.Hash{}
+	}
+	return val[key]
+}
+
+// Copy does a deep copy of the transientStorage
+func (t transientStorage) Copy() transientStorage {
+	storage := make(transientStorage)
+	for key, value := range t {
+		storage[key] = value.Copy()
+	}
+	return storage
+}


Test patch:
diff --git a/action/protocol/execution/evm/transient_storage_test.go b/action/protocol/execution/evm/transient_storage_test.go
new file mode 100644
index 000000000..18b1789f9
--- /dev/null
+++ b/action/protocol/execution/evm/transient_storage_test.go
@@ -0,0 +1,61 @@
+// Copyright (c) 2024 IoTeX Foundation
+// This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability
+// or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed.
+// This source code is governed by Apache License 2.0 that can be found in the LICENSE file.
+
+package evm
+
+import (
+	"testing"
+
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/stretchr/testify/require"
+)
+
+func TestTransientStorage(t *testing.T) {
+	r := require.New(t)
+
+	ts := newTransientStorage()
+	r.NotNil(ts)
+	var (
+		addr0 = common.Address{}
+		addr1 = common.HexToAddress("1234567890")
+		k1    = common.Hash{}
+		k2    = common.HexToHash("34567890ab")
+		v1    = common.HexToHash("567890abcd")
+		v2    = common.HexToHash("7890abcdef")
+	)
+	// new ts is empty
+	h := ts.Get(addr0, k1)
+	r.Zero(h)
+	h = ts.Get(addr1, k2)
+	r.Zero(h)
+	// test Set and Get
+	for _, v := range []struct {
+		addr     common.Address
+		key, val common.Hash
+	}{
+		{addr0, k1, v1},
+		{addr0, k2, v2},
+		{addr1, k1, v2},
+		{addr1, k2, v1},
+	} {
+		ts.Set(v.addr, v.key, v.val)
+		h = ts.Get(v.addr, v.key)
+		r.Equal(v.val, h)
+	}
+	// test Copy
+	ts1 := ts.Copy()
+	for _, v := range []struct {
+		addr     common.Address
+		key, val common.Hash
+	}{
+		{addr0, k1, v1},
+		{addr0, k2, v2},
+		{addr1, k1, v2},
+		{addr1, k2, v1},
+	} {
+		h = ts1.Get(v.addr, v.key)
+		r.Equal(v.val, h)
+	}
+}