diff --git a/core/vm/contracts.go b/core/vm/contracts.go index b7a52c134371..b7193f76f60e 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -61,7 +61,7 @@ var PrecompiledContractsByzantium = PrecompiledContracts{ common.BytesToAddress([]byte{2}): &sha256hash{}, common.BytesToAddress([]byte{3}): &ripemd160hash{}, common.BytesToAddress([]byte{4}): &dataCopy{}, - common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false}, + common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false, eip7823: false}, common.BytesToAddress([]byte{6}): &bn256AddByzantium{}, common.BytesToAddress([]byte{7}): &bn256ScalarMulByzantium{}, common.BytesToAddress([]byte{8}): &bn256PairingByzantium{}, @@ -78,7 +78,7 @@ var PrecompiledContractsIstanbul = PrecompiledContracts{ common.BytesToAddress([]byte{2}): &sha256hash{}, common.BytesToAddress([]byte{3}): &ripemd160hash{}, common.BytesToAddress([]byte{4}): &dataCopy{}, - common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false}, + common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false, eip7823: false}, common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, @@ -89,24 +89,42 @@ var PrecompiledContractsIstanbul = PrecompiledContracts{ common.BytesToAddress([]byte{42}): &XDCxEpochPrice{}, } +// PrecompiledContractsXDCv2 contains the default set of pre-compiled Ethereum +// contracts used in the XDC v2 release. var PrecompiledContractsXDCv2 = PrecompiledContracts{ common.BytesToAddress([]byte{1}): &ecrecover{}, common.BytesToAddress([]byte{2}): &sha256hash{}, common.BytesToAddress([]byte{3}): &ripemd160hash{}, common.BytesToAddress([]byte{4}): &dataCopy{}, - common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false}, + common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false, eip7823: false}, common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, common.BytesToAddress([]byte{9}): &blake2F{}, } +// PrecompiledContractsEIP1559 contains the set of pre-compiled Ethereum +// contracts used in the EIP1559 release. var PrecompiledContractsEIP1559 = PrecompiledContracts{ common.BytesToAddress([]byte{1}): &ecrecover{}, common.BytesToAddress([]byte{2}): &sha256hash{}, common.BytesToAddress([]byte{3}): &ripemd160hash{}, common.BytesToAddress([]byte{4}): &dataCopy{}, - common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true}, + common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true, eip7823: false}, + common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, + common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, + common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, + common.BytesToAddress([]byte{9}): &blake2F{}, +} + +// PrecompiledContractsOsaka contains the set of pre-compiled Ethereum +// contracts used in the Osaka release. +var PrecompiledContractsOsaka = PrecompiledContracts{ + common.BytesToAddress([]byte{1}): &ecrecover{}, + common.BytesToAddress([]byte{2}): &sha256hash{}, + common.BytesToAddress([]byte{3}): &ripemd160hash{}, + common.BytesToAddress([]byte{4}): &dataCopy{}, + common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true, eip7823: true}, common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, @@ -141,6 +159,8 @@ func init() { func activePrecompiledContracts(rules params.Rules) PrecompiledContracts { switch { + case rules.IsOsaka: + return PrecompiledContractsOsaka case rules.IsEIP1559: return PrecompiledContractsEIP1559 case rules.IsXDCxDisable: @@ -290,6 +310,7 @@ func (c *dataCopy) Run(in []byte) ([]byte, error) { // bigModExp implements a native big integer exponential modular operation. type bigModExp struct { eip2565 bool + eip7823 bool } var ( @@ -418,15 +439,24 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 { func (c *bigModExp) Run(input []byte) ([]byte, error) { var ( - baseLen = new(big.Int).SetBytes(getData(input, 0, 32)).Uint64() - expLen = new(big.Int).SetBytes(getData(input, 32, 32)).Uint64() - modLen = new(big.Int).SetBytes(getData(input, 64, 32)).Uint64() + baseLenBig = new(big.Int).SetBytes(getData(input, 0, 32)) + expLenBig = new(big.Int).SetBytes(getData(input, 32, 32)) + modLenBig = new(big.Int).SetBytes(getData(input, 64, 32)) + baseLen = baseLenBig.Uint64() + expLen = expLenBig.Uint64() + modLen = modLenBig.Uint64() + inputLenOverflow = max(baseLenBig.BitLen(), expLenBig.BitLen(), modLenBig.BitLen()) > 64 ) if len(input) > 96 { input = input[96:] } else { input = input[:0] } + + // enforce size cap for inputs + if c.eip7823 && (inputLenOverflow || max(baseLen, expLen, modLen) > 1024) { + return nil, errors.New("one or more of base/exponent/modulus length exceeded 1024 bytes") + } // Handle a special case when both the base and mod length is zero if baseLen == 0 && modLen == 0 { return []byte{}, nil