From db35b2d3e79705d93cea2f3b9360264c2b9a9224 Mon Sep 17 00:00:00 2001 From: Alessandro Tagliapietra <0xalex88@proton.me> Date: Mon, 30 Dec 2024 16:18:31 -0800 Subject: [PATCH] Add frxUSD/sfrxUSD granite fork code change --- .github/CODEOWNERS | 1 - .github/CONTRIBUTING.md | 40 ------- .github/ISSUE_TEMPLATE/bug.md | 31 ----- .github/ISSUE_TEMPLATE/feature.md | 17 --- .github/ISSUE_TEMPLATE/question.md | 9 -- .github/no-response.yml | 11 -- .github/stale.yml | 17 --- .github/workflows/release.yaml | 40 +++++++ Dockerfile | 7 +- consensus/misc/create2deployer_test.go | 52 ++++++-- consensus/misc/frxusd.go | 22 ++++ consensus/misc/frxusd/constants.go | 28 +++++ consensus/misc/frxusd/devnet.go | 41 +++++++ consensus/misc/frxusd/mainnet.go | 41 +++++++ consensus/misc/frxusd/testnet.go | 27 +++++ consensus/misc/frxusd_test.go | 157 +++++++++++++++++++++++++ core/state_processor.go | 1 + miner/worker.go | 1 + 18 files changed, 405 insertions(+), 138 deletions(-) delete mode 100644 .github/CODEOWNERS delete mode 100644 .github/CONTRIBUTING.md delete mode 100644 .github/ISSUE_TEMPLATE/bug.md delete mode 100644 .github/ISSUE_TEMPLATE/feature.md delete mode 100644 .github/ISSUE_TEMPLATE/question.md delete mode 100644 .github/no-response.yml delete mode 100644 .github/stale.yml create mode 100644 .github/workflows/release.yaml create mode 100644 consensus/misc/frxusd.go create mode 100644 consensus/misc/frxusd/constants.go create mode 100644 consensus/misc/frxusd/devnet.go create mode 100644 consensus/misc/frxusd/mainnet.go create mode 100644 consensus/misc/frxusd/testnet.go create mode 100644 consensus/misc/frxusd_test.go diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index e9ba9912c..000000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @ethereum-optimism/op-geth-maintainers diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md deleted file mode 100644 index 969b7f8f9..000000000 --- a/.github/CONTRIBUTING.md +++ /dev/null @@ -1,40 +0,0 @@ -# Contributing - -Thank you for considering to help out with the source code! We welcome -contributions from anyone on the internet, and are grateful for even the -smallest of fixes! - -If you'd like to contribute to go-ethereum, please fork, fix, commit and send a -pull request for the maintainers to review and merge into the main code base. If -you wish to submit more complex changes though, please check up with the core -devs first on [our gitter channel](https://gitter.im/ethereum/go-ethereum) to -ensure those changes are in line with the general philosophy of the project -and/or get some early feedback which can make both your efforts much lighter as -well as our review and merge procedures quick and simple. - -## Coding guidelines - -Please make sure your contributions adhere to our coding guidelines: - - * Code must adhere to the official Go -[formatting](https://golang.org/doc/effective_go.html#formatting) guidelines -(i.e. uses [gofmt](https://golang.org/cmd/gofmt/)). - * Code must be documented adhering to the official Go -[commentary](https://golang.org/doc/effective_go.html#commentary) guidelines. - * Pull requests need to be based on and opened against the `master` branch. - * Commit messages should be prefixed with the package(s) they modify. - * E.g. "eth, rpc: make trace configs optional" - -## Can I have feature X - -Before you submit a feature request, please check and make sure that it isn't -possible through some other means. The JavaScript-enabled console is a powerful -feature in the right hands. Please check our -[Geth documentation page](https://geth.ethereum.org/docs/) for more info -and help. - -## Configuration, dependencies, and tests - -Please see the [Developers' Guide](https://geth.ethereum.org/docs/developers/geth-developer/dev-guide) -for more details on configuring your environment, managing project dependencies -and testing procedures. diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md deleted file mode 100644 index 45bfd986a..000000000 --- a/.github/ISSUE_TEMPLATE/bug.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -name: Report a bug -about: Something with go-ethereum is not working as expected -title: '' -labels: 'type:bug' -assignees: '' ---- - -#### System information - -Geth version: `geth version` -CL client & version: e.g. lighthouse/nimbus/prysm@v1.0.0 -OS & Version: Windows/Linux/OSX -Commit hash : (if `develop`) - -#### Expected behaviour - - -#### Actual behaviour - - -#### Steps to reproduce the behaviour - - -#### Backtrace - -```` -[backtrace] -```` - -When submitting logs: please submit them as text and not screenshots. diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md deleted file mode 100644 index aacd885f9..000000000 --- a/.github/ISSUE_TEMPLATE/feature.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: Request a feature -about: Report a missing feature - e.g. as a step before submitting a PR -title: '' -labels: 'type:feature' -assignees: '' ---- - -# Rationale - -Why should this feature exist? -What are the use-cases? - -# Implementation - -Do you have ideas regarding the implementation of this feature? -Are you willing to implement this feature? \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md deleted file mode 100644 index 8f460ab55..000000000 --- a/.github/ISSUE_TEMPLATE/question.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -name: Ask a question -about: Something is unclear -title: '' -labels: 'type:docs' -assignees: '' ---- - -This should only be used in very rare cases e.g. if you are not 100% sure if something is a bug or asking a question that leads to improving the documentation. For general questions please use [discord](https://discord.gg/nthXNEv) or the Ethereum stack exchange at https://ethereum.stackexchange.com. diff --git a/.github/no-response.yml b/.github/no-response.yml deleted file mode 100644 index 903d4ce85..000000000 --- a/.github/no-response.yml +++ /dev/null @@ -1,11 +0,0 @@ -# Number of days of inactivity before an Issue is closed for lack of response -daysUntilClose: 30 -# Label requiring a response -responseRequiredLabel: "need:more-information" -# Comment to post when closing an Issue for lack of response. Set to `false` to disable -closeComment: > - This issue has been automatically closed because there has been no response - to our request for more information from the original author. With only the - information that is currently in the issue, we don't have enough information - to take action. Please reach out if you have more relevant information or - answers to our questions so that we can investigate further. diff --git a/.github/stale.yml b/.github/stale.yml deleted file mode 100644 index 6d921cc79..000000000 --- a/.github/stale.yml +++ /dev/null @@ -1,17 +0,0 @@ -# Number of days of inactivity before an issue becomes stale -daysUntilStale: 366 -# Number of days of inactivity before a stale issue is closed -daysUntilClose: 42 -# Issues with these labels will never be considered stale -exemptLabels: - - pinned - - security -# Label to use when marking an issue as stale -staleLabel: "status:inactive" -# Comment to post when marking an issue as stale. Set to `false` to disable -markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. Thank you - for your contributions. -# Comment to post when closing a stale issue. Set to `false` to disable -closeComment: false diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 000000000..5cb2e1039 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,40 @@ +name: Release docker image + +on: + workflow_dispatch: + inputs: + version: + description: Version to publish (will be the docker tag) + required: true + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Build and push + uses: docker/build-push-action@v6 + with: + push: true + tags: ghcr.io/fraxfinance/fraxtal-op-geth:${{ inputs.version }} + platforms: linux/amd64,linux/arm64 + cache-from: type=gha + cache-to: type=gha,mode=max + build-args: | + COMMIT=${{ github.sha }} + VERSION=${{ inputs.version }} + BUILDNUM=${{ github.run_number }} diff --git a/Dockerfile b/Dockerfile index ff89e92f2..4356d2f10 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,13 @@ +# Multi arch target +ARG TARGETARCH + # Support setting various labels on the final image ARG COMMIT="" ARG VERSION="" ARG BUILDNUM="" # Build Geth in a stock Go builder container -FROM golang:1.23-alpine AS builder +FROM --platform=$BUILDPLATFORM golang:1.23-alpine AS builder RUN apk add --no-cache gcc musl-dev linux-headers git @@ -14,7 +17,7 @@ COPY go.sum /go-ethereum/ RUN cd /go-ethereum && go mod download ADD . /go-ethereum -RUN cd /go-ethereum && go run build/ci.go install -static ./cmd/geth +RUN cd /go-ethereum && go run build/ci.go install -static -arch=$TARGETARCH ./cmd/geth # Pull Geth into a second stage deploy alpine container FROM alpine:latest diff --git a/consensus/misc/create2deployer_test.go b/consensus/misc/create2deployer_test.go index fc0ef79fd..b41a151eb 100644 --- a/consensus/misc/create2deployer_test.go +++ b/consensus/misc/create2deployer_test.go @@ -69,27 +69,59 @@ func TestEnsureCreate2Deployer(t *testing.T) { tt.override(&cfg) } state := &stateDb{ - codeExists: tt.codeExists, + codeMap: map[common.Address][]byte{}, } EnsureCreate2Deployer(&cfg, tt.timestamp, state) - assert.Equal(t, tt.applied, state.codeSet) + assert.Equal(t, tt.applied, state.GetCodeSize(create2DeployerAddress) > 0) }) } } type stateDb struct { vm.StateDB - codeExists bool - codeSet bool + codeMap map[common.Address][]byte + storage map[common.Address]map[common.Hash]common.Hash } -func (s *stateDb) GetCodeSize(_ common.Address) int { - if s.codeExists { - return 1 +func (s *stateDb) GetCode(addr common.Address) []byte { + s.initCodeMap() + return s.codeMap[addr] +} + +func (s *stateDb) GetCodeSize(addr common.Address) int { + s.initCodeMap() + return len(s.codeMap[addr]) +} + +func (s *stateDb) SetCode(addr common.Address, code []byte) { + s.initCodeMap() + s.codeMap[addr] = code +} + +func (s *stateDb) initCodeMap() { + if s.codeMap == nil { + s.codeMap = make(map[common.Address][]byte) } - return 0 } -func (s *stateDb) SetCode(_ common.Address, _ []byte) { - s.codeSet = true +func (s *stateDb) GetState(addr common.Address, key common.Hash) common.Hash { + if s.storage == nil { + return common.Hash{} + } + if _, ok := s.storage[addr]; !ok { + return common.Hash{} + } + + return s.storage[addr][key] +} + +func (s *stateDb) SetState(addr common.Address, key common.Hash, value common.Hash) { + if s.storage == nil { + s.storage = make(map[common.Address]map[common.Hash]common.Hash) + } + if _, ok := s.storage[addr]; !ok { + s.storage[addr] = map[common.Hash]common.Hash{key: value} + } else { + s.storage[addr][key] = value + } } diff --git a/consensus/misc/frxusd.go b/consensus/misc/frxusd.go new file mode 100644 index 000000000..7c50a9cb6 --- /dev/null +++ b/consensus/misc/frxusd.go @@ -0,0 +1,22 @@ +package misc + +import ( + "github.com/ethereum/go-ethereum/consensus/misc/frxusd" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/params" +) + +func EnsureFrxUSD(c *params.ChainConfig, timestamp uint64, db vm.StateDB) { + if !c.IsOptimism() || c.GraniteTime == nil || *c.GraniteTime != timestamp { + return + } + + switch c.ChainID.Uint64() { + case 2521: + frxusd.RunDevnetMigration(c, timestamp, db) + case 2522: + frxusd.RunTestnetMigration(c, timestamp, db) + default: + frxusd.RunMainnetMigration(c, timestamp, db) + } +} diff --git a/consensus/misc/frxusd/constants.go b/consensus/misc/frxusd/constants.go new file mode 100644 index 000000000..d322caeb8 --- /dev/null +++ b/consensus/misc/frxusd/constants.go @@ -0,0 +1,28 @@ +package frxusd + +import "github.com/ethereum/go-ethereum/common" + +var frxUSDMigrationProxyCodeAddress = common.HexToAddress("0xfc0000000000000000000000000000000000000a") +var frxUSDProxyAdminAddress = common.HexToAddress("0xfc0000000000000000000000000000000000000a") +var frxUSDProxyAdminSlot = common.HexToHash("0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103") +var frxUSDProxyImplementationSlot = common.HexToHash("0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc") + +var frxUSDAddress = common.HexToAddress("0xfc00000000000000000000000000000000000001") +var frxUSDImplementationAddress = common.HexToAddress("0xfcc0d30000000000000000000000000000000001") +var frxUSDNameBytes = common.HexToHash("0x4672617820555344000000000000000000000000000000000000000000000010") // Frax USD +var frxUSDSymbolBytes = common.HexToHash("0x667278555344000000000000000000000000000000000000000000000000000c") // frxUSD +var frxUSDL1Token = common.FromHex("0xCAcd6fd266aF91b8AeD52aCCc382b4e165586E29") + +var sfrxUSDAddress = common.HexToAddress("0xfc00000000000000000000000000000000000008") +var sfrxUSDImplementationAddress = common.HexToAddress("0xfcc0d30000000000000000000000000000000008") +var sfrxUSDNameBytes = common.HexToHash("0x5374616b6564204672617820555344000000000000000000000000000000001e") // Staked Frax USD +var sfrxUSDSymbolBytes = common.HexToHash("0x736672785553440000000000000000000000000000000000000000000000000e") // sfrxUSD +var sfrxUSDL1Token = common.FromHex("0xcf62F905562626CfcDD2261162a51fd02Fc9c5b6") + +var frxUSDL1TokenReplacementIndexes = []uint{2137, 6850, 7218} +var sfrxUSDL1TokenReplacementIndexes = []uint{2137, 6850, 7218} + +var testnetFrxUSDL1TokenReplacementIndexes = []uint{2137, 6962, 7330} + +var devnetFrxUSDL1TokenReplacementIndexes = []uint{693, 1303} +var devnetSfrxUSDL1TokenReplacementIndexes = []uint{693, 1303} diff --git a/consensus/misc/frxusd/devnet.go b/consensus/misc/frxusd/devnet.go new file mode 100644 index 000000000..4b752bbed --- /dev/null +++ b/consensus/misc/frxusd/devnet.go @@ -0,0 +1,41 @@ +package frxusd + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" +) + +func RunDevnetMigration(c *params.ChainConfig, timestamp uint64, db vm.StateDB) { + log.Info("Getting frxUSD/sfrxUSD proxy code", "address", frxUSDMigrationProxyCodeAddress) + proxyCode := db.GetCode(frxUSDMigrationProxyCodeAddress) + log.Info("Moving frxUSD implementation", "from", frxUSDAddress, "to", frxUSDImplementationAddress) + frxUSDImplementationCode := db.GetCode(frxUSDAddress) + for _, i := range devnetFrxUSDL1TokenReplacementIndexes { + copy(frxUSDImplementationCode[i:], frxUSDL1Token) + } + db.SetCode(frxUSDImplementationAddress, frxUSDImplementationCode) + log.Info("Setting frxUSD proxy", "address", frxUSDAddress) + db.SetCode(frxUSDAddress, proxyCode) + log.Info("Setting frxUSD storage variables", "address", frxUSDAddress) + db.SetState(frxUSDAddress, frxUSDProxyAdminSlot, common.BytesToHash(common.LeftPadBytes(frxUSDProxyAdminAddress.Bytes(), common.HashLength))) + db.SetState(frxUSDAddress, frxUSDProxyImplementationSlot, common.BytesToHash(common.LeftPadBytes(frxUSDImplementationAddress.Bytes(), common.HashLength))) + db.SetState(frxUSDAddress, common.HexToHash("0x03"), frxUSDNameBytes) + db.SetState(frxUSDAddress, common.HexToHash("0x04"), frxUSDSymbolBytes) + db.SetState(frxUSDAddress, common.HexToHash("0x04"), frxUSDSymbolBytes) + + log.Info("Moving sfrxUSD implementation", "from", sfrxUSDAddress, "to", sfrxUSDImplementationAddress) + sfrxUSDImplementationCode := db.GetCode(sfrxUSDAddress) + for _, i := range devnetSfrxUSDL1TokenReplacementIndexes { + copy(sfrxUSDImplementationCode[i:], sfrxUSDL1Token) + } + db.SetCode(sfrxUSDImplementationAddress, sfrxUSDImplementationCode) + log.Info("Setting sfrxUSD proxy", "address", frxUSDAddress) + db.SetCode(sfrxUSDAddress, proxyCode) + log.Info("Setting sfrxUSD proxy and storage", "address", sfrxUSDAddress) + db.SetState(sfrxUSDAddress, frxUSDProxyAdminSlot, common.BytesToHash(common.LeftPadBytes(frxUSDProxyAdminAddress.Bytes(), common.HashLength))) + db.SetState(sfrxUSDAddress, frxUSDProxyImplementationSlot, common.BytesToHash(common.LeftPadBytes(sfrxUSDImplementationAddress.Bytes(), common.HashLength))) + db.SetState(sfrxUSDAddress, common.HexToHash("0x03"), sfrxUSDNameBytes) + db.SetState(sfrxUSDAddress, common.HexToHash("0x04"), sfrxUSDSymbolBytes) +} diff --git a/consensus/misc/frxusd/mainnet.go b/consensus/misc/frxusd/mainnet.go new file mode 100644 index 000000000..818f83b5a --- /dev/null +++ b/consensus/misc/frxusd/mainnet.go @@ -0,0 +1,41 @@ +package frxusd + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" +) + +func RunMainnetMigration(c *params.ChainConfig, timestamp uint64, db vm.StateDB) { + log.Info("Getting frxUSD/sfrxUSD proxy code", "address", frxUSDMigrationProxyCodeAddress) + proxyCode := db.GetCode(frxUSDMigrationProxyCodeAddress) + log.Info("Moving frxUSD implementation", "from", frxUSDAddress, "to", frxUSDImplementationAddress) + frxUSDImplementationCode := db.GetCode(frxUSDAddress) + for _, i := range frxUSDL1TokenReplacementIndexes { + copy(frxUSDImplementationCode[i:], frxUSDL1Token) + } + db.SetCode(frxUSDImplementationAddress, frxUSDImplementationCode) + log.Info("Setting frxUSD proxy", "address", frxUSDAddress) + db.SetCode(frxUSDAddress, proxyCode) + log.Info("Setting frxUSD storage variables", "address", frxUSDAddress) + db.SetState(frxUSDAddress, frxUSDProxyAdminSlot, common.BytesToHash(common.LeftPadBytes(frxUSDProxyAdminAddress.Bytes(), common.HashLength))) + db.SetState(frxUSDAddress, frxUSDProxyImplementationSlot, common.BytesToHash(common.LeftPadBytes(frxUSDImplementationAddress.Bytes(), common.HashLength))) + db.SetState(frxUSDAddress, common.HexToHash("0x03"), frxUSDNameBytes) + db.SetState(frxUSDAddress, common.HexToHash("0x04"), frxUSDSymbolBytes) + db.SetState(frxUSDAddress, common.HexToHash("0x04"), frxUSDSymbolBytes) + + log.Info("Moving sfrxUSD implementation", "from", sfrxUSDAddress, "to", sfrxUSDImplementationAddress) + sfrxUSDImplementationCode := db.GetCode(sfrxUSDAddress) + for _, i := range sfrxUSDL1TokenReplacementIndexes { + copy(sfrxUSDImplementationCode[i:], sfrxUSDL1Token) + } + db.SetCode(sfrxUSDImplementationAddress, sfrxUSDImplementationCode) + log.Info("Setting sfrxUSD proxy", "address", frxUSDAddress) + db.SetCode(sfrxUSDAddress, proxyCode) + log.Info("Setting sfrxUSD proxy and storage", "address", sfrxUSDAddress) + db.SetState(sfrxUSDAddress, frxUSDProxyAdminSlot, common.BytesToHash(common.LeftPadBytes(frxUSDProxyAdminAddress.Bytes(), common.HashLength))) + db.SetState(sfrxUSDAddress, frxUSDProxyImplementationSlot, common.BytesToHash(common.LeftPadBytes(sfrxUSDImplementationAddress.Bytes(), common.HashLength))) + db.SetState(sfrxUSDAddress, common.HexToHash("0x03"), sfrxUSDNameBytes) + db.SetState(sfrxUSDAddress, common.HexToHash("0x04"), sfrxUSDSymbolBytes) +} diff --git a/consensus/misc/frxusd/testnet.go b/consensus/misc/frxusd/testnet.go new file mode 100644 index 000000000..8ddd98d88 --- /dev/null +++ b/consensus/misc/frxusd/testnet.go @@ -0,0 +1,27 @@ +package frxusd + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" +) + +func RunTestnetMigration(c *params.ChainConfig, timestamp uint64, db vm.StateDB) { + log.Info("Getting frxUSD proxy code", "address", frxUSDMigrationProxyCodeAddress) + proxyCode := db.GetCode(frxUSDMigrationProxyCodeAddress) + log.Info("Moving frxUSD implementation", "from", frxUSDAddress, "to", frxUSDImplementationAddress) + frxUSDImplementationCode := db.GetCode(frxUSDAddress) + for _, i := range testnetFrxUSDL1TokenReplacementIndexes { + copy(frxUSDImplementationCode[i:], frxUSDL1Token) + } + db.SetCode(frxUSDImplementationAddress, frxUSDImplementationCode) + log.Info("Setting frxUSD proxy", "address", frxUSDAddress) + db.SetCode(frxUSDAddress, proxyCode) + log.Info("Setting frxUSD storage variables", "address", frxUSDAddress) + db.SetState(frxUSDAddress, frxUSDProxyAdminSlot, common.BytesToHash(common.LeftPadBytes(frxUSDProxyAdminAddress.Bytes(), common.HashLength))) + db.SetState(frxUSDAddress, frxUSDProxyImplementationSlot, common.BytesToHash(common.LeftPadBytes(frxUSDImplementationAddress.Bytes(), common.HashLength))) + db.SetState(frxUSDAddress, common.HexToHash("0x03"), frxUSDNameBytes) + db.SetState(frxUSDAddress, common.HexToHash("0x04"), frxUSDSymbolBytes) + db.SetState(frxUSDAddress, common.HexToHash("0x04"), frxUSDSymbolBytes) +} diff --git a/consensus/misc/frxusd_test.go b/consensus/misc/frxusd_test.go new file mode 100644 index 000000000..8b75ba0ee --- /dev/null +++ b/consensus/misc/frxusd_test.go @@ -0,0 +1,157 @@ +package misc + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/params" + "github.com/stretchr/testify/assert" +) + +func TestEnsureFrxUSDMainnet(t *testing.T) { + graniteTime := uint64(1000) + var tests = []struct { + name string + override func(cfg *params.ChainConfig) + timestamp uint64 + codeExists bool + applied bool + }{ + { + name: "at hardfork", + timestamp: graniteTime, + applied: true, + }, + { + name: "another chain ID", + override: func(cfg *params.ChainConfig) { + cfg.ChainID = big.NewInt(params.OPMainnetChainID) + }, + timestamp: graniteTime, + applied: true, + }, + { + name: "code already exists", + timestamp: graniteTime, + codeExists: true, + applied: true, + }, + { + name: "pre hardfork", + timestamp: graniteTime - 1, + applied: false, + }, + { + name: "post hardfork", + timestamp: graniteTime + 1, + applied: false, + }, + { + name: "canyon not configured", + override: func(cfg *params.ChainConfig) { + cfg.GraniteTime = nil + }, + timestamp: graniteTime, + applied: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cfg := params.ChainConfig{ + ChainID: big.NewInt(252), + Optimism: ¶ms.OptimismConfig{}, + GraniteTime: &graniteTime, + } + if tt.override != nil { + tt.override(&cfg) + } + state := &stateDb{ + codeMap: map[common.Address][]byte{ + common.HexToAddress("0xfc0000000000000000000000000000000000000a"): {0}, + common.HexToAddress("0xfc00000000000000000000000000000000000001"): make([]byte, 10000), + common.HexToAddress("0xfc00000000000000000000000000000000000008"): make([]byte, 10000), + }, + } + EnsureFrxUSD(&cfg, tt.timestamp, state) + assert.Equal(t, tt.applied, state.GetCodeSize(common.HexToAddress("0xfcc0d30000000000000000000000000000000001")) > 0) + assert.Equal(t, tt.applied, state.GetCodeSize(common.HexToAddress("0xfcc0d30000000000000000000000000000000008")) > 0) + if tt.applied { + assert.Equal(t, state.GetCode(common.HexToAddress("0xfc00000000000000000000000000000000000001")), state.GetCode(common.HexToAddress("0xfc0000000000000000000000000000000000000a"))) + assert.Equal(t, state.GetCode(common.HexToAddress("0xfc00000000000000000000000000000000000008")), state.GetCode(common.HexToAddress("0xfc0000000000000000000000000000000000000a"))) + } else { + assert.NotEqual(t, state.GetCode(common.HexToAddress("0xfc00000000000000000000000000000000000001")), state.GetCode(common.HexToAddress("0xfc0000000000000000000000000000000000000a"))) + assert.NotEqual(t, state.GetCode(common.HexToAddress("0xfc00000000000000000000000000000000000008")), state.GetCode(common.HexToAddress("0xfc0000000000000000000000000000000000000a"))) + } + }) + } +} + +func TestEnsureFrxUSDTestnet(t *testing.T) { + graniteTime := uint64(1000) + var tests = []struct { + name string + override func(cfg *params.ChainConfig) + timestamp uint64 + codeExists bool + applied bool + }{ + { + name: "at hardfork", + timestamp: graniteTime, + applied: true, + }, + { + name: "code already exists", + timestamp: graniteTime, + codeExists: true, + applied: true, + }, + { + name: "pre hardfork", + timestamp: graniteTime - 1, + applied: false, + }, + { + name: "post hardfork", + timestamp: graniteTime + 1, + applied: false, + }, + { + name: "canyon not configured", + override: func(cfg *params.ChainConfig) { + cfg.GraniteTime = nil + }, + timestamp: graniteTime, + applied: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cfg := params.ChainConfig{ + ChainID: big.NewInt(2522), + Optimism: ¶ms.OptimismConfig{}, + GraniteTime: &graniteTime, + } + if tt.override != nil { + tt.override(&cfg) + } + state := &stateDb{ + codeMap: map[common.Address][]byte{ + common.HexToAddress("0xfc0000000000000000000000000000000000000a"): {0}, + common.HexToAddress("0xfc00000000000000000000000000000000000001"): make([]byte, 10000), + }, + } + EnsureFrxUSD(&cfg, tt.timestamp, state) + assert.Equal(t, tt.applied, state.GetCodeSize(common.HexToAddress("0xfcc0d30000000000000000000000000000000001")) > 0) + assert.True(t, state.GetCodeSize(common.HexToAddress("0xfcc0d30000000000000000000000000000000008")) == 0) + if tt.applied { + assert.Equal(t, state.GetCode(common.HexToAddress("0xfc00000000000000000000000000000000000001")), state.GetCode(common.HexToAddress("0xfc0000000000000000000000000000000000000a"))) + assert.Equal(t, state.GetCode(common.HexToAddress("0xfc00000000000000000000000000000000000008")), []byte(nil)) + } else { + assert.NotEqual(t, state.GetCode(common.HexToAddress("0xfc00000000000000000000000000000000000001")), state.GetCode(common.HexToAddress("0xfc0000000000000000000000000000000000000a"))) + assert.Equal(t, state.GetCode(common.HexToAddress("0xfc00000000000000000000000000000000000008")), []byte(nil)) + } + }) + } +} diff --git a/core/state_processor.go b/core/state_processor.go index a1042cf86..eab6f3120 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -69,6 +69,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg misc.ApplyDAOHardFork(statedb) } misc.EnsureCreate2Deployer(p.config, block.Time(), statedb) + misc.EnsureFrxUSD(p.config, block.Time(), statedb) var ( context vm.BlockContext signer = types.MakeSigner(p.config, header.Number, header.Time) diff --git a/miner/worker.go b/miner/worker.go index c3bd10089..feb9b86fa 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -144,6 +144,7 @@ func (miner *Miner) generateWork(params *generateParams, witness bool) *newPaylo } misc.EnsureCreate2Deployer(miner.chainConfig, work.header.Time, work.state) + misc.EnsureFrxUSD(miner.chainConfig, work.header.Time, work.state) for _, tx := range params.txs { from, _ := types.Sender(work.signer, tx)