Add integration test and dynamic txn unit test.
This commit is contained in:
parent
93e3dba443
commit
80bcb2580f
21
Makefile
Normal file
21
Makefile
Normal file
@ -0,0 +1,21 @@
|
||||
BIN = $(GOPATH)/bin
|
||||
BASE = $(GOPATH)/src/$(PACKAGE)
|
||||
PKGS = go list ./... | grep -v "^vendor/"
|
||||
|
||||
# Tools
|
||||
## Testing library
|
||||
GINKGO = $(BIN)/ginkgo
|
||||
$(BIN)/ginkgo:
|
||||
go get -u github.com/onsi/ginkgo/ginkgo
|
||||
|
||||
.PHONY: integrationtest
|
||||
integrationtest: | $(GINKGO) $(GOOSE)
|
||||
go vet ./...
|
||||
go fmt ./...
|
||||
$(GINKGO) -r test/ -v
|
||||
|
||||
.PHONY: integrationtest_local
|
||||
integrationtest_local: | $(GINKGO) $(GOOSE)
|
||||
go vet ./...
|
||||
go fmt ./...
|
||||
./scripts/run_integration_test.sh
|
@ -36,7 +36,8 @@ func stateValidator() {
|
||||
}
|
||||
|
||||
trail := viper.GetUint64("validate.trail")
|
||||
srvc := validator.NewService(cfg.DB, height, trail)
|
||||
// TODO: add chain config logic here.
|
||||
srvc := validator.NewService(cfg.DB, height, trail, nil)
|
||||
|
||||
_, err = srvc.Start(context.Background())
|
||||
if err != nil {
|
||||
|
46
docker-compose.yml
Normal file
46
docker-compose.yml
Normal file
@ -0,0 +1,46 @@
|
||||
version: '3.2'
|
||||
|
||||
services:
|
||||
contract:
|
||||
depends_on:
|
||||
- dapptools
|
||||
build:
|
||||
context: ./test/contract
|
||||
args:
|
||||
ETH_ADDR: "http://dapptools:8545"
|
||||
environment:
|
||||
ETH_ADDR: "http://dapptools:8545"
|
||||
ports:
|
||||
- "127.0.0.1:3000:3000"
|
||||
|
||||
dapptools:
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- ipld-eth-db
|
||||
image: vulcanize/dapptools:v0.30.0-v1.10.14-statediff-0.0.29
|
||||
environment:
|
||||
DB_USER: vdbm
|
||||
DB_NAME: vulcanize_testing
|
||||
DB_HOST: ipld-eth-db
|
||||
DB_PORT: 5432
|
||||
DB_PASSWORD: password
|
||||
DB_WRITE: $DB_WRITE
|
||||
ports:
|
||||
- "127.0.0.1:8545:8545"
|
||||
- "127.0.0.1:8546:8546"
|
||||
|
||||
ipld-eth-db:
|
||||
restart: always
|
||||
image: vulcanize/ipld-eth-db:v0.2.0
|
||||
environment:
|
||||
POSTGRES_USER: "vdbm"
|
||||
POSTGRES_DB: "vulcanize_testing"
|
||||
POSTGRES_PASSWORD: "password"
|
||||
volumes:
|
||||
- vdb_db_eth_validator:/var/lib/postgresql/data
|
||||
ports:
|
||||
- "127.0.0.1:8077:5432"
|
||||
command: ["postgres", "-c", "log_statement=all"]
|
||||
|
||||
volumes:
|
||||
vdb_db_eth_validator:
|
@ -10,7 +10,23 @@ import (
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var testChainConfig = ¶ms.ChainConfig{
|
||||
var IntegrationTestChainConfig = ¶ms.ChainConfig{
|
||||
ChainID: big.NewInt(4),
|
||||
HomesteadBlock: big.NewInt(0),
|
||||
EIP150Block: big.NewInt(0),
|
||||
EIP155Block: big.NewInt(0),
|
||||
EIP158Block: big.NewInt(0),
|
||||
ByzantiumBlock: big.NewInt(0),
|
||||
ConstantinopleBlock: big.NewInt(0),
|
||||
PetersburgBlock: big.NewInt(0),
|
||||
IstanbulBlock: big.NewInt(0),
|
||||
Clique: ¶ms.CliqueConfig{
|
||||
Period: 0,
|
||||
Epoch: 30000,
|
||||
},
|
||||
}
|
||||
|
||||
var TestChainConfig = ¶ms.ChainConfig{
|
||||
ChainID: big.NewInt(1),
|
||||
HomesteadBlock: big.NewInt(0),
|
||||
EIP150Block: big.NewInt(0),
|
||||
@ -22,7 +38,7 @@ var testChainConfig = ¶ms.ChainConfig{
|
||||
IstanbulBlock: big.NewInt(0),
|
||||
MuirGlacierBlock: big.NewInt(0),
|
||||
BerlinBlock: big.NewInt(0),
|
||||
LondonBlock: big.NewInt(100),
|
||||
LondonBlock: big.NewInt(6),
|
||||
ArrowGlacierBlock: big.NewInt(0),
|
||||
Ethash: new(params.EthashConfig),
|
||||
}
|
||||
|
@ -27,23 +27,24 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
big8 = big.NewInt(8)
|
||||
big32 = big.NewInt(32)
|
||||
testHash = common.HexToHash("0x1283a0bca5cce009bcf3e5a860eccdc202d1345f464024f2ee8ea1e1254349e7")
|
||||
big8 = big.NewInt(8)
|
||||
big32 = big.NewInt(32)
|
||||
)
|
||||
|
||||
type service struct {
|
||||
db *postgres.DB
|
||||
blockNum, trail uint64
|
||||
logger *log.Logger
|
||||
chainCfg *params.ChainConfig
|
||||
}
|
||||
|
||||
func NewService(db *postgres.DB, blockNum, trailNum uint64) *service {
|
||||
func NewService(db *postgres.DB, blockNum, trailNum uint64, chainCfg *params.ChainConfig) *service {
|
||||
return &service{
|
||||
db: db,
|
||||
blockNum: blockNum,
|
||||
trail: trailNum,
|
||||
logger: log.New(),
|
||||
chainCfg: chainCfg,
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,7 +97,7 @@ func NewDB(connectString string, config postgres.ConnectionConfig, node node.Inf
|
||||
|
||||
// Start is used to begin the service
|
||||
func (s *service) Start(ctx context.Context) (uint64, error) {
|
||||
api, err := ethAPI(ctx, s.db)
|
||||
api, err := ethAPI(ctx, s.db, s.chainCfg)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -126,7 +127,6 @@ func (s *service) Start(ctx context.Context) (uint64, error) {
|
||||
|
||||
s.logger.Infof("state root verified for block= %d", idxBlockNum)
|
||||
|
||||
// again fetch head block
|
||||
headBlock, err = api.B.BlockByNumber(ctx, rpc.LatestBlockNumber)
|
||||
if err != nil {
|
||||
return idxBlockNum, err
|
||||
@ -136,14 +136,14 @@ func (s *service) Start(ctx context.Context) (uint64, error) {
|
||||
idxBlockNum++
|
||||
}
|
||||
|
||||
s.logger.Infof("last validated block %v", idxBlockNum)
|
||||
|
||||
s.logger.Infof("last validated block %v", idxBlockNum-1)
|
||||
return idxBlockNum, nil
|
||||
}
|
||||
|
||||
func ethAPI(ctx context.Context, db *postgres.DB) (*ipldEth.PublicEthAPI, error) {
|
||||
func ethAPI(ctx context.Context, db *postgres.DB, chainCfg *params.ChainConfig) (*ipldEth.PublicEthAPI, error) {
|
||||
// TODO: decide network for custom chainConfig.
|
||||
backend, err := NewEthBackend(db, &ipldEth.Config{
|
||||
ChainConfig: chainCfg,
|
||||
GroupCacheConfig: ðServerShared.GroupCacheConfig{
|
||||
StateDB: ethServerShared.GroupConfig{
|
||||
Name: "vulcanize_validator",
|
||||
@ -161,7 +161,6 @@ func ethAPI(ctx context.Context, db *postgres.DB) (*ipldEth.PublicEthAPI, error)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
backend.Config.ChainConfig = setChainConfig(genesisBlock.Hash())
|
||||
}
|
||||
|
||||
@ -259,8 +258,6 @@ func setChainConfig(ghash common.Hash) *params.ChainConfig {
|
||||
return params.RinkebyChainConfig
|
||||
case ghash == params.GoerliGenesisHash:
|
||||
return params.GoerliChainConfig
|
||||
case ghash == testHash:
|
||||
return testChainConfig
|
||||
default:
|
||||
return params.AllEthashProtocolChanges
|
||||
}
|
||||
|
23
scripts/run_integration_test.sh
Executable file
23
scripts/run_integration_test.sh
Executable file
@ -0,0 +1,23 @@
|
||||
set -e
|
||||
set -o xtrace
|
||||
|
||||
export ETH_FORWARD_ETH_CALLS=false
|
||||
export DB_WRITE=true
|
||||
export ETH_HTTP_PATH=""
|
||||
export ETH_PROXY_ON_ERROR=false
|
||||
|
||||
# Clear up existing docker images and volume.
|
||||
docker-compose down --remove-orphans --volumes
|
||||
|
||||
# Build and start the containers.
|
||||
docker-compose -f docker-compose.yml up -d ipld-eth-db dapptools contract
|
||||
|
||||
export PGPASSWORD=password
|
||||
export DATABASE_USER=vdbm
|
||||
export DATABASE_PORT=8077
|
||||
export DATABASE_PASSWORD=password
|
||||
export DATABASE_HOSTNAME=127.0.0.1
|
||||
|
||||
# Wait for containers to be up and execute the integration test.
|
||||
while [ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:8545)" != "200" ]; do echo "waiting for geth-statediff..." && sleep 5; done && \
|
||||
make integrationtest
|
3
test/contract/.dockerignore
Normal file
3
test/contract/.dockerignore
Normal file
@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
artifacts
|
||||
cache
|
5
test/contract/.gitignore
vendored
Normal file
5
test/contract/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
node_modules
|
||||
|
||||
#Hardhat files
|
||||
cache
|
||||
artifacts
|
14
test/contract/Dockerfile
Normal file
14
test/contract/Dockerfile
Normal file
@ -0,0 +1,14 @@
|
||||
FROM node:14
|
||||
|
||||
ARG ETH_ADDR
|
||||
ENV ETH_ADDR $ETH_ADDR
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
COPY . .
|
||||
RUN npm run compile && ls -lah
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
ENTRYPOINT ["npm", "start"]
|
10
test/contract/contracts/GLDToken.sol
Normal file
10
test/contract/contracts/GLDToken.sol
Normal file
@ -0,0 +1,10 @@
|
||||
pragma solidity ^0.8.0;
|
||||
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
||||
contract GLDToken is ERC20 {
|
||||
constructor() ERC20("Gold", "GLD") {
|
||||
_mint(msg.sender, 1000000000000000000000);
|
||||
}
|
||||
function destroy() public {
|
||||
selfdestruct(payable(msg.sender));
|
||||
}
|
||||
}
|
32
test/contract/hardhat.config.js
Normal file
32
test/contract/hardhat.config.js
Normal file
@ -0,0 +1,32 @@
|
||||
require("@nomiclabs/hardhat-waffle");
|
||||
|
||||
// This is a sample Hardhat task. To learn how to create your own go to
|
||||
// https://hardhat.org/guides/create-task.html
|
||||
task("accounts", "Prints the list of accounts", async () => {
|
||||
const accounts = await ethers.getSigners();
|
||||
|
||||
for (const account of accounts) {
|
||||
console.log(account.address);
|
||||
}
|
||||
});
|
||||
|
||||
// You need to export an object to set up your config
|
||||
// Go to https://hardhat.org/config/ to learn more
|
||||
|
||||
/**
|
||||
* @type import('hardhat/config').HardhatUserConfig
|
||||
*/
|
||||
module.exports = {
|
||||
solidity: "0.8.0",
|
||||
networks: {
|
||||
local: {
|
||||
url: 'http://127.0.0.1:8545',
|
||||
chainId: 4
|
||||
},
|
||||
docker: {
|
||||
url: process.env.ETH_ADDR,
|
||||
chainId: 4
|
||||
}
|
||||
}
|
||||
};
|
||||
|
27700
test/contract/package-lock.json
generated
Normal file
27700
test/contract/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
27
test/contract/package.json
Normal file
27
test/contract/package.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "contract",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"compile": "npx hardhat compile",
|
||||
"start": "HARDHAT_NETWORK=docker node src/index.js",
|
||||
"start:local": "ETH_ADDR=http://127.0.0.1:8545 npm run start",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"@openzeppelin/contracts": "^4.0.0",
|
||||
"fastify": "^3.14.2",
|
||||
"hardhat": "^2.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
||||
"@nomiclabs/hardhat-waffle": "^2.0.1",
|
||||
"chai": "^4.3.4",
|
||||
"ethereum-waffle": "^3.3.0",
|
||||
"ethers": "^5.1.0"
|
||||
}
|
||||
}
|
18
test/contract/scripts/deploy.js
Normal file
18
test/contract/scripts/deploy.js
Normal file
@ -0,0 +1,18 @@
|
||||
const hre = require("hardhat");
|
||||
|
||||
async function main() {
|
||||
// await hre.run('compile');
|
||||
// We get the contract to deploy
|
||||
const GLDToken = await hre.ethers.getContractFactory("GLDToken");
|
||||
const token = await GLDToken.deploy();
|
||||
await token.deployed();
|
||||
console.log("GLDToken deployed to:", token.address, token.deployTransaction.hash);
|
||||
}
|
||||
// We recommend this pattern to be able to use async/await everywhere
|
||||
// and properly handle errors.
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
36
test/contract/scripts/sample-script.js
Normal file
36
test/contract/scripts/sample-script.js
Normal file
@ -0,0 +1,36 @@
|
||||
// We require the Hardhat Runtime Environment explicitly here. This is optional
|
||||
// but useful for running the script in a standalone fashion through `node <script>`.
|
||||
//
|
||||
// When running the script with `hardhat run <script>` you'll find the Hardhat
|
||||
// Runtime Environment's members available in the global scope.
|
||||
const hre = require("hardhat");
|
||||
|
||||
async function main() {
|
||||
// Hardhat always runs the compile task when running scripts with its command
|
||||
// line interface.
|
||||
//
|
||||
// If this script is run directly using `node` you may want to call compile
|
||||
// manually to make sure everything is compiled
|
||||
// await hre.run('compile');
|
||||
|
||||
// We get the contract to deploy
|
||||
const Greeter = await hre.ethers.getContractFactory("Greeter");
|
||||
const greeter = await Greeter.deploy("Hello, Hardhat!");
|
||||
|
||||
await greeter.deployed();
|
||||
|
||||
console.log("Greeter deployed to:", greeter.address, "; tx hash: ", greeter.deployTransaction.hash);
|
||||
|
||||
const result = await greeter.setGreeting("Hello 123!");
|
||||
|
||||
console.log("Greeter updated", "; tx hash: ", result.hash, "; block hash: ", result.blockHash);
|
||||
}
|
||||
|
||||
// We recommend this pattern to be able to use async/await everywhere
|
||||
// and properly handle errors.
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
75
test/contract/src/index.js
Normal file
75
test/contract/src/index.js
Normal file
@ -0,0 +1,75 @@
|
||||
const fastify = require('fastify')({ logger: true });
|
||||
const hre = require("hardhat");
|
||||
|
||||
|
||||
// readiness check
|
||||
fastify.get('/v1/healthz', async (req, reply) => {
|
||||
reply
|
||||
.code(200)
|
||||
.header('Content-Type', 'application/json; charset=utf-8')
|
||||
.send({ success: true })
|
||||
});
|
||||
|
||||
fastify.get('/v1/deployContract', async (req, reply) => {
|
||||
const GLDToken = await hre.ethers.getContractFactory("GLDToken");
|
||||
const token = await GLDToken.deploy();
|
||||
await token.deployed();
|
||||
|
||||
return {
|
||||
address: token.address,
|
||||
txHash: token.deployTransaction.hash,
|
||||
blockNumber: token.deployTransaction.blockNumber,
|
||||
blockHash: token.deployTransaction.blockHash,
|
||||
}
|
||||
});
|
||||
|
||||
fastify.get('/v1/destroyContract', async (req, reply) => {
|
||||
const addr = req.query.addr;
|
||||
|
||||
const Token = await hre.ethers.getContractFactory("GLDToken");
|
||||
const token = await Token.attach(addr);
|
||||
|
||||
await token.destroy();
|
||||
const blockNum = await hre.ethers.provider.getBlockNumber()
|
||||
|
||||
return {
|
||||
blockNumber: blockNum,
|
||||
}
|
||||
})
|
||||
|
||||
fastify.get('/v1/sendEth', async (req, reply) => {
|
||||
const to = req.query.to;
|
||||
const value = req.query.value;
|
||||
|
||||
const [owner] = await hre.ethers.getSigners();
|
||||
const tx = await owner.sendTransaction({
|
||||
to,
|
||||
value: hre.ethers.utils.parseEther(value)
|
||||
});
|
||||
await tx.wait(1)
|
||||
|
||||
// console.log(tx);
|
||||
// const coinbaseBalance = await hre.ethers.provider.getBalance(owner.address);
|
||||
// const receiverBalance = await hre.ethers.provider.getBalance(to);
|
||||
// console.log(coinbaseBalance.toString(), receiverBalance.toString());
|
||||
|
||||
return {
|
||||
from: tx.from,
|
||||
to: tx.to,
|
||||
//value: tx.value.toString(),
|
||||
txHash: tx.hash,
|
||||
blockNumber: tx.blockNumber,
|
||||
blockHash: tx.blockHash,
|
||||
}
|
||||
});
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
await fastify.listen(3000, '0.0.0.0');
|
||||
} catch (err) {
|
||||
fastify.log.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
14
test/contract/test/sample-test.js
Normal file
14
test/contract/test/sample-test.js
Normal file
@ -0,0 +1,14 @@
|
||||
const { expect } = require("chai");
|
||||
|
||||
describe("Greeter", function() {
|
||||
it("Should return the new greeting once it's changed", async function() {
|
||||
const Greeter = await ethers.getContractFactory("Greeter");
|
||||
const greeter = await Greeter.deploy("Hello, world!");
|
||||
|
||||
await greeter.deployed();
|
||||
expect(await greeter.greet()).to.equal("Hello, world!");
|
||||
|
||||
await greeter.setGreeting("Hola, mundo!");
|
||||
expect(await greeter.greet()).to.equal("Hola, mundo!");
|
||||
});
|
||||
});
|
19
test/integration_suite_test.go
Normal file
19
test/integration_suite_test.go
Normal file
@ -0,0 +1,19 @@
|
||||
package integration_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func TestIntegration(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "integration test suite")
|
||||
}
|
||||
|
||||
var _ = BeforeSuite(func() {
|
||||
logrus.SetOutput(ioutil.Discard)
|
||||
})
|
65
test/integration_test.go
Normal file
65
test/integration_test.go
Normal file
@ -0,0 +1,65 @@
|
||||
package integration_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/statediff/indexer/node"
|
||||
"github.com/ethereum/go-ethereum/statediff/indexer/postgres"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/Vulcanize/ipld-eth-db-validator/pkg/validator"
|
||||
|
||||
integration "github.com/vulcanize/ipld-eth-server/test"
|
||||
)
|
||||
|
||||
const trail = 0
|
||||
|
||||
var randomAddr = common.HexToAddress("0x1C3ab14BBaD3D99F4203bd7a11aCB94882050E6f")
|
||||
|
||||
var _ = Describe("Integration test", func() {
|
||||
directProxyEthCalls, err := strconv.ParseBool(os.Getenv("ETH_FORWARD_ETH_CALLS"))
|
||||
Expect(err).To(BeNil())
|
||||
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
ctx := context.Background()
|
||||
|
||||
var contract *integration.ContractDeployed
|
||||
var contractErr error
|
||||
sleepInterval := 5 * time.Second
|
||||
|
||||
Describe("Validate state", func() {
|
||||
BeforeEach(func() {
|
||||
if directProxyEthCalls {
|
||||
Skip("skipping no-direct-proxy-forwarding integration tests")
|
||||
}
|
||||
contract, contractErr = integration.DeployContract()
|
||||
time.Sleep(sleepInterval)
|
||||
})
|
||||
|
||||
It("Validate state root", func() {
|
||||
Expect(contractErr).ToNot(HaveOccurred())
|
||||
|
||||
db, _ := setupDB()
|
||||
srvc := validator.NewService(db, uint64(contract.BlockNumber), trail, validator.IntegrationTestChainConfig)
|
||||
_, err = srvc.Start(ctx)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
func setupDB() (*postgres.DB, error) {
|
||||
uri := postgres.DbConnectionString(postgres.ConnectionParams{
|
||||
User: "vdbm",
|
||||
Password: "password",
|
||||
Hostname: "localhost",
|
||||
Name: "vulcanize_testing",
|
||||
Port: 8077,
|
||||
})
|
||||
return validator.NewDB(uri, postgres.ConnectionConfig{}, node.Info{})
|
||||
}
|
118
validator_test/chain_maker.go
Normal file
118
validator_test/chain_maker.go
Normal file
@ -0,0 +1,118 @@
|
||||
package validator_test
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/Vulcanize/ipld-eth-db-validator/pkg/validator"
|
||||
)
|
||||
|
||||
// Test variables
|
||||
var (
|
||||
Testdb = rawdb.NewMemoryDatabase()
|
||||
TestBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
TestBankAddress = crypto.PubkeyToAddress(TestBankKey.PublicKey) //0x71562b71999873DB5b286dF957af199Ec94617F7
|
||||
TestBankFunds = big.NewInt(100000000)
|
||||
Genesis = core.GenesisBlockForTesting(Testdb, TestBankAddress, TestBankFunds)
|
||||
|
||||
Account1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
|
||||
Account2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
|
||||
Account1Addr = crypto.PubkeyToAddress(Account1Key.PublicKey) //0x703c4b2bD70c169f5717101CaeE543299Fc946C7
|
||||
Account2Addr = crypto.PubkeyToAddress(Account2Key.PublicKey) //0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e
|
||||
DeploymentTxData = common.Hex2Bytes("608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600180819055506101e2806100676000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806343d726d61461004657806365f3c31a1461005057806373d4a13a1461007e575b600080fd5b61004e61009c565b005b61007c6004803603602081101561006657600080fd5b810190808035906020019092919050505061017b565b005b610086610185565b6040518082815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610141576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061018c6022913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b8060018190555050565b6001548156fe4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6e2ea265627a7a723158205ba91466129f45285f53176d805117208c231ec6343d7896790e6fc4165b802b64736f6c63430005110032")
|
||||
ContractCode = common.Hex2Bytes("608060405234801561001057600080fd5b50600436106100415760003560e01c806343d726d61461004657806365f3c31a1461005057806373d4a13a1461007e575b600080fd5b61004e61009c565b005b61007c6004803603602081101561006657600080fd5b810190808035906020019092919050505061017b565b005b610086610185565b6040518082815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610141576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018061018c6022913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b8060018190555050565b6001548156fe4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6e2ea265627a7a723158205ba91466129f45285f53176d805117208c231ec6343d7896790e6fc4165b802b64736f6c63430005110032")
|
||||
CodeHash = crypto.Keccak256Hash(ContractCode)
|
||||
ContractAddr common.Address
|
||||
IndexZero = "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
IndexOne = "0000000000000000000000000000000000000000000000000000000000000001"
|
||||
ContractSlotPosition = common.FromHex(IndexOne)
|
||||
ContractSlotKeyHash = crypto.Keccak256Hash(ContractSlotPosition)
|
||||
MiningReward = big.NewInt(2000000000000000000)
|
||||
)
|
||||
|
||||
/* test function signatures
|
||||
put function sig: 65f3c31a
|
||||
close function sig: 43d726d6
|
||||
data function sig: 73d4a13a
|
||||
*/
|
||||
func createLondonTransaction(block *core.BlockGen, addr *common.Address, key *ecdsa.PrivateKey) *types.Transaction {
|
||||
londonTrx := types.NewTx(&types.DynamicFeeTx{
|
||||
ChainID: validator.TestChainConfig.ChainID,
|
||||
Nonce: block.TxNonce(*addr),
|
||||
GasTipCap: big.NewInt(50),
|
||||
GasFeeCap: big.NewInt(1000000000),
|
||||
Gas: 21000,
|
||||
To: addr,
|
||||
Value: big.NewInt(1000),
|
||||
Data: []byte{},
|
||||
})
|
||||
|
||||
transactionSigner := types.MakeSigner(validator.TestChainConfig, block.Number())
|
||||
signedTrx1, err := types.SignTx(londonTrx, transactionSigner, key)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
return signedTrx1
|
||||
}
|
||||
|
||||
// MakeChain creates a chain of n blocks starting at and including parent.
|
||||
// the returned hash chain is ordered head->parent.
|
||||
func MakeChain(n int, parent *types.Block, chainGen func(int, *core.BlockGen)) ([]*types.Block, []types.Receipts, *core.BlockChain) {
|
||||
config := validator.TestChainConfig
|
||||
blocks, receipts := core.GenerateChain(config, parent, ethash.NewFaker(), Testdb, n, chainGen)
|
||||
chain, _ := core.NewBlockChain(Testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil)
|
||||
return append([]*types.Block{parent}, blocks...), receipts, chain
|
||||
}
|
||||
|
||||
func TestChainGen(i int, block *core.BlockGen) {
|
||||
signer := types.HomesteadSigner{}
|
||||
switch i {
|
||||
case 0:
|
||||
// In block 1, the test bank sends account #1 some ether.
|
||||
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), Account1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, TestBankKey)
|
||||
block.AddTx(tx)
|
||||
case 1:
|
||||
// In block 2, the test bank sends some more ether to account #1.
|
||||
// Account1Addr passes it on to account #2.
|
||||
// Account1Addr creates a test contract.
|
||||
tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), Account1Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, TestBankKey)
|
||||
nonce := block.TxNonce(Account1Addr)
|
||||
tx2, _ := types.SignTx(types.NewTransaction(nonce, Account2Addr, big.NewInt(1000), params.TxGas, nil, nil), signer, Account1Key)
|
||||
nonce++
|
||||
tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), 1000000, big.NewInt(0), DeploymentTxData), signer, Account1Key)
|
||||
ContractAddr = crypto.CreateAddress(Account1Addr, nonce)
|
||||
block.AddTx(tx1)
|
||||
block.AddTx(tx2)
|
||||
block.AddTx(tx3)
|
||||
case 2:
|
||||
block.SetCoinbase(Account2Addr)
|
||||
data := common.Hex2Bytes("65F3C31A0000000000000000000000000000000000000000000000000000000000000003")
|
||||
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), ContractAddr, big.NewInt(0), 100000, nil, data), signer, TestBankKey)
|
||||
block.AddTx(tx)
|
||||
case 3:
|
||||
block.SetCoinbase(Account2Addr)
|
||||
data := common.Hex2Bytes("65F3C31A0000000000000000000000000000000000000000000000000000000000000009")
|
||||
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), ContractAddr, big.NewInt(0), 100000, nil, data), signer, TestBankKey)
|
||||
block.AddTx(tx)
|
||||
case 4:
|
||||
block.SetCoinbase(Account1Addr)
|
||||
data := common.Hex2Bytes("65F3C31A0000000000000000000000000000000000000000000000000000000000000000")
|
||||
tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), ContractAddr, big.NewInt(0), 100000, nil, data), signer, TestBankKey)
|
||||
block.AddTx(tx)
|
||||
case 5:
|
||||
block.AddTx(createLondonTransaction(block, &Account1Addr, Account1Key))
|
||||
|
||||
case 6:
|
||||
block.AddTx(createLondonTransaction(block, &Account2Addr, Account2Key))
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package test
|
||||
package validator_test_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
@ -1,4 +1,4 @@
|
||||
package test
|
||||
package validator_test_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -16,16 +16,16 @@ import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
||||
|
||||
"github.com/vulcanize/ipld-eth-server/pkg/eth/test_helpers"
|
||||
|
||||
"github.com/Vulcanize/ipld-eth-db-validator/pkg/validator"
|
||||
"github.com/Vulcanize/ipld-eth-db-validator/validator_test"
|
||||
)
|
||||
|
||||
const (
|
||||
chainLength = 20
|
||||
blockHeight = 1
|
||||
trail = 15
|
||||
trail = 2
|
||||
)
|
||||
|
||||
// SetupDB is use to setup a db for watcher tests
|
||||
@ -34,8 +34,8 @@ func setupDB() (*postgres.DB, error) {
|
||||
User: "vdbm",
|
||||
Password: "password",
|
||||
Hostname: "localhost",
|
||||
Name: "vulcanize_public",
|
||||
Port: 5432,
|
||||
Name: "vulcanize_testing",
|
||||
Port: 8077,
|
||||
})
|
||||
return postgres.NewDB(uri, postgres.ConnectionConfig{}, node.Info{})
|
||||
}
|
||||
@ -59,7 +59,7 @@ var _ = Describe("eth state reading tests", func() {
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
// make the test blockchain (and state)
|
||||
blocks, receipts, chain = test_helpers.MakeChain(chainLength, test_helpers.Genesis, test_helpers.TestChainGen)
|
||||
blocks, receipts, chain = validator_test.MakeChain(chainLength, test_helpers.Genesis, validator_test.TestChainGen)
|
||||
params := statediff.Params{
|
||||
IntermediateStateNodes: true,
|
||||
IntermediateStorageNodes: true,
|
||||
@ -134,7 +134,7 @@ var _ = Describe("eth state reading tests", func() {
|
||||
|
||||
Describe("state_validation", func() {
|
||||
It("Validator", func() {
|
||||
srvc := validator.NewService(db, blockHeight, trail)
|
||||
srvc := validator.NewService(db, blockHeight, trail, validator.TestChainConfig)
|
||||
|
||||
_, err := srvc.Start(context.Background())
|
||||
Expect(err).ToNot(HaveOccurred())
|
Loading…
Reference in New Issue
Block a user