mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
Add poseidon precompile
This commit is contained in:
parent
37b5a40ab8
commit
7c5c706016
4 changed files with 74 additions and 4 deletions
|
|
@ -104,11 +104,16 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{
|
|||
common.BytesToAddress([]byte{18}): &bls12381MapG2{},
|
||||
}
|
||||
|
||||
var PrecompiledContractsMina = map[common.Address]PrecompiledContract{
|
||||
common.BytesToAddress([]byte{0x50}): &MinaPoseidon{},
|
||||
}
|
||||
|
||||
var (
|
||||
PrecompiledAddressesBerlin []common.Address
|
||||
PrecompiledAddressesIstanbul []common.Address
|
||||
PrecompiledAddressesByzantium []common.Address
|
||||
PrecompiledAddressesHomestead []common.Address
|
||||
PrecompiledAddressesMina []common.Address
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
@ -124,19 +129,24 @@ func init() {
|
|||
for k := range PrecompiledContractsBerlin {
|
||||
PrecompiledAddressesBerlin = append(PrecompiledAddressesBerlin, k)
|
||||
}
|
||||
for k := range PrecompiledContractsMina {
|
||||
PrecompiledAddressesMina = append(PrecompiledAddressesMina, k)
|
||||
}
|
||||
}
|
||||
|
||||
// ActivePrecompiles returns the precompiles enabled with the current configuration.
|
||||
func ActivePrecompiles(rules params.Rules) []common.Address {
|
||||
result := PrecompiledAddressesMina
|
||||
|
||||
switch {
|
||||
case rules.IsBerlin:
|
||||
return PrecompiledAddressesBerlin
|
||||
return append(result, PrecompiledAddressesBerlin...)
|
||||
case rules.IsIstanbul:
|
||||
return PrecompiledAddressesIstanbul
|
||||
return append(result, PrecompiledAddressesIstanbul...)
|
||||
case rules.IsByzantium:
|
||||
return PrecompiledAddressesByzantium
|
||||
return append(result, PrecompiledAddressesByzantium...)
|
||||
default:
|
||||
return PrecompiledAddressesHomestead
|
||||
return append(result, PrecompiledAddressesHomestead...)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ type (
|
|||
)
|
||||
|
||||
func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
|
||||
if p, ok := PrecompiledContractsMina[addr]; ok {
|
||||
return p, ok
|
||||
}
|
||||
|
||||
var precompiles map[common.Address]PrecompiledContract
|
||||
switch {
|
||||
case evm.chainRules.IsBerlin:
|
||||
|
|
@ -53,6 +57,7 @@ func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
|
|||
default:
|
||||
precompiles = PrecompiledContractsHomestead
|
||||
}
|
||||
|
||||
p, ok := precompiles[addr]
|
||||
return p, ok
|
||||
}
|
||||
|
|
|
|||
54
core/vm/mina_contracts.go
Normal file
54
core/vm/mina_contracts.go
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
package vm
|
||||
|
||||
/*
|
||||
#cgo LDFLAGS: mina/target/release/libmina.a -ldl
|
||||
#include "../../mina/target/mina.h"
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"bytes"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
)
|
||||
|
||||
type MinaPoseidon struct{}
|
||||
|
||||
func (c *MinaPoseidon) RequiredGas(input []byte) uint64 {
|
||||
return 1000
|
||||
}
|
||||
|
||||
// 0x1f831f84
|
||||
var minaPoseidonSignature = crypto.Keccak256([]byte("poseidonHash(uint8,bytes32[])"))[:4]
|
||||
|
||||
const networkIdIndex = 0
|
||||
const fieldsHeadIndex = networkIdIndex + 32
|
||||
|
||||
func (c *MinaPoseidon) Run(input []byte) ([]byte, error) {
|
||||
if !bytes.Equal(input[:4], minaPoseidonSignature) {
|
||||
return nil, ErrExecutionReverted
|
||||
}
|
||||
|
||||
calldata := input[4:]
|
||||
|
||||
networkId := new(big.Int).SetBytes(getData(calldata, networkIdIndex, 32)).Uint64()
|
||||
|
||||
lenIndex := new(big.Int).SetBytes(getData(calldata, fieldsHeadIndex, 32)).Uint64()
|
||||
fieldsLen := new(big.Int).SetBytes(getData(calldata, lenIndex, 32)).Uint64()
|
||||
|
||||
dataIndex := lenIndex + 32
|
||||
fields := calldata[dataIndex : dataIndex+fieldsLen*32]
|
||||
|
||||
output_buffer := [32]byte{}
|
||||
|
||||
if !C.poseidon_hash(
|
||||
uint32(networkId),
|
||||
(*C.uint8_t)(&fields[0]),
|
||||
C.uintptr_t(fieldsLen),
|
||||
(*C.uint8_t)(&output_buffer[0]),
|
||||
) {
|
||||
return nil, ErrExecutionReverted
|
||||
}
|
||||
|
||||
return output_buffer[:], nil
|
||||
}
|
||||
1
mina/.gitignore
vendored
Normal file
1
mina/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/target
|
||||
Loading…
Reference in a new issue