Skip to content

Commit

Permalink
Introducing OptimizedStack based on uint256 integers (#170)
Browse files Browse the repository at this point in the history
* Introducing OptimizedStack based on uint256 integers (#156)

* Introducing OptimizedStack based on uint256 integers.

* Replacing big.int with uint256 for jump instruction.

* Update state/runtime/evm/instructions.go

Co-authored-by: Goran Rojovic <[email protected]>

* Code review fixes.

* opMStore is changed to use newly introduced WriteToSlice() function with unrolled loop. This allows CPU to execute multiple instructions in parallel providing >200% increased speed compared to uint256.WriteToSlice() implementation. If needed, can be additionally implemented for different array lengths.

* Fixing linter errors.

* setBytes to use uint256 instead of big.int.

* Fixing linter errors.

* Go mod tidy

* Lint fix

* Revert go version

* Address comments

* Remove pointer dereferencing and use value type reference

---------

Co-authored-by: Goran Rojovic <[email protected]>
Co-authored-by: Stefan Negovanović <[email protected]>

* Updating tracer to use optimized stack directly, instead of big.int.

* Removing remaining big.int references from instructions.go and state.go where possible. Removing unused functions and constants.

* Adding error handling for invalid balance and invalid message value.

* Adding benchmark tests for OptimizedStack.

* Group dependencies

* Fixing state error code name for errInvalidBalanceValue.

---------

Co-authored-by: cokicm <[email protected]>
Co-authored-by: Goran Rojovic <[email protected]>
  • Loading branch information
3 people authored May 29, 2024
1 parent 0a412e3 commit f20097c
Show file tree
Hide file tree
Showing 20 changed files with 1,188 additions and 833 deletions.
2 changes: 1 addition & 1 deletion e2e-polybft/e2e/jsonrpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ func TestE2E_JsonRPC(t *testing.T) {
require.NoError(t, err)

resp, err := ethClient.Call(&jsonrpc.CallMsg{
From: types.Address(acctZeroBalance.Address()),
From: acctZeroBalance.Address(),
To: &target,
Data: input,
}, jsonrpc.LatestBlockNumber, nil)
Expand Down
2 changes: 1 addition & 1 deletion e2e-polybft/e2e/storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func TestE2E_Storage(t *testing.T) {
}

txn.SetFrom(sender.Address())
txn.SetTo((*types.Address)(&to))
txn.SetTo(&to)
txn.SetGas(21000)
txn.SetValue(big.NewInt(int64(i)))
txn.SetNonce(uint64(i))
Expand Down
4 changes: 2 additions & 2 deletions e2e-polybft/e2e/txpool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func TestE2E_TxPool_Transfer(t *testing.T) {
if i%2 == 0 {
txData = types.NewDynamicFeeTx(
types.WithFrom(sender.Address()),
types.WithTo((*types.Address)(&to)),
types.WithTo(&to),
types.WithGas(30000), // enough to send a transfer
types.WithValue(big.NewInt(int64(sendAmount))),
types.WithNonce(uint64(i)),
Expand All @@ -69,7 +69,7 @@ func TestE2E_TxPool_Transfer(t *testing.T) {
} else {
txData = types.NewLegacyTx(
types.WithFrom(sender.Address()),
types.WithTo((*types.Address)(&to)),
types.WithTo(&to),
types.WithGas(30000),
types.WithValue(big.NewInt(int64(sendAmount))),
types.WithNonce(uint64(i)),
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ require (
github.com/hashicorp/golang-lru v1.0.2
github.com/hashicorp/hcl v1.0.1-vault-5
github.com/hashicorp/vault/api v1.13.0
github.com/holiman/uint256 v1.2.4
github.com/json-iterator/go v1.1.12
github.com/libp2p/go-libp2p v0.33.2
github.com/libp2p/go-libp2p-kbucket v0.6.3
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,8 @@ github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31
github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
github.com/hashicorp/vault/api v1.13.0 h1:RTCGpE2Rgkn9jyPcFlc7YmNocomda44k5ck8FKMH41Y=
github.com/hashicorp/vault/api v1.13.0/go.mod h1:0cb/uZUv1w2cVu9DIvuW1SMlXXC6qtATJt+LXJRx+kg=
github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU=
github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=
github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
Expand Down
7 changes: 3 additions & 4 deletions state/runtime/evm/dispatch_table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,10 @@ func TestPushOpcodes(t *testing.T) {

assert.False(t, s.stop)

res := s.pop().Bytes()
assert.Len(t, res, c)

assert.True(t, bytes.HasPrefix(code[1:], res))
v := s.pop()
assert.Len(t, v.Bytes(), c)

assert.True(t, bytes.HasPrefix(code[1:], v.Bytes()))
c++
}
}
13 changes: 7 additions & 6 deletions state/runtime/evm/evm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/0xPolygon/polygon-edge/state/runtime"
"github.com/0xPolygon/polygon-edge/state/runtime/tracer"
"github.com/0xPolygon/polygon-edge/types"
"github.com/holiman/uint256"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
Expand Down Expand Up @@ -259,7 +260,7 @@ type mockTracer struct {

func (m *mockTracer) CaptureState(
memory []byte,
stack []*big.Int,
stack []uint256.Int,
opCode int,
contractAddress types.Address,
sp int,
Expand Down Expand Up @@ -330,7 +331,7 @@ func TestRunWithTracer(t *testing.T) {
name: "CaptureState",
args: map[string]interface{}{
"memory": []byte{},
"stack": []*big.Int{},
"stack": []uint256.Int{},
"opCode": int(PUSH1),
"contractAddress": contractAddress,
"sp": 0,
Expand All @@ -353,8 +354,8 @@ func TestRunWithTracer(t *testing.T) {
name: "CaptureState",
args: map[string]interface{}{
"memory": []byte{},
"stack": []*big.Int{
big.NewInt(1),
"stack": []uint256.Int{
*uint256.NewInt(1),
},
"opCode": int(0),
"contractAddress": contractAddress,
Expand All @@ -375,7 +376,7 @@ func TestRunWithTracer(t *testing.T) {
name: "CaptureState",
args: map[string]interface{}{
"memory": []byte{},
"stack": []*big.Int{},
"stack": []uint256.Int{},
"opCode": int(POP),
"contractAddress": contractAddress,
"sp": 0,
Expand Down Expand Up @@ -425,7 +426,7 @@ func TestRunWithTracer(t *testing.T) {
state.config = config

// make sure stack, memory, and returnData are empty
state.stack = make([]*big.Int, 0)
state.stack.data = make([]uint256.Int, 0)
state.memory = make([]byte, 0)
state.returnData = make([]byte, 0)

Expand Down
Loading

0 comments on commit f20097c

Please sign in to comment.