prysm-pulse/contracts/validator-registration-contract/validator_registration_test.go
Kimi Wu 4a29e72d81 1.use 0.5.1 compiler, 2.bug fixing, and 3.align spec2.0 (#1110)
* 1.use 0.5.1 compiler, 2.bug fixing, and 3.align spec2.0

* modify dependency path

* add comment for DEPOSITS_FOR_CHAIN_START
2018-12-18 20:49:02 -05:00

194 lines
5.6 KiB
Go

package vrc
import (
"bytes"
"crypto/ecdsa"
"fmt"
"log"
"math/big"
"testing"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
)
var (
amount33Eth, _ = new(big.Int).SetString("33000000000000000000", 10)
amount32Eth, _ = new(big.Int).SetString("32000000000000000000", 10)
amountLessThan1Eth, _ = new(big.Int).SetString("500000000000000000", 10)
)
type testAccount struct {
addr common.Address
contract *ValidatorRegistration
backend *backends.SimulatedBackend
txOpts *bind.TransactOpts
}
func setup() (*testAccount, error) {
genesis := make(core.GenesisAlloc)
privKey, _ := crypto.GenerateKey()
pubKeyECDSA, ok := privKey.Public().(*ecdsa.PublicKey)
if !ok {
return nil, fmt.Errorf("error casting public key to ECDSA")
}
// strip off the 0x and the first 2 characters 04 which is always the EC prefix and is not required.
publicKeyBytes := crypto.FromECDSAPub(pubKeyECDSA)[4:]
var pubKey = make([]byte, 48)
copy(pubKey[:], []byte(publicKeyBytes))
addr := crypto.PubkeyToAddress(privKey.PublicKey)
txOpts := bind.NewKeyedTransactor(privKey)
startingBalance, _ := new(big.Int).SetString("1000000000000000000000", 10)
genesis[addr] = core.GenesisAccount{Balance: startingBalance}
backend := backends.NewSimulatedBackend(genesis, 2100000)
_, _, contract, err := DeployValidatorRegistration(txOpts, backend)
if err != nil {
return nil, err
}
return &testAccount{addr, contract, backend, txOpts}, nil
}
func TestSetupAndContractRegistration(t *testing.T) {
_, err := setup()
if err != nil {
log.Fatalf("Can not deploy validator registration contract: %v", err)
}
}
// negative test case, deposit with less than 1 ETH which is less than the top off amount.
func TestRegisterWithLessThan1Eth(t *testing.T) {
testAccount, err := setup()
if err != nil {
t.Fatal(err)
}
testAccount.txOpts.Value = amountLessThan1Eth
_, err = testAccount.contract.Deposit(testAccount.txOpts, []byte{})
if err == nil {
t.Error("Validator registration should have failed with insufficient deposit")
}
}
// negative test case, deposit with more than 32 ETH which is more than the asked amount.
func TestRegisterWithMoreThan32Eth(t *testing.T) {
testAccount, err := setup()
if err != nil {
t.Fatal(err)
}
testAccount.txOpts.Value = amount33Eth
_, err = testAccount.contract.Deposit(testAccount.txOpts, []byte{})
if err == nil {
t.Error("Validator registration should have failed with more than asked deposit amount")
}
}
// normal test case, test depositing 32 ETH and verify HashChainValue event is correctly emitted.
func TestValidatorRegisters(t *testing.T) {
testAccount, err := setup()
if err != nil {
t.Fatal(err)
}
testAccount.txOpts.Value = amount32Eth
_, err = testAccount.contract.Deposit(testAccount.txOpts, []byte{'A'})
testAccount.backend.Commit()
if err != nil {
t.Errorf("Validator registration failed: %v", err)
}
_, err = testAccount.contract.Deposit(testAccount.txOpts, []byte{'B'})
testAccount.backend.Commit()
if err != nil {
t.Errorf("Validator registration failed: %v", err)
}
_, err = testAccount.contract.Deposit(testAccount.txOpts, []byte{'C'})
testAccount.backend.Commit()
if err != nil {
t.Errorf("Validator registration failed: %v", err)
}
log, err := testAccount.contract.FilterHashChainValue(&bind.FilterOpts{}, [][]byte{})
defer func() {
err = log.Close()
if err != nil {
t.Fatal(err)
}
}()
if err != nil {
t.Fatal(err)
}
if log.Error() != nil {
t.Fatal(log.Error())
}
log.Next()
if log.Event.TotalDepositcount.Cmp(big.NewInt(0)) != 0 {
t.Errorf("HashChainValue event total desposit count miss matched. Want: %v, Got: %v", big.NewInt(0), log.Event.TotalDepositcount)
}
if !bytes.Equal(log.Event.Data[len(log.Event.Data)-1:], []byte{'A'}) {
t.Errorf("validatorRegistered event randao commitment miss matched. Want: %v, Got: %v", []byte{'A'}, log.Event.Data[len(log.Event.Data)-1:])
}
log.Next()
if log.Event.TotalDepositcount.Cmp(big.NewInt(1)) != 0 {
t.Errorf("HashChainValue event total desposit count miss matched. Want: %v, Got: %v", big.NewInt(1), log.Event.TotalDepositcount)
}
if !bytes.Equal(log.Event.Data[len(log.Event.Data)-1:], []byte{'B'}) {
t.Errorf("validatorRegistered event randao commitment miss matched. Want: %v, Got: %v", []byte{'B'}, log.Event.Data[len(log.Event.Data)-1:])
}
log.Next()
if log.Event.TotalDepositcount.Cmp(big.NewInt(2)) != 0 {
t.Errorf("HashChainValue event total desposit count miss matched. Want: %v, Got: %v", big.NewInt(1), log.Event.TotalDepositcount)
}
if !bytes.Equal(log.Event.Data[len(log.Event.Data)-1:], []byte{'C'}) {
t.Errorf("validatorRegistered event randao commitment miss matched. Want: %v, Got: %v", []byte{'B'}, log.Event.Data[len(log.Event.Data)-1:])
}
}
// normal test case, test beacon chain start log event.
func TestChainStarts(t *testing.T) {
testAccount, err := setup()
if err != nil {
t.Fatal(err)
}
testAccount.txOpts.Value = amount32Eth
for i := 0; i < 9; i++ {
_, err = testAccount.contract.Deposit(testAccount.txOpts, []byte{'A'})
testAccount.backend.Commit()
if err != nil {
t.Errorf("Validator registration failed: %v", err)
}
}
log, err := testAccount.contract.FilterChainStart(&bind.FilterOpts{}, [][]byte{})
defer func() {
err = log.Close()
if err != nil {
t.Fatal(err)
}
}()
if err != nil {
t.Fatal(err)
}
if log.Error() != nil {
t.Fatal(log.Error())
}
log.Next()
if len(log.Event.Time) == 0 {
t.Error("Chain start even did not get emitted, The start time is empty")
}
}