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

CIP-26 precompile #1307

Merged
merged 57 commits into from
Jan 29, 2021
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
5271197
compiles
mrsmkl Nov 16, 2020
864d32b
wip cip22
kobigurk Nov 16, 2020
35a5ee8
implements all the cip22 changes. still remains to move to released c…
kobigurk Nov 16, 2020
34d70fe
remove 32 bit darwin target
kobigurk Nov 16, 2020
1b979f7
build only arm64 for ios
kobigurk Nov 16, 2020
5c7db35
fix typo
kobigurk Nov 16, 2020
82ddcf8
also build for ios/amd64
kobigurk Nov 16, 2020
eaa897c
update celo-bls-go
kobigurk Nov 17, 2020
07bb8db
lint
kobigurk Nov 17, 2020
445e25c
update celo-bls-go
kobigurk Nov 17, 2020
560237d
fix celo-bls-go
kobigurk Nov 17, 2020
ea864b1
Merge branch 'master' of github.com:celo-org/celo-blockchain into mrs…
mrsmkl Nov 19, 2020
39b469c
Merge branch 'kobigurk/cip22' of github.com:celo-org/celo-blockchain …
mrsmkl Nov 19, 2020
fd57717
add round number to epoch snark data
kobigurk Nov 19, 2020
30020a3
lint
kobigurk Nov 19, 2020
b62cddd
use fixed celo-bls-go
kobigurk Nov 19, 2020
55b4fbf
sorting out hardforks
mrsmkl Nov 20, 2020
1abe77d
added unit tests
mrsmkl Nov 20, 2020
0d1bf45
Merge remote-tracking branch 'origin/master' into kobigurk/cip22
kobigurk Nov 23, 2020
d601ee8
switch Celo1 with Donut
kobigurk Nov 23, 2020
cb370b6
replace more Celo1
kobigurk Nov 23, 2020
f011ba3
Fix max non signers
Nov 25, 2020
2beee9d
merge
mrsmkl Dec 1, 2020
482d0ff
still need to modify tests
mrsmkl Dec 1, 2020
b8c282e
tests working
mrsmkl Dec 2, 2020
7588189
Merge branch 'master' of github.com:celo-org/celo-blockchain into mrs…
mrsmkl Dec 2, 2020
08e3680
cleanup
mrsmkl Dec 2, 2020
f485685
merge
mrsmkl Dec 2, 2020
534d953
Update params/protocol_params.go
mrsmkl Dec 2, 2020
a933787
donut precompiles
mrsmkl Dec 2, 2020
bc5a501
Merge branch 'mrsmkl/precompile-bls-key' of github.com:celo-org/celo-…
mrsmkl Dec 2, 2020
253a683
make sure to get the key always
mrsmkl Dec 3, 2020
02ced03
fixing test
mrsmkl Dec 10, 2020
5c01027
Making maxvalidators external constant
Jan 7, 2021
3e090b8
Adding comment
Jan 7, 2021
e3fd5ae
Merge branch 'master' into kobigurk/cip22
kobigurk Jan 7, 2021
8488d5a
merge
mrsmkl Jan 8, 2021
ccd4ed7
Merge branch 'master' of github.com:celo-org/celo-blockchain into mrs…
mrsmkl Jan 8, 2021
b7e4d88
merge
mrsmkl Jan 8, 2021
f81712a
Merge remote-tracking branch 'origin/master' into mrsmkl/precompile-b…
kobigurk Jan 18, 2021
7a26fa9
Merge branch 'master' of github.com:celo-org/celo-blockchain into mr…
mrsmkl Jan 20, 2021
a0b3e4d
uncompress the bls keys when creating the snapshot
mrsmkl Jan 20, 2021
60b7444
uncompress here
mrsmkl Jan 20, 2021
4eac714
cleanup
mrsmkl Jan 20, 2021
f87f8a0
separate serialization with cached bls key
mrsmkl Jan 20, 2021
9162700
lint
mrsmkl Jan 20, 2021
e9f9b0d
clean up
mrsmkl Jan 22, 2021
3eed19e
Merge branch 'master' of github.com:celo-org/celo-blockchain into mrs…
mrsmkl Jan 28, 2021
15088e8
trying to get android to compile
mrsmkl Jan 28, 2021
b088522
trying to get android to compile
mrsmkl Jan 28, 2021
24d533c
review comments
mrsmkl Jan 29, 2021
4a8fdda
cleanup
mrsmkl Jan 29, 2021
570f9e1
cleanup
mrsmkl Jan 29, 2021
b938e23
copy method
mrsmkl Jan 29, 2021
8efc8fc
some tool keeps changing this
mrsmkl Jan 29, 2021
3180b92
store snapshot here
mrsmkl Jan 29, 2021
c5891c6
fix comment
mrsmkl Jan 29, 2021
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
1 change: 1 addition & 0 deletions consensus/istanbul/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,7 @@ func (sb *Backend) verifyValSetDiff(proposal istanbul.Proposal, block *types.Blo
oldValSet = append(oldValSet, istanbul.ValidatorData{
Address: val.Address(),
BLSPublicKey: val.BLSPublicKey(),
Uncompressed: val.BLSPublicKeyUncompressed(),
})
}

Expand Down
1 change: 1 addition & 0 deletions consensus/istanbul/backend/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type Snapshot struct {
// method does not initialize the set of recent validators, so only ever use if for
// the genesis block.
func newSnapshot(epoch uint64, number uint64, hash common.Hash, valSet istanbul.ValidatorSet) *Snapshot {
valSet.CacheUncompressed()
snap := &Snapshot{
Epoch: epoch,
Number: number,
Expand Down
11 changes: 9 additions & 2 deletions consensus/istanbul/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -618,8 +618,15 @@ func (c *core) createRoundState() (RoundState, error) {
roundState, err = c.rsdb.GetRoundStateFor(lastStoredView)

if err != nil {
logger.Error("Failed to fetch lastStoredRoundState", "err", err)
return nil, err
logger.Warn("Failed to fetch lastStoredRoundState", "err", err)
if err == leveldb.ErrNotFound {
mrsmkl marked this conversation as resolved.
Show resolved Hide resolved
logger.Info("Creating new RoundState", "reason", "No storedView found")
} else {
logger.Info("Creating new RoundState", "reason", "old view", "stored_view", lastStoredView, "requested_seq", nextSequence)
}
valSet := c.backend.Validators(headBlock)
proposer := c.selectProposer(valSet, headAuthor, 0)
roundState = newRoundState(&istanbul.View{Sequence: nextSequence, Round: common.Big0}, valSet, proposer)
}
}

Expand Down
1 change: 1 addition & 0 deletions consensus/istanbul/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ func ValidatorSetDiff(oldValSet []ValidatorData, newValSet []ValidatorData) ([]V
addedValidators = append(addedValidators, ValidatorData{
newVal.Address,
newVal.BLSPublicKey,
newVal.Uncompressed,
})
}
}
Expand Down
2 changes: 2 additions & 0 deletions consensus/istanbul/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,15 @@ func TestValidatorSetDiff(t *testing.T) {
convertedInputOldValSet = append(convertedInputOldValSet, ValidatorData{
addr,
blscrypto.SerializedPublicKey{},
nil,
})
}
convertedInputNewValSet := []ValidatorData{}
for _, addr := range tt.inputNewValset {
convertedInputNewValSet = append(convertedInputNewValSet, ValidatorData{
addr,
blscrypto.SerializedPublicKey{},
nil,
})
}
addedVals, removedVals := ValidatorSetDiff(convertedInputOldValSet, convertedInputNewValSet)
Expand Down
7 changes: 7 additions & 0 deletions consensus/istanbul/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ var (
type ValidatorData struct {
Address common.Address
BLSPublicKey blscrypto.SerializedPublicKey
Uncompressed []byte
}

type Validator interface {
Expand All @@ -44,6 +45,9 @@ type Validator interface {

BLSPublicKey() blscrypto.SerializedPublicKey

BLSPublicKeyUncompressed() []byte
CacheUncompressed()

// Serialize returns binary reprenstation of the Validator
// can be use used to instantiate a validator with DeserializeValidator()
Serialize() ([]byte, error)
Expand Down Expand Up @@ -120,6 +124,8 @@ type ValidatorSet interface {
// Copy validator set
Copy() ValidatorSet

CacheUncompressed()
mrsmkl marked this conversation as resolved.
Show resolved Hide resolved

// Serialize returns binary reprentation of the ValidatorSet
// can be use used to instantiate a validator with DeserializeValidatorSet()
Serialize() ([]byte, error)
Expand All @@ -146,6 +152,7 @@ func CombineIstanbulExtraToValidatorData(addrs []common.Address, blsPublicKeys [
validators = append(validators, ValidatorData{
Address: addrs[i],
BLSPublicKey: blsPublicKeys[i],
Uncompressed: nil,
})
}

Expand Down
20 changes: 20 additions & 0 deletions consensus/istanbul/validator/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,38 @@ import (
type defaultValidator struct {
address common.Address
blsPublicKey blscrypto.SerializedPublicKey
uncompressed []byte
mrsmkl marked this conversation as resolved.
Show resolved Hide resolved
}

func newValidatorFromData(data *istanbul.ValidatorData) *defaultValidator {
uncompressed := data.Uncompressed
if len(uncompressed) == 0 {
mrsmkl marked this conversation as resolved.
Show resolved Hide resolved
uncompressed = nil
mrsmkl marked this conversation as resolved.
Show resolved Hide resolved
}
return &defaultValidator{
address: data.Address,
blsPublicKey: data.BLSPublicKey,
uncompressed: uncompressed,
}
}

func (val *defaultValidator) AsData() *istanbul.ValidatorData {
return &istanbul.ValidatorData{
Address: val.address,
BLSPublicKey: val.blsPublicKey,
Uncompressed: val.uncompressed,
}
}

func (val *defaultValidator) Address() common.Address { return val.address }
func (val *defaultValidator) BLSPublicKey() blscrypto.SerializedPublicKey { return val.blsPublicKey }
func (val *defaultValidator) BLSPublicKeyUncompressed() []byte { return val.uncompressed }
mrsmkl marked this conversation as resolved.
Show resolved Hide resolved
func (val *defaultValidator) String() string { return val.Address().String() }

func (val *defaultValidator) CacheUncompressed() {
val.uncompressed = blscrypto.UncompressKey(val.blsPublicKey)
}

func (val *defaultValidator) Serialize() ([]byte, error) { return rlp.EncodeToBytes(val) }

// JSON Encoding -----------------------------------------------------------------------
Expand Down Expand Up @@ -145,6 +157,14 @@ func (valSet *defaultSet) String() string {
return fmt.Sprintf("{randomness: %s, validators: %s}", valSet.randomness.String(), buf.String())
}

func (valSet *defaultSet) CacheUncompressed() {
valSet.validatorMu.RLock()
defer valSet.validatorMu.RUnlock()
for _, v := range valSet.validators {
v.CacheUncompressed()
}
}

func (valSet *defaultSet) Size() int {
valSet.validatorMu.RLock()
defer valSet.validatorMu.RUnlock()
Expand Down
1 change: 1 addition & 0 deletions consensus/istanbul/validator/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func New(addr common.Address, blsPublicKey blscrypto.SerializedPublicKey) istanb
return &defaultValidator{
address: addr,
blsPublicKey: blsPublicKey,
uncompressed: nil,
}
}

Expand Down
1 change: 1 addition & 0 deletions contract_comm/validators/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ func GetValidatorData(header *types.Header, state vm.StateDB, validatorAddresses
validator := istanbul.ValidatorData{
Address: addr,
BLSPublicKey: blsKeyFixedSize,
Uncompressed: nil,
}
validatorData = append(validatorData, validator)
}
Expand Down
68 changes: 67 additions & 1 deletion core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ var PrecompiledContractsDonut = map[common.Address]PrecompiledContract{
b12_377G2MultiExpAddress: nil,
b12_377PairingAddress: nil,
cip20Address: nil,
cip26Address: nil,
cip26Address: &getValidatorBLS{},
}

// RunPrecompiledContract runs and evaluates the output of a precompiled contract.
Expand Down Expand Up @@ -945,6 +945,72 @@ func (c *getValidator) Run(input []byte, caller common.Address, evm *EVM, gas ui
return addressBytes, gas, nil
}

type getValidatorBLS struct{}

func (c *getValidatorBLS) RequiredGas(input []byte) uint64 {
return params.GetValidatorBLSGas
}

func copyBEtoLE(result []byte, offset int, uncompressedBytes []byte, offset2 int) {
for i := 0; i < 48; i++ {
result[63-i+offset] = uncompressedBytes[i+offset2]
}
}

// Return the validator BLS public key for the validator at given index. The public key is given in uncompressed format, 4*48 bytes.
func (c *getValidatorBLS) Run(input []byte, caller common.Address, evm *EVM, gas uint64) ([]byte, uint64, error) {
gas, err := debitRequiredGas(c, input, gas)
if err != nil {
return nil, gas, err
}

// input is comprised of two arguments:
// index: 32 byte integer representing the index of the validator to get
// blockNumber: 32 byte integer representing the block number to access
if len(input) < 64 {
return nil, gas, ErrInputLength
}

index := new(big.Int).SetBytes(input[0:32])

blockNumber := new(big.Int).SetBytes(input[32:64])
if blockNumber.Cmp(common.Big0) == 0 {
// Validator set for the genesis block is empty, so any index is out of bounds.
return nil, gas, ErrValidatorsOutOfBounds
}
if blockNumber.Cmp(evm.Context.BlockNumber) > 0 {
return nil, gas, ErrBlockNumberOutOfBounds
}

// Note: Passing empty hash as here as it is an extra expense and the hash is not actually used.
validators := evm.Context.Engine.GetValidators(new(big.Int).Sub(blockNumber, common.Big1), common.Hash{})

// Ensure index, which is guaranteed to be non-negative, is valid.
if index.Cmp(big.NewInt(int64(len(validators)))) >= 0 {
return nil, gas, ErrValidatorsOutOfBounds
}

uncompressedBytes := validators[index.Uint64()].BLSPublicKeyUncompressed()
if len(uncompressedBytes) == 0 {
mrsmkl marked this conversation as resolved.
Show resolved Hide resolved
uncompressedBytes = blscrypto.UncompressKey(validators[index.Uint64()].BLSPublicKey())
}
if len(uncompressedBytes) != 192 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this check be done the moment we compute the uncompressed key??

are all the others callers left to do the validation themselves, as if .BLSPublicKeyUncompressed() could return an invalid version of this???

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will return a string with length 0 if the compressed BLS public key is invalid. Of course, this should never be the case, but I think it's better to not crash with out of bounds access here.

return nil, gas, ErrUnexpected
}

result := make([]byte, 256)
for i := 0; i < 256; i++ {
result[i] = 0
}

copyBEtoLE(result, 0, uncompressedBytes, 0)
copyBEtoLE(result, 64, uncompressedBytes, 48)
copyBEtoLE(result, 128, uncompressedBytes, 96)
copyBEtoLE(result, 192, uncompressedBytes, 144)

return result, gas, nil
}

type numberValidators struct{}

func (c *numberValidators) RequiredGas(input []byte) uint64 {
Expand Down
68 changes: 61 additions & 7 deletions core/vm/contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/consensus/istanbul"
"github.com/ethereum/go-ethereum/consensus/istanbul/validator"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"golang.org/x/crypto/sha3"
Expand All @@ -54,7 +55,11 @@ func (e mockEngine) GetValidators(number *big.Int, _ common.Hash) []istanbul.Val
hash := sha3.Sum256(preimage)
var validators []istanbul.Validator
for i := 0; i < 16; i, hash = i+1, sha3.Sum256(hash[:]) {
validators = append(validators, validator.New(common.BytesToAddress(hash[:]), blscrypto.SerializedPublicKey{}))
key, _ := crypto.ToECDSA(hash[:])
blsPrivateKey, _ := blscrypto.ECDSAToBLS(key)
blsPublicKey, _ := blscrypto.PrivateToPublic(blsPrivateKey)
addr := crypto.PubkeyToAddress(key.PublicKey)
validators = append(validators, validator.New(addr, blsPublicKey))
}
return validators
}
Expand Down Expand Up @@ -579,12 +584,12 @@ var getValidatorTests = []precompiledTest{
},
{
input: "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff",
expected: "000000000000000000000000fa55ba38ef5f98473db2771dd03c17c02bbe0fdc",
expected: "000000000000000000000000fbb697cf00d3de24bc81225b4b2a9e7e763f8136",
name: "correct_block_0xff_index_0x0",
},
{
input: "000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ff",
expected: "00000000000000000000000068e2962e75d952ffabb71170783df3c2c85f7939",
expected: "0000000000000000000000003e70ba60978582c2770aa95579e542a521456668",
name: "correct_block_0xff_index_0xa",
},
{
Expand All @@ -595,7 +600,50 @@ var getValidatorTests = []precompiledTest{
},
{
input: "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002710",
expected: "00000000000000000000000024e11f684408ce3e35772daa281facf81d8be157",
expected: "000000000000000000000000a7fdb33d85f63259ff56133b5be795ef669a5756",
name: "correct_chain_head",
},
{
input: "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002711",
expected: "block number out of bounds",
name: "invalid_future_block",
errorExpected: true,
},
}

var getValidatorBLSPublicKeyTests = []precompiledTest{
// Input is { validator index | block number }. Output is validator BLS public key.
{
input: "",
expected: "invalid input length",
name: "input_invalid_empty",
errorExpected: true,
},
{
input: "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
expected: "validator index out of bounds",
name: "invalid_genesis_block",
errorExpected: true,
},
{
input: "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff",
expected: "00000000000000000000000000000000001fd78b7dee6db285d05c16aedcc6f33652607220efb1ab99d512c77d3dd77dba78c81d4190b4a633720d92c1a577f9000000000000000000000000000000000021bd7f370c65fba1afbcf16e256a82b6cdfea0a27d8df313edd1a881f41780609ee055b78974b1c8d97dac3c9461c300000000000000000000000000000000016366c10606045d43fb18300560995394a24bd1358b9210540f4ec29fdaaf8506af7651a8504230734a62b6599f744c0000000000000000000000000000000000209e3562ca2dc97e0182cd354662ff20bc2f312866b4655c3eed0af045de4133ab8b5f5a4cde9b2f12113e47d1157e",
name: "correct_block_0xff_index_0x0",
},
{
input: "000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ff",
expected: "00000000000000000000000000000000015398774c6805e5f7edc1cd2ce40c44bd5b430caa3dfefe740b12efa1708bb20aeadce71d5bfe288158b87f07dc82c700000000000000000000000000000000000d3dca6f108fa022d1e106db969e36622eaec7b2a4b3eefa94aee9982a0133ca09a86b142b71fab14c770e7e70763a0000000000000000000000000000000000ac437ff49e987559a9c9ec9a421d46f6b1044b2888e4c23653827e94b9c3729c897fc02db7364694f8bc5e783529c30000000000000000000000000000000000bc9531ebddea1c9ca9a08c0eafd7d0d734d17d54150d75c5d3d0ab3d416807693da02dababe8ef734a50083c2ef889",
name: "correct_block_0xff_index_0xa",
},
{
input: "000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000ff",
expected: "validator index out of bounds",
name: "invalid_index_out_of_bounds",
errorExpected: true,
},
{
input: "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002710",
expected: "000000000000000000000000000000000173d1ea9889757e8f176737629c7b6c446a6832ddec53562ebe0cda09455792927597a3025dd613021de96ebc2ecc130000000000000000000000000000000000866721e8b88328b0df9e6c52bd9bdcce076d9febeba542cf7d48e7fae54bbe783c785131678fb3f15c665f5c1fd1c500000000000000000000000000000000008a6412232130f837d31ce5223e088e338997fad1de25908ae7e4b65bfe2fe4839dcd41f5ae613d146796d98d65255c000000000000000000000000000000000039d57467b392c8c30b81e961469ff750a3473ffa423c12f671264ea9967f5bfd21b0247d02e132cdfd2682cf207ff9",
name: "correct_chain_head",
},
{
Expand Down Expand Up @@ -734,7 +782,7 @@ func testPrecompiled(addr string, test precompiledTest, t *testing.T) {
}

func testPrecompiledOOG(addr string, test precompiledTest, t *testing.T) {
p := PrecompiledContractsIstanbul[common.HexToAddress(addr)]
p := PrecompiledContractsDonut[common.HexToAddress(addr)]
in := common.Hex2Bytes(test.input)
contract := NewContract(AccountRef(common.HexToAddress("1337")),
nil, new(big.Int), p.RequiredGas(in)-1)
Expand All @@ -752,7 +800,7 @@ func testPrecompiledOOG(addr string, test precompiledTest, t *testing.T) {
}

func testPrecompiledFailure(addr string, test precompiledFailureTest, t *testing.T) {
p := PrecompiledContractsIstanbul[common.HexToAddress(addr)]
p := PrecompiledContractsDonut[common.HexToAddress(addr)]
in := common.Hex2Bytes(test.input)
contract := NewContract(AccountRef(common.HexToAddress("31337")),
nil, new(big.Int), p.RequiredGas(in))
Expand All @@ -774,7 +822,7 @@ func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) {
if test.noBenchmark {
return
}
p := PrecompiledContractsIstanbul[common.HexToAddress(addr)]
p := PrecompiledContractsDonut[common.HexToAddress(addr)]
in := common.Hex2Bytes(test.input)
reqGas := p.RequiredGas(in)
contract := NewContract(AccountRef(common.HexToAddress("1337")),
Expand Down Expand Up @@ -949,6 +997,12 @@ func TestGetValidator(t *testing.T) {
}
}

func TestGetValidatorBLSPublicKey(t *testing.T) {
for _, test := range getValidatorBLSPublicKeyTests {
testPrecompiled("e1", test, t)
}
}

// Tests sample inputs for numberValidators
func TestNumberValidators(t *testing.T) {
for _, test := range numberValidatorsTests {
Expand Down
6 changes: 6 additions & 0 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, err
if evm.chainRules.IsIstanbul {
precompiles = PrecompiledContractsIstanbul
}
if evm.chainRules.IsDonut {
precompiles = PrecompiledContractsDonut
}
if p := precompiles[*contract.CodeAddr]; p != nil {
return RunPrecompiledContract(p, input, contract, evm)
}
Expand Down Expand Up @@ -254,6 +257,9 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
if evm.chainRules.IsIstanbul {
precompiles = PrecompiledContractsIstanbul
}
if evm.chainRules.IsDonut {
precompiles = PrecompiledContractsDonut
}
if precompiles[addr] == nil && evm.chainRules.IsEIP158 && value.Sign() == 0 {
// Calling a non existing account, don't do anything, but ping the tracer
if evm.vmConfig.Debug && evm.depth == 0 {
Expand Down
Loading