Add mina poseidon precompile unit tests

This commit is contained in:
Martin Ondejka 2023-04-20 15:48:26 +02:00
parent 48ec3a52c1
commit f9d1bf15af
4 changed files with 87 additions and 7 deletions

View file

@ -65,6 +65,8 @@ var allPrecompiles = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{16}): &bls12381Pairing{}, common.BytesToAddress([]byte{16}): &bls12381Pairing{},
common.BytesToAddress([]byte{17}): &bls12381MapG1{}, common.BytesToAddress([]byte{17}): &bls12381MapG1{},
common.BytesToAddress([]byte{18}): &bls12381MapG2{}, common.BytesToAddress([]byte{18}): &bls12381MapG2{},
common.BytesToAddress([]byte{0x50}): &MinaPoseidon{},
common.BytesToAddress([]byte{0x51}): &MinaSigner{},
} }
// EIP-152 test vectors // EIP-152 test vectors
@ -311,6 +313,7 @@ func TestPrecompiledBLS12381G2MultiExp(t *testing.T) { testJson("blsG2MultiExp",
func TestPrecompiledBLS12381Pairing(t *testing.T) { testJson("blsPairing", "10", t) } func TestPrecompiledBLS12381Pairing(t *testing.T) { testJson("blsPairing", "10", t) }
func TestPrecompiledBLS12381MapG1(t *testing.T) { testJson("blsMapG1", "11", t) } func TestPrecompiledBLS12381MapG1(t *testing.T) { testJson("blsMapG1", "11", t) }
func TestPrecompiledBLS12381MapG2(t *testing.T) { testJson("blsMapG2", "12", t) } func TestPrecompiledBLS12381MapG2(t *testing.T) { testJson("blsMapG2", "12", t) }
func TestPrecompiledMinaPoseidon(t *testing.T) { testJson("minaPoseidon", "50", t) }
func BenchmarkPrecompiledBLS12381G1Add(b *testing.B) { benchJson("blsG1Add", "0a", b) } func BenchmarkPrecompiledBLS12381G1Add(b *testing.B) { benchJson("blsG1Add", "0a", b) }
func BenchmarkPrecompiledBLS12381G1Mul(b *testing.B) { benchJson("blsG1Mul", "0b", b) } func BenchmarkPrecompiledBLS12381G1Mul(b *testing.B) { benchJson("blsG1Mul", "0b", b) }
@ -321,6 +324,7 @@ func BenchmarkPrecompiledBLS12381G2MultiExp(b *testing.B) { benchJson("blsG2Mult
func BenchmarkPrecompiledBLS12381Pairing(b *testing.B) { benchJson("blsPairing", "10", b) } func BenchmarkPrecompiledBLS12381Pairing(b *testing.B) { benchJson("blsPairing", "10", b) }
func BenchmarkPrecompiledBLS12381MapG1(b *testing.B) { benchJson("blsMapG1", "11", b) } func BenchmarkPrecompiledBLS12381MapG1(b *testing.B) { benchJson("blsMapG1", "11", b) }
func BenchmarkPrecompiledBLS12381MapG2(b *testing.B) { benchJson("blsMapG2", "12", b) } func BenchmarkPrecompiledBLS12381MapG2(b *testing.B) { benchJson("blsMapG2", "12", b) }
func BenchmarkPrecompiledMinaPoseidon(b *testing.B) { benchJson("minaPoseidon", "50", b) }
// Failure tests // Failure tests
func TestPrecompiledBLS12381G1AddFail(t *testing.T) { testJsonFail("blsG1Add", "0a", t) } func TestPrecompiledBLS12381G1AddFail(t *testing.T) { testJsonFail("blsG1Add", "0a", t) }
@ -332,6 +336,7 @@ func TestPrecompiledBLS12381G2MultiExpFail(t *testing.T) { testJsonFail("blsG2Mu
func TestPrecompiledBLS12381PairingFail(t *testing.T) { testJsonFail("blsPairing", "10", t) } func TestPrecompiledBLS12381PairingFail(t *testing.T) { testJsonFail("blsPairing", "10", t) }
func TestPrecompiledBLS12381MapG1Fail(t *testing.T) { testJsonFail("blsMapG1", "11", t) } func TestPrecompiledBLS12381MapG1Fail(t *testing.T) { testJsonFail("blsMapG1", "11", t) }
func TestPrecompiledBLS12381MapG2Fail(t *testing.T) { testJsonFail("blsMapG2", "12", t) } func TestPrecompiledBLS12381MapG2Fail(t *testing.T) { testJsonFail("blsMapG2", "12", t) }
func TestPrecompiledMinaPoseidonFail(t *testing.T) { testJsonFail("minaPoseidon", "50", t) }
func loadJson(name string) ([]precompiledTest, error) { func loadJson(name string) ([]precompiledTest, error) {
data, err := os.ReadFile(fmt.Sprintf("testdata/precompiles/%v.json", name)) data, err := os.ReadFile(fmt.Sprintf("testdata/precompiles/%v.json", name))

View file

@ -33,6 +33,7 @@ package vm
import "C" import "C"
import ( import (
"bytes" "bytes"
"errors"
"github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
@ -65,9 +66,14 @@ func (c *MinaPoseidon) RequiredGas(input []byte) uint64 {
// 0x1f831f84 // 0x1f831f84
var poseidonHashSignature = crypto.Keccak256([]byte("poseidonHash(uint8,bytes32[])"))[:4] var poseidonHashSignature = crypto.Keccak256([]byte("poseidonHash(uint8,bytes32[])"))[:4]
var (
errMinaPoseidonInvalidSignature = errors.New("invalid function signature")
errMinaPoseidonCallingRustLibFailed = errors.New("calling rust library failed")
)
func (c *MinaPoseidon) Run(input []byte) ([]byte, error) { func (c *MinaPoseidon) Run(input []byte) ([]byte, error) {
if len(input) < 4 || !bytes.Equal(input[:4], poseidonHashSignature) { if len(input) < 4 || !bytes.Equal(input[:4], poseidonHashSignature) {
return packErr("Invalid signature"), ErrExecutionReverted return packErr("Invalid signature"), errMinaPoseidonInvalidSignature
} }
calldata := input[4:] calldata := input[4:]
@ -84,19 +90,22 @@ func (c *MinaPoseidon) Run(input []byte) ([]byte, error) {
networkId := unpacked[0].(uint8) networkId := unpacked[0].(uint8)
fields := unpacked[1].([][32]uint8) fields := unpacked[1].([][32]uint8)
if len(fields) == 0 {
return packErr("Unable to verify for 0 fields"), ErrExecutionReverted
}
output_buffer := [32]byte{} output_buffer := [32]byte{}
var fields_ptr *C.uint8_t
if len(fields) == 0 {
fields_ptr = (*C.uint8_t)(nil)
} else {
fields_ptr = (*C.uint8_t)(&fields[0][0])
}
if !C.poseidon( if !C.poseidon(
C.uint8_t(networkId), C.uint8_t(networkId),
(*C.uint8_t)(&fields[0][0]), fields_ptr,
C.uintptr_t(len(fields)), C.uintptr_t(len(fields)),
(*C.uint8_t)(&output_buffer[0]), (*C.uint8_t)(&output_buffer[0]),
) { ) {
return packErr("Calling Poseidon hash failed"), ErrExecutionReverted return packErr("Calling Poseidon hash failed"), errMinaPoseidonCallingRustLibFailed
} }
return output_buffer[:], nil return output_buffer[:], nil

View file

@ -0,0 +1,22 @@
[
{
"Input": "aabbccdd",
"ExpectedError": "invalid function signature",
"Name": "mina_poseidon_invalid_signature"
},
{
"Input": "1f831f84",
"ExpectedError": "abi: attempting to unmarshall an empty string while arguments are expected",
"Name": "mina_poseidon_invalid_calldata 1"
},
{
"Input": "1f831f84aabbccdd",
"ExpectedError": "abi: cannot marshal in to go type: length insufficient 4 require 32",
"Name": "mina_poseidon_invalid_calldata 2"
},
{
"Input": "1f831f84000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"ExpectedError": "calling rust library failed",
"Name": "mina_poseidon_invalid_field"
}
]

View file

@ -0,0 +1,44 @@
[
{
"Input": "1f831f84000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000",
"Expected": "a8eb9ee0f30046308abbfa5d20af73c81bbdabc25b459785024d045228bead2f",
"Name": "vector 1",
"Gas": 1000,
"NoBenchmark": false
},
{
"Input": "1f831f84000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001f2eee8d8f6e5fb182c610cae6c5393fce69dc4d900e7b4923b074e54ad00fb36",
"Expected": "fb5992f65c07f9335995f43fd791d39012ad466717729e61045c297507054f3d",
"Name": "vector 2",
"Gas": 1000,
"NoBenchmark": false
},
{
"Input": "1f831f84000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002bd3f1c8f183ceedea15080edbe79d30bd7d613b86bf2ba12007091c60ae3933765e4f04ab87706bab06d13c7eee0a7807d0b8ce268b4ece6aab1e0508ec9c42f",
"Expected": "fe2436f2027620a11233318b55d0a117086f09674826d1b7ce08d48ad0736c33",
"Name": "vector 3",
"Gas": 1000,
"NoBenchmark": false
},
{
"Input": "1f831f84000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003f5ea61ce47773495363dc4f6a41c3e2da14b13d6dd173acf87c9ca7357fb2400f28573f49c658b4ba151e82ed0bd6aaab045311d1a72df58c21eed462bede01873cf45c39285f17ccea99e0daeb547430cf7921218fe3726010f608e682a841a",
"Expected": "9b1b94444a54af49a7623d1fe1ca72649f0a098daf5704925f024eb6ab0e4b3f",
"Name": "vector 4",
"Gas": 1000,
"NoBenchmark": false
},
{
"Input": "1f831f840000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000044c28b87198e0012207f93cdbdaa35355ec8213fa97a60e62701f62602d4659200787a40fc046c4dd0ff3cad0e54006577fece871c774707494984f1c7d3347271504ffe48e4e6dfcc4ded439edd386cf271b69d94afae83079f3ee3e7c04d52d290b6506516fe7588b5100f8db2e871427c6d74e7a60ab656f43dd9bc687c312",
"Expected": "47ecd3bf2eed86dcf8d2cef3d7667104689dba4d9bcb54006e0c66f6ec8c5a16",
"Name": "vector 5",
"Gas": 1000,
"NoBenchmark": false
},
{
"Input": "1f831f84000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000005da99182b35f2cd9f8a137052c4262576377a16deb83652db459a74893a0cf73c9805573990c4028292c9db171cd2b97902f9fc494983f6f7e0a0c184bc55df1b90ff1001b9dab21358aad1f6b7906a56d0c039502c1590c3ef9921a8951e440988b56238a0eda34576db959fecd1c3790bb5311fdb231753243c5085974a5b37896a7727e511a4c30d99082bf3542623fb702afab0b62ebbf301ed51e38f6812",
"Expected": "09a2d55277908b7c8214f745b3605f0f9055dcd4c9b594cdd759292c34c3a20c",
"Name": "vector 6",
"Gas": 1000,
"NoBenchmark": false
}
]