Skip to content

Commit

Permalink
addBalance precompile is added
Browse files Browse the repository at this point in the history
  • Loading branch information
esiler committed Dec 25, 2024
1 parent b465ad5 commit 8b25cf7
Show file tree
Hide file tree
Showing 9 changed files with 353 additions and 2 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
github.com/developerblockchain/zkrp v0.0.0-20230207172934-f832ddb0731c // indirect
github.com/distribution/reference v0.5.0 // indirect
github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/docker/go-connections v0.4.0 // indirect
Expand Down
100 changes: 100 additions & 0 deletions go.sum

Large diffs are not rendered by default.

56 changes: 56 additions & 0 deletions precompile/contracts/addbalance/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package addbalance

import (
"github.com/ava-labs/subnet-evm/precompile/precompileconfig"
"github.com/ethereum/go-ethereum/common"
)

var _ precompileconfig.Config = &Config{}

// Config implements the StatefulPrecompileConfig interface while adding in the
// TxAllowList specific precompile config.
type Config struct {
precompileconfig.Upgrade
}

// NewConfig returns a config for a network upgrade at [blockTimestamp] that enables
// TxAllowList with the given [admins], [enableds] and [managers] as members of the allowlist.
func NewConfig(blockTimestamp *uint64, admins []common.Address, enableds []common.Address, managers []common.Address) *Config {
return &Config{
Upgrade: precompileconfig.Upgrade{BlockTimestamp: blockTimestamp},
}
}

// NewDisableConfig returns config for a network upgrade at [blockTimestamp]
// that disables TxAllowList.
func NewDisableConfig(blockTimestamp *uint64) *Config {
return &Config{
Upgrade: precompileconfig.Upgrade{
BlockTimestamp: blockTimestamp,
Disable: true,
},
}
}

func (c *Config) Key() string { return ConfigKey }

// Equal returns true if [cfg] is a [*TxAllowListConfig] and it has been configured identical to [c].
func (c *Config) Equal(cfg precompileconfig.Config) bool {
// typecast before comparison
other, ok := (cfg).(*Config)
if !ok {
return false
}
// CUSTOM CODE STARTS HERE
// modify this boolean accordingly with your custom Config, to check if [other] and the current [c] are equal
// if Config contains only Upgrade you can skip modifying it.
equals := c.Upgrade.Equal(&other.Upgrade)
return equals
}

func (c *Config) Verify(chainConfig precompileconfig.ChainConfig) error {
return nil
}
48 changes: 48 additions & 0 deletions precompile/contracts/addbalance/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package addbalance

import (
"testing"

"github.com/ava-labs/subnet-evm/precompile/allowlist"
"github.com/ava-labs/subnet-evm/precompile/precompileconfig"
"github.com/ava-labs/subnet-evm/precompile/testutils"
"github.com/ava-labs/subnet-evm/utils"
"github.com/ethereum/go-ethereum/common"
"go.uber.org/mock/gomock"
)

func TestVerify(t *testing.T) {
allowlist.VerifyPrecompileWithAllowListTests(t, Module, nil)
}

func TestEqual(t *testing.T) {
admins := []common.Address{allowlist.TestAdminAddr}
enableds := []common.Address{allowlist.TestEnabledAddr}
managers := []common.Address{allowlist.TestManagerAddr}
tests := map[string]testutils.ConfigEqualTest{
"non-nil config and nil other": {
Config: NewConfig(utils.NewUint64(3), admins, enableds, managers),
Other: nil,
Expected: false,
},
"different type": {
Config: NewConfig(nil, nil, nil, nil),
Other: precompileconfig.NewMockConfig(gomock.NewController(t)),
Expected: false,
},
"different timestamp": {
Config: NewConfig(utils.NewUint64(3), admins, enableds, managers),
Other: NewConfig(utils.NewUint64(4), admins, enableds, managers),
Expected: false,
},
"same config": {
Config: NewConfig(utils.NewUint64(3), admins, enableds, managers),
Other: NewConfig(utils.NewUint64(3), admins, enableds, managers),
Expected: true,
},
}
allowlist.EqualPrecompileWithAllowListTests(t, Module, tests)
}
1 change: 1 addition & 0 deletions precompile/contracts/addbalance/contract.abi
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"inputs":[{"internalType":"bytes","name":"_b1","type":"bytes"},{"internalType":"bytes","name":"_b2","type":"bytes"}],"name":"addEncBalances","outputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"stateMutability":"nonpayable","type":"function"}]
74 changes: 74 additions & 0 deletions precompile/contracts/addbalance/contract.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package addbalance

import (
_ "embed"
"fmt"
"github.com/ava-labs/subnet-evm/precompile/contract"
"github.com/ava-labs/subnet-evm/vmerrs"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"takaszk-v2/zeroknowledge"
)

const (
// GasCost Gas costs for each function. These are set to 1 by default.
// You should set a gas cost for each function in your contract.
// Generally, you should not set gas costs very low as this may cause your network to be vulnerable to DoS attacks.
// There are some predefined gas costs in contract/utils.go that you can use.
GasCost uint64 = 18 /* SET A GAS COST HERE */
)

// Singleton StatefulPrecompiledContract and signatures.
var (
// Singleton StatefulPrecompiledContract for setting fee configs by permissioned callers.
AddBalancePrecompile contract.StatefulPrecompiledContract = createAddBalancePrecompile()

// AddEncBalancesRawABI contains the raw ABI of AddEncBalances contract.
//go:embed contract.abi
AddEncBalancesRawABI string

AddEncBalancesABI = contract.ParseABI(AddEncBalancesRawABI)
)

func addEncBalances(accessibleState contract.AccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) {
if remainingGas, err = contract.DeductGas(suppliedGas, GasCost); err != nil {
return nil, 0, err
}
if readOnly {
return nil, remainingGas, vmerrs.ErrWriteProtection
}

logger := log.New("blockNumber", accessibleState.GetBlockContext().Number())
logger.Info("::::::::::::::::::::addEncBalances called:::::::::::::::::")

result := zeroknowledge.AddOrSubBalance(input, true, &err)

return result, remainingGas, err
}

// createAddEncBalancesPrecompile returns a StatefulPrecompiledContract with getters and setters for the precompile.

func createAddBalancePrecompile() contract.StatefulPrecompiledContract {
var functions []*contract.StatefulPrecompileFunction

abiFunctionMap := map[string]contract.RunStatefulPrecompileFunc{
"addEncBalances": addEncBalances,
}

for name, function := range abiFunctionMap {
method, ok := AddEncBalancesABI.Methods[name]
if !ok {
panic(fmt.Errorf("given method (%s) does not exist in the ABI", name))
}
functions = append(functions, contract.NewStatefulPrecompileFunction(method.ID, function))
}
// Construct the contract with no fallback function.
statefulContract, err := contract.NewStatefulPrecompileContract(nil, functions)
if err != nil {
panic(err)
}
return statefulContract
}
19 changes: 19 additions & 0 deletions precompile/contracts/addbalance/contract_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// (c) 2019-2023, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package addbalance

import (
"testing"

"github.com/ava-labs/subnet-evm/core/state"
"github.com/ava-labs/subnet-evm/precompile/allowlist"
)

func TestTxAllowListRun(t *testing.T) {
allowlist.RunPrecompileWithAllowListTests(t, Module, state.NewTestStateDB, nil)
}

func BenchmarkTxAllowList(b *testing.B) {
allowlist.BenchPrecompileWithAllowList(b, Module, state.NewTestStateDB, nil)
}
52 changes: 52 additions & 0 deletions precompile/contracts/addbalance/module.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package addbalance

import (
"fmt"

"github.com/ava-labs/subnet-evm/precompile/contract"
"github.com/ava-labs/subnet-evm/precompile/modules"
"github.com/ava-labs/subnet-evm/precompile/precompileconfig"
"github.com/ethereum/go-ethereum/common"
)

var _ contract.Configurator = &configurator{}

// ConfigKey is the key used in json config files to specify this precompile config.
// must be unique across all precompiles.
const ConfigKey = "addBalanceConfig"

var ContractAddress = common.HexToAddress("0x0300000000000000000000000000000000000018")

var Module = modules.Module{
ConfigKey: ConfigKey,
Address: ContractAddress,
Contract: AddBalancePrecompile,
Configurator: &configurator{},
}

type configurator struct{}

func init() {
if err := modules.RegisterModule(Module); err != nil {
panic(err)
}
}

// MakeConfig returns a new precompile config instance.
// This is required to Marshal/Unmarshal the precompile config.
func (*configurator) MakeConfig() precompileconfig.Config {
return new(Config)
}

// Configure configures [state] with the given [cfg] precompileconfig.
// This function is called by the EVM once per precompile contract activation.
func (*configurator) Configure(chainConfig precompileconfig.ChainConfig, cfg precompileconfig.Config, state contract.StateDB, blockContext contract.ConfigurationBlockContext) error {
if _, ok := cfg.(*Config); !ok {
return fmt.Errorf("expected config type %T, got %T: %v", &Config{}, cfg, cfg)
}

return nil
}
4 changes: 2 additions & 2 deletions precompile/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (

_ "github.com/ava-labs/subnet-evm/precompile/contracts/warp"
// ADD YOUR PRECOMPILE HERE
// _ "github.com/ava-labs/subnet-evm/precompile/contracts/yourprecompile"
_ "github.com/ava-labs/subnet-evm/precompile/contracts/addbalance"
)

// This list is kept just for reference. The actual addresses defined in respective packages of precompiles.
Expand All @@ -41,4 +41,4 @@ import (
// RewardManagerAddress = common.HexToAddress("0x0200000000000000000000000000000000000004")
// WarpAddress = common.HexToAddress("0x0200000000000000000000000000000000000005")
// ADD YOUR PRECOMPILE HERE
// {YourPrecompile}Address = common.HexToAddress("0x03000000000000000000000000000000000000??")
// AddBalanceAddress = common.HexToAddress("0x0300000000000000000000000000000000000018")

0 comments on commit 8b25cf7

Please sign in to comment.