diff --git a/README.md b/README.md index 77a403f7..6019071a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -## Go Ethereum +## Zion -Official Golang implementation of the Ethereum protocol. +Zion is a fork of Golang implementation of the Ethereum protocol, intigrated with hotsuff consensus algorithm thus supporting higher TPS senario. [![API Reference]( https://camo.githubusercontent.com/915b7be44ada53c290eb157634330494ebe3e30a/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f676f6c616e672f6764646f3f7374617475732e737667 @@ -9,9 +9,6 @@ https://camo.githubusercontent.com/915b7be44ada53c290eb157634330494ebe3e30a/6874 [![Travis](https://travis-ci.com/ethereum/go-ethereum.svg?branch=master)](https://travis-ci.com/ethereum/go-ethereum) [![Discord](https://img.shields.io/badge/discord-join%20chat-blue.svg)](https://discord.gg/nthXNEv) -Automated builds are available for stable releases and the unstable master branch. Binary -archives are published at https://geth.ethereum.org/downloads/. - ## Building the source For prerequisites and detailed build instructions please read the [Installation Instructions](https://geth.ethereum.org/docs/install-and-build/installing-geth). @@ -31,7 +28,7 @@ make all ## Executables -The go-ethereum project comes with several wrappers/executables found in the `cmd` +The zion project comes with several wrappers/executables found in the `cmd` directory. | Command | Description | @@ -52,121 +49,6 @@ Going through all the possible command line flags is out of scope here (please c but we've enumerated a few common parameter combos to get you up to speed quickly on how you can run your own `geth` instance. -### Full node on the main Ethereum network - -By far the most common scenario is people wanting to simply interact with the Ethereum -network: create accounts; transfer funds; deploy and interact with contracts. For this -particular use-case the user doesn't care about years-old historical data, so we can -fast-sync quickly to the current state of the network. To do so: - -```shell -$ geth console -``` - -This command will: - * Start `geth` in fast sync mode (default, can be changed with the `--syncmode` flag), - causing it to download more data in exchange for avoiding processing the entire history - of the Ethereum network, which is very CPU intensive. - * Start up `geth`'s built-in interactive [JavaScript console](https://geth.ethereum.org/docs/interface/javascript-console), - (via the trailing `console` subcommand) through which you can interact using [`web3` methods](https://web3js.readthedocs.io/en/) - (note: the `web3` version bundled within `geth` is very old, and not up to date with official docs), - as well as `geth`'s own [management APIs](https://geth.ethereum.org/docs/rpc/server). - This tool is optional and if you leave it out you can always attach to an already running - `geth` instance with `geth attach`. - -### A Full node on the Görli test network - -Transitioning towards developers, if you'd like to play around with creating Ethereum -contracts, you almost certainly would like to do that without any real money involved until -you get the hang of the entire system. In other words, instead of attaching to the main -network, you want to join the **test** network with your node, which is fully equivalent to -the main network, but with play-Ether only. - -```shell -$ geth --goerli console -``` - -The `console` subcommand has the exact same meaning as above and they are equally -useful on the testnet too. Please, see above for their explanations if you've skipped here. - -Specifying the `--goerli` flag, however, will reconfigure your `geth` instance a bit: - - * Instead of connecting the main Ethereum network, the client will connect to the Görli - test network, which uses different P2P bootnodes, different network IDs and genesis - states. - * Instead of using the default data directory (`~/.ethereum` on Linux for example), `geth` - will nest itself one level deeper into a `goerli` subfolder (`~/.ethereum/goerli` on - Linux). Note, on OSX and Linux this also means that attaching to a running testnet node - requires the use of a custom endpoint since `geth attach` will try to attach to a - production node endpoint by default, e.g., - `geth attach /goerli/geth.ipc`. Windows users are not affected by - this. - -*Note: Although there are some internal protective measures to prevent transactions from -crossing over between the main network and test network, you should make sure to always -use separate accounts for play-money and real-money. Unless you manually move -accounts, `geth` will by default correctly separate the two networks and will not make any -accounts available between them.* - -### Full node on the Rinkeby test network - -Go Ethereum also supports connecting to the older proof-of-authority based test network -called [*Rinkeby*](https://www.rinkeby.io) which is operated by members of the community. - -```shell -$ geth --rinkeby console -``` - -### Full node on the Ropsten test network - -In addition to Görli and Rinkeby, Geth also supports the ancient Ropsten testnet. The -Ropsten test network is based on the Ethash proof-of-work consensus algorithm. As such, -it has certain extra overhead and is more susceptible to reorganization attacks due to the -network's low difficulty/security. - -```shell -$ geth --ropsten console -``` - -*Note: Older Geth configurations store the Ropsten database in the `testnet` subdirectory.* - -### Configuration - -As an alternative to passing the numerous flags to the `geth` binary, you can also pass a -configuration file via: - -```shell -$ geth --config /path/to/your_config.toml -``` - -To get an idea how the file should look like you can use the `dumpconfig` subcommand to -export your existing configuration: - -```shell -$ geth --your-favourite-flags dumpconfig -``` - -*Note: This works only with `geth` v1.6.0 and above.* - -#### Docker quick start - -One of the quickest ways to get Ethereum up and running on your machine is by using -Docker: - -```shell -docker run -d --name ethereum-node -v /Users/alice/ethereum:/root \ - -p 8545:8545 -p 30303:30303 \ - ethereum/client-go -``` - -This will start `geth` in fast-sync mode with a DB memory allowance of 1GB just as the -above command does. It will also create a persistent volume in your home directory for -saving your blockchain as well as map the default ports. There is also an `alpine` tag -available for a slim version of the image. - -Do not forget `--http.addr 0.0.0.0`, if you want to access RPC from other containers -and/or hosts. By default, `geth` binds to the local interface and RPC endpoints is not -accessible from the outside. ### Programmatically interfacing `geth` nodes @@ -211,119 +93,11 @@ APIs!** ### Operating a private network -Maintaining your own private network is more involved as a lot of configurations taken for -granted in the official networks need to be manually set up. - -#### Defining the private genesis state - -First, you'll need to create the genesis state of your networks, which all nodes need to be -aware of and agree upon. This consists of a small JSON file (e.g. call it `genesis.json`): - -```json -{ - "config": { - "chainId": , - "homesteadBlock": 0, - "eip150Block": 0, - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "berlinBlock": 0 - }, - "alloc": {}, - "coinbase": "0x0000000000000000000000000000000000000000", - "difficulty": "0x20000", - "extraData": "", - "gasLimit": "0x2fefd8", - "nonce": "0x0000000000000042", - "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp": "0x00" -} -``` - -The above fields should be fine for most purposes, although we'd recommend changing -the `nonce` to some random value so you prevent unknown remote nodes from being able -to connect to you. If you'd like to pre-fund some accounts for easier testing, create -the accounts and populate the `alloc` field with their addresses. - -```json -"alloc": { - "0x0000000000000000000000000000000000000001": { - "balance": "111111111" - }, - "0x0000000000000000000000000000000000000002": { - "balance": "222222222" - } -} -``` - -With the genesis state defined in the above JSON file, you'll need to initialize **every** -`geth` node with it prior to starting it up to ensure all blockchain parameters are correctly -set: - -```shell -$ geth init path/to/genesis.json -``` - -#### Creating the rendezvous point - -With all nodes that you want to run initialized to the desired genesis state, you'll need to -start a bootstrap node that others can use to find each other in your network and/or over -the internet. The clean way is to configure and run a dedicated bootnode: +[Go to install guide](docs/install_guide/install.md) -```shell -$ bootnode --genkey=boot.key -$ bootnode --nodekey=boot.key -``` - -With the bootnode online, it will display an [`enode` URL](https://eth.wiki/en/fundamentals/enode-url-format) -that other nodes can use to connect to it and exchange peer information. Make sure to -replace the displayed IP address information (most probably `[::]`) with your externally -accessible IP to get the actual `enode` URL. - -*Note: You could also use a full-fledged `geth` node as a bootnode, but it's the less -recommended way.* - -#### Starting up your member nodes - -With the bootnode operational and externally reachable (you can try -`telnet ` to ensure it's indeed reachable), start every subsequent `geth` -node pointed to the bootnode for peer discovery via the `--bootnodes` flag. It will -probably also be desirable to keep the data directory of your private network separated, so -do also specify a custom `--datadir` flag. - -```shell -$ geth --datadir=path/to/custom/data/folder --bootnodes= -``` - -*Note: Since your network will be completely cut off from the main and test networks, you'll -also need to configure a miner to process transactions and create new blocks for you.* - -#### Running a private miner - -Mining on the public Ethereum network is a complex task as it's only feasible using GPUs, -requiring an OpenCL or CUDA enabled `ethminer` instance. For information on such a -setup, please consult the [EtherMining subreddit](https://www.reddit.com/r/EtherMining/) -and the [ethminer](https://github.com/ethereum-mining/ethminer) repository. - -In a private network setting, however a single CPU miner instance is more than enough for -practical purposes as it can produce a stable stream of blocks at the correct intervals -without needing heavy resources (consider running on a single thread, no need for multiple -ones either). To start a `geth` instance for mining, run it with all your usual flags, extended -by: - -```shell -$ geth --mine --miner.threads=1 --miner.etherbase=0x0000000000000000000000000000000000000000 -``` +## JSON-RPC API Documentation -Which will start mining blocks and transactions on a single CPU thread, crediting all -proceedings to the account specified by `--miner.etherbase`. You can further tune the mining -by changing the default gas limit blocks converge to (`--miner.targetgaslimit`) and the price -transactions are accepted at (`--miner.gasprice`). +[Go to Zion JSON-RPC Specification](docs/jsonrpc/jsonrpc.md) ## Contribution diff --git a/abigen b/abigen new file mode 100755 index 00000000..93658f06 Binary files /dev/null and b/abigen differ diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index 88dcfbeb..39d5e397 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -37,6 +37,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/event" + "github.com/google/uuid" ) var ( @@ -505,3 +506,24 @@ func zeroKey(k *ecdsa.PrivateKey) { b[i] = 0 } } + +func GenerateKeyJson(key *ecdsa.PrivateKey, password string) (string, error) { + // Create the keyfile object with a random UUID. + UUID, err := uuid.NewRandom() + if err != nil { + return "", err + } + keyStore := &Key{ + Id: UUID, + Address: crypto.PubkeyToAddress(key.PublicKey), + PrivateKey: key, + } + + // Encrypt key with passphrase. + scryptN, scryptP := StandardScryptN, StandardScryptP + keyjson, err := EncryptKey(keyStore, password, scryptN, scryptP) + if err != nil { + return "", err + } + return string(keyjson), nil +} diff --git a/build/IMaasConfig.abi b/build/IMaasConfig.abi new file mode 100644 index 00000000..c1e19ede --- /dev/null +++ b/build/IMaasConfig.abi @@ -0,0 +1 @@ +[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"bool","name":"doBlock","type":"bool"}],"name":"BlockAccount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"ChangeOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"doEnable","type":"bool"}],"name":"EnableGasManage","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"addrs","type":"address[]"},{"indexed":false,"internalType":"bool","name":"addOrRemove","type":"bool"}],"name":"SetAdmins","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"bool","name":"isManager","type":"bool"}],"name":"SetGasManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"addrs","type":"address[]"},{"indexed":false,"internalType":"bool","name":"addOrRemove","type":"bool"}],"name":"SetGasUsers","type":"event"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"doBlock","type":"bool"}],"name":"blockAccount","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"changeOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"doEnable","type":"bool"}],"name":"enableGasManage","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAdminList","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBlacklist","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGasManagerList","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGasUserList","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isBlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isGasManageEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isGasManager","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isGasUser","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addrs","type":"address[]"},{"internalType":"bool","name":"addOrRemove","type":"bool"}],"name":"setAdmins","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"isManager","type":"bool"}],"name":"setGasManager","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addrs","type":"address[]"},{"internalType":"bool","name":"addOrRemove","type":"bool"}],"name":"setGasUsers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/cmd/geth/genesisTool.go b/cmd/geth/genesisTool.go new file mode 100644 index 00000000..92cdb5b6 --- /dev/null +++ b/cmd/geth/genesisTool.go @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2022 The Zion Authors + * This file is part of The Zion library. + * + * The Zion is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Zion is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The Zion. If not, see . + */ + +package main + +import ( + "encoding/json" + + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus/hotstuff/tool" + "github.com/ethereum/go-ethereum/crypto" + "gopkg.in/urfave/cli.v1" +) + +var ( + genesisToolCommand = cli.Command{ + Name: "genesisTool", + Usage: "A set of commands facilitating generating genesis configuration of maas chain", + Category: "MISCELLANEOUS COMMANDS", + Description: "", + Subcommands: []cli.Command{ + { + Name: "generate", + Flags: []cli.Flag{ + basePathFlag, + nodeCountFlag, + nodePassFlag, + }, + Action: utils.MigrateFlags(generateMaasGensis), + }, + }, + } +) + +var ( + basePathFlag = cli.StringFlag{ + Name: "basePath", + Usage: "The path to store genesis configuration files", + } + nodeCountFlag = cli.IntFlag{ + Name: "nodeCount", + Usage: "The node count", + } + nodePassFlag = cli.StringFlag{ + Name: "nodePass", + Usage: "The node password to generate keystore json", + } +) + +type KeystoreFile struct { + Address string `json:"address"` + Crypto keystore.CryptoJSON `json:"crypto"` + Id string `json:"id"` + Version int `json:"version"` +} + +func generateMaasGensis(ctx *cli.Context) error { + basePath := ctx.String(basePathFlag.Name) + if basePath == "" { + basePath = utils.DefaultBasePath() + } else if basePath[len(basePath)-1:] != "/" { + basePath += "/" + } + nodeNum := ctx.Int(nodeCountFlag.Name) + if nodeNum < 4 { + utils.Fatalf("got %v nodes, but hotstuff BFT requires at least 4 nodes", nodeNum) + } + nodePass := ctx.String(nodePassFlag.Name) + if nodePass == "" { + utils.Fatalf("node password id required") + } + + genesis := new(utils.MaasGenesis) + genesis.Default() + + staticNodes := make([]string, 0) + + nodes := make([]*tool.Node, 0) + metaNodes := make([]*utils.Node, 0) + + for i := 0; i < nodeNum; i++ { + key, _ := crypto.GenerateKey() + addr := crypto.PubkeyToAddress(key.PublicKey) + + nodekey := hexutil.Encode(crypto.FromECDSA(key)) + keyjson, _ := keystore.GenerateKeyJson(key, nodePass) + nodeInf, _ := tool.NodeKey2NodeInfo(nodekey) + staticInf := tool.NodeStaticInfoTemp(nodeInf) + + node := &tool.Node{ + Address: addr.Hex(), + NodeKey: nodekey, + Static: staticInf, + KeyStore: keyjson, + } + nodes = append(nodes, node) + } + + sortedNodes := tool.SortNodes(nodes) + genesisExtra, err := tool.Encode(tool.NodesAddress(sortedNodes)) + if err != nil { + utils.Fatalf(err.Error()) + } + + genesis.Alloc = make(map[string]struct { + PublicKey string `json:"publicKey"` + Balance string `json:"balance"` + }, 0) + + for _, v := range sortedNodes { + nodeInf, err := tool.NodeKey2NodeInfo(v.NodeKey) + if err != nil { + utils.Fatalf(err.Error()) + } + + pubInf, err := tool.NodeKey2PublicInfo(v.NodeKey) + if err != nil { + utils.Fatalf(err.Error()) + } + + genesis.Alloc[v.Address] = struct { + PublicKey string `json:"publicKey"` + Balance string `json:"balance"` + }{ + pubInf, + "100000000000000000000000000000", + } + var keystoreObj KeystoreFile + json.Unmarshal([]byte(v.KeyStore), &keystoreObj) + metaNode := &utils.Node{ + Address: v.Address, + NodeKey: v.NodeKey, + PubKey: pubInf, + Static: v.Static, + KeyStore: keystoreObj, + } + + metaNodes = append(metaNodes, metaNode) + staticNodes = append(staticNodes, tool.NodeStaticInfoTemp(nodeInf)) + } + filePaths := [3]string{} + contents := [3]string{} + + genesis.ExtraData = genesisExtra + geneJson, _ := genesis.Encode() + contents[0] = geneJson + + filePaths[0] = basePath + "genesis.json" + staticNodesEnc, err := json.MarshalIndent(staticNodes, "", "\t") + if err != nil { + utils.Fatalf(err.Error()) + } + contents[1] = string(staticNodesEnc) + filePaths[1] = basePath + "static-nodes.json" + + sortedNodesEnc, _ := json.MarshalIndent(metaNodes, "", "\t") + contents[2] = string(sortedNodesEnc) + filePaths[2] = basePath + "nodes.json" + err = utils.DumpGenesis(filePaths, contents) + if err != nil { + utils.Fatalf(err.Error()) + } + return nil +} diff --git a/cmd/geth/genesisTool_test.go b/cmd/geth/genesisTool_test.go new file mode 100644 index 00000000..facab0e3 --- /dev/null +++ b/cmd/geth/genesisTool_test.go @@ -0,0 +1,41 @@ +package main + +import ( + "errors" + "github.com/ethereum/go-ethereum/cmd/utils" + "testing" +) + +func TestGenesisTool(t *testing.T){ + type TestCase struct { + AllArgs []string + Expect error + AfterHandler func(c *TestCase) + } + testCases := []*TestCase{ + { + []string{"genesisTool", "generate", "3"}, + errors.New("Fatal: got 3 nodes, but hotstuff BFT requires at least 4 nodes"), + nil, + }, + { + []string{"genesisTool", "generate", "5", "-basePath", "./temp/"}, + nil, + func(c *TestCase) { + basePath := c.AllArgs[4] + utils.DeleteBasePath(basePath) + }, + }, + } + + for _, testCase := range testCases { + geth := runGeth(t, testCase.AllArgs...) + if testCase.Expect != nil { + geth.ExpectRegexp(testCase.Expect.Error()) + } + geth.ExpectRegexp("") + if testCase.AfterHandler != nil { + testCase.AfterHandler(testCase) + } + } +} diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 52cff0e7..10310697 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -155,6 +155,7 @@ var ( utils.MinerNotifyFullFlag, configFileFlag, utils.CatalystFlag, + utils.NodeWhitePathFlag, } rpcFlags = []cli.Flag{ @@ -238,6 +239,7 @@ func init() { utils.ShowDeprecated, // See snapshot.go snapshotCommand, + genesisToolCommand, } sort.Sort(cli.CommandsByName(app.Commands)) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index d3fb3f2c..043f0dbc 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -236,7 +236,7 @@ var ( } WhitelistFlag = cli.StringFlag{ Name: "whitelist", - Usage: "Comma separated block number-to-hash mappings to enforce (=)", + Usage: "Only address in whitelist can connect", } BloomFilterSizeFlag = cli.Uint64Flag{ Name: "bloomfilter.size", @@ -501,6 +501,10 @@ var ( Name: "allow-insecure-unlock", Usage: "Allow insecure account unlocking when account-related RPCs are exposed by http", } + NodeWhitePathFlag = cli.StringFlag{ + Name: "node.whitelist", + Usage: "node whitelist config file path", + } RPCGlobalGasCapFlag = cli.Uint64Flag{ Name: "rpc.gascap", Usage: "Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite)", @@ -1246,6 +1250,12 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) { if ctx.GlobalIsSet(InsecureUnlockAllowedFlag.Name) { cfg.InsecureUnlockAllowed = ctx.GlobalBool(InsecureUnlockAllowedFlag.Name) } + // set node whitelist file path + if !ctx.GlobalIsSet(NodeWhitePathFlag.Name) { + ctx.GlobalSet(NodeWhitePathFlag.Name, "node-whitelist.json") + } + cfg.NodeWhitePath = ctx.GlobalString(NodeWhitePathFlag.Name) + // params.StartNodeWhiteLoadTask(cfg.NodeWhitePath) } func setSmartCard(ctx *cli.Context, cfg *node.Config) { diff --git a/cmd/utils/maas_genesis.go b/cmd/utils/maas_genesis.go new file mode 100644 index 00000000..002bef16 --- /dev/null +++ b/cmd/utils/maas_genesis.go @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2022 The Zion Authors + * This file is part of The Zion library. + * + * The Zion is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Zion is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The Zion. If not, see . + */ + +package utils + +import ( + "encoding/json" + "io/ioutil" + "os" + "path" + "path/filepath" +) + +type MaasGenesis struct { + Config struct { + ChainId uint64 `json:"chainId"` + HomesteadBlock uint64 `json:"homesteadBlock"` + Eip150Block uint64 `json:"eip150Block"` + Eip155Block uint64 `json:"eip155Block"` + Eip158Block uint64 `json:"eip158Block"` + ByzantiumBlock uint64 `json:"byzantiumBlock"` + ConstantinopleBlock uint64 `json:"constantinopleBlock"` + PetersburgBlock uint64 `json:"petersburgBlock"` + IstanbulBlock uint64 `json:"istanbulBlock"` + HotStuff struct { + Protocol string `json:"protocol"` + } `json:"hotstuff"` + } `json:"config"` + Alloc map[string]struct { + PublicKey string `json:"publicKey"` + Balance string `json:"balance"` + } `json:"alloc"` + Coinbase string `json:"coinbase"` + Difficulty string `json:"difficulty"` + ExtraData string `json:"extraData"` + GasLimit string `json:"gasLimit"` + Nonce string `json:"nonce"` + Mixhash string `json:"mixhash"` + ParentHash string `json:"parentHash"` + Timestamp string `json:"timestamp"` +} + +func (m *MaasGenesis) Encode() (string, error) { + genesisJson, err := json.MarshalIndent(m, "", "\t") + return string(genesisJson), err +} + +func (m *MaasGenesis) Decode(data string) error { + dataBytes := []byte(data) + err := json.Unmarshal(dataBytes, m) + return err +} + +// Default genesis is not a valid block +// it's used only for initialization purpose +func (m *MaasGenesis) Default() { + m.Config = struct { + ChainId uint64 `json:"chainId"` + HomesteadBlock uint64 `json:"homesteadBlock"` + Eip150Block uint64 `json:"eip150Block"` + Eip155Block uint64 `json:"eip155Block"` + Eip158Block uint64 `json:"eip158Block"` + ByzantiumBlock uint64 `json:"byzantiumBlock"` + ConstantinopleBlock uint64 `json:"constantinopleBlock"` + PetersburgBlock uint64 `json:"petersburgBlock"` + IstanbulBlock uint64 `json:"istanbulBlock"` + HotStuff struct { + Protocol string `json:"protocol"` + } `json:"hotstuff"` + }{ + 10898, 0, 0, 0, 0, 0, 0, 0, 0, + struct { + Protocol string `json:"protocol"` + }{ + "basic", + }, + } + + m.Coinbase = "0x0000000000000000000000000000000000000000" + m.Difficulty = "0x1" + //"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000f8daf893940f45dafcd39e1c59202e91306a1671cb7f8884be944ba9732e2358f41e682b7a7aab71e614e08383df946519d82d761c275f01de6f197542de924296928e946cfd8d31a55cdf03303e280792c7d6ce855601f394782833979973d83cd48332e09938b95f9ba32b5094990f7aafa09fea4583c0c72063b306cde54e1e8f949bcd01b46b98254ee3611eb1501a12780343f7d2b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080", + m.GasLimit = "0xffffffff" + m.Nonce = "0x4510809143055965" + m.Mixhash = "0x0000000000000000000000000000000000000000000000000000000000000000" + m.ParentHash = "0x0000000000000000000000000000000000000000000000000000000000000000" + m.Timestamp = "0x00" +} + +func DumpGenesis(filePaths [3]string, contents [3]string) error { + for k, file_ := range filePaths { + err := ensureBaseDir(file_) + if err != nil { + return err + } + f, err := os.Create(file_) + if err != nil { + return err + } + defer f.Close() + _, err = f.Write([]byte(contents[k])) + if err != nil { + return err + } + } + return nil +} + +// If there is no such directory, it will creates this dir +func ensureBaseDir(fpath string) error { + baseDir := path.Dir(fpath) + info, err := os.Stat(baseDir) + if err == nil && info.IsDir() { + return nil + } + return os.MkdirAll(baseDir, 0755) +} + +func DefaultBasePath() (basePath string) { + exePath, _ := os.Executable() + dir := filepath.Dir(exePath) + "/" + return dir +} + +type Node struct { + Address string `json:"address"` + NodeKey string `json:"nodeKey"` + KeyStore interface{} `json:"keystore"` + PubKey string `json:"pubKey"` + Static string `json:"static"` +} + +func (m *Node) Encode() (string, error) { + genesisJson, err := json.MarshalIndent(m, "", "\t") + return string(genesisJson), err +} + +func (m *Node) Decode(data string) error { + dataBytes := []byte(data) + err := json.Unmarshal(dataBytes, m) + return err +} + +// This is only used in unit test +func DeleteBasePath(basePath string) { + dir, _ := ioutil.ReadDir(basePath) + for _, d := range dir { + os.RemoveAll(path.Join([]string{basePath, d.Name()}...)) + } + os.Remove(basePath) +} diff --git a/cmd/utils/maas_genesis_test.go b/cmd/utils/maas_genesis_test.go new file mode 100644 index 00000000..c621447a --- /dev/null +++ b/cmd/utils/maas_genesis_test.go @@ -0,0 +1,51 @@ +package utils + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestMaasGenesisFuncs(t *testing.T) { + genesis := new(MaasGenesis) + genesis.Default() + genesisStr, err := genesis.Encode() + t.Log(genesisStr) + assert.NoError(t, err) + got := new(MaasGenesis) + err = got.Decode(genesisStr) + assert.NoError(t, err) + assert.Equal(t, genesis, got) +} + +func TestDumpGenesis(t *testing.T) { + filePaths := [3]string{ + "./temp/genesis.json", + "./temp/static-nodes.json", + "./temp/nodes.json", + } + + contents := [3]string{} + // not valid data, only for test + contents[0] = "{\n \"config\": {\n \"chainId\": 10898, \n \"homesteadBlock\": 0,\n \"eip150Block\": 0,\n \"eip155Block\": 0,\n \"eip158Block\": 0,\n \"byzantiumBlock\": 0,\n \"constantinopleBlock\": 0,\n \"petersburgBlock\": 0,\n \"istanbulBlock\": 0,\n \"hotstuff\": {\n \"protocol\": \"basic\"\n }\n },\n \"alloc\": {\n \"0x0F45DAfCD39e1C59202e91306A1671cB7f8884be\": {\"publicKey\": \"0x039053297a9feb8c56ccd78592ed3d98dd6165131d3c9ee3398f720c9de65a7b74\", \"balance\": \"100000000000000000000000000000\"},\n \"0x4ba9732E2358F41E682B7a7AAb71e614e08383dF\": {\"publicKey\": \"0x034b6bb61d6ab259d460701957784ba415ab05bf4b9093eab4eb64a2d4a588ffd2\", \"balance\": \"100000000000000000000000000000\"},\n \"0x6519d82d761c275f01de6F197542dE924296928E\": {\"publicKey\": \"0x031edfa05742afbf0059141ebd0949e8f3766a6718e2d4b4df39ac7d96cda9bb46\", \"balance\": \"100000000000000000000000000000\"},\n \"0x6cfd8d31A55CDf03303E280792C7D6cE855601f3\": {\"publicKey\": \"0x0270a210c0b6a437943423afef05403e1f9fbbe5dad4d9317233f4ad5e58ee17ff\", \"balance\": \"100000000000000000000000000000\"},\n \"0x782833979973d83Cd48332E09938B95f9ba32B50\": {\"publicKey\": \"0x036f25d77c154017db892c763354e8cd7f54a91246f74c7a6400e3cba4f30e73b8\", \"balance\": \"100000000000000000000000000000\"},\n \"0x990f7AaFA09FEa4583c0C72063b306cdE54e1e8F\": {\"publicKey\": \"0x03a9d10e5ca3475b47a7dc1a72679cb377b4dfb8dd5046b92bf8ba721f2985f053\", \"balance\": \"100000000000000000000000000000\"},\n \"0x9BCd01b46b98254eE3611Eb1501A12780343f7D2\": {\"publicKey\": \"0x03f8e5aab12985e7e058d0b47afafa8ac5fb813fde8051354403c320d9cc38a3b1\", \"balance\": \"100000000000000000000000000000\"}\n },\n \"coinbase\": \"0x0000000000000000000000000000000000000000\",\n \"difficulty\": \"0x1\",\n \"extraData\": \"0x0000000000000000000000000000000000000000000000000000000000000000f8daf893940f45dafcd39e1c59202e91306a1671cb7f8884be944ba9732e2358f41e682b7a7aab71e614e08383df946519d82d761c275f01de6f197542de924296928e946cfd8d31a55cdf03303e280792c7d6ce855601f394782833979973d83cd48332e09938b95f9ba32b5094990f7aafa09fea4583c0c72063b306cde54e1e8f949bcd01b46b98254ee3611eb1501a12780343f7d2b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080\",\n \"gasLimit\": \"0xffffffff\",\n \"nonce\": \"0x4510809143055965\",\n \"mixhash\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n \"parentHash\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n \"timestamp\": \"0x00\"\n}" + contents[1] = "[\n \"enode://9053297a9feb8c56ccd78592ed3d98dd6165131d3c9ee3398f720c9de65a7b74fc18a9f870cf757d3aeed03c32dbacfc6aa41007b6b0192631859b7769d0689f@127.0.0.1:30300?discport=0\",\n \"enode://4b6bb61d6ab259d460701957784ba415ab05bf4b9093eab4eb64a2d4a588ffd229fccde97d14c0c6f14ffcedd73d56e8be3a2cea49ec58243a01ad311edb943d@127.0.0.1:30300?discport=0\",\n \"enode://1edfa05742afbf0059141ebd0949e8f3766a6718e2d4b4df39ac7d96cda9bb46a6a4e304c4cdd2d7bed2c29c7857b039d2bb08f4b81cee92cbbfe4155c76fc11@127.0.0.1:30300?discport=0\",\n \"enode://70a210c0b6a437943423afef05403e1f9fbbe5dad4d9317233f4ad5e58ee17ff24b9f527b48ffdc5279ddc065e5810c8d647af85ab40a295676667ba085638c8@127.0.0.1:30300?discport=0\",\n \"enode://6f25d77c154017db892c763354e8cd7f54a91246f74c7a6400e3cba4f30e73b81894600d3505c59df5ad9711621de07b80166dffacfcee9a2f4fff2b3f0c31dd@127.0.0.1:30300?discport=0\",\n \"enode://a9d10e5ca3475b47a7dc1a72679cb377b4dfb8dd5046b92bf8ba721f2985f053538623149f3a7e59a78ae6f7c7d3305b76689b989863b12aab1c8b86837a3ef1@127.0.0.1:30300?discport=0\",\n \"enode://f8e5aab12985e7e058d0b47afafa8ac5fb813fde8051354403c320d9cc38a3b1e34da681ffd1c41c99b50cdb04292d6228357686b264846f5b55e2ef67df547b@127.0.0.1:30300?discport=0\"\n]\n" + contents[2] = "[\n {\n \"Address\": \"0x152e6e7C0d1637Cfc3C909852BD9914A67F91340\",\n \"NodeKey\": \"0x22b2c3a6f4be86581dbc729acba0048d70e6a960847d61902dc54e0dad0b8a00\",\n \"Static\": \"enode://13ec7f7dde00342f076bdbaafa1488b864fb7d34a744379a421d6546e4ea76f74d364fa3b1350622760674110ccae61c450631d69c20ac58b711f2e55c934bcf@127.0.0.1:30300?discport=0\"\n },\n {\n \"Address\": \"0x1E306D7C8Ea7b042ecc974A7609a84b888453Cd8\",\n \"NodeKey\": \"0xc9ac34375e9f739b5951058f17afb7264a77ad7decf086e85eafb1c9af8305a1\",\n \"Static\": \"enode://c0e4ac8fa2daab3994b15ffa95284f62ae647e1a7b572f899d77eafd0b2f8be8e337260129acf98832a453ef25e749c10c13d45e5990fd27979c9c70357301f5@127.0.0.1:30300?discport=0\"\n },\n {\n \"Address\": \"0x2B707ae427547Ae18c7bddB5FDbd78a14386E874\",\n \"NodeKey\": \"0xf07946ed4c70a4c1bf7bdf33d0d7cd870b24f27c450c3a14cef824dde1e26b9c\",\n \"Static\": \"enode://4deb701b087b33338e93bb87f6a843015a0d18987ff8f187f7f25dd822deedeb0bed2069070ace715e01bc9a0a0ae5016ae85e66f5293056571e3a0854aba26f@127.0.0.1:30300?discport=0\"\n },\n {\n \"Address\": \"0x525b5500eE75fE2A84Cc879Cf55BB9e691A802EB\",\n \"NodeKey\": \"0x2f09f88be6885546c2faba9d8835d772d8f2325d64273d7153432effdc78224f\",\n \"Static\": \"enode://115ef399832f714c7723a42fb2d6707094020eb6446fdeeb72c0cb137e773984bdb4242b4c22691ed154129ef8f0216ee78d0df873a625aba156abf3628904b8@127.0.0.1:30300?discport=0\"\n }\n]\n" + err := DumpGenesis(filePaths, contents) + assert.NoError(t, err) + DeleteBasePath("./temp/") +} + +func TestNodeFuncs(t *testing.T) { + node := new(Node) + node.Address = common.HexToAddress("0x123").String() + node.NodeKey = "0x1231231asasd" + node.PubKey = "0x123dsaad122" + node.Static = "enode:1231asdas" + nodeJson, err := node.Encode() + assert.NoError(t, err) + got := new(Node) + err = got.Decode(nodeJson) + assert.NoError(t, err) + assert.Equal(t, got, node) +} + diff --git a/consensus/hotstuff/config.go b/consensus/hotstuff/config.go index aab960b3..6acbe5b0 100644 --- a/consensus/hotstuff/config.go +++ b/consensus/hotstuff/config.go @@ -36,8 +36,8 @@ type Config struct { // todo: modify request timeout, and miner recommit default value is 3s. recommit time should be > blockPeriod var DefaultBasicConfig = &Config{ - RequestTimeout: 4000, - BlockPeriod: 1, + RequestTimeout: 6000, + BlockPeriod: 3, LeaderPolicy: RoundRobin, Epoch: 30000, Test: false, diff --git a/consensus/hotstuff/tool/encoder.go b/consensus/hotstuff/tool/encoder.go index 7b62b270..cc40da91 100644 --- a/consensus/hotstuff/tool/encoder.go +++ b/consensus/hotstuff/tool/encoder.go @@ -25,10 +25,13 @@ import ( "fmt" "strings" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus/hotstuff" "github.com/ethereum/go-ethereum/consensus/hotstuff/validator" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + + //"github.com/ethereum/go-ethereum/consensus/hotstuff/backend" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/rlp" @@ -54,9 +57,10 @@ func Encode(validators []common.Address) (string, error) { } type Node struct { - Address string - NodeKey string - Static string + Address string + NodeKey string + Static string + KeyStore string } func SortNodes(src []*Node) []*Node { @@ -70,6 +74,7 @@ func SortNodes(src []*Node) []*Node { // sort address valset := validator.NewSet(oriAddrs, hotstuff.RoundRobin) + //valset := backend.NewDefaultValSet(oriAddrs) list := make([]*Node, 0) for _, val := range valset.AddressList() { diff --git a/consensus/hotstuff/tool/encoder_test.go b/consensus/hotstuff/tool/encoder_test.go index a2525b9f..7232e70c 100644 --- a/consensus/hotstuff/tool/encoder_test.go +++ b/consensus/hotstuff/tool/encoder_test.go @@ -20,11 +20,15 @@ package tool import ( "encoding/json" + "log" "testing" + "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus/hotstuff" "github.com/ethereum/go-ethereum/consensus/hotstuff/validator" + "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/assert" ) @@ -80,22 +84,41 @@ func TestEncode(t *testing.T) { } var testOriginValAndNodeKeys = []*Node{ - { - Address: "0x258af48e28e4a6846e931ddff8e1cdf8579821e5", - NodeKey: "4b0c9b9d685db17ac9f295cb12f9d7d2369f5bf524b3ce52ce424031cafda1ae", - }, - { - Address: "0x6a708455c8777630aac9d1e7702d13f7a865b27c", - NodeKey: "3d9c828244d3b2da70233a0a2aea7430feda17bded6edd7f0c474163802a431c", - }, - { - Address: "0x8c09d936a1b408d6e0afaa537ba4e06c4504a0ae", - NodeKey: "cc69b13ca2c5cd4d76bb881f6ad18d93bd947042c0f3a7adc80bdd17dac68210", - }, - { - Address: "0xad3bf5ed640cc72f37bd21d64a65c3c756e9c88c", - NodeKey: "018c71d5e3b245117ffba0975e46129371473c6a1d231c5eddf7a8364d704846", - }, + // local side chain + //{ + // Address: "0x09f4E484D43B3D6b20957F7E1760beE3C6F62186", + // NodeKey: "562aa98da69477996bd82422b97698541f25e71ba2f803970947b3ad8bdb7afa", + //}, + //{ + // Address: "0x294b8211E7010f457d85942aC874d076D739E32a", + // NodeKey: "8bea3ce27136df435ada62a40a4226404879b3c42e2e86ba9a236b4a61c99c26", + //}, + //{ + // Address: "0x9deAD91D8632DCEEC701710bAF7922324DD45F58", + // NodeKey: "53f7d9ec7657cdd3a3eaa8ddd126d36fbc60203448fca1bbfccec0d59d173da6", + //}, + //{ + // Address: "0xc5e2344b875e236b3475e9e4E70448525cA5210F", + // NodeKey: "305baf1e19a2da40b413dfb62b206b0ac74cb3d7e975cb70fe8391cbbe174f2a", + //}, + + // local main chain + //{ + // Address: "0x258af48e28e4a6846e931ddff8e1cdf8579821e5", + // NodeKey: "4b0c9b9d685db17ac9f295cb12f9d7d2369f5bf524b3ce52ce424031cafda1ae", + //}, + //{ + // Address: "0x6a708455c8777630aac9d1e7702d13f7a865b27c", + // NodeKey: "3d9c828244d3b2da70233a0a2aea7430feda17bded6edd7f0c474163802a431c", + //}, + //{ + // Address: "0x8c09d936a1b408d6e0afaa537ba4e06c4504a0ae", + // NodeKey: "cc69b13ca2c5cd4d76bb881f6ad18d93bd947042c0f3a7adc80bdd17dac68210", + //}, + //{ + // Address: "0xad3bf5ed640cc72f37bd21d64a65c3c756e9c88c", + // NodeKey: "018c71d5e3b245117ffba0975e46129371473c6a1d231c5eddf7a8364d704846", + //}, //{ // Address: "0xc095448424a5ecd5ca7ccdadfaad127a9d7e88ec", // NodeKey: "49e26aa4d60196153153388a24538c2693d65f0010a3a488c0c4c2b2a64b2de4", @@ -111,13 +134,39 @@ var testOriginValAndNodeKeys = []*Node{ } func TestEncodeSalt(t *testing.T) { - sortedNodes := SortNodes(testOriginValAndNodeKeys) + dumpNodes(t, testOriginValAndNodeKeys) +} + +func TestGenerateAndEncode(t *testing.T) { + nodes := generateNodes(7) + dumpNodes(t, nodes) +} + +func TestGenerateKeyStore(t *testing.T) { + nodekey := "26cc96a0d256d45e1515bf325bec1925746d796b3637b147f35a01d6c2d6399b" + passphrase := "Onchain@Maas" + + privateKey, err := crypto.HexToECDSA(nodekey) + if err != nil { + log.Fatal(err) + } + + keyjson, err := keystore.GenerateKeyJson(privateKey, passphrase) + if err != nil { + t.Fatalf("Error encrypting key: %v", err) + } + log.Println(string(keyjson)) +} + +func dumpNodes(t *testing.T, nodes []*Node) { + sortedNodes := SortNodes(nodes) staticNodes := make([]string, 0) for _, v := range sortedNodes { nodeInf, err := NodeKey2NodeInfo(v.NodeKey) if err != nil { t.Fatal(err) } + pubInf, err := NodeKey2PublicInfo(v.NodeKey) if err != nil { t.Fatal(err) @@ -138,3 +187,26 @@ func TestEncodeSalt(t *testing.T) { staticNodesEnc, err := json.MarshalIndent(staticNodes, "", "\t") t.Log(string(staticNodesEnc)) } + +func generateNodes(n int) []*Node { + nodes := make([]*Node, 0) + + for i := 0; i < n; i++ { + key, _ := crypto.GenerateKey() + addr := crypto.PubkeyToAddress(key.PublicKey) + + nodekey := hexutil.Encode(crypto.FromECDSA(key)) + nodeInf, _ := NodeKey2NodeInfo(nodekey) + + staticInf := NodeStaticInfoTemp(nodeInf) + + node := &Node{ + Address: addr.Hex(), + NodeKey: nodekey, + Static: staticInf, + } + nodes = append(nodes, node) + } + + return nodes +} diff --git a/contracts/native/boot/boot.go b/contracts/native/boot/boot.go index 2e9daeea..a97d710f 100644 --- a/contracts/native/boot/boot.go +++ b/contracts/native/boot/boot.go @@ -18,22 +18,11 @@ package boot import ( - "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/governance" - "github.com/ethereum/go-ethereum/contracts/native/governance/neo3_state_manager" + "github.com/ethereum/go-ethereum/contracts/native/governance/maas_config" "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - "github.com/ethereum/go-ethereum/contracts/native/governance/relayer_manager" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/header_sync" ) func InitialNativeContracts() { - governance.InitGovernance() - header_sync.InitHeaderSync() - cross_chain_manager.InitCrossChainManager() - neo3_state_manager.InitNeo3StateManager() node_manager.InitNodeManager() - relayer_manager.InitRelayerManager() - side_chain_manager.InitSideChainManager() - + maas_config.InitMaasConfig() } diff --git a/contracts/native/contract.go b/contracts/native/contract.go index cf8c05e7..743bf97e 100644 --- a/contracts/native/contract.go +++ b/contracts/native/contract.go @@ -129,32 +129,60 @@ func (s *NativeContract) Invoke() ([]byte, error) { return ret, err } -func (s *NativeContract) AddNotify(abi *abiPkg.ABI, topics []string, data ...interface{}) (err error) { - +func (s *NativeContract) AddNotify(abi *abiPkg.ABI, topics []string, data ...interface{}) error { var topicIDs []common.Hash - for _, topic := range topics { - eventInfo, ok := abi.Events[topic] - if !ok { - eventInfo, ok = abi.Events["evt"+abiPkg.ToCamelCase(topic)] - if !ok { - err = fmt.Errorf("topic %s/%s not exists", topic, "evt"+abiPkg.ToCamelCase(topic)) - return - } - } - topicIDs = append(topicIDs, eventInfo.ID) + if topics == nil || len(topics) == 0 { + return fmt.Errorf("AddNotify, topics length invalid") } topic := topics[0] - if _, ok := abi.Events[topic]; !ok { - topic = "evt" + abiPkg.ToCamelCase(topic) + topic, event, err := getTopicAndEvent(abi, topic) + if err != nil { + return fmt.Errorf("AddNotify, getTopicAndEvent err: %v", err) + } + topicIDs = append(topicIDs, event.ID) + + if len(data) != len(event.Inputs) { + return fmt.Errorf("AddNotify, args length not equal to params number") } + + for i, input := range event.Inputs { + if !input.Indexed { + continue + } + + topicID, ok := data[i].(common.Hash) + if !ok { + return fmt.Errorf("AddNotify, indexed field should be type of common.Hash") + } + topicIDs = append(topicIDs, topicID) + } + packedData, err := utils.PackEvents(abi, topic, data...) if err != nil { - err = fmt.Errorf("AddNotify, PackEvents error: %v", err) - return + return fmt.Errorf("AddNotify, PackEvents error: %v", err) } emitter := utils.NewEventEmitter(s.ref.CurrentContext().ContractAddress, s.ContractRef().BlockHeight().Uint64(), s.StateDB()) emitter.Event(topicIDs, packedData) - return + + return nil +} + +func topic2CamelCase(topic string) string { + return "evt" + abiPkg.ToCamelCase(topic) +} + +func getTopicAndEvent(abi *abiPkg.ABI, topic string) (string, *abiPkg.Event, error) { + eventInfo, ok := abi.Events[topic] + if ok { + return topic, &eventInfo, nil + } + + topicWithCamel := topic2CamelCase(topic) + eventInfo, ok = abi.Events[topicWithCamel] + if ok { + return topicWithCamel, &eventInfo, nil + } + return topic, nil, fmt.Errorf("topic %s not exist", topic) } diff --git a/contracts/native/contract_test.go b/contracts/native/contract_test.go new file mode 100644 index 00000000..481e2e76 --- /dev/null +++ b/contracts/native/contract_test.go @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2021 The Zion Authors + * This file is part of The Zion library. + * + * The Zion is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Zion is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The Zion. If not, see . + */ + +package native + +import ( + "math/big" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/stretchr/testify/assert" +) + +func TestAddNotify(t *testing.T) { + // event CrossChainEvent(address indexed sender, bytes txId, address proxyOrAssetContract); + abiJsonStr := `[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bytes","name":"txId","type":"bytes"},{"indexed":false,"internalType":"address","name":"proxyOrAssetContract","type":"address"}],"name":"CrossChainEvent","type":"event"}]` + topic := "CrossChainEvent" + sender := common.HexToHash("0x123") + txId := []byte{'1', 'a'} + proxy := common.HexToAddress("0x3a") + + ab, _ := abi.JSON(strings.NewReader(abiJsonStr)) + db := rawdb.NewMemoryDatabase() + sdb, _ := state.New(common.Hash{}, state.NewDatabase(db), nil) + ctx := NewNativeContract(sdb, nil) + ref := NewContractRef(sdb, common.Address{}, common.Address{}, big.NewInt(1), common.Hash{}, 0, nil) + ref.PushContext(&Context{ + Caller: common.Address{}, + ContractAddress: common.Address{}, + Payload: nil, + }) + ctx.ref = ref + + assert.NoError(t, ctx.AddNotify(&ab, []string{topic}, sender, txId, proxy)) +} diff --git a/contracts/native/cross_chain_manager/bsc/bsc_handler.go b/contracts/native/cross_chain_manager/bsc/bsc_handler.go deleted file mode 100644 index 5f39a840..00000000 --- a/contracts/native/cross_chain_manager/bsc/bsc_handler.go +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package bsc - -import ( - "bytes" - "encoding/hex" - "encoding/json" - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - scom "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/common" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/bsc" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth/types" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/light" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie" -) - -// Handler ... -type Handler struct { -} - -// NewHandler ... -func NewHandler() *Handler { - return &Handler{} -} - -// MakeDepositProposal ... -func (h *Handler) MakeDepositProposal(service *native.NativeContract) (*scom.MakeTxParam, error) { - ctx := service.ContractRef().CurrentContext() - params := &scom.EntranceParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodImportOuterTransfer, params, ctx.Payload); err != nil { - return nil, err - } - - sideChain, err := side_chain_manager.GetSideChain(service, params.SourceChainID) - if err != nil { - return nil, fmt.Errorf("eth MakeDepositProposal, side_chain_manager.GetSideChain error: %v", err) - } - - value, err := verifyFromTx(service, params.Proof, params.Extra, params.SourceChainID, params.Height, sideChain) - if err != nil { - return nil, fmt.Errorf("eth MakeDepositProposal, verifyFromEthTx error: %s", err) - } - - if err := scom.CheckDoneTx(service, value.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("eth MakeDepositProposal, check done transaction error:%s", err) - } - if err := scom.PutDoneTx(service, value.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("eth MakeDepositProposal, PutDoneTx error:%s", err) - } - return value, nil -} - -func verifyFromTx(native *native.NativeContract, proof, extra []byte, fromChainID uint64, height uint32, sideChain *side_chain_manager.SideChain) (param *scom.MakeTxParam, err error) { - cheight, err := bsc.GetCanonicalHeight(native, fromChainID) - if err != nil { - return - } - - cheight32 := uint32(cheight) - - if cheight32 < height || cheight32-height < uint32(sideChain.BlocksToWait-1) { - return nil, fmt.Errorf("verifyFromTx, transaction is not confirmed, current height: %d, input height: %d", cheight, height) - } - - headerWithSum, err := bsc.GetCanonicalHeader(native, fromChainID, uint64(height)) - if err != nil { - return nil, fmt.Errorf("verifyFromTx, GetCanonicalHeader height:%d, error:%s", height, err) - } - - bscProof := new(Proof) - err = json.Unmarshal(proof, bscProof) - if err != nil { - return nil, fmt.Errorf("verifyFromTx, unmarshal proof error:%s", err) - } - - if len(bscProof.StorageProofs) != 1 { - return nil, fmt.Errorf("verifyFromTx, incorrect proof format") - } - - proofResult, err := verifyMerkleProof(bscProof, headerWithSum.Header, sideChain.CCMCAddress) - if err != nil { - return nil, fmt.Errorf("verifyFromTx, verifyMerkleProof error:%v", err) - } - - if proofResult == nil { - return nil, fmt.Errorf("verifyFromTx, verifyMerkleProof failed") - } - - if !checkProofResult(proofResult, extra) { - return nil, fmt.Errorf("verifyFromTx, verify proof value hash failed, proof result:%x, extra:%x", proofResult, extra) - } - - txParam, err := scom.DecodeTxParam(extra) - if err != nil { - return nil, fmt.Errorf("verifyFromTx, deserialize merkleValue error:%s", err) - } - return txParam, nil -} - -// Proof ... -type Proof struct { - Address string `json:"address"` - Balance string `json:"balance"` - CodeHash string `json:"codeHash"` - Nonce string `json:"nonce"` - StorageHash string `json:"storageHash"` - AccountProof []string `json:"accountProof"` - StorageProofs []StorageProof `json:"storageProof"` -} - -// StorageProof ... -type StorageProof struct { - Key string `json:"key"` - Value string `json:"value"` - Proof []string `json:"proof"` -} - -// ProofAccount ... -type ProofAccount struct { - Nounce *big.Int - Balance *big.Int - Storage common.Hash - Codehash common.Hash -} - -func verifyMerkleProof(bscProof *Proof, blockData *types.Header, contractAddr []byte) ([]byte, error) { - //1. prepare verify account - nodeList := new(light.NodeList) - - for _, s := range bscProof.AccountProof { - p := scom.Replace0x(s) - nodeList.Put(nil, common.Hex2Bytes(p)) - } - ns := nodeList.NodeSet() - - addr := common.Hex2Bytes(scom.Replace0x(bscProof.Address)) - if !bytes.Equal(addr, contractAddr) { - return nil, fmt.Errorf("verifyMerkleProof, contract address is error, proof address: %s, side chain address: %s", bscProof.Address, hex.EncodeToString(contractAddr)) - } - acctKey := crypto.Keccak256(addr) - - //2. verify account proof - acctVal, err := trie.VerifyProof(blockData.Root, acctKey, ns) - if err != nil { - return nil, fmt.Errorf("verifyMerkleProof, verify account proof error:%s", err) - } - - nounce := new(big.Int) - _, ok := nounce.SetString(scom.Replace0x(bscProof.Nonce), 16) - if !ok { - return nil, fmt.Errorf("verifyMerkleProof, invalid format of nounce:%s", bscProof.Nonce) - } - - balance := new(big.Int) - _, ok = balance.SetString(scom.Replace0x(bscProof.Balance), 16) - if !ok { - return nil, fmt.Errorf("verifyMerkleProof, invalid format of balance:%s", bscProof.Balance) - } - - storageHash := common.HexToHash(scom.Replace0x(bscProof.StorageHash)) - codeHash := common.HexToHash(scom.Replace0x(bscProof.CodeHash)) - - acct := &ProofAccount{ - Nounce: nounce, - Balance: balance, - Storage: storageHash, - Codehash: codeHash, - } - - acctrlp, err := rlp.EncodeToBytes(acct) - if err != nil { - return nil, err - } - - if !bytes.Equal(acctrlp, acctVal) { - return nil, fmt.Errorf("verifyMerkleProof, verify account proof failed, wanted:%v, get:%v", acctrlp, acctVal) - } - - //3.verify storage proof - nodeList = new(light.NodeList) - if len(bscProof.StorageProofs) != 1 { - return nil, fmt.Errorf("verifyMerkleProof, invalid storage proof format") - } - - sp := bscProof.StorageProofs[0] - storageKey := crypto.Keccak256(common.HexToHash(scom.Replace0x(sp.Key)).Bytes()) - - for _, prf := range sp.Proof { - nodeList.Put(nil, common.Hex2Bytes(scom.Replace0x(prf))) - } - - ns = nodeList.NodeSet() - val, err := trie.VerifyProof(storageHash, storageKey, ns) - if err != nil { - return nil, fmt.Errorf("verifyMerkleProof, verify storage proof error:%s", err) - } - - return val, nil -} - -func checkProofResult(result, value []byte) bool { - var tempBytes []byte - err := rlp.DecodeBytes(result, &tempBytes) - if err != nil { - log.Errorf("checkProofResult, rlp.DecodeBytes error:%s\n", err) - return false - } - // - var s []byte - for i := len(tempBytes); i < 32; i++ { - s = append(s, 0) - } - s = append(s, tempBytes...) - hash := crypto.Keccak256(value) - return bytes.Equal(s, hash) -} diff --git a/contracts/native/cross_chain_manager/common/abi.go b/contracts/native/cross_chain_manager/common/abi.go deleted file mode 100644 index 6c5308ab..00000000 --- a/contracts/native/cross_chain_manager/common/abi.go +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package common - -import ( - "fmt" - "strings" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/contracts/native/go_abi/cross_chain_manager_abi" -) - -var ( - MethodContractName = cross_chain_manager_abi.MethodName - MethodImportOuterTransfer = cross_chain_manager_abi.MethodImportOuterTransfer - MethodMultiSign = cross_chain_manager_abi.MethodMultiSign - MethodBlackChain = cross_chain_manager_abi.MethodBlackChain - MethodWhiteChain = cross_chain_manager_abi.MethodWhiteChain -) - -var ABI *abi.ABI - -func init() { - ABI = GetABI() -} - -func GetABI() *abi.ABI { - ab, err := abi.JSON(strings.NewReader(cross_chain_manager_abi.CrossChainManagerABI)) - if err != nil { - panic(fmt.Sprintf("failed to load abi json string: [%v]", err)) - } - return &ab -} - -type BlackChainParam struct { - ChainID uint64 -} diff --git a/contracts/native/cross_chain_manager/common/param.go b/contracts/native/cross_chain_manager/common/param.go deleted file mode 100644 index 1cc7fb1f..00000000 --- a/contracts/native/cross_chain_manager/common/param.go +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package common - -import ( - "fmt" - "io" - "math/big" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/rlp" - polycomm "github.com/polynetwork/poly/common" -) - -const ( - KEY_PREFIX_BTC = "btc" - - KEY_PREFIX_BTC_VOTE = "btcVote" - REQUEST = "request" - DONE_TX = "doneTx" - - NOTIFY_MAKE_PROOF_EVENT = "makeProof" -) - -type ChainHandler interface { - MakeDepositProposal(service *native.NativeContract) (*MakeTxParam, error) -} - -type InitRedeemScriptParam struct { - RedeemScript string -} - -func (this *InitRedeemScriptParam) Serialization(sink *polycomm.ZeroCopySink) { - sink.WriteString(this.RedeemScript) -} - -func (this *InitRedeemScriptParam) Deserialization(source *polycomm.ZeroCopySource) error { - redeemScript, eof := source.NextString() - if eof { - return fmt.Errorf("MultiSignParam deserialize redeemScript error") - } - - this.RedeemScript = redeemScript - return nil -} - -type EntranceParam struct { - SourceChainID uint64 `json:"sourceChainId"` - Height uint32 `json:"height"` - Proof []byte `json:"proof"` - RelayerAddress []byte `json:"relayerAddress"` //in zion can be empty because caller can get through ctx - Extra []byte `json:"extra"` - HeaderOrCrossChainMsg []byte `json:"headerOrCrossChainMsg"` -} - -func (this *EntranceParam) Serialization(sink *polycomm.ZeroCopySink) { - sink.WriteUint64(this.SourceChainID) - sink.WriteUint32(this.Height) - sink.WriteVarBytes(this.Proof) - sink.WriteVarBytes(this.RelayerAddress) - sink.WriteVarBytes(this.Extra) - sink.WriteVarBytes(this.HeaderOrCrossChainMsg) -} - -func (this *EntranceParam) Deserialization(source *polycomm.ZeroCopySource) error { - sourceChainID, eof := source.NextUint64() - if eof { - return fmt.Errorf("EntranceParam deserialize sourcechainid error") - } - - height, eof := source.NextUint32() - if eof { - return fmt.Errorf("EntranceParam deserialize height error") - } - proof, eof := source.NextVarBytes() - if eof { - return fmt.Errorf("EntranceParam deserialize proof error") - } - relayerAddr, eof := source.NextVarBytes() - if eof { - return fmt.Errorf("EntranceParam deserialize relayerAddr error") - } - extra, eof := source.NextVarBytes() - if eof { - return fmt.Errorf("EntranceParam deserialize txdata error") - } - headerOrCrossChainMsg, eof := source.NextVarBytes() - if eof { - return fmt.Errorf("EntranceParam deserialize headerOrCrossChainMsg error") - } - this.SourceChainID = sourceChainID - this.Height = height - this.Proof = proof - this.RelayerAddress = relayerAddr - this.Extra = extra - this.HeaderOrCrossChainMsg = headerOrCrossChainMsg - return nil -} - -type MakeTxParam struct { - TxHash []byte - CrossChainID []byte - FromContractAddress []byte - ToChainID uint64 - ToContractAddress []byte - Method string - Args []byte -} - -func (m *MakeTxParam) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, []interface{}{m.TxHash, m.CrossChainID, m.FromContractAddress, m.ToChainID, - m.ToContractAddress, m.Method, m.Args}) -} -func (m *MakeTxParam) DecodeRLP(s *rlp.Stream) error { - var data struct { - TxHash []byte - CrossChainID []byte - FromContractAddress []byte - ToChainID uint64 - ToContractAddress []byte - Method string - Args []byte - } - - if err := s.Decode(&data); err != nil { - return err - } - m.TxHash, m.CrossChainID, m.FromContractAddress, m.ToChainID, m.ToContractAddress, m.Method, m.Args = - data.TxHash, data.CrossChainID, data.FromContractAddress, data.ToChainID, data.ToContractAddress, data.Method, data.Args - return nil -} - -//used for param from evm contract -type MakeTxParamShim struct { - TxHash []byte - CrossChainID []byte - FromContractAddress []byte - ToChainID *big.Int - ToContractAddress []byte - Method []byte - Args []byte -} - -func DecodeTxParam(data []byte) (param *MakeTxParam, err error) { - BytesTy, _ := abi.NewType("bytes", "", nil) - IntTy, _ := abi.NewType("int", "", nil) - // StringTy, _ := abi.NewType("string", "", nil) - - TxParam := abi.Arguments{ - {Type: BytesTy, Name: "txHash"}, - {Type: BytesTy, Name: "crossChainID"}, - {Type: BytesTy, Name: "fromContractAddress"}, - {Type: IntTy, Name: "toChainID"}, - {Type: BytesTy, Name: "toContractAddress"}, - {Type: BytesTy, Name: "method"}, - {Type: BytesTy, Name: "args"}, - } - - args, err := TxParam.Unpack(data) - if err != nil { - return - } - - shim := new(MakeTxParamShim) - err = TxParam.Copy(shim, args) - if err != nil { - return nil, err - } - param = &MakeTxParam{ - TxHash: shim.TxHash, - CrossChainID: shim.CrossChainID, - FromContractAddress: shim.FromContractAddress, - ToChainID: shim.ToChainID.Uint64(), - ToContractAddress: shim.ToContractAddress, - Method: string(shim.Method), - Args: shim.Args, - } - return -} - -func EncodeTxParam(param *MakeTxParam) (data []byte, err error) { - BytesTy, _ := abi.NewType("bytes", "", nil) - IntTy, _ := abi.NewType("int", "", nil) - - TxParam := abi.Arguments{ - {Type: BytesTy, Name: "txHash"}, - {Type: BytesTy, Name: "crossChainID"}, - {Type: BytesTy, Name: "fromContractAddress"}, - {Type: IntTy, Name: "toChainID"}, - {Type: BytesTy, Name: "toContractAddress"}, - {Type: BytesTy, Name: "method"}, - {Type: BytesTy, Name: "args"}, - } - - shim := &MakeTxParamShim{ - TxHash: param.TxHash, - CrossChainID: param.CrossChainID, - FromContractAddress: param.FromContractAddress, - ToChainID: new(big.Int).SetUint64(param.ToChainID), - ToContractAddress: param.ToContractAddress, - Method: []byte(param.Method), - Args: param.Args, - } - - data, err = TxParam.Pack(shim.TxHash, shim.CrossChainID, shim.FromContractAddress, shim.ToChainID, shim.ToContractAddress, shim.Method, shim.Args) - return -} - -type ToMerkleValue struct { - TxHash []byte - FromChainID uint64 - MakeTxParam *MakeTxParam -} - -func (m *ToMerkleValue) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, []interface{}{m.TxHash, m.FromChainID, m.MakeTxParam}) -} - -func (m *ToMerkleValue) DecodeRLP(s *rlp.Stream) error { - var data struct { - TxHash []byte - FromChainID uint64 - MakeTxParam *MakeTxParam - } - - if err := s.Decode(&data); err != nil { - return err - } - m.TxHash, m.FromChainID, m.MakeTxParam = data.TxHash, data.FromChainID, data.MakeTxParam - return nil -} - -type MultiSignParam struct { - ChainID uint64 - RedeemKey string - TxHash []byte - Address string - Signs [][]byte -} - -func (this *MultiSignParam) Serialization(sink *polycomm.ZeroCopySink) { - sink.WriteUint64(this.ChainID) - sink.WriteString(this.RedeemKey) - sink.WriteVarBytes(this.TxHash) - sink.WriteVarBytes([]byte(this.Address)) - sink.WriteUint64(uint64(len(this.Signs))) - for _, v := range this.Signs { - sink.WriteVarBytes(v) - } -} - -func (this *MultiSignParam) Deserialization(source *polycomm.ZeroCopySource) error { - chainID, eof := source.NextUint64() - if eof { - return fmt.Errorf("MultiSignParam deserialize txHash error") - } - redeemKey, eof := source.NextString() - if eof { - return fmt.Errorf("MultiSignParam deserialize redeemKey error") - } - txHash, eof := source.NextVarBytes() - if eof { - return fmt.Errorf("MultiSignParam deserialize txHash error") - } - address, eof := source.NextString() - if eof { - return fmt.Errorf("MultiSignParam deserialize address error") - } - n, eof := source.NextUint64() - if eof { - return fmt.Errorf("MultiSignParam deserialize signs length error") - } - signs := make([][]byte, 0) - for i := 0; uint64(i) < n; i++ { - v, eof := source.NextVarBytes() - if eof { - return fmt.Errorf("deserialize Signs error") - } - signs = append(signs, v) - } - - this.ChainID = chainID - this.RedeemKey = redeemKey - this.TxHash = txHash - this.Address = address - this.Signs = signs - return nil -} diff --git a/contracts/native/cross_chain_manager/common/utils.go b/contracts/native/cross_chain_manager/common/utils.go deleted file mode 100644 index 2209dd60..00000000 --- a/contracts/native/cross_chain_manager/common/utils.go +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package common - -import ( - "fmt" - "strings" - - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/utils" - cstates "github.com/polynetwork/poly/core/states" -) - -func Replace0x(s string) string { - return strings.Replace(strings.ToLower(s), "0x", "", 1) -} - -func PutDoneTx(native *native.NativeContract, crossChainID []byte, chainID uint64) error { - contract := utils.CrossChainManagerContractAddress - chainIDBytes := utils.GetUint64Bytes(chainID) - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(DONE_TX), chainIDBytes, crossChainID), - cstates.GenRawStorageItem(crossChainID)) - return nil -} - -func CheckDoneTx(native *native.NativeContract, crossChainID []byte, chainID uint64) error { - contract := utils.CrossChainManagerContractAddress - chainIDBytes := utils.GetUint64Bytes(chainID) - value, err := native.GetCacheDB().Get(utils.ConcatKey(contract, []byte(DONE_TX), chainIDBytes, crossChainID)) - if err != nil { - return fmt.Errorf("checkDoneTx, native.GetCacheDB().Get error: %v", err) - } - if value != nil { - return fmt.Errorf("checkDoneTx, tx already done") - } - return nil -} - -func NotifyMakeProof(native *native.NativeContract, merkleValueHex string, key string) error { - return native.AddNotify(ABI, []string{NOTIFY_MAKE_PROOF_EVENT}, merkleValueHex, native.ContractRef().BlockHeight().Uint64(), key) -} diff --git a/contracts/native/cross_chain_manager/consensus_vote/storage.go b/contracts/native/cross_chain_manager/consensus_vote/storage.go deleted file mode 100644 index d9dc479b..00000000 --- a/contracts/native/cross_chain_manager/consensus_vote/storage.go +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ - -package consensus_vote - -import ( - "errors" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/rlp" -) - -var ErrEof = errors.New("EOF") - -const ( - SKP_VOTE_MESSAGE = "st_vote_message" - SKP_SIGNER_MAP = "st_signer_map" -) - -func getVoteMessage(s *native.NativeContract, hash common.Hash) (*VoteMessage, error) { - key := voteMessageKey(hash) - value, err := get(s, key) - if err != nil { - return nil, err - } - var msg *VoteMessage - if err := rlp.DecodeBytes(value, &msg); err != nil { - return nil, err - } - return msg, nil -} - -func storeVoteMessage(s *native.NativeContract, sign *VoteMessage) error { - key := voteMessageKey(sign.Hash()) - value, err := rlp.EncodeToBytes(sign) - if err != nil { - return err - } - set(s, key, value) - return nil -} - -func storeSignerAndCheckQuorum(s *native.NativeContract, hash common.Hash, signer common.Address, quorum int) (bool, error) { - height := s.ContractRef().BlockHeight().Uint64() - data, err := getSignerList(s, hash) - if err != nil { - if err.Error() == ErrEof.Error() { - data = &SignerList{ - StartHeight: height, - SignerList: make([]*SignerInfo, 0), - } - } else { - return false, err - } - } - data.SignerList = append(data.SignerList, &SignerInfo{Address: signer, SignHeight: height}) - - flag := false - //check quorum and store quorum height - if data.EndHeight == 0 { - size := len(data.SignerList) - if size >= quorum { - data.EndHeight = height - flag = true - } - } - - //store signer map - key := signerMapKey(hash) - value, err := rlp.EncodeToBytes(data) - if err != nil { - return false, err - } - set(s, key, value) - - return flag, nil -} - -func findSigner(s *native.NativeContract, hash common.Hash, signer common.Address) bool { - signerList, err := getSignerList(s, hash) - if err != nil { - return false - } - for _, v := range signerList.SignerList { - if v.Address == signer { - return true - } - } - return false -} - -func getSignerList(s *native.NativeContract, hash common.Hash) (*SignerList, error) { - key := signerMapKey(hash) - value, err := get(s, key) - if err != nil { - return nil, err - } - - var signerList *SignerList - if err := rlp.DecodeBytes(value, &signerList); err != nil { - return nil, err - } - return signerList, nil -} - -func getSignerSize(s *native.NativeContract, hash common.Hash) int { - signerList, err := getSignerList(s, hash) - if err != nil { - return 0 - } - return len(signerList.SignerList) -} - -// ==================================================================== -// -// storage basic operations -// -// ==================================================================== - -func get(s *native.NativeContract, key []byte) ([]byte, error) { - return customGet(s.GetCacheDB(), key) -} - -func set(s *native.NativeContract, key, value []byte) { - customSet(s.GetCacheDB(), key, value) -} - -func del(s *native.NativeContract, key []byte) { - customDel(s.GetCacheDB(), key) -} - -func customGet(db *state.CacheDB, key []byte) ([]byte, error) { - value, err := db.Get(key) - if err != nil { - return nil, err - } else if value == nil || len(value) == 0 { - return nil, ErrEof - } else { - return value, nil - } -} - -func customSet(db *state.CacheDB, key, value []byte) { - db.Put(key, value) -} - -func customDel(db *state.CacheDB, key []byte) { - db.Delete(key) -} - -// ==================================================================== -// -// storage keys -// -// ==================================================================== - -func voteMessageKey(hash common.Hash) []byte { - return utils.ConcatKey(utils.CrossChainManagerContractAddress, []byte(SKP_VOTE_MESSAGE), hash.Bytes()) -} - -func signerMapKey(hash common.Hash) []byte { - return utils.ConcatKey(utils.CrossChainManagerContractAddress, []byte(SKP_SIGNER_MAP), hash.Bytes()) -} diff --git a/contracts/native/cross_chain_manager/consensus_vote/types.go b/contracts/native/cross_chain_manager/consensus_vote/types.go deleted file mode 100644 index 80bf46fe..00000000 --- a/contracts/native/cross_chain_manager/consensus_vote/types.go +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ - -package consensus_vote - -import ( - "io" - "sync/atomic" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" -) - -type SignerList struct { - StartHeight uint64 - EndHeight uint64 - SignerList []*SignerInfo -} - -func (m *SignerList) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, []interface{}{m.StartHeight, m.EndHeight, m.SignerList}) -} - -func (m *SignerList) DecodeRLP(s *rlp.Stream) error { - var data struct { - StartHeight uint64 - EndHeight uint64 - SignerMap []*SignerInfo - } - - if err := s.Decode(&data); err != nil { - return err - } - m.StartHeight = data.StartHeight - m.EndHeight = data.EndHeight - m.SignerList = data.SignerMap - return nil -} - -type SignerInfo struct { - Address common.Address - SignHeight uint64 -} - -func (m *SignerInfo) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, []interface{}{m.Address, m.SignHeight}) -} - -func (m *SignerInfo) DecodeRLP(s *rlp.Stream) error { - var data struct { - Address common.Address - SignHeight uint64 - } - - if err := s.Decode(&data); err != nil { - return err - } - m.Address = data.Address - m.SignHeight = data.SignHeight - return nil -} - -type VoteMessage struct { - Input []byte - hash atomic.Value -} - -func (m *VoteMessage) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, []interface{}{m.Input}) -} -func (m *VoteMessage) DecodeRLP(s *rlp.Stream) error { - var data struct { - Input []byte - } - - if err := s.Decode(&data); err != nil { - return err - } - m.Input = data.Input - return nil -} -func (m *VoteMessage) Hash() common.Hash { - if hash := m.hash.Load(); hash != nil { - return hash.(common.Hash) - } - var inf = struct { - Input []byte - }{ - Input: m.Input, - } - v := RLPHash(inf) - m.hash.Store(v) - return v -} - -func RLPHash(v interface{}) (h common.Hash) { - hw := sha3.NewLegacyKeccak256() - rlp.Encode(hw, v) - hw.Sum(h[:0]) - return h -} diff --git a/contracts/native/cross_chain_manager/consensus_vote/utils.go b/contracts/native/cross_chain_manager/consensus_vote/utils.go deleted file mode 100644 index 63ad2d6f..00000000 --- a/contracts/native/cross_chain_manager/consensus_vote/utils.go +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ - -package consensus_vote - -import ( - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - "github.com/ethereum/go-ethereum/log" -) - -func CheckConsensusSigns(s *native.NativeContract, input []byte) (bool, error) { - ctx := s.ContractRef().CurrentContext() - caller := ctx.Caller - - // get epoch info - epochBytes, err := node_manager.GetCurrentEpoch(s) - if err != nil { - log.Trace("checkConsensusSign", "get current epoch bytes failed", err) - return false, node_manager.ErrEpochNotExist - } - output := new(node_manager.MethodEpochOutput) - output.Decode(epochBytes) - epoch := output.Epoch - - // check authority - if err := node_manager.CheckAuthority(caller, caller, epoch); err != nil { - log.Trace("checkConsensusSign", "check authority failed", err) - return false, node_manager.ErrInvalidAuthority - } - - // get or set consensus sign info - msg := &VoteMessage{Input: input} - if exist, err := getVoteMessage(s, msg.Hash()); err != nil { - if err.Error() == "EOF" { - if err := storeVoteMessage(s, msg); err != nil { - log.Trace("checkConsensusSign", "store sign failed", err, "hash", msg.Hash().Hex()) - return false, node_manager.ErrStorage - } - } else { - log.Trace("checkConsensusSign", "get sign failed", err, "hash", msg.Hash().Hex()) - return false, node_manager.ErrConsensusSignNotExist - } - } else if exist.Hash() != msg.Hash() { - log.Trace("checkConsensusSign", "check sign hash failed, expect", exist.Hash().Hex(), "got", msg.Hash().Hex()) - return false, node_manager.ErrInvalidSign - } - - // check duplicate signature - if findSigner(s, msg.Hash(), caller) { - log.Trace("checkConsensusSign", "signer already exist", caller.Hex(), "hash", msg.Hash().Hex()) - return false, node_manager.ErrDuplicateSigner - } - - // store signer address and check quorum - ok, err := storeSignerAndCheckQuorum(s, msg.Hash(), caller, epoch.QuorumSize()) - if err != nil { - log.Trace("checkConsensusSign", "store signer failed", err, "hash", msg.Hash().Hex()) - return false, node_manager.ErrStorage - } - - return ok, nil -} diff --git a/contracts/native/cross_chain_manager/consensus_vote/vote_handler.go b/contracts/native/cross_chain_manager/consensus_vote/vote_handler.go deleted file mode 100644 index 4011cb97..00000000 --- a/contracts/native/cross_chain_manager/consensus_vote/vote_handler.go +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ - -package consensus_vote - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/contracts/native" - scom "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/common" - "github.com/ethereum/go-ethereum/contracts/native/utils" - polycomm "github.com/polynetwork/poly/common" -) - -type VoteHandler struct { -} - -func NewVoteHandler() *VoteHandler { - return &VoteHandler{} -} - -func (this *VoteHandler) MakeDepositProposal(service *native.NativeContract) (*scom.MakeTxParam, error) { - ctx := service.ContractRef().CurrentContext() - params := &scom.EntranceParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodImportOuterTransfer, params, ctx.Payload); err != nil { - return nil, err - } - - //use sourcechainid, height, extra as unique id - unique := &scom.EntranceParam{ - SourceChainID: params.SourceChainID, - Height: params.Height, - Extra: params.Extra, - } - sink := polycomm.NewZeroCopySink(nil) - unique.Serialization(sink) - - ok, err := CheckConsensusSigns(service, sink.Bytes()) - if err != nil { - return nil, fmt.Errorf("vote MakeDepositProposal, CheckConsensusSigns error: %v", err) - } - if ok { - txParam, err := scom.DecodeTxParam(params.Extra) - if err != nil { - return nil, fmt.Errorf("vote MakeDepositProposal, deserialize MakeTxParam error:%s", err) - } - if err := scom.CheckDoneTx(service, txParam.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("vote MakeDepositProposal, check done transaction error:%s", err) - } - if err := scom.PutDoneTx(service, txParam.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("vote MakeDepositProposal, PutDoneTx error:%s", err) - } - return txParam, nil - } - return nil, nil -} diff --git a/contracts/native/cross_chain_manager/cosmos/cosmos_handler.go b/contracts/native/cross_chain_manager/cosmos/cosmos_handler.go deleted file mode 100644 index 5b0a6ea7..00000000 --- a/contracts/native/cross_chain_manager/cosmos/cosmos_handler.go +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2020 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package cosmos - -import ( - "bytes" - "fmt" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store/rootmulti" - "github.com/ethereum/go-ethereum/contracts/native" - scom "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/common" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/cosmos" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/merkle" - "github.com/tendermint/tendermint/crypto/multisig" - "github.com/tendermint/tendermint/crypto/secp256k1" -) - -type CosmosHandler struct{} - -func NewCosmosHandler() *CosmosHandler { - return &CosmosHandler{} -} - -type CosmosProofValue struct { - Kp string - Value []byte -} - -func newCDC() *codec.Codec { - cdc := codec.New() - cdc.RegisterInterface((*crypto.PubKey)(nil), nil) - cdc.RegisterConcrete(ed25519.PubKeyEd25519{}, ed25519.PubKeyAminoName, nil) - cdc.RegisterConcrete(secp256k1.PubKeySecp256k1{}, secp256k1.PubKeyAminoName, nil) - cdc.RegisterConcrete(multisig.PubKeyMultisigThreshold{}, multisig.PubKeyMultisigThresholdAminoRoute, nil) - - cdc.RegisterInterface((*crypto.PrivKey)(nil), nil) - cdc.RegisterConcrete(ed25519.PrivKeyEd25519{}, ed25519.PrivKeyAminoName, nil) - cdc.RegisterConcrete(secp256k1.PrivKeySecp256k1{}, secp256k1.PrivKeyAminoName, nil) - return cdc -} - -func (this *CosmosHandler) MakeDepositProposal(service *native.NativeContract) (*scom.MakeTxParam, error) { - ctx := service.ContractRef().CurrentContext() - params := &scom.EntranceParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodImportOuterTransfer, params, ctx.Payload); err != nil { - return nil, err - } - - info, err := cosmos.GetEpochSwitchInfo(service, params.SourceChainID) - if err != nil { - return nil, fmt.Errorf("Cosmos MakeDepositProposal, failed to get epoch switching height: %v", err) - } - if info.Height > int64(params.Height) { - return nil, fmt.Errorf("Cosmos MakeDepositProposal, the height %d of header is lower than epoch "+ - "switching height %d", params.Height, info.Height) - } - - if len(params.HeaderOrCrossChainMsg) == 0 { - return nil, fmt.Errorf("you must commit the header used to verify transaction's proof and get none") - } - cdc := newCDC() - var myHeader cosmos.CosmosHeader - if err := cdc.UnmarshalBinaryBare(params.HeaderOrCrossChainMsg, &myHeader); err != nil { - return nil, fmt.Errorf("Cosmos MakeDepositProposal, unmarshal cosmos header failed: %v", err) - } - if myHeader.Header.Height != int64(params.Height) { - return nil, fmt.Errorf("Cosmos MakeDepositProposal, "+ - "height of your header is %d not equal to %d in parameter", myHeader.Header.Height, params.Height) - } - if err = cosmos.VerifyCosmosHeader(&myHeader, info); err != nil { - return nil, fmt.Errorf("Cosmos MakeDepositProposal, failed to verify cosmos header: %v", err) - } - if !bytes.Equal(myHeader.Header.ValidatorsHash, myHeader.Header.NextValidatorsHash) && - myHeader.Header.Height > info.Height { - cosmos.PutEpochSwitchInfo(service, params.SourceChainID, &cosmos.CosmosEpochSwitchInfo{ - Height: myHeader.Header.Height, - BlockHash: myHeader.Header.Hash(), - NextValidatorsHash: myHeader.Header.NextValidatorsHash, - ChainID: myHeader.Header.ChainID, - }) - } - - var proofValue CosmosProofValue - if err = cdc.UnmarshalBinaryBare(params.Extra, &proofValue); err != nil { - return nil, fmt.Errorf("Cosmos MakeDepositProposal, unmarshal proof value err: %v", err) - } - var proof merkle.Proof - err = cdc.UnmarshalBinaryBare(params.Proof, &proof) - if err != nil { - return nil, fmt.Errorf("Cosmos MakeDepositProposal, unmarshal proof err: %v", err) - } - if len(proofValue.Kp) != 0 { - prt := rootmulti.DefaultProofRuntime() - err = prt.VerifyValue(&proof, myHeader.Header.AppHash, proofValue.Kp, proofValue.Value) - if err != nil { - return nil, fmt.Errorf("Cosmos MakeDepositProposal, proof error: %s", err) - } - } else { - prt := rootmulti.DefaultProofRuntime() - err = prt.VerifyAbsence(&proof, myHeader.Header.AppHash, string(proofValue.Value)) - if err != nil { - return nil, fmt.Errorf("Cosmos MakeDepositProposal, proof error: %s", err) - } - } - txParam, err := scom.DecodeTxParam(proofValue.Value) - if err != nil { - return nil, fmt.Errorf("Cosmos MakeDepositProposal, deserialize merkleValue error:%s", err) - } - if err := scom.CheckDoneTx(service, txParam.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("Cosmos MakeDepositProposal, check done transaction error:%s", err) - } - if err := scom.PutDoneTx(service, txParam.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("Cosmos MakeDepositProposal, PutDoneTx error:%s", err) - } - return txParam, nil -} diff --git a/contracts/native/cross_chain_manager/entrance.go b/contracts/native/cross_chain_manager/entrance.go deleted file mode 100644 index 10f53b7b..00000000 --- a/contracts/native/cross_chain_manager/entrance.go +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package cross_chain_manager - -import ( - "encoding/hex" - "fmt" - - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/bsc" - scom "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/common" - "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/consensus_vote" - "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/cosmos" - "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/eth" - "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/heco" - "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/msc" - "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/okex" - "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/polygon" - "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/quorum" - "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/zilliqa" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" -) - -const contractName = "cross chain manager" - -const ( - BLACKED_CHAIN = "BlackedChain" -) - -var ( - this = native.NativeContractAddrMap[native.NativeCrossChain] - gasTable = map[string]uint64{ - scom.MethodContractName: 0, - scom.MethodImportOuterTransfer: 0, - scom.MethodMultiSign: 100000, - scom.MethodBlackChain: 0, - scom.MethodWhiteChain: 0, - } -) - -func InitCrossChainManager() { - native.Contracts[this] = RegisterCrossChainManagerContract -} - -func RegisterCrossChainManagerContract(s *native.NativeContract) { - s.Prepare(scom.ABI, gasTable) - - s.Register(scom.MethodContractName, Name) - s.Register(scom.MethodImportOuterTransfer, ImportOuterTransfer) - s.Register(scom.MethodBlackChain, BlackChain) - s.Register(scom.MethodWhiteChain, WhiteChain) -} - -func GetChainHandler(router uint64) (scom.ChainHandler, error) { - switch router { - case utils.VOTE_ROUTER: - return consensus_vote.NewVoteHandler(), nil - case utils.BSC_ROUTER: - return bsc.NewHandler(), nil - case utils.ETH_ROUTER: - return eth.NewETHHandler(), nil - case utils.HECO_ROUTER: - return heco.NewHecoHandler(), nil - case utils.MSC_ROUTER: - return msc.NewHandler(), nil - case utils.OKEX_ROUTER: - return okex.NewHandler(), nil - case utils.QUORUM_ROUTER: - return quorum.NewQuorumHandler(), nil - case utils.POLYGON_BOR_ROUTER: - return polygon.NewHandler(), nil - case utils.COSMOS_ROUTER: - return cosmos.NewCosmosHandler(), nil - case utils.ZILLIQA_ROUTER: - return zilliqa.NewHandler(), nil - default: - return nil, fmt.Errorf("not a supported router:%d", router) - } -} - -func Name(s *native.NativeContract) ([]byte, error) { - return utils.PackOutputs(scom.ABI, scom.MethodContractName, contractName) -} - -func ImportOuterTransfer(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &scom.EntranceParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodImportOuterTransfer, params, ctx.Payload); err != nil { - return nil, err - } - - chainID := params.SourceChainID - blacked, err := CheckIfChainBlacked(native, chainID) - if err != nil { - return nil, fmt.Errorf("ImportExTransfer, CheckIfChainBlacked error: %v", err) - } - if blacked { - return nil, fmt.Errorf("ImportExTransfer, source chain is blacked") - } - - //check if chainid exist - sideChain, err := side_chain_manager.GetSideChain(native, chainID) - if err != nil { - return nil, fmt.Errorf("ImportExTransfer, side_chain_manager.GetSideChain error: %v", err) - } - if sideChain == nil { - return nil, fmt.Errorf("ImportExTransfer, side chain %d is not registered", chainID) - } - - handler, err := GetChainHandler(sideChain.Router) - if err != nil { - return nil, err - } - //1. verify tx - txParam, err := handler.MakeDepositProposal(native) - if err != nil { - return nil, err - } - if txParam == nil && sideChain.Router == utils.VOTE_ROUTER { - return utils.PackOutputs(scom.ABI, scom.MethodImportOuterTransfer, true) - } - - //2. make target chain tx - targetid := txParam.ToChainID - blacked, err = CheckIfChainBlacked(native, targetid) - if err != nil { - return nil, fmt.Errorf("ImportExTransfer, CheckIfChainBlacked error: %v", err) - } - if blacked { - return nil, fmt.Errorf("ImportExTransfer, target chain is blacked") - } - - //check if chainid exist - sideChain, err = side_chain_manager.GetSideChain(native, targetid) - if err != nil { - return nil, fmt.Errorf("ImportExTransfer, side_chain_manager.GetSideChain error: %v", err) - } - if sideChain == nil { - return nil, fmt.Errorf("ImportExTransfer, side chain %d is not registered", targetid) - } - if sideChain.Router == utils.BTC_ROUTER { - return nil, fmt.Errorf("btc is not supported") - } - - //NOTE, you need to store the tx in this - err = MakeTransaction(native, txParam, chainID) - if err != nil { - return nil, err - } - - return utils.PackOutputs(scom.ABI, scom.MethodImportOuterTransfer, true) -} - -func MakeTransaction(service *native.NativeContract, params *scom.MakeTxParam, fromChainID uint64) error { - - txHash := service.ContractRef().TxHash() - merkleValue := &scom.ToMerkleValue{ - TxHash: txHash[:], - FromChainID: fromChainID, - MakeTxParam: params, - } - - value, err := rlp.EncodeToBytes(merkleValue) - if err != nil { - return fmt.Errorf("MakeTransaction, rlp.EncodeToBytes merkle value error:%s", err) - } - err = PutRequest(service, merkleValue.TxHash, params.ToChainID, value) - if err != nil { - return fmt.Errorf("MakeTransaction, putRequest error:%s", err) - } - chainIDBytes := utils.GetUint64Bytes(params.ToChainID) - key := hex.EncodeToString(utils.ConcatKey(utils.CrossChainManagerContractAddress, []byte(scom.REQUEST), chainIDBytes, merkleValue.TxHash)) - err = scom.NotifyMakeProof(service, hex.EncodeToString(value), key) - if err != nil { - return fmt.Errorf("MakeTransaction, NotifyMakeProof error:%s", err) - } - return nil -} - -func PutRequest(native *native.NativeContract, txHash []byte, chainID uint64, request []byte) error { - hash := crypto.Keccak256(request) - contract := utils.CrossChainManagerContractAddress - chainIDBytes := utils.GetUint64Bytes(chainID) - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(scom.REQUEST), chainIDBytes, txHash), hash) - return nil -} - -func BlackChain(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &scom.BlackChainParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodBlackChain, params, ctx.Payload); err != nil { - return nil, err - } - - // Get current epoch operator - ok, err := node_manager.CheckConsensusSigns(native, scom.MethodBlackChain, utils.GetUint64Bytes(params.ChainID), native.ContractRef().MsgSender()) - if err != nil { - return nil, fmt.Errorf("BlackChain, CheckConsensusSigns error: %v", err) - } - if !ok { - return utils.PackOutputs(scom.ABI, scom.MethodBlackChain, true) - } - - PutBlackChain(native, params.ChainID) - return utils.PackOutputs(scom.ABI, scom.MethodBlackChain, true) -} - -func WhiteChain(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &scom.BlackChainParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodWhiteChain, params, ctx.Payload); err != nil { - return nil, err - } - - // Get current epoch operator - ok, err := node_manager.CheckConsensusSigns(native, scom.MethodWhiteChain, ctx.Payload, native.ContractRef().MsgSender()) - if err != nil { - return nil, fmt.Errorf("WhiteChain, CheckConsensusSigns error: %v", err) - } - if !ok { - return utils.PackOutputs(scom.ABI, scom.MethodWhiteChain, true) - } - - RemoveBlackChain(native, params.ChainID) - return utils.PackOutputs(scom.ABI, scom.MethodWhiteChain, true) -} diff --git a/contracts/native/cross_chain_manager/entrance_cosmos_test.go b/contracts/native/cross_chain_manager/entrance_cosmos_test.go deleted file mode 100644 index 1ba78469..00000000 --- a/contracts/native/cross_chain_manager/entrance_cosmos_test.go +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (C) 2020 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package cross_chain_manager - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/accounts/abi" - ccmcom "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/common" - - synccom "github.com/ethereum/go-ethereum/contracts/native/header_sync/cosmos" - - "crypto/ecdsa" - "encoding/hex" - "encoding/json" - "math/big" - "reflect" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/polynetwork/poly/common" - - "github.com/ethereum/go-ethereum/contracts/native" - - scom "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - // scomcc "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/common" - - "github.com/ethereum/go-ethereum/contracts/native/header_sync/zilliqa" - - cosmoscc "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/cosmos" - - "github.com/ethereum/go-ethereum/contracts/native/utils" - - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - - "strings" - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/ethereum/go-ethereum/contracts/native/governance" - "github.com/ethereum/go-ethereum/contracts/native/governance/neo3_state_manager" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - "github.com/ethereum/go-ethereum/contracts/native/governance/relayer_manager" - "github.com/ethereum/go-ethereum/contracts/native/header_sync" - - "github.com/ethereum/go-ethereum/crypto" - cstates "github.com/polynetwork/poly/core/states" -) - -const ( - SUCCESS = iota - HEADER_NOT_EXIST - PROOF_FORMAT_ERROR - VERIFY_PROOT_ERROR - TX_HAS_COMMIT - UNKNOWN -) - -func typeOfError(e error) int { - if e == nil { - return SUCCESS - } - errDesc := e.Error() - if strings.Contains(errDesc, "GetHeaderByHeight, height is too big") { - return HEADER_NOT_EXIST - } else if strings.Contains(errDesc, "unmarshal proof error:") { - return PROOF_FORMAT_ERROR - } else if strings.Contains(errDesc, "verify proof value hash failed") { - return VERIFY_PROOT_ERROR - } else if strings.Contains(errDesc, "check done transaction error:checkDoneTx, tx already done") { - return TX_HAS_COMMIT - } - return UNKNOWN -} - -var ( - sdb *state.StateDB - acct *ecdsa.PublicKey - caller ethcommon.Address - contractRef *native.ContractRef -) - -func init() { - governance.InitGovernance() - header_sync.InitHeaderSync() - InitCrossChainManager() - - neo3_state_manager.InitNeo3StateManager() - node_manager.InitNodeManager() - relayer_manager.InitRelayerManager() - side_chain_manager.InitSideChainManager() - - db := rawdb.NewMemoryDatabase() - sdb, _ = state.New(ethcommon.Hash{}, state.NewDatabase(db), nil) - - cacheDB := (*state.CacheDB)(sdb) - - blockNumber := big.NewInt(1) - key, _ := crypto.GenerateKey() - acct = &key.PublicKey - caller = crypto.PubkeyToAddress(*acct) - putPeerMapPoolAndView(cacheDB) - contractRef = native.NewContractRef(sdb, caller, caller, blockNumber, ethcommon.Hash{}, 60000000, nil) -} - -func putPeerMapPoolAndView(db *state.CacheDB) { - /* key, _ := crypto.GenerateKey() - acct = &key.PublicKey - - caller = crypto.PubkeyToAddress(*acct) */ - - peerPoolMap := new(node_manager.PeerPoolMap) - peerPoolMap.PeerPoolMap = make(map[string]*node_manager.PeerPoolItem) - pkStr := hex.EncodeToString(crypto.FromECDSAPub(acct)) - peerPoolMap.PeerPoolMap[pkStr] = &node_manager.PeerPoolItem{ - Index: uint32(0), - PeerPubkey: pkStr, - Address: crypto.PubkeyToAddress(*acct), - Status: node_manager.ConsensusStatus, - } - view := uint32(0) - viewBytes := utils.GetUint32Bytes(view) - sink := common.NewZeroCopySink(nil) - peerPoolMap.Serialization(sink) - db.Put(utils.ConcatKey(utils.NodeManagerContractAddress, []byte(node_manager.PEER_POOL), viewBytes), cstates.GenRawStorageItem(sink.Bytes())) - - sink.Reset() - - govView := node_manager.GovernanceView{ - View: view, - } - govView.Serialization(sink) - db.Put(utils.ConcatKey(utils.NodeManagerContractAddress, []byte(node_manager.GOVERNANCE_VIEW)), cstates.GenRawStorageItem(sink.Bytes())) -} - -func RegisterSideChainManager(contractRef *native.ContractRef, chainId uint64) { - param := new(side_chain_manager.RegisterSideChainParam) - param.BlocksToWait = 4 - param.ChainId = chainId - param.Name = "mychain" - param.Router = 3 - param.Address = caller - - extraInfo := zilliqa.ExtraInfo{NumOfGuardList: 1} - b, _ := json.Marshal(extraInfo) - param.ExtraInfo = b - - input, err := utils.PackMethodWithStruct(side_chain_manager.GetABI(), side_chain_manager.MethodRegisterSideChain, param) - if err != nil { - panic(err) - } - - _, _, err = contractRef.NativeCall(caller, utils.SideChainManagerContractAddress, input) - - if err != nil { - // panic(err) - } -} - -func NewNative(name string, param interface{}) (*native.NativeContract, error) { - if scom.ABI == nil { - scom.ABI = scom.GetABI() - } - if ccmcom.ABI == nil { - ccmcom.ABI = ccmcom.GetABI() - } - - var abi *abi.ABI - var chainName string - if name == ccmcom.MethodImportOuterTransfer { - abi = ccmcom.ABI - chainName = "SourceChainID" - } else { - abi = scom.ABI - chainName = "ChainID" - } - - input, err := utils.PackMethodWithStruct(abi, name, param) - if err != nil { - return nil, err - } - - contractRef.PushContext(&native.Context{ - Caller: caller, - ContractAddress: utils.CrossChainManagerContractAddress, - Payload: input, - }) - - c := native.NewNativeContract(sdb, contractRef) - - chainId := reflect.Indirect(reflect.ValueOf(param)).FieldByName(chainName).Uint() - RegisterSideChainManager(contractRef, uint64(chainId)) - - /* - input, err := utils.PackMethodWithStruct(scom.GetABI(), name, param) - if err != nil { - return nil, err - } - - ret, leftOverGas, err := contractRef.NativeCall(ethcommon.Address{}, utils.HeaderSyncContractAddress, input) - if err != nil { - return nil, err - } - fmt.Printf("ret: %s, gas: %d", hex.EncodeToString(ret), leftOverGas) */ - return c, nil - - //result, err := utils.PackOutputs(header_sync.ABI, header_sync.MethodSyncBlockHeader, true) - //_ = result -} - -func TestProofHandle(t *testing.T) { - cosmosHeaderSync := synccom.NewCosmosHandler() - cosmosProofHandler := cosmoscc.NewCosmosHandler() - - { - header158265, _ := hex.DecodeString("0aaa020a02080a120963632d636f736d6f7318b9d409220b08f4caa0f80510938acd582a480a207923c1a8915f5cada506fea0546448e3efbe020fc753c00b21b1a64cc3ce80df12240801122066e362ca5f6ca4f9f8018be4ceb2a496e7a9f610b5ca667b7dbcf71a58b76928322061f85cd26b4e0a1c67ea44c01952b1bb20fa4fa3be03dbee3b4c6f21a791302742202ba25d7ae03b9152a4d8c4ab317ddb7bb3fcb834384ced538262e25834e6dcf14a202ba25d7ae03b9152a4d8c4ab317ddb7bb3fcb834384ced538262e25834e6dcf15220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a202e63b1a0d5253c4ac9155078c8af0a1143e141f76b30bf02e877d50ffb493bbd72147f6abffe3fcf4afe3ce80e3080b749e170edbd24128c0308b9d4091a480a200b4a771c5506d5f860cc6f382fb4b0595aa857f92770419ad60a41156b19a47f1224080112203e315512893270ae79fdcdb53c210ded93815246a4e09baf6c2dfef5a26fd18e2268080212143a91887425aa1f560e2badd6e538d4baf7fa00501a0c08f9caa0f80510d89f82ec012240ba168ad6e1338bead146843cf7f8aad498cc8380c4bfea0ded39a9f4d9c7dd8f81f1f74bca536248de657551acc7912ab9d716669e728f46267007decee1810b2268080212147f6abffe3fcf4afe3ce80e3080b749e170edbd241a0c08f9caa0f80510e7b48eff012240512f3802e7381917d0dc99a12e500d8e562e4ac9e4751873eee99361277fe08773956a58fe3897b9a698e8acaa131a2903f63c20f319326ace787df0ffc5cc03226808021214e069c1227791131227fc946bee54eec2a39e191a1a0c08f9caa0f8051087a6bbed0122401b0bed5bcd5e9802815f60632d3bbc05b312059f8ae6034e32c2645a420fa711d162360f48212ca322458ea58cdca00367755aca03d8f3a1662058d6affa90001a4a0a143a91887425aa1f560e2badd6e538d4baf7fa005012251624de6420166388e0880ac8085074b64568310429f81252b6a93c05e1194a3108b2563d341864209cffffffffffffffff011a4a0a147f6abffe3fcf4afe3ce80e3080b749e170edbd2412251624de6420de052c42d0dc18e1bc64dc002a19214d537b83ae80afa9893a98352a7f2f025d1864209cffffffffffffffff011a420a14e069c1227791131227fc946bee54eec2a39e191a12251624de642095d57297855fdfb0e90a9193ce08c35d5eca6f555a4865803ba7ab4493b696c0186420c801") - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = 5 - param.GenesisHeader = header158265 - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - native, err := NewNative(scom.MethodSyncGenesisHeader, param) - if err != nil { - fmt.Printf("%v", err) - } - err = cosmosHeaderSync.SyncGenesisHeader(native) - assert.NoError(t, err) - assert.Equal(t, SUCCESS, typeOfError(err)) - } - { - param := new(ccmcom.EntranceParam) - header158266, _ := hex.DecodeString("0aab020a02080a120963632d636f736d6f7318bad409220c08f9caa0f8051087a6bbed012a480a200b4a771c5506d5f860cc6f382fb4b0595aa857f92770419ad60a41156b19a47f1224080112203e315512893270ae79fdcdb53c210ded93815246a4e09baf6c2dfef5a26fd18e3220574b32fd389adcc8859daba476617fd8a7b01beb71569d6d4d9b0fb2cea52fc142202ba25d7ae03b9152a4d8c4ab317ddb7bb3fcb834384ced538262e25834e6dcf14a202ba25d7ae03b9152a4d8c4ab317ddb7bb3fcb834384ced538262e25834e6dcf15220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a203de956dd11723d5156d5f1a5cd699ea0f90e12a0226cfb1d9ba9370a997b1cf37214e069c1227791131227fc946bee54eec2a39e191a128c0308bad4091a480a20df4b9fb65ad659fbb30c19d95db808facee2d8bd0f8813a00c1700008f5fdc251224080112201bace219166e7795bc43b46ce13763a48a428a56e5e77f61d60a5d57557b1a612268080212143a91887425aa1f560e2badd6e538d4baf7fa00501a0c08fecaa0f80510a9a78a990322402f18580f66f09a9ace3a9603b548d44d5a0c6bb1a0cf1e13dea8da33fd54cddcb5b3e8fe3183f55b1d41f38a974679341b9cbb620f6facb93221a7070154fa072268080212147f6abffe3fcf4afe3ce80e3080b749e170edbd241a0c08fecaa0f80510bbc1f6aa03224041689ac9485674d15b668b505ffd068d314302213fb0c65cd18ecc56273f9e46ac29b644c638784b2eaf192b09940519ea336a34357d23f5321005962dafe40f226808021214e069c1227791131227fc946bee54eec2a39e191a1a0c08fecaa0f80510c3d0939a032240bb9afa5da243f9d31120f9cde6ebf19f4ab3ea17f93136d093379901820978c4c6f102694f6e8e45923b129531aeb2e707944972d9ae8442816a879d5b2bf10b1a3f0a143a91887425aa1f560e2badd6e538d4baf7fa005012251624de6420166388e0880ac8085074b64568310429f81252b6a93c05e1194a3108b2563d3418641a3f0a147f6abffe3fcf4afe3ce80e3080b749e170edbd2412251624de6420de052c42d0dc18e1bc64dc002a19214d537b83ae80afa9893a98352a7f2f025d18641a3f0a14e069c1227791131227fc946bee54eec2a39e191a12251624de642095d57297855fdfb0e90a9193ce08c35d5eca6f555a4865803ba7ab4493b696c01864") - proof, _ := hex.DecodeString("0af8060a066961766c3a761221010cff2e4b056a7b60706a8b04a9644c0b3f64eb45b91207e3250fbf0b63fe2fea1aca06c8060ac5060a2c082c10c5e81418ead3092a20972ce346217e2816d6656a653139eb5da9df1b6aba887748805d8d427d1577720a2c082a10b5920918ead3092a20371ca08defc0d5398dc142a22728e0e70c75d7507dfb5bb0b00619821df061820a2c082610fbad0318ead3092a20779899f4f63ee075b9f9c91445852573b8f1625f06f6e0e280a54ee9c53a95ad0a2c082410c7d00118ead3092a20265b7e16940e4ddffbd6c58fc38a700a4677bd206092e57d6c032873947eabb00a2b082010e55418ead309222073b0934005c30dedd32076d4cde64d368f61e694d806c42dc2f11b57c98047330a2b081e10be2518ead30922204b8222f4e53f53aff819b4cde10e8d7e03b7f9bcee0a799fd81db26a04acda600a2b081c10f91018ead3092a20d6ecfd8bfb9e7fb5942f4fceb011c071c1dca484ef5cdbbb2dc43751b955bfa50a2b081810e00618ead3092a209f1ee19951fa6290176e3b2a01b89bc80300472455d2712622abba61abfd494c0a2b081410850318ead3092a20dce62197fa36c33fc9bbf34bc375f97505d1e4a9fbfef2ba276f9628b024e2f30a2b081210bc0118ead3092220a9b7297d892985030be8dbe7fe749819b0c18bdd470eec4aecbb3151532b8ee00a2a0810106218ead30922202499b57c97dca2cd39f6ada9e4ee9cf4a2cf08a058f939ab2d20ac0cbe9d74620a2a080e103518ead309222017a18df6ff2f05488f75e72f13e772246c433a548590c5eee68ee20c7d65db630a2a080c102118ead3092220f3f0446557d058f0174deb5be115a550a3c636c49782f1c1acbf6e6443139c8b0a2a080a101118ead3092a20c649987a077a2c94b15648c326a024f47301f047f138b00c209ed2d66f0a95780a2a0806100718ead30922209c5f8b85d3803d31a45526bde38e6e32885a60e5f06c0d7c6ccc2463117900310a2a0804100418ead3092a20e41c3ee9e92ade194864a9a57dfc046388850ab3948a42a22739495f3ad8b5bd0a2a0802100218ead3092220b5e03ff6caf94b3974801718848ebe4dd93b74a22185c037b65b6ba943193c491a490a21010cff2e4b056a7b60706a8b04a9644c0b3f64eb45b91207e3250fbf0b63fe2fea12200cff2e4b056a7b60706a8b04a9644c0b3f64eb45b91207e3250fbf0b63fe2fea18ead3090af3050a0a6d756c746973746f7265120363636d1adf05dd050ada050a0c0a02667412060a0408b9d4090a330a077374616b696e6712280a2608b9d4091220b1a7eb220985230ad9eba03c47f3bd2f50c97786f3d6b44e8da02bb5b52199130a2f0a03676f7612280a2608b9d409122060cd137c1962ecac616389d68034833f2921509c2d285aa5f5153997ce968a740a350a096c6f636b70726f787912280a2608b9d4091220d2f0be6c9705f890c8e36ccef34689ac12a97df0c3cf0ad47bb3a24ebc5de1c90a2f0a0361636312280a2608b9d40912209d61df98e62da7252fabd3d01c43a2817a5dbdc5ca0049ebb48c1a3905df028c0a300a046d61696e12280a2608b9d4091220b19cf098b43b3c7d54799fef0944aa95099f82ddc219fa0c8092e452a282bf410a320a06706172616d7312280a2608b9d40912207737db314fdce9b7f9c4465cef7907beba483ddd91ce8198110232d3e54ca5bd0a320a06737570706c7912280a2608b9d40912202ee92cfcc9864b3162a2e55cefaf01affde2ef8d5b1c5783ad65de0619865efd0a380a0c646973747269627574696f6e12280a2608b9d40912204756c628aab3ddcc79270d54a203a67b8ee29a7687d6d622eac94037126fa6c90a360a0a68656164657273796e6312280a2608b9d409122077d4041830be3efb87398e0cd9d498a79dd8ec64f61f11f0b546e3e0a0ac29550a300a046d696e7412280a2608b9d409122071910be7aac211a257acc9911163af5d2df5adcf44ed4ae74296a64a6dd474350a110a077570677261646512060a0408b9d4090a340a08736c617368696e6712280a2608b9d409122043e97c84e24fc993fc0cefdf997259780d3cf98ed6fe08ebdc558d4076a4dabd0a300a046274637812280a2608b9d409122005927576dd48ec703d3e7e19a953c4f11c4663c85442d5dd4d29d5c4b756e4090a2f0a0363636d12280a2608b9d409122087f352a3daf136c825bdbdcd8a0bd19aa43106b22307d4cc366f8aaece1c2c400a120a0865766964656e636512060a0408b9d409") - value, _ := hex.DecodeString("0a542f63636d2f2530312530432546462e4b2530356a253742253630706a253842253034254139644c25304225334664254542452542392531322530372545332532352530462542462530426325464525324625454112a9012042b9a0d08f76be124dcc3026a5f7fe228fada451c21184d654fffe662e7086530302987714f71b55ef55cedc91fd007f7a9ba386ec978f3aa8030000000000000014b7041bc96b15da728fdfc1c47cbfc687b845adeb06756e6c6f636b4a14000000000000000000000000000000000000000114f3b8a17f1f957f60c88f105e32ebff3f022e56a44500000000000000000000000000000000000000000000000000000000000000") - param.SourceChainID = 5 - param.Height = 158266 - param.Proof = proof - param.RelayerAddress = []byte{} - param.Extra = value - param.HeaderOrCrossChainMsg = header158266 - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - native, err := NewNative(ccmcom.MethodImportOuterTransfer, param) - if err != nil { - fmt.Printf("%v", err) - } - _, err = cosmosProofHandler.MakeDepositProposal(native) - assert.NoError(t, err) - assert.Equal(t, SUCCESS, typeOfError(err)) - } -} diff --git a/contracts/native/cross_chain_manager/eth/eth_handler.go b/contracts/native/cross_chain_manager/eth/eth_handler.go deleted file mode 100644 index 4761470e..00000000 --- a/contracts/native/cross_chain_manager/eth/eth_handler.go +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package eth - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/contracts/native" - scom "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/common" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/utils" -) - -type ETHHandler struct { -} - -func NewETHHandler() *ETHHandler { - return ÐHandler{} -} - -func (this *ETHHandler) MakeDepositProposal(service *native.NativeContract) (*scom.MakeTxParam, error) { - ctx := service.ContractRef().CurrentContext() - params := &scom.EntranceParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodImportOuterTransfer, params, ctx.Payload); err != nil { - return nil, err - } - - sideChain, err := side_chain_manager.GetSideChain(service, params.SourceChainID) - if err != nil { - return nil, fmt.Errorf("eth MakeDepositProposal, side_chain_manager.GetSideChain error: %v", err) - } - - value, err := verifyFromEthTx(service, params.Proof, params.Extra, params.SourceChainID, params.Height, sideChain) - if err != nil { - return nil, fmt.Errorf("eth MakeDepositProposal, verifyFromEthTx error: %s", err) - } - if err := scom.CheckDoneTx(service, value.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("eth MakeDepositProposal, check done transaction error:%s", err) - } - if err := scom.PutDoneTx(service, value.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("eth MakeDepositProposal, PutDoneTx error:%s", err) - } - return value, nil -} diff --git a/contracts/native/cross_chain_manager/eth/proof.go b/contracts/native/cross_chain_manager/eth/proof.go deleted file mode 100644 index d02e1b1c..00000000 --- a/contracts/native/cross_chain_manager/eth/proof.go +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package eth - -import ( - "bytes" - "encoding/hex" - "fmt" - "math/big" - "strconv" - "strings" - - ethcomm "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" -) - -type Proof struct { - AssetAddress string - FromAddress string - ToChainID uint64 - ToAddress string - Args []byte -} - -type StorageProof struct { - Key string `json:"key"` - Value string `json:"value"` - Proof []string `json:"proof"` -} - -type ETHProof struct { - Address string `json:"address"` - Balance string `json:"balance"` - CodeHash string `json:"codeHash"` - Nonce string `json:"nonce"` - StorageHash string `json:"storageHash"` - AccountProof []string `json:"accountProof"` - StorageProofs []StorageProof `json:"storageProof"` -} - -func (this *ETHProof) String() string { - bs := bytes.NewBuffer([]byte("ETHProof:\n")) - bs.WriteString("AccountProof:\n") - for _, a := range this.AccountProof { - bs.WriteString(a + "\n") - } - bs.WriteString("Address:") - bs.WriteString(this.Address + "\n") - bs.WriteString("StorageProof:\n") - for _, s := range this.StorageProofs { - bs.WriteString(s.Key + "\n") - bs.WriteString("proofs:\n[") - bs.WriteString(strings.Join(s.Proof, "\n")) - bs.WriteString("]\n") - - bs.WriteString(s.Value + "\n") - } - return bs.String() -} - -func MappingKeyAt(position1 string, position2 string) ([]byte, error) { - - p1, err := hex.DecodeString(position1) - if err != nil { - return nil, err - } - - p2, err := hex.DecodeString(position2) - - if err != nil { - return nil, err - } - - key := crypto.Keccak256(ethcomm.LeftPadBytes(p1, 32), ethcomm.LeftPadBytes(p2, 32)) - - return key, nil -} - -func (this *Proof) Deserialize(raw string) error { - vals := strings.Split(raw, "#") - if len(vals) != 6 { - return fmt.Errorf("error count of proof deserialize") - } - this.AssetAddress = vals[0] - this.FromAddress = vals[1] - cid, err := strconv.Atoi(vals[2]) - if err != nil { - return fmt.Errorf("chain id is not correct") - } - this.ToChainID = uint64(cid) - this.ToAddress = vals[3] - amt := new(big.Int) - _, b := amt.SetString(vals[4], 10) - if !b { - return fmt.Errorf("amount is not correct") - } - this.Args = []byte(vals[5]) - //this.Amount = amt - //decimal, err := strconv.Atoi(vals[5]) - //if err != nil { - // return fmt.Errorf("decimal is not correct") - //} - //this.Decimal = decimal - - return nil -} diff --git a/contracts/native/cross_chain_manager/eth/states.go b/contracts/native/cross_chain_manager/eth/states.go deleted file mode 100644 index af42b2cf..00000000 --- a/contracts/native/cross_chain_manager/eth/states.go +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package eth - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/common" -) - -type ProofAccount struct { - Nounce *big.Int - Balance *big.Int - Storage common.Hash - Codehash common.Hash -} diff --git a/contracts/native/cross_chain_manager/eth/utils.go b/contracts/native/cross_chain_manager/eth/utils.go deleted file mode 100644 index 7f069fda..00000000 --- a/contracts/native/cross_chain_manager/eth/utils.go +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ - -package eth - -import ( - "bytes" - "encoding/hex" - "encoding/json" - "fmt" - "math/big" - - ecom "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - scom "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/common" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/light" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie" -) - -func verifyFromEthTx(native *native.NativeContract, proof, extra []byte, fromChainID uint64, height uint32, sideChain *side_chain_manager.SideChain) (*scom.MakeTxParam, error) { - bestHeader, _, err := eth.GetCurrentHeader(native, fromChainID) - if err != nil { - return nil, fmt.Errorf("VerifyFromEthProof, get current header fail, error:%s", err) - } - bestHeight := uint32(bestHeader.Number.Uint64()) - if bestHeight < height || bestHeight-height < uint32(sideChain.BlocksToWait-1) { - return nil, fmt.Errorf("VerifyFromEthProof, transaction is not confirmed, current height: %d, input height: %d", bestHeight, height) - } - - blockData, _, err := eth.GetHeaderByHeight(native, uint64(height), fromChainID) - if err != nil { - return nil, fmt.Errorf("VerifyFromEthProof, get header by height, height:%d, error:%s", height, err) - } - - ethProof := new(ETHProof) - err = json.Unmarshal(proof, ethProof) - if err != nil { - return nil, fmt.Errorf("VerifyFromEthProof, unmarshal proof error:%s", err) - } - - if len(ethProof.StorageProofs) != 1 { - return nil, fmt.Errorf("VerifyFromEthProof, incorrect proof format") - } - - //todo 1. verify the proof with header - //determine where the k and v from - proofResult, err := VerifyMerkleProof(ethProof, blockData, sideChain.CCMCAddress) - if err != nil { - return nil, fmt.Errorf("VerifyFromEthProof, verifyMerkleProof error:%v", err) - } - if proofResult == nil { - return nil, fmt.Errorf("VerifyFromEthProof, verifyMerkleProof failed!") - } - - if !CheckProofResult(proofResult, extra) { - return nil, fmt.Errorf("VerifyFromEthProof, verify proof value hash failed, proof result:%x, extra:%x", proofResult, extra) - } - - txParam, err := scom.DecodeTxParam(extra) - if err != nil { - return nil, fmt.Errorf("VerifyFromEthProof, deserialize merkleValue error:%s", err) - } - return txParam, nil -} - -// used by quorum -func VerifyMerkleProofLegacy(ethProof *ETHProof, blockData *types.Header, contractAddr []byte) ([]byte, error) { - return VerifyMerkleProof(ethProof, eth.To1559(blockData), contractAddr) -} - -func VerifyMerkleProof(ethProof *ETHProof, blockData *eth.Header, contractAddr []byte) ([]byte, error) { - //1. prepare verify account - nodeList := new(light.NodeList) - - for _, s := range ethProof.AccountProof { - p := scom.Replace0x(s) - nodeList.Put(nil, ecom.Hex2Bytes(p)) - } - ns := nodeList.NodeSet() - - addr := ecom.Hex2Bytes(scom.Replace0x(ethProof.Address)) - if !bytes.Equal(addr, contractAddr) { - return nil, fmt.Errorf("verifyMerkleProof, contract address is error, proof address: %s, side chain address: %s", ethProof.Address, hex.EncodeToString(contractAddr)) - } - acctKey := crypto.Keccak256(addr) - - // 2. verify account proof - acctVal, err := trie.VerifyProof(blockData.Root, acctKey, ns) - if err != nil { - return nil, fmt.Errorf("verifyMerkleProof, verify account proof error:%s\n", err) - } - - nounce := new(big.Int) - _, ok := nounce.SetString(scom.Replace0x(ethProof.Nonce), 16) - if !ok { - return nil, fmt.Errorf("verifyMerkleProof, invalid format of nounce:%s\n", ethProof.Nonce) - } - - balance := new(big.Int) - _, ok = balance.SetString(scom.Replace0x(ethProof.Balance), 16) - if !ok { - return nil, fmt.Errorf("verifyMerkleProof, invalid format of balance:%s\n", ethProof.Balance) - } - - storageHash := ecom.HexToHash(scom.Replace0x(ethProof.StorageHash)) - codeHash := ecom.HexToHash(scom.Replace0x(ethProof.CodeHash)) - - acct := &ProofAccount{ - Nounce: nounce, - Balance: balance, - Storage: storageHash, - Codehash: codeHash, - } - - acctrlp, err := rlp.EncodeToBytes(acct) - if err != nil { - return nil, err - } - - if !bytes.Equal(acctrlp, acctVal) { - return nil, fmt.Errorf("verifyMerkleProof, verify account proof failed, wanted:%v, get:%v", acctrlp, acctVal) - } - - //3.verify storage proof - nodeList = new(light.NodeList) - if len(ethProof.StorageProofs) != 1 { - return nil, fmt.Errorf("verifyMerkleProof, invalid storage proof format") - } - - sp := ethProof.StorageProofs[0] - storageKey := crypto.Keccak256(ecom.HexToHash(scom.Replace0x(sp.Key)).Bytes()) - - for _, prf := range sp.Proof { - nodeList.Put(nil, ecom.Hex2Bytes(scom.Replace0x(prf))) - } - - ns = nodeList.NodeSet() - val, err := trie.VerifyProof(storageHash, storageKey, ns) - if err != nil { - return nil, fmt.Errorf("verifyMerkleProof, verify storage proof error:%s\n", err) - } - - return val, nil -} - -func CheckProofResult(result, value []byte) bool { - var s_temp []byte - err := rlp.DecodeBytes(result, &s_temp) - if err != nil { - log.Errorf("checkProofResult, rlp.DecodeBytes error:%s\n", err) - return false - } - // - var s []byte - for i := len(s_temp); i < 32; i++ { - s = append(s, 0) - } - s = append(s, s_temp...) - hash := crypto.Keccak256(value) - return bytes.Equal(s, hash) -} diff --git a/contracts/native/cross_chain_manager/heco/heco_handler.go b/contracts/native/cross_chain_manager/heco/heco_handler.go deleted file mode 100644 index 00c5210e..00000000 --- a/contracts/native/cross_chain_manager/heco/heco_handler.go +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ - -package heco - -import ( - "bytes" - "encoding/hex" - "encoding/json" - "fmt" - "math/big" - - ecommon "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - scom "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/common" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/heco" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/light" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie" -) - -// Handler ... -type HecoHandler struct { -} - -// NewHandler ... -func NewHecoHandler() *HecoHandler { - return &HecoHandler{} -} - -// MakeDepositProposal ... -func (h *HecoHandler) MakeDepositProposal(service *native.NativeContract) (*scom.MakeTxParam, error) { - ctx := service.ContractRef().CurrentContext() - params := &scom.EntranceParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodImportOuterTransfer, params, ctx.Payload); err != nil { - return nil, err - } - - sideChain, err := side_chain_manager.GetSideChain(service, params.SourceChainID) - if err != nil { - return nil, fmt.Errorf("heco MakeDepositProposal, side_chain_manager.GetSideChain error: %v", err) - } - - value, err := verifyFromHecoTx(service, params.Proof, params.Extra, params.SourceChainID, params.Height, sideChain) - if err != nil { - return nil, fmt.Errorf("heco MakeDepositProposal, verifyFromEthTx error: %s", err) - } - - if err := scom.CheckDoneTx(service, value.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("heco MakeDepositProposal, check done transaction error:%s", err) - } - if err := scom.PutDoneTx(service, value.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("heco MakeDepositProposal, PutDoneTx error:%s", err) - } - return value, nil -} - -func verifyFromHecoTx(native *native.NativeContract, proof, extra []byte, fromChainID uint64, height uint32, sideChain *side_chain_manager.SideChain) (param *scom.MakeTxParam, err error) { - cheight, err := heco.GetCanonicalHeight(native, fromChainID) - if err != nil { - return - } - - cheight32 := uint32(cheight) - - if cheight32 < height || cheight32-height < uint32(sideChain.BlocksToWait-1) { - return nil, fmt.Errorf("verifyFromHecoTx, transaction is not confirmed, current height: %d, input height: %d", cheight, height) - } - - headerWithSum, err := heco.GetCanonicalHeader(native, fromChainID, uint64(height)) - if err != nil { - return nil, fmt.Errorf("verifyFromHecoTx, GetCanonicalHeader height:%d, error:%s", height, err) - } - - hecoProof := new(Proof) - err = json.Unmarshal(proof, hecoProof) - if err != nil { - return nil, fmt.Errorf("verifyFromHecoTx, unmarshal proof error:%s", err) - } - - if len(hecoProof.StorageProofs) != 1 { - return nil, fmt.Errorf("verifyFromHecoTx, incorrect proof format") - } - - proofResult, err := verifyMerkleProof(hecoProof, headerWithSum.Header, sideChain.CCMCAddress) - if err != nil { - return nil, fmt.Errorf("verifyFromHecoTx, verifyMerkleProof error:%v", err) - } - - if proofResult == nil { - return nil, fmt.Errorf("verifyFromHecoTx, verifyMerkleProof failed") - } - - if !checkProofResult(proofResult, extra) { - return nil, fmt.Errorf("verifyFromHecoTx, verify proof value hash failed, proof result:%x, extra:%x", proofResult, extra) - } - - txParam, err := scom.DecodeTxParam(extra) - if err != nil { - return nil, fmt.Errorf("verifyFromHecoTx, deserialize merkleValue error:%s", err) - } - return txParam, nil -} - -// Proof ... -type Proof struct { - Address string `json:"address"` - Balance string `json:"balance"` - CodeHash string `json:"codeHash"` - Nonce string `json:"nonce"` - StorageHash string `json:"storageHash"` - AccountProof []string `json:"accountProof"` - StorageProofs []StorageProof `json:"storageProof"` -} - -// StorageProof ... -type StorageProof struct { - Key string `json:"key"` - Value string `json:"value"` - Proof []string `json:"proof"` -} - -// ProofAccount ... -type ProofAccount struct { - Nounce *big.Int - Balance *big.Int - Storage ecommon.Hash - Codehash ecommon.Hash -} - -func verifyMerkleProof(hecoProof *Proof, blockData *eth.Header, contractAddr []byte) ([]byte, error) { - //1. prepare verify account - nodeList := new(light.NodeList) - - for _, s := range hecoProof.AccountProof { - p := scom.Replace0x(s) - nodeList.Put(nil, ecommon.Hex2Bytes(p)) - } - ns := nodeList.NodeSet() - - addr := ecommon.Hex2Bytes(scom.Replace0x(hecoProof.Address)) - if !bytes.Equal(addr, contractAddr) { - return nil, fmt.Errorf("verifyMerkleProof, contract address is error, proof address: %s, side chain address: %s", hecoProof.Address, hex.EncodeToString(contractAddr)) - } - acctKey := crypto.Keccak256(addr) - - //2. verify account proof - acctVal, err := trie.VerifyProof(blockData.Root, acctKey, ns) - if err != nil { - return nil, fmt.Errorf("verifyMerkleProof, verify account proof error:%s", err) - } - - nounce := new(big.Int) - _, ok := nounce.SetString(scom.Replace0x(hecoProof.Nonce), 16) - if !ok { - return nil, fmt.Errorf("verifyMerkleProof, invalid format of nounce:%s", hecoProof.Nonce) - } - - balance := new(big.Int) - _, ok = balance.SetString(scom.Replace0x(hecoProof.Balance), 16) - if !ok { - return nil, fmt.Errorf("verifyMerkleProof, invalid format of balance:%s", hecoProof.Balance) - } - - storageHash := ecommon.HexToHash(scom.Replace0x(hecoProof.StorageHash)) - codeHash := ecommon.HexToHash(scom.Replace0x(hecoProof.CodeHash)) - - acct := &ProofAccount{ - Nounce: nounce, - Balance: balance, - Storage: storageHash, - Codehash: codeHash, - } - - acctrlp, err := rlp.EncodeToBytes(acct) - if err != nil { - return nil, err - } - - if !bytes.Equal(acctrlp, acctVal) { - return nil, fmt.Errorf("verifyMerkleProof, verify account proof failed, wanted:%v, get:%v", acctrlp, acctVal) - } - - //3.verify storage proof - nodeList = new(light.NodeList) - if len(hecoProof.StorageProofs) != 1 { - return nil, fmt.Errorf("verifyMerkleProof, invalid storage proof format") - } - - sp := hecoProof.StorageProofs[0] - storageKey := crypto.Keccak256(ecommon.HexToHash(scom.Replace0x(sp.Key)).Bytes()) - - for _, prf := range sp.Proof { - nodeList.Put(nil, ecommon.Hex2Bytes(scom.Replace0x(prf))) - } - - ns = nodeList.NodeSet() - val, err := trie.VerifyProof(storageHash, storageKey, ns) - if err != nil { - return nil, fmt.Errorf("verifyMerkleProof, verify storage proof error:%s", err) - } - - return val, nil -} - -func checkProofResult(result, value []byte) bool { - var tempBytes []byte - err := rlp.DecodeBytes(result, &tempBytes) - if err != nil { - log.Errorf("checkProofResult, rlp.DecodeBytes error:%s\n", err) - return false - } - // - var s []byte - for i := len(tempBytes); i < 32; i++ { - s = append(s, 0) - } - s = append(s, tempBytes...) - hash := crypto.Keccak256(value) - return bytes.Equal(s, hash) -} diff --git a/contracts/native/cross_chain_manager/msc/msc_handler.go b/contracts/native/cross_chain_manager/msc/msc_handler.go deleted file mode 100644 index 611b683a..00000000 --- a/contracts/native/cross_chain_manager/msc/msc_handler.go +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package msc - -import ( - "bytes" - "encoding/hex" - "encoding/json" - "fmt" - "math/big" - - ecommon "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - scom "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/common" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth/types" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/msc" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/light" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie" -) - -// Handler ... -type Handler struct { -} - -// NewHandler ... -func NewHandler() *Handler { - return &Handler{} -} - -// MakeDepositProposal ... -func (h *Handler) MakeDepositProposal(service *native.NativeContract) (*scom.MakeTxParam, error) { - ctx := service.ContractRef().CurrentContext() - params := &scom.EntranceParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodImportOuterTransfer, params, ctx.Payload); err != nil { - return nil, err - } - - sideChain, err := side_chain_manager.GetSideChain(service, params.SourceChainID) - if err != nil { - return nil, fmt.Errorf("msc MakeDepositProposal, side_chain_manager.GetSideChain error: %v", err) - } - - value, err := verifyFromTx(service, params.Proof, params.Extra, params.SourceChainID, params.Height, sideChain) - if err != nil { - return nil, fmt.Errorf("msc MakeDepositProposal, verifyFromEthTx error: %s", err) - } - - if err := scom.CheckDoneTx(service, value.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("msc MakeDepositProposal, check done transaction error:%s", err) - } - if err := scom.PutDoneTx(service, value.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("msc MakeDepositProposal, PutDoneTx error:%s", err) - } - return value, nil -} - -func verifyFromTx(native *native.NativeContract, proof, extra []byte, fromChainID uint64, height uint32, sideChain *side_chain_manager.SideChain) (param *scom.MakeTxParam, err error) { - cheight, err := msc.GetCanonicalHeight(native, fromChainID) - if err != nil { - return - } - - cheight32 := uint32(cheight) - - if cheight32 < height || cheight32-height < uint32(sideChain.BlocksToWait-1) { - return nil, fmt.Errorf("verifyFromTx, transaction is not confirmed, current height: %d, input height: %d", cheight, height) - } - - headerWithSum, err := msc.GetCanonicalHeader(native, fromChainID, uint64(height)) - if err != nil { - return nil, fmt.Errorf("verifyFromTx, GetCanonicalHeader height:%d, error:%s", height, err) - } - - mscProof := new(Proof) - err = json.Unmarshal(proof, mscProof) - if err != nil { - return nil, fmt.Errorf("verifyFromTx, unmarshal proof error:%s", err) - } - - if len(mscProof.StorageProofs) != 1 { - return nil, fmt.Errorf("verifyFromTx, incorrect proof format") - } - - proofResult, err := verifyMerkleProof(mscProof, headerWithSum.Header, sideChain.CCMCAddress) - if err != nil { - return nil, fmt.Errorf("verifyFromTx, verifyMerkleProof error:%v", err) - } - - if proofResult == nil { - return nil, fmt.Errorf("verifyFromTx, verifyMerkleProof failed") - } - - if !checkProofResult(proofResult, extra) { - return nil, fmt.Errorf("verifyFromTx, verify proof value hash failed, proof result:%x, extra:%x", proofResult, extra) - } - - txParam, err := scom.DecodeTxParam(extra) - if err != nil { - return nil, fmt.Errorf("verifyFromTx, deserialize merkleValue error:%s", err) - } - return txParam, nil -} - -// Proof ... -type Proof struct { - Address string `json:"address"` - Balance string `json:"balance"` - CodeHash string `json:"codeHash"` - Nonce string `json:"nonce"` - StorageHash string `json:"storageHash"` - AccountProof []string `json:"accountProof"` - StorageProofs []StorageProof `json:"storageProof"` -} - -// StorageProof ... -type StorageProof struct { - Key string `json:"key"` - Value string `json:"value"` - Proof []string `json:"proof"` -} - -// ProofAccount ... -type ProofAccount struct { - Nounce *big.Int - Balance *big.Int - Storage ecommon.Hash - Codehash ecommon.Hash -} - -func verifyMerkleProof(mscProof *Proof, blockData *types.Header, contractAddr []byte) ([]byte, error) { - //1. prepare verify account - nodeList := new(light.NodeList) - - for _, s := range mscProof.AccountProof { - p := scom.Replace0x(s) - nodeList.Put(nil, ecommon.Hex2Bytes(p)) - } - ns := nodeList.NodeSet() - - addr := ecommon.Hex2Bytes(scom.Replace0x(mscProof.Address)) - if !bytes.Equal(addr, contractAddr) { - return nil, fmt.Errorf("verifyMerkleProof, contract address is error, proof address: %s, side chain address: %s", mscProof.Address, hex.EncodeToString(contractAddr)) - } - acctKey := crypto.Keccak256(addr) - - //2. verify account proof - acctVal, err := trie.VerifyProof(blockData.Root, acctKey, ns) - if err != nil { - return nil, fmt.Errorf("verifyMerkleProof, verify account proof error:%s", err) - } - - nounce := new(big.Int) - _, ok := nounce.SetString(scom.Replace0x(mscProof.Nonce), 16) - if !ok { - return nil, fmt.Errorf("verifyMerkleProof, invalid format of nounce:%s", mscProof.Nonce) - } - - balance := new(big.Int) - _, ok = balance.SetString(scom.Replace0x(mscProof.Balance), 16) - if !ok { - return nil, fmt.Errorf("verifyMerkleProof, invalid format of balance:%s", mscProof.Balance) - } - - storageHash := ecommon.HexToHash(scom.Replace0x(mscProof.StorageHash)) - codeHash := ecommon.HexToHash(scom.Replace0x(mscProof.CodeHash)) - - acct := &ProofAccount{ - Nounce: nounce, - Balance: balance, - Storage: storageHash, - Codehash: codeHash, - } - - acctrlp, err := rlp.EncodeToBytes(acct) - if err != nil { - return nil, err - } - - if !bytes.Equal(acctrlp, acctVal) { - return nil, fmt.Errorf("verifyMerkleProof, verify account proof failed, wanted:%v, get:%v", acctrlp, acctVal) - } - - //3.verify storage proof - nodeList = new(light.NodeList) - if len(mscProof.StorageProofs) != 1 { - return nil, fmt.Errorf("verifyMerkleProof, invalid storage proof format") - } - - sp := mscProof.StorageProofs[0] - storageKey := crypto.Keccak256(ecommon.HexToHash(scom.Replace0x(sp.Key)).Bytes()) - - for _, prf := range sp.Proof { - nodeList.Put(nil, ecommon.Hex2Bytes(scom.Replace0x(prf))) - } - - ns = nodeList.NodeSet() - val, err := trie.VerifyProof(storageHash, storageKey, ns) - if err != nil { - return nil, fmt.Errorf("verifyMerkleProof, verify storage proof error:%s", err) - } - - return val, nil -} - -func checkProofResult(result, value []byte) bool { - var tempBytes []byte - err := rlp.DecodeBytes(result, &tempBytes) - if err != nil { - log.Errorf("checkProofResult, rlp.DecodeBytes error:%s\n", err) - return false - } - // - var s []byte - for i := len(tempBytes); i < 32; i++ { - s = append(s, 0) - } - s = append(s, tempBytes...) - hash := crypto.Keccak256(value) - return bytes.Equal(s, hash) -} diff --git a/contracts/native/cross_chain_manager/okex/okex_handler.go b/contracts/native/cross_chain_manager/okex/okex_handler.go deleted file mode 100644 index 9e8b91b6..00000000 --- a/contracts/native/cross_chain_manager/okex/okex_handler.go +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package okex - -import ( - "bytes" - "fmt" - - "github.com/cosmos/cosmos-sdk/store/rootmulti" - ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - scom "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/common" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/okex" - "github.com/ethereum/go-ethereum/contracts/native/utils" - ethcrypto "github.com/ethereum/go-ethereum/crypto" - "github.com/tendermint/tendermint/crypto/merkle" -) - -type OKHandler struct{} - -func NewHandler() *OKHandler { - return &OKHandler{} -} - -type CosmosProofValue struct { - Kp string - Value []byte -} - -var ( - KeyPrefixStorage = []byte{0x05} -) - -func (this *OKHandler) MakeDepositProposal(service *native.NativeContract) (*scom.MakeTxParam, error) { - ctx := service.ContractRef().CurrentContext() - params := &scom.EntranceParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodImportOuterTransfer, params, ctx.Payload); err != nil { - return nil, err - } - info, err := okex.GetEpochSwitchInfo(service, params.SourceChainID) - if err != nil { - return nil, fmt.Errorf("okex MakeDepositProposal, failed to get epoch switching height: %v", err) - } - if info.Height > int64(params.Height) { - return nil, fmt.Errorf("okex MakeDepositProposal, the height %d of header is lower than epoch "+ - "switching height %d", params.Height, info.Height) - } - - if len(params.HeaderOrCrossChainMsg) == 0 { - return nil, fmt.Errorf("you must commit the header used to verify transaction's proof and get none") - } - cdc := okex.NewCDC() - var myHeader okex.CosmosHeader - if err := cdc.UnmarshalBinaryBare(params.HeaderOrCrossChainMsg, &myHeader); err != nil { - return nil, fmt.Errorf("okex MakeDepositProposal, unmarshal okex header failed: %v", err) - } - if myHeader.Header.Height != int64(params.Height) { - return nil, fmt.Errorf("okex MakeDepositProposal, "+ - "height of your header is %d not equal to %d in parameter", myHeader.Header.Height, params.Height) - } - if err = okex.VerifyCosmosHeader(&myHeader, info); err != nil { - return nil, fmt.Errorf("okex MakeDepositProposal, failed to verify okex header: %v", err) - } - if !bytes.Equal(myHeader.Header.ValidatorsHash, myHeader.Header.NextValidatorsHash) && - myHeader.Header.Height > info.Height { - okex.PutEpochSwitchInfo(service, params.SourceChainID, &okex.CosmosEpochSwitchInfo{ - Height: myHeader.Header.Height, - BlockHash: myHeader.Header.Hash(), - NextValidatorsHash: myHeader.Header.NextValidatorsHash, - ChainID: myHeader.Header.ChainID, - }) - } - - var proofValue CosmosProofValue - if err = cdc.UnmarshalBinaryBare(params.Extra, &proofValue); err != nil { - return nil, fmt.Errorf("okex MakeDepositProposal, unmarshal proof value err: %v", err) - } - var proof merkle.Proof - err = cdc.UnmarshalBinaryBare(params.Proof, &proof) - if err != nil { - return nil, fmt.Errorf("okex MakeDepositProposal, unmarshal proof err: %v", err) - } - sideChain, err := side_chain_manager.GetSideChain(service, params.SourceChainID) - if err != nil { - return nil, fmt.Errorf("okex MakeDepositProposal, side_chain_manager.GetSideChain error: %v", err) - } - if len(proof.Ops) != 2 { - return nil, fmt.Errorf("proof size wrong") - } - if len(proof.Ops[0].Key) != 1+ethcommon.HashLength+ethcommon.AddressLength { - return nil, fmt.Errorf("storage key length not correct") - } - if !bytes.HasPrefix(proof.Ops[0].Key, append(KeyPrefixStorage, sideChain.CCMCAddress...)) { - return nil, fmt.Errorf("storage key not from ccmc") - } - if !bytes.Equal(proof.Ops[1].Key, []byte("evm")) { - return nil, fmt.Errorf("wrong module for proof") - } - if len(proofValue.Kp) == 0 { - return nil, fmt.Errorf("Cosmos MakeDepositProposal, Kp is nil") - } - - prt := rootmulti.DefaultProofRuntime() - err = prt.VerifyValue(&proof, myHeader.Header.AppHash, proofValue.Kp, ethcrypto.Keccak256(proofValue.Value)) - if err != nil { - return nil, fmt.Errorf("Cosmos MakeDepositProposal, proof error: %s", err) - } - txParam, err := scom.DecodeTxParam(proofValue.Value) - if err != nil { - return nil, fmt.Errorf("Cosmos MakeDepositProposal, deserialize merkleValue error:%s", err) - } - if err := scom.CheckDoneTx(service, txParam.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("Cosmos MakeDepositProposal, check done transaction error:%s", err) - } - if err := scom.PutDoneTx(service, txParam.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("Cosmos MakeDepositProposal, PutDoneTx error:%s", err) - } - return txParam, nil -} diff --git a/contracts/native/cross_chain_manager/polygon/bor_handler.go b/contracts/native/cross_chain_manager/polygon/bor_handler.go deleted file mode 100644 index 49f2e4fd..00000000 --- a/contracts/native/cross_chain_manager/polygon/bor_handler.go +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package polygon - -import ( - "bytes" - "encoding/hex" - "encoding/json" - "fmt" - "math/big" - - ecommon "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - scom "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/common" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth/types" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/polygon" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/light" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie" -) - -// BorHandler ... -type BorHandler struct { -} - -// NewHandler ... -func NewHandler() *BorHandler { - return &BorHandler{} -} - -// MakeDepositProposal ... -func (h *BorHandler) MakeDepositProposal(service *native.NativeContract) (*scom.MakeTxParam, error) { - ctx := service.ContractRef().CurrentContext() - params := &scom.EntranceParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodImportOuterTransfer, params, ctx.Payload); err != nil { - return nil, err - } - - sideChain, err := side_chain_manager.GetSideChain(service, params.SourceChainID) - if err != nil { - return nil, fmt.Errorf("eth MakeDepositProposal, side_chain_manager.GetSideChain error: %v", err) - } - - value, err := verifyFromTx(service, params.Proof, params.Extra, params.SourceChainID, params.Height, sideChain) - if err != nil { - return nil, fmt.Errorf("eth MakeDepositProposal, verifyFromEthTx error: %s", err) - } - - if err := scom.CheckDoneTx(service, value.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("eth MakeDepositProposal, check done transaction error:%s", err) - } - if err := scom.PutDoneTx(service, value.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("eth MakeDepositProposal, PutDoneTx error:%s", err) - } - return value, nil -} - -func verifyFromTx(native *native.NativeContract, proof, extra []byte, fromChainID uint64, height uint32, sideChain *side_chain_manager.SideChain) (param *scom.MakeTxParam, err error) { - cheight, err := polygon.GetCanonicalHeight(native, fromChainID) - if err != nil { - return - } - - cheight32 := uint32(cheight) - - if cheight32 < height || cheight32-height < uint32(sideChain.BlocksToWait-1) { - return nil, fmt.Errorf("verifyFromTx, transaction is not confirmed, current height: %d, input height: %d", cheight, height) - } - - headerWithSum, err := polygon.GetCanonicalHeader(native, fromChainID, uint64(height)) - if err != nil { - return nil, fmt.Errorf("verifyFromTx, GetCanonicalHeader height:%d, error:%s", height, err) - } - - polygonProof := new(Proof) - err = json.Unmarshal(proof, polygonProof) - if err != nil { - return nil, fmt.Errorf("verifyFromTx, unmarshal proof error:%s", err) - } - - if len(polygonProof.StorageProofs) != 1 { - return nil, fmt.Errorf("verifyFromTx, incorrect proof format") - } - - proofResult, err := verifyMerkleProof(polygonProof, &headerWithSum.HeaderWithOptionalSnap.Header, sideChain.CCMCAddress) - if err != nil { - return nil, fmt.Errorf("verifyFromTx, verifyMerkleProof error:%v", err) - } - - if proofResult == nil { - return nil, fmt.Errorf("verifyFromTx, verifyMerkleProof failed") - } - - if !checkProofResult(proofResult, extra) { - return nil, fmt.Errorf("verifyFromTx, verify proof value hash failed, proof result:%x, extra:%x", proofResult, extra) - } - - txParam, err := scom.DecodeTxParam(extra) - if err != nil { - return nil, fmt.Errorf("verifyFromTx, deserialize merkleValue error:%s", err) - } - return txParam, nil -} - -// Proof ... -type Proof struct { - Address string `json:"address"` - Balance string `json:"balance"` - CodeHash string `json:"codeHash"` - Nonce string `json:"nonce"` - StorageHash string `json:"storageHash"` - AccountProof []string `json:"accountProof"` - StorageProofs []StorageProof `json:"storageProof"` -} - -// StorageProof ... -type StorageProof struct { - Key string `json:"key"` - Value string `json:"value"` - Proof []string `json:"proof"` -} - -// ProofAccount ... -type ProofAccount struct { - Nounce *big.Int - Balance *big.Int - Storage ecommon.Hash - Codehash ecommon.Hash -} - -func verifyMerkleProof(polygonProof *Proof, blockData *types.Header, contractAddr []byte) ([]byte, error) { - //1. prepare verify account - nodeList := new(light.NodeList) - - for _, s := range polygonProof.AccountProof { - p := scom.Replace0x(s) - nodeList.Put(nil, ecommon.Hex2Bytes(p)) - } - ns := nodeList.NodeSet() - - addr := ecommon.Hex2Bytes(scom.Replace0x(polygonProof.Address)) - if !bytes.Equal(addr, contractAddr) { - return nil, fmt.Errorf("verifyMerkleProof, contract address is error, proof address: %s, side chain address: %s", polygonProof.Address, hex.EncodeToString(contractAddr)) - } - acctKey := crypto.Keccak256(addr) - - //2. verify account proof - acctVal, err := trie.VerifyProof(blockData.Root, acctKey, ns) - if err != nil { - return nil, fmt.Errorf("verifyMerkleProof, verify account proof error:%s", err) - } - - nounce := new(big.Int) - _, ok := nounce.SetString(scom.Replace0x(polygonProof.Nonce), 16) - if !ok { - return nil, fmt.Errorf("verifyMerkleProof, invalid format of nounce:%s", polygonProof.Nonce) - } - - balance := new(big.Int) - _, ok = balance.SetString(scom.Replace0x(polygonProof.Balance), 16) - if !ok { - return nil, fmt.Errorf("verifyMerkleProof, invalid format of balance:%s", polygonProof.Balance) - } - - storageHash := ecommon.HexToHash(scom.Replace0x(polygonProof.StorageHash)) - codeHash := ecommon.HexToHash(scom.Replace0x(polygonProof.CodeHash)) - - acct := &ProofAccount{ - Nounce: nounce, - Balance: balance, - Storage: storageHash, - Codehash: codeHash, - } - - acctrlp, err := rlp.EncodeToBytes(acct) - if err != nil { - return nil, err - } - - if !bytes.Equal(acctrlp, acctVal) { - return nil, fmt.Errorf("verifyMerkleProof, verify account proof failed, wanted:%v, get:%v", acctrlp, acctVal) - } - - //3.verify storage proof - nodeList = new(light.NodeList) - if len(polygonProof.StorageProofs) != 1 { - return nil, fmt.Errorf("verifyMerkleProof, invalid storage proof format") - } - - sp := polygonProof.StorageProofs[0] - storageKey := crypto.Keccak256(ecommon.HexToHash(scom.Replace0x(sp.Key)).Bytes()) - - for _, prf := range sp.Proof { - nodeList.Put(nil, ecommon.Hex2Bytes(scom.Replace0x(prf))) - } - - ns = nodeList.NodeSet() - val, err := trie.VerifyProof(storageHash, storageKey, ns) - if err != nil { - return nil, fmt.Errorf("verifyMerkleProof, verify storage proof error:%s", err) - } - - return val, nil -} - -func checkProofResult(result, value []byte) bool { - var tempBytes []byte - err := rlp.DecodeBytes(result, &tempBytes) - if err != nil { - log.Errorf("checkProofResult, rlp.DecodeBytes error:%s\n", err) - return false - } - // - var s []byte - for i := len(tempBytes); i < 32; i++ { - s = append(s, 0) - } - s = append(s, tempBytes...) - hash := crypto.Keccak256(value) - return bytes.Equal(s, hash) -} diff --git a/contracts/native/cross_chain_manager/quorum/quorum_handler.go b/contracts/native/cross_chain_manager/quorum/quorum_handler.go deleted file mode 100644 index 0c836861..00000000 --- a/contracts/native/cross_chain_manager/quorum/quorum_handler.go +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package quorum - -import ( - "encoding/json" - "errors" - "fmt" - - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/common" - scom "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/common" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth/types" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/quorum" - "github.com/ethereum/go-ethereum/contracts/native/utils" -) - -type QuorumHandler struct{} - -func NewQuorumHandler() *QuorumHandler { - return &QuorumHandler{} -} - -func (this *QuorumHandler) MakeDepositProposal(ns *native.NativeContract) (*common.MakeTxParam, error) { - ctx := ns.ContractRef().CurrentContext() - params := &common.EntranceParam{} - if err := utils.UnpackMethod(common.ABI, common.MethodImportOuterTransfer, params, ctx.Payload); err != nil { - return nil, err - } - - sideChain, err := side_chain_manager.GetSideChain(ns, params.SourceChainID) - if err != nil { - return nil, fmt.Errorf("Quorum MakeDepositProposal, side_chain_manager.GetSideChain error: %v", err) - } - if sideChain == nil { - return nil, errors.New("Quorum MakeDepositProposal, side chain not found") - } - - val, err := scom.DecodeTxParam(params.Extra) - if err != nil { - return nil, fmt.Errorf("Quorum MakeDepositProposal, failed to deserialize MakeTxParam: %v", err) - } - if err := common.CheckDoneTx(ns, val.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("Quorum MakeDepositProposal, check done transaction error: %v", err) - } - if err := common.PutDoneTx(ns, val.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("Quorum MakeDepositProposal, PutDoneTx error: %v", err) - } - - header := &types.Header{} - if err := json.Unmarshal(params.HeaderOrCrossChainMsg, header); err != nil { - return nil, fmt.Errorf("Quorum MakeDepositProposal, deserialize header err: %v", err) - } - valh, err := quorum.GetCurrentValHeight(ns, params.SourceChainID) - if err != nil { - return nil, fmt.Errorf("Quorum MakeDepositProposal, failed to get current validators height: %v", err) - } - if header.Number.Uint64() < valh { - return nil, fmt.Errorf("Quorum MakeDepositProposal, height of header %d is less than epoch height %d", header.Number.Uint64(), valh) - } - vs, err := quorum.GetValSet(ns, params.SourceChainID) - if err != nil { - return nil, fmt.Errorf("Quorum MakeDepositProposal, failed to get quorum validators: %v", err) - } - if _, err := quorum.VerifyQuorumHeader(vs, header, false); err != nil { - return nil, fmt.Errorf("Quorum MakeDepositProposal, failed to verify quorum header %s: %v", header.Hash().String(), err) - } - - if err := verifyFromQuorumTx(params.Proof, params.Extra, header, sideChain); err != nil { - return nil, fmt.Errorf("Quorum MakeDepositProposal, verifyFromEthTx error: %s", err) - } - - return val, nil -} diff --git a/contracts/native/cross_chain_manager/quorum/utils.go b/contracts/native/cross_chain_manager/quorum/utils.go deleted file mode 100644 index 1bddc199..00000000 --- a/contracts/native/cross_chain_manager/quorum/utils.go +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package quorum - -import ( - "encoding/json" - "fmt" - - eth2 "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/eth" - cmanager "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth/types" -) - -func verifyFromQuorumTx(proof, extra []byte, hdr *types.Header, sideChain *cmanager.SideChain) error { - ethProof := new(eth2.ETHProof) - if err := json.Unmarshal(proof, ethProof); err != nil { - return fmt.Errorf("VerifyFromEthProof, unmarshal proof error:%s", err) - } - if len(ethProof.StorageProofs) != 1 { - return fmt.Errorf("VerifyFromEthProof, incorrect proof format") - } - proofResult, err := eth2.VerifyMerkleProofLegacy(ethProof, hdr, sideChain.CCMCAddress) - if err != nil { - return fmt.Errorf("VerifyFromEthProof, verifyMerkleProof error:%v", err) - } - if proofResult == nil { - return fmt.Errorf("VerifyFromEthProof, verifyMerkleProof failed!") - } - if !eth2.CheckProofResult(proofResult, extra) { - return fmt.Errorf("VerifyFromEthProof, verify proof value hash failed, proof result:%x, extra:%x", proofResult, extra) - } - return nil -} diff --git a/contracts/native/cross_chain_manager/test/vote_handler_test.go b/contracts/native/cross_chain_manager/test/vote_handler_test.go deleted file mode 100644 index 076f1e7f..00000000 --- a/contracts/native/cross_chain_manager/test/vote_handler_test.go +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ - -package test - -import ( - "crypto/ecdsa" - "log" - "math/big" - "testing" - - scom "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/common" - "github.com/stretchr/testify/assert" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" -) - -var ( - sdb *state.StateDB - testGenesisNum = 4 - acct *ecdsa.PublicKey - testGenesisPeers *node_manager.Peers -) - -const ( - CHAIN_ID uint64 = 1 -) - -func init() { - key, _ := crypto.GenerateKey() - acct = &key.PublicKey - - node_manager.InitNodeManager() - side_chain_manager.InitSideChainManager() - cross_chain_manager.InitCrossChainManager() - db := rawdb.NewMemoryDatabase() - sdb, _ = state.New(common.Hash{}, state.NewDatabase(db), nil) - testGenesisPeers = generateTestPeers(testGenesisNum) - storeGenesisEpoch(sdb, testGenesisPeers) - - putSideChain() -} - -func putSideChain() { - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, common.EmptyAddress, common.EmptyAddress, blockNumber, common.Hash{}, extra, nil) - contract := native.NewNativeContract(sdb, contractRef) - - err := side_chain_manager.PutSideChain(contract, &side_chain_manager.SideChain{ - Router: utils.VOTE_ROUTER, - ChainId: CHAIN_ID, - }) - if err != nil { - log.Fatalf("PutSideChain fail:%v", err) - return - } - sideChain, err := side_chain_manager.GetSideChain(contract, CHAIN_ID) - if err != nil { - log.Fatalf("PutSideChain fail:%v", err) - return - } - - if sideChain.ChainId != CHAIN_ID { - log.Fatalf("GetSideChain mismatch") - } -} - -func TestNoAuthImportOuterTransfer(t *testing.T) { - var err error - param := new(scom.EntranceParam) - param.SourceChainID = CHAIN_ID - param.Height = 12345 - makeTxParam := &scom.MakeTxParam{ - TxHash: []byte{0x01, 0x02}, - CrossChainID: []byte{0x01, 0x02}, - FromContractAddress: []byte{0x01, 0x02}, - ToChainID: 2, - ToContractAddress: []byte{0x01, 0x02}, - Method: "lock", - Args: []byte{0x01, 0x02}, - } - param.Extra, err = rlp.EncodeToBytes(makeTxParam) - assert.Nil(t, err) - - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodImportOuterTransfer, param) - assert.Nil(t, err) - - caller := crypto.PubkeyToAddress(*acct) - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, 0+extra, nil) - _, _, err = contractRef.NativeCall(caller, utils.CrossChainManagerContractAddress, input) - assert.Errorf(t, err, "vote MakeDepositProposal, CheckConsensusSigns error: invalid authority") -} - -func TestNormalImportOuterTransfer(t *testing.T) { - var err error - param := new(scom.EntranceParam) - param.SourceChainID = CHAIN_ID - param.Height = 12345 - makeTxParam := &scom.MakeTxParam{ - TxHash: []byte{0x01, 0x02}, - CrossChainID: []byte{0x01, 0x02}, - FromContractAddress: []byte{0x01, 0x02}, - ToChainID: 1, - ToContractAddress: []byte{0x01, 0x02}, - Method: "lock", - Args: []byte{0x01, 0x02}, - } - param.Extra, err = scom.EncodeTxParam(makeTxParam) - assert.Nil(t, err) - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodImportOuterTransfer, param) - assert.Nil(t, err) - - for i := 0; i < testGenesisNum; i++ { - caller := testGenesisPeers.List[i].Address - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, 0+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.CrossChainManagerContractAddress, input) - assert.Nil(t, err) - result, err := utils.PackOutputs(scom.ABI, scom.MethodImportOuterTransfer, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - } -} - -func TestDupImportOuterTransfer(t *testing.T) { - var err error - param := new(scom.EntranceParam) - param.SourceChainID = CHAIN_ID - param.Height = 12345 - makeTxParam := &scom.MakeTxParam{ - TxHash: []byte{0x01, 0x02}, - CrossChainID: []byte{0x01, 0x02}, - FromContractAddress: []byte{0x01, 0x02}, - ToChainID: 1, - ToContractAddress: []byte{0x01, 0x02}, - Method: "lock", - Args: []byte{0x01, 0x02}, - } - param.Extra, err = scom.EncodeTxParam(makeTxParam) - assert.Nil(t, err) - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodImportOuterTransfer, param) - assert.Nil(t, err) - - caller := testGenesisPeers.List[0].Address - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, 0+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.CrossChainManagerContractAddress, input) - assert.Nil(t, err) - result, err := utils.PackOutputs(scom.ABI, scom.MethodImportOuterTransfer, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - - for i := 0; i < testGenesisNum; i++ { - caller := testGenesisPeers.List[0].Address - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, 0+extra, nil) - _, _, err := contractRef.NativeCall(caller, utils.CrossChainManagerContractAddress, input) - assert.Errorf(t, err, "vote MakeDepositProposal, CheckConsensusSigns error: duplicate signer") - } -} - -// generateTestPeer ONLY used for testing -func generateTestPeer() *node_manager.PeerInfo { - pk, _ := crypto.GenerateKey() - return &node_manager.PeerInfo{ - PubKey: hexutil.Encode(crypto.CompressPubkey(&pk.PublicKey)), - Address: crypto.PubkeyToAddress(pk.PublicKey), - } -} - -func generateTestPeers(n int) *node_manager.Peers { - peers := &node_manager.Peers{List: make([]*node_manager.PeerInfo, n)} - for i := 0; i < n; i++ { - peers.List[i] = generateTestPeer() - } - return peers -} - -func storeGenesisEpoch(s *state.StateDB, peers *node_manager.Peers) (*node_manager.EpochInfo, error) { - cache := (*state.CacheDB)(s) - epoch := &node_manager.EpochInfo{ - ID: node_manager.StartEpochID, - Peers: peers, - StartHeight: 0, - } - - // store current epoch and epoch info - if err := setEpoch(cache, epoch); err != nil { - return nil, err - } - - // store current hash - curKey := curEpochKey() - cache.Put(curKey, epoch.Hash().Bytes()) - - // store genesis epoch id to list - value, err := rlp.EncodeToBytes(&node_manager.HashList{List: []common.Hash{epoch.Hash()}}) - if err != nil { - return nil, err - } - proposalKey := proposalsKey(epoch.ID) - cache.Put(proposalKey, value) - - // store genesis epoch proof - key := epochProofKey(node_manager.EpochProofHash(epoch.ID)) - cache.Put(key, epoch.Hash().Bytes()) - - return epoch, nil -} - -func setEpoch(s *state.CacheDB, epoch *node_manager.EpochInfo) error { - hash := epoch.Hash() - key := epochKey(hash) - - value, err := rlp.EncodeToBytes(epoch) - if err != nil { - return err - } - - s.Put(key, value) - return nil -} - -func epochKey(epochHash common.Hash) []byte { - return utils.ConcatKey(utils.NodeManagerContractAddress, []byte("st_epoch"), epochHash.Bytes()) -} - -func curEpochKey() []byte { - return utils.ConcatKey(utils.NodeManagerContractAddress, []byte("st_cur_epoch"), []byte("1")) -} - -func epochProofKey(proofHashKey common.Hash) []byte { - return utils.ConcatKey(utils.NodeManagerContractAddress, []byte("st_proof"), proofHashKey.Bytes()) -} - -func proposalsKey(epochID uint64) []byte { - return utils.ConcatKey(utils.NodeManagerContractAddress, []byte("st_proposal"), utils.GetUint64Bytes(epochID)) -} diff --git a/contracts/native/cross_chain_manager/utils.go b/contracts/native/cross_chain_manager/utils.go deleted file mode 100644 index 60effeda..00000000 --- a/contracts/native/cross_chain_manager/utils.go +++ /dev/null @@ -1,35 +0,0 @@ -package cross_chain_manager - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/utils" - cstates "github.com/polynetwork/poly/core/states" -) - -func PutBlackChain(native *native.NativeContract, chainID uint64) { - contract := utils.CrossChainManagerContractAddress - chainIDBytes := utils.GetUint64Bytes(chainID) - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(BLACKED_CHAIN), chainIDBytes), - cstates.GenRawStorageItem(chainIDBytes)) -} - -func RemoveBlackChain(native *native.NativeContract, chainID uint64) { - contract := utils.CrossChainManagerContractAddress - chainIDBytes := utils.GetUint64Bytes(chainID) - native.GetCacheDB().Delete(utils.ConcatKey(contract, []byte(BLACKED_CHAIN), chainIDBytes)) -} - -func CheckIfChainBlacked(native *native.NativeContract, chainID uint64) (bool, error) { - contract := utils.CrossChainManagerContractAddress - chainIDBytes := utils.GetUint64Bytes(chainID) - chainIDStore, err := native.GetCacheDB().Get(utils.ConcatKey(contract, []byte(BLACKED_CHAIN), chainIDBytes)) - if err != nil { - return true, fmt.Errorf("CheckBlackChain, get black chainIDStore error: %v", err) - } - if chainIDStore == nil { - return false, nil - } - return true, nil -} diff --git a/contracts/native/cross_chain_manager/zilliqa/zilliqa_handler.go b/contracts/native/cross_chain_manager/zilliqa/zilliqa_handler.go deleted file mode 100644 index dfbb8637..00000000 --- a/contracts/native/cross_chain_manager/zilliqa/zilliqa_handler.go +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ - -package zilliqa - -import ( - "encoding/json" - "fmt" - "strings" - - "github.com/Zilliqa/gozilliqa-sdk/core" - "github.com/Zilliqa/gozilliqa-sdk/mpt" - "github.com/Zilliqa/gozilliqa-sdk/util" - "github.com/ethereum/go-ethereum/contracts/native" - scom "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager/common" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/zilliqa" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/crypto" -) - -// Handler ... -type Handler struct { -} - -// NewHandler ... -func NewHandler() *Handler { - return &Handler{} -} - -// MakeDepositProposal ... -func (h *Handler) MakeDepositProposal(service *native.NativeContract) (*scom.MakeTxParam, error) { - ctx := service.ContractRef().CurrentContext() - params := &scom.EntranceParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodImportOuterTransfer, params, ctx.Payload); err != nil { - return nil, err - } - - sideChain, err := side_chain_manager.GetSideChain(service, params.SourceChainID) - if err != nil { - return nil, fmt.Errorf("zilliqa MakeDepositProposal, side_chain_manager.GetSideChain error: %v", err) - } - - value, err := verifyFromTx(service, params.Proof, params.Extra, params.SourceChainID, params.Height, sideChain) - if err != nil { - return nil, fmt.Errorf("zil MakeDepositProposal, verifyFromZILTx error: %s", err) - } - - if err := scom.CheckDoneTx(service, value.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("zil MakeDepositProposal, check done transaction error:%s", err) - } - if err := scom.PutDoneTx(service, value.CrossChainID, params.SourceChainID); err != nil { - return nil, fmt.Errorf("zil MakeDepositProposal, PutDoneTx error:%s", err) - } - return value, nil -} - -// should be the same as relayer side -type ZILProof struct { - AccountProof []string `json:"accountProof"` - StorageProofs []StorageProof `json:"storageProof"` -} - -// key should be storage key (in zilliqa) -type StorageProof struct { - Key []byte `json:"key"` - Value []byte `json:"value"` - Proof []string `json:"proof"` -} - -func verifyFromTx(native *native.NativeContract, proof, extra []byte, fromChainID uint64, height uint32, sideChain *side_chain_manager.SideChain) (param *scom.MakeTxParam, err error) { - bestHeader, err := zilliqa.GetCurrentTxHeader(native, fromChainID) - if err != nil { - return nil, fmt.Errorf("VerifyFromZilProof, get current header fail, error:%s", err) - } - - bestHeight := uint32(bestHeader.BlockHeader.BlockNum) - if bestHeight < height { - return nil, fmt.Errorf("VerifyFromZilProof, transaction is not confirmed, current height: %d, input height: %d", bestHeight, height) - } - blockData, err := zilliqa.GetTxHeaderByHeight(native, uint64(height), fromChainID) - if err != nil { - return nil, fmt.Errorf("VerifyFromZilProof, get header by height, height:%d, error:%s", height, err) - } - - var zilProof ZILProof - err = json.Unmarshal(proof, &zilProof) - if err != nil { - return nil, fmt.Errorf("VerifyFromZilProof, unmarshal proof error:%s", err) - } - - if len(zilProof.StorageProofs) != 1 { - return nil, fmt.Errorf("VerifyFromZilProof, incorrect proof format") - } - - var pf [][]byte - for _, p := range zilProof.AccountProof { - bytes := util.DecodeHex(p) - pf = append(pf, bytes) - } - - db := mpt.NewFromProof(pf) - root := blockData.BlockHeader.HashSet.StateRootHash[:] - key := strings.TrimPrefix(util.EncodeHex(sideChain.CCMCAddress), "0x") - accountBaseBytes, err := mpt.Verify([]byte(key), db, root) - if err != nil { - return nil, fmt.Errorf("verifyMerkleProof, verify account proof error:%s, key is %s proof is: %+v, root is %s", err, key, zilProof.AccountProof, util.EncodeHex(root)) - } - - accountBase, err := core.AccountBaseFromBytes(accountBaseBytes) - if err != nil { - return nil, fmt.Errorf("verifyMerkleProof, get account info error:%s\n", err) - } - - var proof2 [][]byte - for _, p := range zilProof.StorageProofs[0].Proof { - bytes := util.DecodeHex(p) - proof2 = append(proof2, bytes) - } - - db2 := mpt.NewFromProof(proof2) - storageKey := util.DecodeHex(string(zilProof.StorageProofs[0].Key)) - hashedStorageKey := util.Sha256(storageKey) - proofResult, err := mpt.Verify([]byte((util.EncodeHex(hashedStorageKey))), db2, accountBase.StorageRoot) - if err != nil { - return nil, fmt.Errorf("verifyMerkleProof, verify state proof error:%s, key is %s account proof is: %+v, state proof is: %+v, account bytes is: %s, root is %s", err, - util.EncodeHex(storageKey), zilProof.AccountProof, zilProof.StorageProofs[0].Proof, util.EncodeHex(accountBaseBytes), util.EncodeHex(accountBase.StorageRoot)) - } - - if proofResult == nil { - return nil, fmt.Errorf("verifyMerkleProof, verify state proof error:%s, key is %s account proof is: %+v, state proof is: %+v, account bytes is: %s, root is %s", "result is nil", - util.EncodeHex(storageKey), zilProof.AccountProof, zilProof.StorageProofs[0].Proof, util.EncodeHex(accountBaseBytes), util.EncodeHex(accountBase.StorageRoot)) - } - - if !checkProofResult(proofResult, extra) { - return nil, fmt.Errorf("verifyMerkleProof, check state proof result failed proof result: %s, extra: %s", util.EncodeHex(proofResult), util.EncodeHex(extra)) - } - - txParam, err := scom.DecodeTxParam(extra) - if err != nil { - return nil, fmt.Errorf("VerifyFromZilProof, deserialize merkleValue error:%s", err) - } - return txParam, nil -} - -func checkProofResult(result, value []byte) bool { - origin := strings.ToLower(string(result)) - origin = strings.TrimPrefix(strings.ReplaceAll(origin, "\"", ""), "0x") - - hash := crypto.Keccak256(value) - target := util.EncodeHex(hash) - target = strings.ToLower(target) - target = strings.TrimPrefix(target, "0x") - - return origin == target -} diff --git a/contracts/native/go_abi/cross_chain_manager_abi/cross_chain_manager_abi.go b/contracts/native/go_abi/cross_chain_manager_abi/cross_chain_manager_abi.go deleted file mode 100644 index a57cf16a..00000000 --- a/contracts/native/go_abi/cross_chain_manager_abi/cross_chain_manager_abi.go +++ /dev/null @@ -1,860 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package cross_chain_manager_abi - -import ( - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -var ( - MethodBlackChain = "BlackChain" - - MethodMultiSign = "MultiSign" - - MethodWhiteChain = "WhiteChain" - - MethodImportOuterTransfer = "importOuterTransfer" - - MethodName = "name" -) - -// CrossChainManagerABI is the input ABI used to generate the binding from. -const CrossChainManagerABI = "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"TxHash\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"MultiSign\",\"type\":\"bytes\"}],\"name\":\"btcTxMultiSignEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"FromChainID\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"ChainID\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"buf\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"FromTxHash\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"RedeemKey\",\"type\":\"string\"}],\"name\":\"btcTxToRelayEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"rk\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"buf\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint64[]\",\"name\":\"amts\",\"type\":\"uint64[]\"}],\"name\":\"makeBtcTxEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"merkleValueHex\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"BlockHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"key\",\"type\":\"string\"}],\"name\":\"makeProof\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"ChainID\",\"type\":\"uint64\"}],\"name\":\"BlackChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"ChainID\",\"type\":\"uint64\"},{\"internalType\":\"string\",\"name\":\"RedeemKey\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"TxHash\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"Address\",\"type\":\"string\"},{\"internalType\":\"bytes[]\",\"name\":\"Signs\",\"type\":\"bytes[]\"}],\"name\":\"MultiSign\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"ChainID\",\"type\":\"uint64\"}],\"name\":\"WhiteChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"SourceChainID\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"Height\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"Proof\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"RelayerAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"Extra\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"HeaderOrCrossChainMsg\",\"type\":\"bytes\"}],\"name\":\"importOuterTransfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"Name\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" - -// CrossChainManagerFuncSigs maps the 4-byte function signature to its string representation. -var CrossChainManagerFuncSigs = map[string]string{ - "8a449f03": "BlackChain(uint64)", - "48c79d9d": "MultiSign(uint64,string,bytes,string,bytes[])", - "99d0e87a": "WhiteChain(uint64)", - "5b60b01e": "importOuterTransfer(uint64,uint32,bytes,bytes,bytes,bytes)", - "06fdde03": "name()", -} - -// CrossChainManagerBin is the compiled bytecode used for deploying new contracts. -var CrossChainManagerBin = "0x608060405234801561001057600080fd5b50610475806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806306fdde031461005c57806348c79d9d146100745780635b60b01e1461009d5780638a449f03146100b757806399d0e87a146100b7575b600080fd5b606060405161006b91906103a3565b60405180910390f35b61008d61008236600461018e565b600095945050505050565b604051901515815260200161006b565b61008d6100ab3660046102d6565b60009695505050505050565b61008d6100c536600461016c565b50600090565b600082601f8301126100dc57600080fd5b813567ffffffffffffffff8111156100f6576100f6610429565b610109601f8201601f19166020016103f8565b81815284602083860101111561011e57600080fd5b816020850160208301376000918101602001919091529392505050565b803563ffffffff8116811461014f57600080fd5b919050565b803567ffffffffffffffff8116811461014f57600080fd5b60006020828403121561017e57600080fd5b61018782610154565b9392505050565b600080600080600060a086880312156101a657600080fd5b6101af86610154565b945060208087013567ffffffffffffffff808211156101cd57600080fd5b6101d98a838b016100cb565b965060408901359150808211156101ef57600080fd5b6101fb8a838b016100cb565b9550606089013591508082111561021157600080fd5b61021d8a838b016100cb565b9450608089013591508082111561023357600080fd5b818901915089601f83011261024757600080fd5b81358181111561025957610259610429565b8060051b6102688582016103f8565b8281528581019085870183870188018f101561028357600080fd5b600093505b848410156102c157858135111561029e57600080fd5b6102ad8f8983358a01016100cb565b835260019390930192918701918701610288565b50809750505050505050509295509295909350565b60008060008060008060c087890312156102ef57600080fd5b6102f887610154565b95506103066020880161013b565b9450604087013567ffffffffffffffff8082111561032357600080fd5b61032f8a838b016100cb565b9550606089013591508082111561034557600080fd5b6103518a838b016100cb565b9450608089013591508082111561036757600080fd5b6103738a838b016100cb565b935060a089013591508082111561038957600080fd5b5061039689828a016100cb565b9150509295509295509295565b600060208083528351808285015260005b818110156103d0578581018301518582016040015282016103b4565b818111156103e2576000604083870101525b50601f01601f1916929092016040019392505050565b604051601f8201601f1916810167ffffffffffffffff8111828210171561042157610421610429565b604052919050565b634e487b7160e01b600052604160045260246000fdfea2646970667358221220cb47f48504debcee7fac8555b2c134ff9fdff419dfbc5f0c487127571e51b34d64736f6c63430008060033" - -// DeployCrossChainManager deploys a new Ethereum contract, binding an instance of CrossChainManager to it. -func DeployCrossChainManager(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *CrossChainManager, error) { - parsed, err := abi.JSON(strings.NewReader(CrossChainManagerABI)) - if err != nil { - return common.Address{}, nil, nil, err - } - - address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(CrossChainManagerBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &CrossChainManager{CrossChainManagerCaller: CrossChainManagerCaller{contract: contract}, CrossChainManagerTransactor: CrossChainManagerTransactor{contract: contract}, CrossChainManagerFilterer: CrossChainManagerFilterer{contract: contract}}, nil -} - -// CrossChainManager is an auto generated Go binding around an Ethereum contract. -type CrossChainManager struct { - CrossChainManagerCaller // Read-only binding to the contract - CrossChainManagerTransactor // Write-only binding to the contract - CrossChainManagerFilterer // Log filterer for contract events -} - -// CrossChainManagerCaller is an auto generated read-only Go binding around an Ethereum contract. -type CrossChainManagerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// CrossChainManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type CrossChainManagerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// CrossChainManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type CrossChainManagerFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// CrossChainManagerSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type CrossChainManagerSession struct { - Contract *CrossChainManager // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// CrossChainManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type CrossChainManagerCallerSession struct { - Contract *CrossChainManagerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// CrossChainManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type CrossChainManagerTransactorSession struct { - Contract *CrossChainManagerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// CrossChainManagerRaw is an auto generated low-level Go binding around an Ethereum contract. -type CrossChainManagerRaw struct { - Contract *CrossChainManager // Generic contract binding to access the raw methods on -} - -// CrossChainManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type CrossChainManagerCallerRaw struct { - Contract *CrossChainManagerCaller // Generic read-only contract binding to access the raw methods on -} - -// CrossChainManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type CrossChainManagerTransactorRaw struct { - Contract *CrossChainManagerTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewCrossChainManager creates a new instance of CrossChainManager, bound to a specific deployed contract. -func NewCrossChainManager(address common.Address, backend bind.ContractBackend) (*CrossChainManager, error) { - contract, err := bindCrossChainManager(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &CrossChainManager{CrossChainManagerCaller: CrossChainManagerCaller{contract: contract}, CrossChainManagerTransactor: CrossChainManagerTransactor{contract: contract}, CrossChainManagerFilterer: CrossChainManagerFilterer{contract: contract}}, nil -} - -// NewCrossChainManagerCaller creates a new read-only instance of CrossChainManager, bound to a specific deployed contract. -func NewCrossChainManagerCaller(address common.Address, caller bind.ContractCaller) (*CrossChainManagerCaller, error) { - contract, err := bindCrossChainManager(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &CrossChainManagerCaller{contract: contract}, nil -} - -// NewCrossChainManagerTransactor creates a new write-only instance of CrossChainManager, bound to a specific deployed contract. -func NewCrossChainManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*CrossChainManagerTransactor, error) { - contract, err := bindCrossChainManager(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &CrossChainManagerTransactor{contract: contract}, nil -} - -// NewCrossChainManagerFilterer creates a new log filterer instance of CrossChainManager, bound to a specific deployed contract. -func NewCrossChainManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*CrossChainManagerFilterer, error) { - contract, err := bindCrossChainManager(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &CrossChainManagerFilterer{contract: contract}, nil -} - -// bindCrossChainManager binds a generic wrapper to an already deployed contract. -func bindCrossChainManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(CrossChainManagerABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_CrossChainManager *CrossChainManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _CrossChainManager.Contract.CrossChainManagerCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_CrossChainManager *CrossChainManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _CrossChainManager.Contract.CrossChainManagerTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_CrossChainManager *CrossChainManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _CrossChainManager.Contract.CrossChainManagerTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_CrossChainManager *CrossChainManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _CrossChainManager.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_CrossChainManager *CrossChainManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _CrossChainManager.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_CrossChainManager *CrossChainManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _CrossChainManager.Contract.contract.Transact(opts, method, params...) -} - -// BlackChain is a paid mutator transaction binding the contract method 0x8a449f03. -// -// Solidity: function BlackChain(uint64 ChainID) returns(bool success) -func (_CrossChainManager *CrossChainManagerTransactor) BlackChain(opts *bind.TransactOpts, ChainID uint64) (*types.Transaction, error) { - return _CrossChainManager.contract.Transact(opts, "BlackChain", ChainID) -} - -// BlackChain is a paid mutator transaction binding the contract method 0x8a449f03. -// -// Solidity: function BlackChain(uint64 ChainID) returns(bool success) -func (_CrossChainManager *CrossChainManagerSession) BlackChain(ChainID uint64) (*types.Transaction, error) { - return _CrossChainManager.Contract.BlackChain(&_CrossChainManager.TransactOpts, ChainID) -} - -// BlackChain is a paid mutator transaction binding the contract method 0x8a449f03. -// -// Solidity: function BlackChain(uint64 ChainID) returns(bool success) -func (_CrossChainManager *CrossChainManagerTransactorSession) BlackChain(ChainID uint64) (*types.Transaction, error) { - return _CrossChainManager.Contract.BlackChain(&_CrossChainManager.TransactOpts, ChainID) -} - -// MultiSign is a paid mutator transaction binding the contract method 0x48c79d9d. -// -// Solidity: function MultiSign(uint64 ChainID, string RedeemKey, bytes TxHash, string Address, bytes[] Signs) returns(bool success) -func (_CrossChainManager *CrossChainManagerTransactor) MultiSign(opts *bind.TransactOpts, ChainID uint64, RedeemKey string, TxHash []byte, Address string, Signs [][]byte) (*types.Transaction, error) { - return _CrossChainManager.contract.Transact(opts, "MultiSign", ChainID, RedeemKey, TxHash, Address, Signs) -} - -// MultiSign is a paid mutator transaction binding the contract method 0x48c79d9d. -// -// Solidity: function MultiSign(uint64 ChainID, string RedeemKey, bytes TxHash, string Address, bytes[] Signs) returns(bool success) -func (_CrossChainManager *CrossChainManagerSession) MultiSign(ChainID uint64, RedeemKey string, TxHash []byte, Address string, Signs [][]byte) (*types.Transaction, error) { - return _CrossChainManager.Contract.MultiSign(&_CrossChainManager.TransactOpts, ChainID, RedeemKey, TxHash, Address, Signs) -} - -// MultiSign is a paid mutator transaction binding the contract method 0x48c79d9d. -// -// Solidity: function MultiSign(uint64 ChainID, string RedeemKey, bytes TxHash, string Address, bytes[] Signs) returns(bool success) -func (_CrossChainManager *CrossChainManagerTransactorSession) MultiSign(ChainID uint64, RedeemKey string, TxHash []byte, Address string, Signs [][]byte) (*types.Transaction, error) { - return _CrossChainManager.Contract.MultiSign(&_CrossChainManager.TransactOpts, ChainID, RedeemKey, TxHash, Address, Signs) -} - -// WhiteChain is a paid mutator transaction binding the contract method 0x99d0e87a. -// -// Solidity: function WhiteChain(uint64 ChainID) returns(bool success) -func (_CrossChainManager *CrossChainManagerTransactor) WhiteChain(opts *bind.TransactOpts, ChainID uint64) (*types.Transaction, error) { - return _CrossChainManager.contract.Transact(opts, "WhiteChain", ChainID) -} - -// WhiteChain is a paid mutator transaction binding the contract method 0x99d0e87a. -// -// Solidity: function WhiteChain(uint64 ChainID) returns(bool success) -func (_CrossChainManager *CrossChainManagerSession) WhiteChain(ChainID uint64) (*types.Transaction, error) { - return _CrossChainManager.Contract.WhiteChain(&_CrossChainManager.TransactOpts, ChainID) -} - -// WhiteChain is a paid mutator transaction binding the contract method 0x99d0e87a. -// -// Solidity: function WhiteChain(uint64 ChainID) returns(bool success) -func (_CrossChainManager *CrossChainManagerTransactorSession) WhiteChain(ChainID uint64) (*types.Transaction, error) { - return _CrossChainManager.Contract.WhiteChain(&_CrossChainManager.TransactOpts, ChainID) -} - -// ImportOuterTransfer is a paid mutator transaction binding the contract method 0x5b60b01e. -// -// Solidity: function importOuterTransfer(uint64 SourceChainID, uint32 Height, bytes Proof, bytes RelayerAddress, bytes Extra, bytes HeaderOrCrossChainMsg) returns(bool success) -func (_CrossChainManager *CrossChainManagerTransactor) ImportOuterTransfer(opts *bind.TransactOpts, SourceChainID uint64, Height uint32, Proof []byte, RelayerAddress []byte, Extra []byte, HeaderOrCrossChainMsg []byte) (*types.Transaction, error) { - return _CrossChainManager.contract.Transact(opts, "importOuterTransfer", SourceChainID, Height, Proof, RelayerAddress, Extra, HeaderOrCrossChainMsg) -} - -// ImportOuterTransfer is a paid mutator transaction binding the contract method 0x5b60b01e. -// -// Solidity: function importOuterTransfer(uint64 SourceChainID, uint32 Height, bytes Proof, bytes RelayerAddress, bytes Extra, bytes HeaderOrCrossChainMsg) returns(bool success) -func (_CrossChainManager *CrossChainManagerSession) ImportOuterTransfer(SourceChainID uint64, Height uint32, Proof []byte, RelayerAddress []byte, Extra []byte, HeaderOrCrossChainMsg []byte) (*types.Transaction, error) { - return _CrossChainManager.Contract.ImportOuterTransfer(&_CrossChainManager.TransactOpts, SourceChainID, Height, Proof, RelayerAddress, Extra, HeaderOrCrossChainMsg) -} - -// ImportOuterTransfer is a paid mutator transaction binding the contract method 0x5b60b01e. -// -// Solidity: function importOuterTransfer(uint64 SourceChainID, uint32 Height, bytes Proof, bytes RelayerAddress, bytes Extra, bytes HeaderOrCrossChainMsg) returns(bool success) -func (_CrossChainManager *CrossChainManagerTransactorSession) ImportOuterTransfer(SourceChainID uint64, Height uint32, Proof []byte, RelayerAddress []byte, Extra []byte, HeaderOrCrossChainMsg []byte) (*types.Transaction, error) { - return _CrossChainManager.Contract.ImportOuterTransfer(&_CrossChainManager.TransactOpts, SourceChainID, Height, Proof, RelayerAddress, Extra, HeaderOrCrossChainMsg) -} - -// Name is a paid mutator transaction binding the contract method 0x06fdde03. -// -// Solidity: function name() returns(string Name) -func (_CrossChainManager *CrossChainManagerTransactor) Name(opts *bind.TransactOpts) (*types.Transaction, error) { - return _CrossChainManager.contract.Transact(opts, "name") -} - -// Name is a paid mutator transaction binding the contract method 0x06fdde03. -// -// Solidity: function name() returns(string Name) -func (_CrossChainManager *CrossChainManagerSession) Name() (*types.Transaction, error) { - return _CrossChainManager.Contract.Name(&_CrossChainManager.TransactOpts) -} - -// Name is a paid mutator transaction binding the contract method 0x06fdde03. -// -// Solidity: function name() returns(string Name) -func (_CrossChainManager *CrossChainManagerTransactorSession) Name() (*types.Transaction, error) { - return _CrossChainManager.Contract.Name(&_CrossChainManager.TransactOpts) -} - -// CrossChainManagerBtcTxMultiSignEventIterator is returned from FilterBtcTxMultiSignEvent and is used to iterate over the raw logs and unpacked data for BtcTxMultiSignEvent events raised by the CrossChainManager contract. -type CrossChainManagerBtcTxMultiSignEventIterator struct { - Event *CrossChainManagerBtcTxMultiSignEvent // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *CrossChainManagerBtcTxMultiSignEventIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(CrossChainManagerBtcTxMultiSignEvent) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(CrossChainManagerBtcTxMultiSignEvent) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *CrossChainManagerBtcTxMultiSignEventIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *CrossChainManagerBtcTxMultiSignEventIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// CrossChainManagerBtcTxMultiSignEvent represents a BtcTxMultiSignEvent event raised by the CrossChainManager contract. -type CrossChainManagerBtcTxMultiSignEvent struct { - TxHash []byte - MultiSign []byte - Raw types.Log // Blockchain specific contextual infos -} - -// FilterBtcTxMultiSignEvent is a free log retrieval operation binding the contract event 0x62fb550ff7fa48f759b0e56ea24757e77b5612d11efbcbdbed9545982cfe1770. -// -// Solidity: event btcTxMultiSignEvent(bytes TxHash, bytes MultiSign) -func (_CrossChainManager *CrossChainManagerFilterer) FilterBtcTxMultiSignEvent(opts *bind.FilterOpts) (*CrossChainManagerBtcTxMultiSignEventIterator, error) { - - logs, sub, err := _CrossChainManager.contract.FilterLogs(opts, "btcTxMultiSignEvent") - if err != nil { - return nil, err - } - return &CrossChainManagerBtcTxMultiSignEventIterator{contract: _CrossChainManager.contract, event: "btcTxMultiSignEvent", logs: logs, sub: sub}, nil -} - -// WatchBtcTxMultiSignEvent is a free log subscription operation binding the contract event 0x62fb550ff7fa48f759b0e56ea24757e77b5612d11efbcbdbed9545982cfe1770. -// -// Solidity: event btcTxMultiSignEvent(bytes TxHash, bytes MultiSign) -func (_CrossChainManager *CrossChainManagerFilterer) WatchBtcTxMultiSignEvent(opts *bind.WatchOpts, sink chan<- *CrossChainManagerBtcTxMultiSignEvent) (event.Subscription, error) { - - logs, sub, err := _CrossChainManager.contract.WatchLogs(opts, "btcTxMultiSignEvent") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(CrossChainManagerBtcTxMultiSignEvent) - if err := _CrossChainManager.contract.UnpackLog(event, "btcTxMultiSignEvent", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseBtcTxMultiSignEvent is a log parse operation binding the contract event 0x62fb550ff7fa48f759b0e56ea24757e77b5612d11efbcbdbed9545982cfe1770. -// -// Solidity: event btcTxMultiSignEvent(bytes TxHash, bytes MultiSign) -func (_CrossChainManager *CrossChainManagerFilterer) ParseBtcTxMultiSignEvent(log types.Log) (*CrossChainManagerBtcTxMultiSignEvent, error) { - event := new(CrossChainManagerBtcTxMultiSignEvent) - if err := _CrossChainManager.contract.UnpackLog(event, "btcTxMultiSignEvent", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// CrossChainManagerBtcTxToRelayEventIterator is returned from FilterBtcTxToRelayEvent and is used to iterate over the raw logs and unpacked data for BtcTxToRelayEvent events raised by the CrossChainManager contract. -type CrossChainManagerBtcTxToRelayEventIterator struct { - Event *CrossChainManagerBtcTxToRelayEvent // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *CrossChainManagerBtcTxToRelayEventIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(CrossChainManagerBtcTxToRelayEvent) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(CrossChainManagerBtcTxToRelayEvent) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *CrossChainManagerBtcTxToRelayEventIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *CrossChainManagerBtcTxToRelayEventIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// CrossChainManagerBtcTxToRelayEvent represents a BtcTxToRelayEvent event raised by the CrossChainManager contract. -type CrossChainManagerBtcTxToRelayEvent struct { - FromChainID uint64 - ChainID uint64 - Buf string - FromTxHash string - RedeemKey string - Raw types.Log // Blockchain specific contextual infos -} - -// FilterBtcTxToRelayEvent is a free log retrieval operation binding the contract event 0x59c070ab5215dda625f463061a0ad421505b2cca1066a8597411c72a5ecac51b. -// -// Solidity: event btcTxToRelayEvent(uint64 FromChainID, uint64 ChainID, string buf, string FromTxHash, string RedeemKey) -func (_CrossChainManager *CrossChainManagerFilterer) FilterBtcTxToRelayEvent(opts *bind.FilterOpts) (*CrossChainManagerBtcTxToRelayEventIterator, error) { - - logs, sub, err := _CrossChainManager.contract.FilterLogs(opts, "btcTxToRelayEvent") - if err != nil { - return nil, err - } - return &CrossChainManagerBtcTxToRelayEventIterator{contract: _CrossChainManager.contract, event: "btcTxToRelayEvent", logs: logs, sub: sub}, nil -} - -// WatchBtcTxToRelayEvent is a free log subscription operation binding the contract event 0x59c070ab5215dda625f463061a0ad421505b2cca1066a8597411c72a5ecac51b. -// -// Solidity: event btcTxToRelayEvent(uint64 FromChainID, uint64 ChainID, string buf, string FromTxHash, string RedeemKey) -func (_CrossChainManager *CrossChainManagerFilterer) WatchBtcTxToRelayEvent(opts *bind.WatchOpts, sink chan<- *CrossChainManagerBtcTxToRelayEvent) (event.Subscription, error) { - - logs, sub, err := _CrossChainManager.contract.WatchLogs(opts, "btcTxToRelayEvent") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(CrossChainManagerBtcTxToRelayEvent) - if err := _CrossChainManager.contract.UnpackLog(event, "btcTxToRelayEvent", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseBtcTxToRelayEvent is a log parse operation binding the contract event 0x59c070ab5215dda625f463061a0ad421505b2cca1066a8597411c72a5ecac51b. -// -// Solidity: event btcTxToRelayEvent(uint64 FromChainID, uint64 ChainID, string buf, string FromTxHash, string RedeemKey) -func (_CrossChainManager *CrossChainManagerFilterer) ParseBtcTxToRelayEvent(log types.Log) (*CrossChainManagerBtcTxToRelayEvent, error) { - event := new(CrossChainManagerBtcTxToRelayEvent) - if err := _CrossChainManager.contract.UnpackLog(event, "btcTxToRelayEvent", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// CrossChainManagerMakeBtcTxEventIterator is returned from FilterMakeBtcTxEvent and is used to iterate over the raw logs and unpacked data for MakeBtcTxEvent events raised by the CrossChainManager contract. -type CrossChainManagerMakeBtcTxEventIterator struct { - Event *CrossChainManagerMakeBtcTxEvent // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *CrossChainManagerMakeBtcTxEventIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(CrossChainManagerMakeBtcTxEvent) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(CrossChainManagerMakeBtcTxEvent) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *CrossChainManagerMakeBtcTxEventIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *CrossChainManagerMakeBtcTxEventIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// CrossChainManagerMakeBtcTxEvent represents a MakeBtcTxEvent event raised by the CrossChainManager contract. -type CrossChainManagerMakeBtcTxEvent struct { - Rk string - Buf string - Amts []uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterMakeBtcTxEvent is a free log retrieval operation binding the contract event 0xa00d721fd040a2b479d1adf886244de04bdbb3e3e310dc75f1036e2602726234. -// -// Solidity: event makeBtcTxEvent(string rk, string buf, uint64[] amts) -func (_CrossChainManager *CrossChainManagerFilterer) FilterMakeBtcTxEvent(opts *bind.FilterOpts) (*CrossChainManagerMakeBtcTxEventIterator, error) { - - logs, sub, err := _CrossChainManager.contract.FilterLogs(opts, "makeBtcTxEvent") - if err != nil { - return nil, err - } - return &CrossChainManagerMakeBtcTxEventIterator{contract: _CrossChainManager.contract, event: "makeBtcTxEvent", logs: logs, sub: sub}, nil -} - -// WatchMakeBtcTxEvent is a free log subscription operation binding the contract event 0xa00d721fd040a2b479d1adf886244de04bdbb3e3e310dc75f1036e2602726234. -// -// Solidity: event makeBtcTxEvent(string rk, string buf, uint64[] amts) -func (_CrossChainManager *CrossChainManagerFilterer) WatchMakeBtcTxEvent(opts *bind.WatchOpts, sink chan<- *CrossChainManagerMakeBtcTxEvent) (event.Subscription, error) { - - logs, sub, err := _CrossChainManager.contract.WatchLogs(opts, "makeBtcTxEvent") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(CrossChainManagerMakeBtcTxEvent) - if err := _CrossChainManager.contract.UnpackLog(event, "makeBtcTxEvent", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseMakeBtcTxEvent is a log parse operation binding the contract event 0xa00d721fd040a2b479d1adf886244de04bdbb3e3e310dc75f1036e2602726234. -// -// Solidity: event makeBtcTxEvent(string rk, string buf, uint64[] amts) -func (_CrossChainManager *CrossChainManagerFilterer) ParseMakeBtcTxEvent(log types.Log) (*CrossChainManagerMakeBtcTxEvent, error) { - event := new(CrossChainManagerMakeBtcTxEvent) - if err := _CrossChainManager.contract.UnpackLog(event, "makeBtcTxEvent", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// CrossChainManagerMakeProofIterator is returned from FilterMakeProof and is used to iterate over the raw logs and unpacked data for MakeProof events raised by the CrossChainManager contract. -type CrossChainManagerMakeProofIterator struct { - Event *CrossChainManagerMakeProof // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *CrossChainManagerMakeProofIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(CrossChainManagerMakeProof) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(CrossChainManagerMakeProof) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *CrossChainManagerMakeProofIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *CrossChainManagerMakeProofIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// CrossChainManagerMakeProof represents a MakeProof event raised by the CrossChainManager contract. -type CrossChainManagerMakeProof struct { - MerkleValueHex string - BlockHeight uint64 - Key string - Raw types.Log // Blockchain specific contextual infos -} - -// FilterMakeProof is a free log retrieval operation binding the contract event 0x25680d41ae78d1188140c6547c9b1890e26bbfa2e0c5b5f1d81aef8985f4d49d. -// -// Solidity: event makeProof(string merkleValueHex, uint64 BlockHeight, string key) -func (_CrossChainManager *CrossChainManagerFilterer) FilterMakeProof(opts *bind.FilterOpts) (*CrossChainManagerMakeProofIterator, error) { - - logs, sub, err := _CrossChainManager.contract.FilterLogs(opts, "makeProof") - if err != nil { - return nil, err - } - return &CrossChainManagerMakeProofIterator{contract: _CrossChainManager.contract, event: "makeProof", logs: logs, sub: sub}, nil -} - -// WatchMakeProof is a free log subscription operation binding the contract event 0x25680d41ae78d1188140c6547c9b1890e26bbfa2e0c5b5f1d81aef8985f4d49d. -// -// Solidity: event makeProof(string merkleValueHex, uint64 BlockHeight, string key) -func (_CrossChainManager *CrossChainManagerFilterer) WatchMakeProof(opts *bind.WatchOpts, sink chan<- *CrossChainManagerMakeProof) (event.Subscription, error) { - - logs, sub, err := _CrossChainManager.contract.WatchLogs(opts, "makeProof") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(CrossChainManagerMakeProof) - if err := _CrossChainManager.contract.UnpackLog(event, "makeProof", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseMakeProof is a log parse operation binding the contract event 0x25680d41ae78d1188140c6547c9b1890e26bbfa2e0c5b5f1d81aef8985f4d49d. -// -// Solidity: event makeProof(string merkleValueHex, uint64 BlockHeight, string key) -func (_CrossChainManager *CrossChainManagerFilterer) ParseMakeProof(log types.Log) (*CrossChainManagerMakeProof, error) { - event := new(CrossChainManagerMakeProof) - if err := _CrossChainManager.contract.UnpackLog(event, "makeProof", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} diff --git a/contracts/native/go_abi/header_sync_abi/header_sync_abi.go b/contracts/native/go_abi/header_sync_abi/header_sync_abi.go deleted file mode 100644 index b31f3ac6..00000000 --- a/contracts/native/go_abi/header_sync_abi/header_sync_abi.go +++ /dev/null @@ -1,567 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package header_sync_abi - -import ( - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -var ( - MethodName = "name" - - MethodSyncBlockHeader = "syncBlockHeader" - - MethodSyncCrossChainMsg = "syncCrossChainMsg" - - MethodSyncGenesisHeader = "syncGenesisHeader" -) - -// HeaderSyncABI is the input ABI used to generate the binding from. -const HeaderSyncABI = "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainID\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"BlockHash\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"Height\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"NextValidatorsHash\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"InfoChainID\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"BlockHeight\",\"type\":\"uint64\"}],\"name\":\"OKEpochSwitchInfoEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"chainID\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"height\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"blockHash\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"BlockHeight\",\"type\":\"uint256\"}],\"name\":\"syncHeader\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"Name\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"ChainID\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"Address\",\"type\":\"address\"},{\"internalType\":\"bytes[]\",\"name\":\"Headers\",\"type\":\"bytes[]\"}],\"name\":\"syncBlockHeader\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"ChainID\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"Address\",\"type\":\"address\"},{\"internalType\":\"bytes[]\",\"name\":\"CrossChainMsgs\",\"type\":\"bytes[]\"}],\"name\":\"syncCrossChainMsg\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"ChainID\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"GenesisHeader\",\"type\":\"bytes\"}],\"name\":\"syncGenesisHeader\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" - -// HeaderSyncFuncSigs maps the 4-byte function signature to its string representation. -var HeaderSyncFuncSigs = map[string]string{ - "06fdde03": "name()", - "72ce6700": "syncBlockHeader(uint64,address,bytes[])", - "21b5cff5": "syncCrossChainMsg(uint64,address,bytes[])", - "b5ace618": "syncGenesisHeader(uint64,bytes)", -} - -// HeaderSyncBin is the compiled bytecode used for deploying new contracts. -var HeaderSyncBin = "0x608060405234801561001057600080fd5b5061034b806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306fdde031461005157806321b5cff51461006957806372ce670014610069578063b5ace61814610090575b600080fd5b60606040516100609190610279565b60405180910390f35b610080610077366004610133565b60009392505050565b6040519015158152602001610060565b61008061009e36600461022b565b600092915050565b600082601f8301126100b757600080fd5b813567ffffffffffffffff8111156100d1576100d16102ff565b6100e4601f8201601f19166020016102ce565b8181528460208386010111156100f957600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff8116811461012e57600080fd5b919050565b60008060006060848603121561014857600080fd5b61015184610116565b92506020848101356001600160a01b038116811461016e57600080fd5b9250604085013567ffffffffffffffff8082111561018b57600080fd5b818701915087601f83011261019f57600080fd5b8135818111156101b1576101b16102ff565b8060051b6101c08582016102ce565b8281528581019085870183870188018d10156101db57600080fd5b60009350835b85811015610218578135878111156101f7578586fd5b6102058f8b838c01016100a6565b85525092880192908801906001016101e1565b5050809750505050505050509250925092565b6000806040838503121561023e57600080fd5b61024783610116565b9150602083013567ffffffffffffffff81111561026357600080fd5b61026f858286016100a6565b9150509250929050565b600060208083528351808285015260005b818110156102a65785810183015185820160400152820161028a565b818111156102b8576000604083870101525b50601f01601f1916929092016040019392505050565b604051601f8201601f1916810167ffffffffffffffff811182821017156102f7576102f76102ff565b604052919050565b634e487b7160e01b600052604160045260246000fdfea26469706673582212204231d0ee59fc1838c92d148dc40fade4e810e808d3b6d562c1891ea89e6b013a64736f6c63430008060033" - -// DeployHeaderSync deploys a new Ethereum contract, binding an instance of HeaderSync to it. -func DeployHeaderSync(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *HeaderSync, error) { - parsed, err := abi.JSON(strings.NewReader(HeaderSyncABI)) - if err != nil { - return common.Address{}, nil, nil, err - } - - address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(HeaderSyncBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &HeaderSync{HeaderSyncCaller: HeaderSyncCaller{contract: contract}, HeaderSyncTransactor: HeaderSyncTransactor{contract: contract}, HeaderSyncFilterer: HeaderSyncFilterer{contract: contract}}, nil -} - -// HeaderSync is an auto generated Go binding around an Ethereum contract. -type HeaderSync struct { - HeaderSyncCaller // Read-only binding to the contract - HeaderSyncTransactor // Write-only binding to the contract - HeaderSyncFilterer // Log filterer for contract events -} - -// HeaderSyncCaller is an auto generated read-only Go binding around an Ethereum contract. -type HeaderSyncCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// HeaderSyncTransactor is an auto generated write-only Go binding around an Ethereum contract. -type HeaderSyncTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// HeaderSyncFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type HeaderSyncFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// HeaderSyncSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type HeaderSyncSession struct { - Contract *HeaderSync // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// HeaderSyncCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type HeaderSyncCallerSession struct { - Contract *HeaderSyncCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// HeaderSyncTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type HeaderSyncTransactorSession struct { - Contract *HeaderSyncTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// HeaderSyncRaw is an auto generated low-level Go binding around an Ethereum contract. -type HeaderSyncRaw struct { - Contract *HeaderSync // Generic contract binding to access the raw methods on -} - -// HeaderSyncCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type HeaderSyncCallerRaw struct { - Contract *HeaderSyncCaller // Generic read-only contract binding to access the raw methods on -} - -// HeaderSyncTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type HeaderSyncTransactorRaw struct { - Contract *HeaderSyncTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewHeaderSync creates a new instance of HeaderSync, bound to a specific deployed contract. -func NewHeaderSync(address common.Address, backend bind.ContractBackend) (*HeaderSync, error) { - contract, err := bindHeaderSync(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &HeaderSync{HeaderSyncCaller: HeaderSyncCaller{contract: contract}, HeaderSyncTransactor: HeaderSyncTransactor{contract: contract}, HeaderSyncFilterer: HeaderSyncFilterer{contract: contract}}, nil -} - -// NewHeaderSyncCaller creates a new read-only instance of HeaderSync, bound to a specific deployed contract. -func NewHeaderSyncCaller(address common.Address, caller bind.ContractCaller) (*HeaderSyncCaller, error) { - contract, err := bindHeaderSync(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &HeaderSyncCaller{contract: contract}, nil -} - -// NewHeaderSyncTransactor creates a new write-only instance of HeaderSync, bound to a specific deployed contract. -func NewHeaderSyncTransactor(address common.Address, transactor bind.ContractTransactor) (*HeaderSyncTransactor, error) { - contract, err := bindHeaderSync(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &HeaderSyncTransactor{contract: contract}, nil -} - -// NewHeaderSyncFilterer creates a new log filterer instance of HeaderSync, bound to a specific deployed contract. -func NewHeaderSyncFilterer(address common.Address, filterer bind.ContractFilterer) (*HeaderSyncFilterer, error) { - contract, err := bindHeaderSync(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &HeaderSyncFilterer{contract: contract}, nil -} - -// bindHeaderSync binds a generic wrapper to an already deployed contract. -func bindHeaderSync(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(HeaderSyncABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_HeaderSync *HeaderSyncRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _HeaderSync.Contract.HeaderSyncCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_HeaderSync *HeaderSyncRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _HeaderSync.Contract.HeaderSyncTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_HeaderSync *HeaderSyncRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _HeaderSync.Contract.HeaderSyncTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_HeaderSync *HeaderSyncCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _HeaderSync.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_HeaderSync *HeaderSyncTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _HeaderSync.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_HeaderSync *HeaderSyncTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _HeaderSync.Contract.contract.Transact(opts, method, params...) -} - -// Name is a paid mutator transaction binding the contract method 0x06fdde03. -// -// Solidity: function name() returns(string Name) -func (_HeaderSync *HeaderSyncTransactor) Name(opts *bind.TransactOpts) (*types.Transaction, error) { - return _HeaderSync.contract.Transact(opts, "name") -} - -// Name is a paid mutator transaction binding the contract method 0x06fdde03. -// -// Solidity: function name() returns(string Name) -func (_HeaderSync *HeaderSyncSession) Name() (*types.Transaction, error) { - return _HeaderSync.Contract.Name(&_HeaderSync.TransactOpts) -} - -// Name is a paid mutator transaction binding the contract method 0x06fdde03. -// -// Solidity: function name() returns(string Name) -func (_HeaderSync *HeaderSyncTransactorSession) Name() (*types.Transaction, error) { - return _HeaderSync.Contract.Name(&_HeaderSync.TransactOpts) -} - -// SyncBlockHeader is a paid mutator transaction binding the contract method 0x72ce6700. -// -// Solidity: function syncBlockHeader(uint64 ChainID, address Address, bytes[] Headers) returns(bool success) -func (_HeaderSync *HeaderSyncTransactor) SyncBlockHeader(opts *bind.TransactOpts, ChainID uint64, Address common.Address, Headers [][]byte) (*types.Transaction, error) { - return _HeaderSync.contract.Transact(opts, "syncBlockHeader", ChainID, Address, Headers) -} - -// SyncBlockHeader is a paid mutator transaction binding the contract method 0x72ce6700. -// -// Solidity: function syncBlockHeader(uint64 ChainID, address Address, bytes[] Headers) returns(bool success) -func (_HeaderSync *HeaderSyncSession) SyncBlockHeader(ChainID uint64, Address common.Address, Headers [][]byte) (*types.Transaction, error) { - return _HeaderSync.Contract.SyncBlockHeader(&_HeaderSync.TransactOpts, ChainID, Address, Headers) -} - -// SyncBlockHeader is a paid mutator transaction binding the contract method 0x72ce6700. -// -// Solidity: function syncBlockHeader(uint64 ChainID, address Address, bytes[] Headers) returns(bool success) -func (_HeaderSync *HeaderSyncTransactorSession) SyncBlockHeader(ChainID uint64, Address common.Address, Headers [][]byte) (*types.Transaction, error) { - return _HeaderSync.Contract.SyncBlockHeader(&_HeaderSync.TransactOpts, ChainID, Address, Headers) -} - -// SyncCrossChainMsg is a paid mutator transaction binding the contract method 0x21b5cff5. -// -// Solidity: function syncCrossChainMsg(uint64 ChainID, address Address, bytes[] CrossChainMsgs) returns(bool success) -func (_HeaderSync *HeaderSyncTransactor) SyncCrossChainMsg(opts *bind.TransactOpts, ChainID uint64, Address common.Address, CrossChainMsgs [][]byte) (*types.Transaction, error) { - return _HeaderSync.contract.Transact(opts, "syncCrossChainMsg", ChainID, Address, CrossChainMsgs) -} - -// SyncCrossChainMsg is a paid mutator transaction binding the contract method 0x21b5cff5. -// -// Solidity: function syncCrossChainMsg(uint64 ChainID, address Address, bytes[] CrossChainMsgs) returns(bool success) -func (_HeaderSync *HeaderSyncSession) SyncCrossChainMsg(ChainID uint64, Address common.Address, CrossChainMsgs [][]byte) (*types.Transaction, error) { - return _HeaderSync.Contract.SyncCrossChainMsg(&_HeaderSync.TransactOpts, ChainID, Address, CrossChainMsgs) -} - -// SyncCrossChainMsg is a paid mutator transaction binding the contract method 0x21b5cff5. -// -// Solidity: function syncCrossChainMsg(uint64 ChainID, address Address, bytes[] CrossChainMsgs) returns(bool success) -func (_HeaderSync *HeaderSyncTransactorSession) SyncCrossChainMsg(ChainID uint64, Address common.Address, CrossChainMsgs [][]byte) (*types.Transaction, error) { - return _HeaderSync.Contract.SyncCrossChainMsg(&_HeaderSync.TransactOpts, ChainID, Address, CrossChainMsgs) -} - -// SyncGenesisHeader is a paid mutator transaction binding the contract method 0xb5ace618. -// -// Solidity: function syncGenesisHeader(uint64 ChainID, bytes GenesisHeader) returns(bool success) -func (_HeaderSync *HeaderSyncTransactor) SyncGenesisHeader(opts *bind.TransactOpts, ChainID uint64, GenesisHeader []byte) (*types.Transaction, error) { - return _HeaderSync.contract.Transact(opts, "syncGenesisHeader", ChainID, GenesisHeader) -} - -// SyncGenesisHeader is a paid mutator transaction binding the contract method 0xb5ace618. -// -// Solidity: function syncGenesisHeader(uint64 ChainID, bytes GenesisHeader) returns(bool success) -func (_HeaderSync *HeaderSyncSession) SyncGenesisHeader(ChainID uint64, GenesisHeader []byte) (*types.Transaction, error) { - return _HeaderSync.Contract.SyncGenesisHeader(&_HeaderSync.TransactOpts, ChainID, GenesisHeader) -} - -// SyncGenesisHeader is a paid mutator transaction binding the contract method 0xb5ace618. -// -// Solidity: function syncGenesisHeader(uint64 ChainID, bytes GenesisHeader) returns(bool success) -func (_HeaderSync *HeaderSyncTransactorSession) SyncGenesisHeader(ChainID uint64, GenesisHeader []byte) (*types.Transaction, error) { - return _HeaderSync.Contract.SyncGenesisHeader(&_HeaderSync.TransactOpts, ChainID, GenesisHeader) -} - -// HeaderSyncOKEpochSwitchInfoEventIterator is returned from FilterOKEpochSwitchInfoEvent and is used to iterate over the raw logs and unpacked data for OKEpochSwitchInfoEvent events raised by the HeaderSync contract. -type HeaderSyncOKEpochSwitchInfoEventIterator struct { - Event *HeaderSyncOKEpochSwitchInfoEvent // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HeaderSyncOKEpochSwitchInfoEventIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HeaderSyncOKEpochSwitchInfoEvent) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HeaderSyncOKEpochSwitchInfoEvent) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HeaderSyncOKEpochSwitchInfoEventIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HeaderSyncOKEpochSwitchInfoEventIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// HeaderSyncOKEpochSwitchInfoEvent represents a OKEpochSwitchInfoEvent event raised by the HeaderSync contract. -type HeaderSyncOKEpochSwitchInfoEvent struct { - ChainID uint64 - BlockHash string - Height uint64 - NextValidatorsHash string - InfoChainID string - BlockHeight uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterOKEpochSwitchInfoEvent is a free log retrieval operation binding the contract event 0xbfd2d7144ec37c6f85850914f6d172957dd090c508f40d540062f1cd06c0852a. -// -// Solidity: event OKEpochSwitchInfoEvent(uint64 chainID, string BlockHash, uint64 Height, string NextValidatorsHash, string InfoChainID, uint64 BlockHeight) -func (_HeaderSync *HeaderSyncFilterer) FilterOKEpochSwitchInfoEvent(opts *bind.FilterOpts) (*HeaderSyncOKEpochSwitchInfoEventIterator, error) { - - logs, sub, err := _HeaderSync.contract.FilterLogs(opts, "OKEpochSwitchInfoEvent") - if err != nil { - return nil, err - } - return &HeaderSyncOKEpochSwitchInfoEventIterator{contract: _HeaderSync.contract, event: "OKEpochSwitchInfoEvent", logs: logs, sub: sub}, nil -} - -// WatchOKEpochSwitchInfoEvent is a free log subscription operation binding the contract event 0xbfd2d7144ec37c6f85850914f6d172957dd090c508f40d540062f1cd06c0852a. -// -// Solidity: event OKEpochSwitchInfoEvent(uint64 chainID, string BlockHash, uint64 Height, string NextValidatorsHash, string InfoChainID, uint64 BlockHeight) -func (_HeaderSync *HeaderSyncFilterer) WatchOKEpochSwitchInfoEvent(opts *bind.WatchOpts, sink chan<- *HeaderSyncOKEpochSwitchInfoEvent) (event.Subscription, error) { - - logs, sub, err := _HeaderSync.contract.WatchLogs(opts, "OKEpochSwitchInfoEvent") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HeaderSyncOKEpochSwitchInfoEvent) - if err := _HeaderSync.contract.UnpackLog(event, "OKEpochSwitchInfoEvent", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseOKEpochSwitchInfoEvent is a log parse operation binding the contract event 0xbfd2d7144ec37c6f85850914f6d172957dd090c508f40d540062f1cd06c0852a. -// -// Solidity: event OKEpochSwitchInfoEvent(uint64 chainID, string BlockHash, uint64 Height, string NextValidatorsHash, string InfoChainID, uint64 BlockHeight) -func (_HeaderSync *HeaderSyncFilterer) ParseOKEpochSwitchInfoEvent(log types.Log) (*HeaderSyncOKEpochSwitchInfoEvent, error) { - event := new(HeaderSyncOKEpochSwitchInfoEvent) - if err := _HeaderSync.contract.UnpackLog(event, "OKEpochSwitchInfoEvent", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// HeaderSyncSyncHeaderIterator is returned from FilterSyncHeader and is used to iterate over the raw logs and unpacked data for SyncHeader events raised by the HeaderSync contract. -type HeaderSyncSyncHeaderIterator struct { - Event *HeaderSyncSyncHeader // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HeaderSyncSyncHeaderIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HeaderSyncSyncHeader) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HeaderSyncSyncHeader) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HeaderSyncSyncHeaderIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HeaderSyncSyncHeaderIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// HeaderSyncSyncHeader represents a SyncHeader event raised by the HeaderSync contract. -type HeaderSyncSyncHeader struct { - ChainID uint64 - Height uint64 - BlockHash string - BlockHeight *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterSyncHeader is a free log retrieval operation binding the contract event 0xe4d5dbebcfbd7358435d9d612bc7b584bc51faf456160631d2537a0de2e1a236. -// -// Solidity: event syncHeader(uint64 chainID, uint64 height, string blockHash, uint256 BlockHeight) -func (_HeaderSync *HeaderSyncFilterer) FilterSyncHeader(opts *bind.FilterOpts) (*HeaderSyncSyncHeaderIterator, error) { - - logs, sub, err := _HeaderSync.contract.FilterLogs(opts, "syncHeader") - if err != nil { - return nil, err - } - return &HeaderSyncSyncHeaderIterator{contract: _HeaderSync.contract, event: "syncHeader", logs: logs, sub: sub}, nil -} - -// WatchSyncHeader is a free log subscription operation binding the contract event 0xe4d5dbebcfbd7358435d9d612bc7b584bc51faf456160631d2537a0de2e1a236. -// -// Solidity: event syncHeader(uint64 chainID, uint64 height, string blockHash, uint256 BlockHeight) -func (_HeaderSync *HeaderSyncFilterer) WatchSyncHeader(opts *bind.WatchOpts, sink chan<- *HeaderSyncSyncHeader) (event.Subscription, error) { - - logs, sub, err := _HeaderSync.contract.WatchLogs(opts, "syncHeader") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HeaderSyncSyncHeader) - if err := _HeaderSync.contract.UnpackLog(event, "syncHeader", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseSyncHeader is a log parse operation binding the contract event 0xe4d5dbebcfbd7358435d9d612bc7b584bc51faf456160631d2537a0de2e1a236. -// -// Solidity: event syncHeader(uint64 chainID, uint64 height, string blockHash, uint256 BlockHeight) -func (_HeaderSync *HeaderSyncFilterer) ParseSyncHeader(log types.Log) (*HeaderSyncSyncHeader, error) { - event := new(HeaderSyncSyncHeader) - if err := _HeaderSync.contract.UnpackLog(event, "syncHeader", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} diff --git a/contracts/native/go_abi/maas_config_abi/maas_config_abi.go b/contracts/native/go_abi/maas_config_abi/maas_config_abi.go new file mode 100644 index 00000000..fdb12841 --- /dev/null +++ b/contracts/native/go_abi/maas_config_abi/maas_config_abi.go @@ -0,0 +1,1534 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package maas_config_abi + +import ( + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +var ( + MethodBlockAccount = "blockAccount" + + MethodChangeOwner = "changeOwner" + + MethodEnableGasManage = "enableGasManage" + + MethodSetAdmins = "setAdmins" + + MethodSetGasManager = "setGasManager" + + MethodSetGasUsers = "setGasUsers" + + MethodGetAdminList = "getAdminList" + + MethodGetBlacklist = "getBlacklist" + + MethodGetGasManagerList = "getGasManagerList" + + MethodGetGasUserList = "getGasUserList" + + MethodGetOwner = "getOwner" + + MethodIsAdmin = "isAdmin" + + MethodIsBlocked = "isBlocked" + + MethodIsGasManageEnabled = "isGasManageEnabled" + + MethodIsGasManager = "isGasManager" + + MethodIsGasUser = "isGasUser" + + MethodName = "name" + + EventBlockAccount = "BlockAccount" + + EventChangeOwner = "ChangeOwner" + + EventEnableGasManage = "EnableGasManage" + + EventSetAdmins = "SetAdmins" + + EventSetGasManager = "SetGasManager" + + EventSetGasUsers = "SetGasUsers" +) + +// MaasConfigABI is the input ABI used to generate the binding from. +const MaasConfigABI = "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"doBlock\",\"type\":\"bool\"}],\"name\":\"BlockAccount\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"ChangeOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"doEnable\",\"type\":\"bool\"}],\"name\":\"EnableGasManage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"addrs\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"addOrRemove\",\"type\":\"bool\"}],\"name\":\"SetAdmins\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isManager\",\"type\":\"bool\"}],\"name\":\"SetGasManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"addrs\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"addOrRemove\",\"type\":\"bool\"}],\"name\":\"SetGasUsers\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"doBlock\",\"type\":\"bool\"}],\"name\":\"blockAccount\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"changeOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"doEnable\",\"type\":\"bool\"}],\"name\":\"enableGasManage\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminList\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlacklist\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasManagerList\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasUserList\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"isAdmin\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"isBlocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isGasManageEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"isGasManager\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"isGasUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"addrs\",\"type\":\"address[]\"},{\"internalType\":\"bool\",\"name\":\"addOrRemove\",\"type\":\"bool\"}],\"name\":\"setAdmins\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isManager\",\"type\":\"bool\"}],\"name\":\"setGasManager\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"addrs\",\"type\":\"address[]\"},{\"internalType\":\"bool\",\"name\":\"addOrRemove\",\"type\":\"bool\"}],\"name\":\"setGasUsers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" + +// MaasConfig is an auto generated Go binding around an Ethereum contract. +type MaasConfig struct { + MaasConfigCaller // Read-only binding to the contract + MaasConfigTransactor // Write-only binding to the contract + MaasConfigFilterer // Log filterer for contract events +} + +// MaasConfigCaller is an auto generated read-only Go binding around an Ethereum contract. +type MaasConfigCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MaasConfigTransactor is an auto generated write-only Go binding around an Ethereum contract. +type MaasConfigTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MaasConfigFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type MaasConfigFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MaasConfigSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type MaasConfigSession struct { + Contract *MaasConfig // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// MaasConfigCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type MaasConfigCallerSession struct { + Contract *MaasConfigCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// MaasConfigTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type MaasConfigTransactorSession struct { + Contract *MaasConfigTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// MaasConfigRaw is an auto generated low-level Go binding around an Ethereum contract. +type MaasConfigRaw struct { + Contract *MaasConfig // Generic contract binding to access the raw methods on +} + +// MaasConfigCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type MaasConfigCallerRaw struct { + Contract *MaasConfigCaller // Generic read-only contract binding to access the raw methods on +} + +// MaasConfigTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type MaasConfigTransactorRaw struct { + Contract *MaasConfigTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewMaasConfig creates a new instance of MaasConfig, bound to a specific deployed contract. +func NewMaasConfig(address common.Address, backend bind.ContractBackend) (*MaasConfig, error) { + contract, err := bindMaasConfig(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MaasConfig{MaasConfigCaller: MaasConfigCaller{contract: contract}, MaasConfigTransactor: MaasConfigTransactor{contract: contract}, MaasConfigFilterer: MaasConfigFilterer{contract: contract}}, nil +} + +// NewMaasConfigCaller creates a new read-only instance of MaasConfig, bound to a specific deployed contract. +func NewMaasConfigCaller(address common.Address, caller bind.ContractCaller) (*MaasConfigCaller, error) { + contract, err := bindMaasConfig(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MaasConfigCaller{contract: contract}, nil +} + +// NewMaasConfigTransactor creates a new write-only instance of MaasConfig, bound to a specific deployed contract. +func NewMaasConfigTransactor(address common.Address, transactor bind.ContractTransactor) (*MaasConfigTransactor, error) { + contract, err := bindMaasConfig(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MaasConfigTransactor{contract: contract}, nil +} + +// NewMaasConfigFilterer creates a new log filterer instance of MaasConfig, bound to a specific deployed contract. +func NewMaasConfigFilterer(address common.Address, filterer bind.ContractFilterer) (*MaasConfigFilterer, error) { + contract, err := bindMaasConfig(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MaasConfigFilterer{contract: contract}, nil +} + +// bindMaasConfig binds a generic wrapper to an already deployed contract. +func bindMaasConfig(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(MaasConfigABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_MaasConfig *MaasConfigRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MaasConfig.Contract.MaasConfigCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_MaasConfig *MaasConfigRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MaasConfig.Contract.MaasConfigTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_MaasConfig *MaasConfigRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MaasConfig.Contract.MaasConfigTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_MaasConfig *MaasConfigCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MaasConfig.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_MaasConfig *MaasConfigTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MaasConfig.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_MaasConfig *MaasConfigTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MaasConfig.Contract.contract.Transact(opts, method, params...) +} + +// GetAdminList is a free data retrieval call binding the contract method 0xd9f774fc. +// +// Solidity: function getAdminList() view returns(string) +func (_MaasConfig *MaasConfigCaller) GetAdminList(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _MaasConfig.contract.Call(opts, &out, "getAdminList") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// GetAdminList is a free data retrieval call binding the contract method 0xd9f774fc. +// +// Solidity: function getAdminList() view returns(string) +func (_MaasConfig *MaasConfigSession) GetAdminList() (string, error) { + return _MaasConfig.Contract.GetAdminList(&_MaasConfig.CallOpts) +} + +// GetAdminList is a free data retrieval call binding the contract method 0xd9f774fc. +// +// Solidity: function getAdminList() view returns(string) +func (_MaasConfig *MaasConfigCallerSession) GetAdminList() (string, error) { + return _MaasConfig.Contract.GetAdminList(&_MaasConfig.CallOpts) +} + +// GetBlacklist is a free data retrieval call binding the contract method 0x338d6c30. +// +// Solidity: function getBlacklist() view returns(string) +func (_MaasConfig *MaasConfigCaller) GetBlacklist(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _MaasConfig.contract.Call(opts, &out, "getBlacklist") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// GetBlacklist is a free data retrieval call binding the contract method 0x338d6c30. +// +// Solidity: function getBlacklist() view returns(string) +func (_MaasConfig *MaasConfigSession) GetBlacklist() (string, error) { + return _MaasConfig.Contract.GetBlacklist(&_MaasConfig.CallOpts) +} + +// GetBlacklist is a free data retrieval call binding the contract method 0x338d6c30. +// +// Solidity: function getBlacklist() view returns(string) +func (_MaasConfig *MaasConfigCallerSession) GetBlacklist() (string, error) { + return _MaasConfig.Contract.GetBlacklist(&_MaasConfig.CallOpts) +} + +// GetGasManagerList is a free data retrieval call binding the contract method 0xffa8ad5e. +// +// Solidity: function getGasManagerList() view returns(string) +func (_MaasConfig *MaasConfigCaller) GetGasManagerList(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _MaasConfig.contract.Call(opts, &out, "getGasManagerList") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// GetGasManagerList is a free data retrieval call binding the contract method 0xffa8ad5e. +// +// Solidity: function getGasManagerList() view returns(string) +func (_MaasConfig *MaasConfigSession) GetGasManagerList() (string, error) { + return _MaasConfig.Contract.GetGasManagerList(&_MaasConfig.CallOpts) +} + +// GetGasManagerList is a free data retrieval call binding the contract method 0xffa8ad5e. +// +// Solidity: function getGasManagerList() view returns(string) +func (_MaasConfig *MaasConfigCallerSession) GetGasManagerList() (string, error) { + return _MaasConfig.Contract.GetGasManagerList(&_MaasConfig.CallOpts) +} + +// GetGasUserList is a free data retrieval call binding the contract method 0xd46af6ae. +// +// Solidity: function getGasUserList() view returns(string) +func (_MaasConfig *MaasConfigCaller) GetGasUserList(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _MaasConfig.contract.Call(opts, &out, "getGasUserList") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// GetGasUserList is a free data retrieval call binding the contract method 0xd46af6ae. +// +// Solidity: function getGasUserList() view returns(string) +func (_MaasConfig *MaasConfigSession) GetGasUserList() (string, error) { + return _MaasConfig.Contract.GetGasUserList(&_MaasConfig.CallOpts) +} + +// GetGasUserList is a free data retrieval call binding the contract method 0xd46af6ae. +// +// Solidity: function getGasUserList() view returns(string) +func (_MaasConfig *MaasConfigCallerSession) GetGasUserList() (string, error) { + return _MaasConfig.Contract.GetGasUserList(&_MaasConfig.CallOpts) +} + +// GetOwner is a free data retrieval call binding the contract method 0x893d20e8. +// +// Solidity: function getOwner() view returns(address) +func (_MaasConfig *MaasConfigCaller) GetOwner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _MaasConfig.contract.Call(opts, &out, "getOwner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetOwner is a free data retrieval call binding the contract method 0x893d20e8. +// +// Solidity: function getOwner() view returns(address) +func (_MaasConfig *MaasConfigSession) GetOwner() (common.Address, error) { + return _MaasConfig.Contract.GetOwner(&_MaasConfig.CallOpts) +} + +// GetOwner is a free data retrieval call binding the contract method 0x893d20e8. +// +// Solidity: function getOwner() view returns(address) +func (_MaasConfig *MaasConfigCallerSession) GetOwner() (common.Address, error) { + return _MaasConfig.Contract.GetOwner(&_MaasConfig.CallOpts) +} + +// IsAdmin is a free data retrieval call binding the contract method 0x24d7806c. +// +// Solidity: function isAdmin(address addr) view returns(bool) +func (_MaasConfig *MaasConfigCaller) IsAdmin(opts *bind.CallOpts, addr common.Address) (bool, error) { + var out []interface{} + err := _MaasConfig.contract.Call(opts, &out, "isAdmin", addr) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsAdmin is a free data retrieval call binding the contract method 0x24d7806c. +// +// Solidity: function isAdmin(address addr) view returns(bool) +func (_MaasConfig *MaasConfigSession) IsAdmin(addr common.Address) (bool, error) { + return _MaasConfig.Contract.IsAdmin(&_MaasConfig.CallOpts, addr) +} + +// IsAdmin is a free data retrieval call binding the contract method 0x24d7806c. +// +// Solidity: function isAdmin(address addr) view returns(bool) +func (_MaasConfig *MaasConfigCallerSession) IsAdmin(addr common.Address) (bool, error) { + return _MaasConfig.Contract.IsAdmin(&_MaasConfig.CallOpts, addr) +} + +// IsBlocked is a free data retrieval call binding the contract method 0xfbac3951. +// +// Solidity: function isBlocked(address addr) view returns(bool) +func (_MaasConfig *MaasConfigCaller) IsBlocked(opts *bind.CallOpts, addr common.Address) (bool, error) { + var out []interface{} + err := _MaasConfig.contract.Call(opts, &out, "isBlocked", addr) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsBlocked is a free data retrieval call binding the contract method 0xfbac3951. +// +// Solidity: function isBlocked(address addr) view returns(bool) +func (_MaasConfig *MaasConfigSession) IsBlocked(addr common.Address) (bool, error) { + return _MaasConfig.Contract.IsBlocked(&_MaasConfig.CallOpts, addr) +} + +// IsBlocked is a free data retrieval call binding the contract method 0xfbac3951. +// +// Solidity: function isBlocked(address addr) view returns(bool) +func (_MaasConfig *MaasConfigCallerSession) IsBlocked(addr common.Address) (bool, error) { + return _MaasConfig.Contract.IsBlocked(&_MaasConfig.CallOpts, addr) +} + +// IsGasManageEnabled is a free data retrieval call binding the contract method 0x4c1e5356. +// +// Solidity: function isGasManageEnabled() view returns(bool) +func (_MaasConfig *MaasConfigCaller) IsGasManageEnabled(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _MaasConfig.contract.Call(opts, &out, "isGasManageEnabled") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsGasManageEnabled is a free data retrieval call binding the contract method 0x4c1e5356. +// +// Solidity: function isGasManageEnabled() view returns(bool) +func (_MaasConfig *MaasConfigSession) IsGasManageEnabled() (bool, error) { + return _MaasConfig.Contract.IsGasManageEnabled(&_MaasConfig.CallOpts) +} + +// IsGasManageEnabled is a free data retrieval call binding the contract method 0x4c1e5356. +// +// Solidity: function isGasManageEnabled() view returns(bool) +func (_MaasConfig *MaasConfigCallerSession) IsGasManageEnabled() (bool, error) { + return _MaasConfig.Contract.IsGasManageEnabled(&_MaasConfig.CallOpts) +} + +// IsGasManager is a free data retrieval call binding the contract method 0x535f9720. +// +// Solidity: function isGasManager(address addr) view returns(bool) +func (_MaasConfig *MaasConfigCaller) IsGasManager(opts *bind.CallOpts, addr common.Address) (bool, error) { + var out []interface{} + err := _MaasConfig.contract.Call(opts, &out, "isGasManager", addr) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsGasManager is a free data retrieval call binding the contract method 0x535f9720. +// +// Solidity: function isGasManager(address addr) view returns(bool) +func (_MaasConfig *MaasConfigSession) IsGasManager(addr common.Address) (bool, error) { + return _MaasConfig.Contract.IsGasManager(&_MaasConfig.CallOpts, addr) +} + +// IsGasManager is a free data retrieval call binding the contract method 0x535f9720. +// +// Solidity: function isGasManager(address addr) view returns(bool) +func (_MaasConfig *MaasConfigCallerSession) IsGasManager(addr common.Address) (bool, error) { + return _MaasConfig.Contract.IsGasManager(&_MaasConfig.CallOpts, addr) +} + +// IsGasUser is a free data retrieval call binding the contract method 0xbcf3e01e. +// +// Solidity: function isGasUser(address addr) view returns(bool) +func (_MaasConfig *MaasConfigCaller) IsGasUser(opts *bind.CallOpts, addr common.Address) (bool, error) { + var out []interface{} + err := _MaasConfig.contract.Call(opts, &out, "isGasUser", addr) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsGasUser is a free data retrieval call binding the contract method 0xbcf3e01e. +// +// Solidity: function isGasUser(address addr) view returns(bool) +func (_MaasConfig *MaasConfigSession) IsGasUser(addr common.Address) (bool, error) { + return _MaasConfig.Contract.IsGasUser(&_MaasConfig.CallOpts, addr) +} + +// IsGasUser is a free data retrieval call binding the contract method 0xbcf3e01e. +// +// Solidity: function isGasUser(address addr) view returns(bool) +func (_MaasConfig *MaasConfigCallerSession) IsGasUser(addr common.Address) (bool, error) { + return _MaasConfig.Contract.IsGasUser(&_MaasConfig.CallOpts, addr) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_MaasConfig *MaasConfigCaller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _MaasConfig.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_MaasConfig *MaasConfigSession) Name() (string, error) { + return _MaasConfig.Contract.Name(&_MaasConfig.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_MaasConfig *MaasConfigCallerSession) Name() (string, error) { + return _MaasConfig.Contract.Name(&_MaasConfig.CallOpts) +} + +// BlockAccount is a paid mutator transaction binding the contract method 0x52c163bb. +// +// Solidity: function blockAccount(address addr, bool doBlock) returns(bool) +func (_MaasConfig *MaasConfigTransactor) BlockAccount(opts *bind.TransactOpts, addr common.Address, doBlock bool) (*types.Transaction, error) { + return _MaasConfig.contract.Transact(opts, "blockAccount", addr, doBlock) +} + +// BlockAccount is a paid mutator transaction binding the contract method 0x52c163bb. +// +// Solidity: function blockAccount(address addr, bool doBlock) returns(bool) +func (_MaasConfig *MaasConfigSession) BlockAccount(addr common.Address, doBlock bool) (*types.Transaction, error) { + return _MaasConfig.Contract.BlockAccount(&_MaasConfig.TransactOpts, addr, doBlock) +} + +// BlockAccount is a paid mutator transaction binding the contract method 0x52c163bb. +// +// Solidity: function blockAccount(address addr, bool doBlock) returns(bool) +func (_MaasConfig *MaasConfigTransactorSession) BlockAccount(addr common.Address, doBlock bool) (*types.Transaction, error) { + return _MaasConfig.Contract.BlockAccount(&_MaasConfig.TransactOpts, addr, doBlock) +} + +// ChangeOwner is a paid mutator transaction binding the contract method 0xa6f9dae1. +// +// Solidity: function changeOwner(address addr) returns(bool) +func (_MaasConfig *MaasConfigTransactor) ChangeOwner(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) { + return _MaasConfig.contract.Transact(opts, "changeOwner", addr) +} + +// ChangeOwner is a paid mutator transaction binding the contract method 0xa6f9dae1. +// +// Solidity: function changeOwner(address addr) returns(bool) +func (_MaasConfig *MaasConfigSession) ChangeOwner(addr common.Address) (*types.Transaction, error) { + return _MaasConfig.Contract.ChangeOwner(&_MaasConfig.TransactOpts, addr) +} + +// ChangeOwner is a paid mutator transaction binding the contract method 0xa6f9dae1. +// +// Solidity: function changeOwner(address addr) returns(bool) +func (_MaasConfig *MaasConfigTransactorSession) ChangeOwner(addr common.Address) (*types.Transaction, error) { + return _MaasConfig.Contract.ChangeOwner(&_MaasConfig.TransactOpts, addr) +} + +// EnableGasManage is a paid mutator transaction binding the contract method 0x7785555d. +// +// Solidity: function enableGasManage(bool doEnable) returns(bool) +func (_MaasConfig *MaasConfigTransactor) EnableGasManage(opts *bind.TransactOpts, doEnable bool) (*types.Transaction, error) { + return _MaasConfig.contract.Transact(opts, "enableGasManage", doEnable) +} + +// EnableGasManage is a paid mutator transaction binding the contract method 0x7785555d. +// +// Solidity: function enableGasManage(bool doEnable) returns(bool) +func (_MaasConfig *MaasConfigSession) EnableGasManage(doEnable bool) (*types.Transaction, error) { + return _MaasConfig.Contract.EnableGasManage(&_MaasConfig.TransactOpts, doEnable) +} + +// EnableGasManage is a paid mutator transaction binding the contract method 0x7785555d. +// +// Solidity: function enableGasManage(bool doEnable) returns(bool) +func (_MaasConfig *MaasConfigTransactorSession) EnableGasManage(doEnable bool) (*types.Transaction, error) { + return _MaasConfig.Contract.EnableGasManage(&_MaasConfig.TransactOpts, doEnable) +} + +// SetAdmins is a paid mutator transaction binding the contract method 0x030e2c88. +// +// Solidity: function setAdmins(address[] addrs, bool addOrRemove) returns(bool) +func (_MaasConfig *MaasConfigTransactor) SetAdmins(opts *bind.TransactOpts, addrs []common.Address, addOrRemove bool) (*types.Transaction, error) { + return _MaasConfig.contract.Transact(opts, "setAdmins", addrs, addOrRemove) +} + +// SetAdmins is a paid mutator transaction binding the contract method 0x030e2c88. +// +// Solidity: function setAdmins(address[] addrs, bool addOrRemove) returns(bool) +func (_MaasConfig *MaasConfigSession) SetAdmins(addrs []common.Address, addOrRemove bool) (*types.Transaction, error) { + return _MaasConfig.Contract.SetAdmins(&_MaasConfig.TransactOpts, addrs, addOrRemove) +} + +// SetAdmins is a paid mutator transaction binding the contract method 0x030e2c88. +// +// Solidity: function setAdmins(address[] addrs, bool addOrRemove) returns(bool) +func (_MaasConfig *MaasConfigTransactorSession) SetAdmins(addrs []common.Address, addOrRemove bool) (*types.Transaction, error) { + return _MaasConfig.Contract.SetAdmins(&_MaasConfig.TransactOpts, addrs, addOrRemove) +} + +// SetGasManager is a paid mutator transaction binding the contract method 0xab75fbe7. +// +// Solidity: function setGasManager(address addr, bool isManager) returns(bool) +func (_MaasConfig *MaasConfigTransactor) SetGasManager(opts *bind.TransactOpts, addr common.Address, isManager bool) (*types.Transaction, error) { + return _MaasConfig.contract.Transact(opts, "setGasManager", addr, isManager) +} + +// SetGasManager is a paid mutator transaction binding the contract method 0xab75fbe7. +// +// Solidity: function setGasManager(address addr, bool isManager) returns(bool) +func (_MaasConfig *MaasConfigSession) SetGasManager(addr common.Address, isManager bool) (*types.Transaction, error) { + return _MaasConfig.Contract.SetGasManager(&_MaasConfig.TransactOpts, addr, isManager) +} + +// SetGasManager is a paid mutator transaction binding the contract method 0xab75fbe7. +// +// Solidity: function setGasManager(address addr, bool isManager) returns(bool) +func (_MaasConfig *MaasConfigTransactorSession) SetGasManager(addr common.Address, isManager bool) (*types.Transaction, error) { + return _MaasConfig.Contract.SetGasManager(&_MaasConfig.TransactOpts, addr, isManager) +} + +// SetGasUsers is a paid mutator transaction binding the contract method 0x99e3017d. +// +// Solidity: function setGasUsers(address[] addrs, bool addOrRemove) returns(bool) +func (_MaasConfig *MaasConfigTransactor) SetGasUsers(opts *bind.TransactOpts, addrs []common.Address, addOrRemove bool) (*types.Transaction, error) { + return _MaasConfig.contract.Transact(opts, "setGasUsers", addrs, addOrRemove) +} + +// SetGasUsers is a paid mutator transaction binding the contract method 0x99e3017d. +// +// Solidity: function setGasUsers(address[] addrs, bool addOrRemove) returns(bool) +func (_MaasConfig *MaasConfigSession) SetGasUsers(addrs []common.Address, addOrRemove bool) (*types.Transaction, error) { + return _MaasConfig.Contract.SetGasUsers(&_MaasConfig.TransactOpts, addrs, addOrRemove) +} + +// SetGasUsers is a paid mutator transaction binding the contract method 0x99e3017d. +// +// Solidity: function setGasUsers(address[] addrs, bool addOrRemove) returns(bool) +func (_MaasConfig *MaasConfigTransactorSession) SetGasUsers(addrs []common.Address, addOrRemove bool) (*types.Transaction, error) { + return _MaasConfig.Contract.SetGasUsers(&_MaasConfig.TransactOpts, addrs, addOrRemove) +} + +// MaasConfigBlockAccountIterator is returned from FilterBlockAccount and is used to iterate over the raw logs and unpacked data for BlockAccount events raised by the MaasConfig contract. +type MaasConfigBlockAccountIterator struct { + Event *MaasConfigBlockAccount // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *MaasConfigBlockAccountIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(MaasConfigBlockAccount) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(MaasConfigBlockAccount) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *MaasConfigBlockAccountIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *MaasConfigBlockAccountIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// MaasConfigBlockAccount represents a BlockAccount event raised by the MaasConfig contract. +type MaasConfigBlockAccount struct { + Addr common.Address + DoBlock bool + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBlockAccount is a free log retrieval operation binding the contract event 0x977826a31e63a99f714f2677060d8f5d42a578272b31da3a8088f758ca915fdf. +// +// Solidity: event BlockAccount(address indexed addr, bool doBlock) +func (_MaasConfig *MaasConfigFilterer) FilterBlockAccount(opts *bind.FilterOpts, addr []common.Address) (*MaasConfigBlockAccountIterator, error) { + + var addrRule []interface{} + for _, addrItem := range addr { + addrRule = append(addrRule, addrItem) + } + + logs, sub, err := _MaasConfig.contract.FilterLogs(opts, "BlockAccount", addrRule) + if err != nil { + return nil, err + } + return &MaasConfigBlockAccountIterator{contract: _MaasConfig.contract, event: "BlockAccount", logs: logs, sub: sub}, nil +} + +// WatchBlockAccount is a free log subscription operation binding the contract event 0x977826a31e63a99f714f2677060d8f5d42a578272b31da3a8088f758ca915fdf. +// +// Solidity: event BlockAccount(address indexed addr, bool doBlock) +func (_MaasConfig *MaasConfigFilterer) WatchBlockAccount(opts *bind.WatchOpts, sink chan<- *MaasConfigBlockAccount, addr []common.Address) (event.Subscription, error) { + + var addrRule []interface{} + for _, addrItem := range addr { + addrRule = append(addrRule, addrItem) + } + + logs, sub, err := _MaasConfig.contract.WatchLogs(opts, "BlockAccount", addrRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(MaasConfigBlockAccount) + if err := _MaasConfig.contract.UnpackLog(event, "BlockAccount", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseBlockAccount is a log parse operation binding the contract event 0x977826a31e63a99f714f2677060d8f5d42a578272b31da3a8088f758ca915fdf. +// +// Solidity: event BlockAccount(address indexed addr, bool doBlock) +func (_MaasConfig *MaasConfigFilterer) ParseBlockAccount(log types.Log) (*MaasConfigBlockAccount, error) { + event := new(MaasConfigBlockAccount) + if err := _MaasConfig.contract.UnpackLog(event, "BlockAccount", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// MaasConfigChangeOwnerIterator is returned from FilterChangeOwner and is used to iterate over the raw logs and unpacked data for ChangeOwner events raised by the MaasConfig contract. +type MaasConfigChangeOwnerIterator struct { + Event *MaasConfigChangeOwner // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *MaasConfigChangeOwnerIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(MaasConfigChangeOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(MaasConfigChangeOwner) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *MaasConfigChangeOwnerIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *MaasConfigChangeOwnerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// MaasConfigChangeOwner represents a ChangeOwner event raised by the MaasConfig contract. +type MaasConfigChangeOwner struct { + OldOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterChangeOwner is a free log retrieval operation binding the contract event 0x9aecf86140d81442289f667eb72e1202a8fbb3478a686659952e145e85319656. +// +// Solidity: event ChangeOwner(address indexed oldOwner, address indexed newOwner) +func (_MaasConfig *MaasConfigFilterer) FilterChangeOwner(opts *bind.FilterOpts, oldOwner []common.Address, newOwner []common.Address) (*MaasConfigChangeOwnerIterator, error) { + + var oldOwnerRule []interface{} + for _, oldOwnerItem := range oldOwner { + oldOwnerRule = append(oldOwnerRule, oldOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _MaasConfig.contract.FilterLogs(opts, "ChangeOwner", oldOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &MaasConfigChangeOwnerIterator{contract: _MaasConfig.contract, event: "ChangeOwner", logs: logs, sub: sub}, nil +} + +// WatchChangeOwner is a free log subscription operation binding the contract event 0x9aecf86140d81442289f667eb72e1202a8fbb3478a686659952e145e85319656. +// +// Solidity: event ChangeOwner(address indexed oldOwner, address indexed newOwner) +func (_MaasConfig *MaasConfigFilterer) WatchChangeOwner(opts *bind.WatchOpts, sink chan<- *MaasConfigChangeOwner, oldOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var oldOwnerRule []interface{} + for _, oldOwnerItem := range oldOwner { + oldOwnerRule = append(oldOwnerRule, oldOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _MaasConfig.contract.WatchLogs(opts, "ChangeOwner", oldOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(MaasConfigChangeOwner) + if err := _MaasConfig.contract.UnpackLog(event, "ChangeOwner", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseChangeOwner is a log parse operation binding the contract event 0x9aecf86140d81442289f667eb72e1202a8fbb3478a686659952e145e85319656. +// +// Solidity: event ChangeOwner(address indexed oldOwner, address indexed newOwner) +func (_MaasConfig *MaasConfigFilterer) ParseChangeOwner(log types.Log) (*MaasConfigChangeOwner, error) { + event := new(MaasConfigChangeOwner) + if err := _MaasConfig.contract.UnpackLog(event, "ChangeOwner", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// MaasConfigEnableGasManageIterator is returned from FilterEnableGasManage and is used to iterate over the raw logs and unpacked data for EnableGasManage events raised by the MaasConfig contract. +type MaasConfigEnableGasManageIterator struct { + Event *MaasConfigEnableGasManage // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *MaasConfigEnableGasManageIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(MaasConfigEnableGasManage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(MaasConfigEnableGasManage) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *MaasConfigEnableGasManageIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *MaasConfigEnableGasManageIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// MaasConfigEnableGasManage represents a EnableGasManage event raised by the MaasConfig contract. +type MaasConfigEnableGasManage struct { + DoEnable bool + Raw types.Log // Blockchain specific contextual infos +} + +// FilterEnableGasManage is a free log retrieval operation binding the contract event 0x111c6b6046c3758a3f3b689ceb6a3362e939a61fb4ef99d757314899dc46d3a9. +// +// Solidity: event EnableGasManage(bool doEnable) +func (_MaasConfig *MaasConfigFilterer) FilterEnableGasManage(opts *bind.FilterOpts) (*MaasConfigEnableGasManageIterator, error) { + + logs, sub, err := _MaasConfig.contract.FilterLogs(opts, "EnableGasManage") + if err != nil { + return nil, err + } + return &MaasConfigEnableGasManageIterator{contract: _MaasConfig.contract, event: "EnableGasManage", logs: logs, sub: sub}, nil +} + +// WatchEnableGasManage is a free log subscription operation binding the contract event 0x111c6b6046c3758a3f3b689ceb6a3362e939a61fb4ef99d757314899dc46d3a9. +// +// Solidity: event EnableGasManage(bool doEnable) +func (_MaasConfig *MaasConfigFilterer) WatchEnableGasManage(opts *bind.WatchOpts, sink chan<- *MaasConfigEnableGasManage) (event.Subscription, error) { + + logs, sub, err := _MaasConfig.contract.WatchLogs(opts, "EnableGasManage") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(MaasConfigEnableGasManage) + if err := _MaasConfig.contract.UnpackLog(event, "EnableGasManage", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseEnableGasManage is a log parse operation binding the contract event 0x111c6b6046c3758a3f3b689ceb6a3362e939a61fb4ef99d757314899dc46d3a9. +// +// Solidity: event EnableGasManage(bool doEnable) +func (_MaasConfig *MaasConfigFilterer) ParseEnableGasManage(log types.Log) (*MaasConfigEnableGasManage, error) { + event := new(MaasConfigEnableGasManage) + if err := _MaasConfig.contract.UnpackLog(event, "EnableGasManage", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// MaasConfigSetAdminsIterator is returned from FilterSetAdmins and is used to iterate over the raw logs and unpacked data for SetAdmins events raised by the MaasConfig contract. +type MaasConfigSetAdminsIterator struct { + Event *MaasConfigSetAdmins // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *MaasConfigSetAdminsIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(MaasConfigSetAdmins) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(MaasConfigSetAdmins) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *MaasConfigSetAdminsIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *MaasConfigSetAdminsIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// MaasConfigSetAdmins represents a SetAdmins event raised by the MaasConfig contract. +type MaasConfigSetAdmins struct { + Addrs []common.Address + AddOrRemove bool + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSetAdmins is a free log retrieval operation binding the contract event 0x32150139712a20940bb7e316d890207124a84bd89e7a101f92d4280f5bfcfd7b. +// +// Solidity: event SetAdmins(address[] addrs, bool addOrRemove) +func (_MaasConfig *MaasConfigFilterer) FilterSetAdmins(opts *bind.FilterOpts) (*MaasConfigSetAdminsIterator, error) { + + logs, sub, err := _MaasConfig.contract.FilterLogs(opts, "SetAdmins") + if err != nil { + return nil, err + } + return &MaasConfigSetAdminsIterator{contract: _MaasConfig.contract, event: "SetAdmins", logs: logs, sub: sub}, nil +} + +// WatchSetAdmins is a free log subscription operation binding the contract event 0x32150139712a20940bb7e316d890207124a84bd89e7a101f92d4280f5bfcfd7b. +// +// Solidity: event SetAdmins(address[] addrs, bool addOrRemove) +func (_MaasConfig *MaasConfigFilterer) WatchSetAdmins(opts *bind.WatchOpts, sink chan<- *MaasConfigSetAdmins) (event.Subscription, error) { + + logs, sub, err := _MaasConfig.contract.WatchLogs(opts, "SetAdmins") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(MaasConfigSetAdmins) + if err := _MaasConfig.contract.UnpackLog(event, "SetAdmins", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSetAdmins is a log parse operation binding the contract event 0x32150139712a20940bb7e316d890207124a84bd89e7a101f92d4280f5bfcfd7b. +// +// Solidity: event SetAdmins(address[] addrs, bool addOrRemove) +func (_MaasConfig *MaasConfigFilterer) ParseSetAdmins(log types.Log) (*MaasConfigSetAdmins, error) { + event := new(MaasConfigSetAdmins) + if err := _MaasConfig.contract.UnpackLog(event, "SetAdmins", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// MaasConfigSetGasManagerIterator is returned from FilterSetGasManager and is used to iterate over the raw logs and unpacked data for SetGasManager events raised by the MaasConfig contract. +type MaasConfigSetGasManagerIterator struct { + Event *MaasConfigSetGasManager // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *MaasConfigSetGasManagerIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(MaasConfigSetGasManager) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(MaasConfigSetGasManager) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *MaasConfigSetGasManagerIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *MaasConfigSetGasManagerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// MaasConfigSetGasManager represents a SetGasManager event raised by the MaasConfig contract. +type MaasConfigSetGasManager struct { + Addr common.Address + IsManager bool + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSetGasManager is a free log retrieval operation binding the contract event 0xeaac726c152213e277ad13b3d78c4faa36fdec67f6a49d8bc1d581fb014a4c59. +// +// Solidity: event SetGasManager(address indexed addr, bool isManager) +func (_MaasConfig *MaasConfigFilterer) FilterSetGasManager(opts *bind.FilterOpts, addr []common.Address) (*MaasConfigSetGasManagerIterator, error) { + + var addrRule []interface{} + for _, addrItem := range addr { + addrRule = append(addrRule, addrItem) + } + + logs, sub, err := _MaasConfig.contract.FilterLogs(opts, "SetGasManager", addrRule) + if err != nil { + return nil, err + } + return &MaasConfigSetGasManagerIterator{contract: _MaasConfig.contract, event: "SetGasManager", logs: logs, sub: sub}, nil +} + +// WatchSetGasManager is a free log subscription operation binding the contract event 0xeaac726c152213e277ad13b3d78c4faa36fdec67f6a49d8bc1d581fb014a4c59. +// +// Solidity: event SetGasManager(address indexed addr, bool isManager) +func (_MaasConfig *MaasConfigFilterer) WatchSetGasManager(opts *bind.WatchOpts, sink chan<- *MaasConfigSetGasManager, addr []common.Address) (event.Subscription, error) { + + var addrRule []interface{} + for _, addrItem := range addr { + addrRule = append(addrRule, addrItem) + } + + logs, sub, err := _MaasConfig.contract.WatchLogs(opts, "SetGasManager", addrRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(MaasConfigSetGasManager) + if err := _MaasConfig.contract.UnpackLog(event, "SetGasManager", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSetGasManager is a log parse operation binding the contract event 0xeaac726c152213e277ad13b3d78c4faa36fdec67f6a49d8bc1d581fb014a4c59. +// +// Solidity: event SetGasManager(address indexed addr, bool isManager) +func (_MaasConfig *MaasConfigFilterer) ParseSetGasManager(log types.Log) (*MaasConfigSetGasManager, error) { + event := new(MaasConfigSetGasManager) + if err := _MaasConfig.contract.UnpackLog(event, "SetGasManager", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// MaasConfigSetGasUsersIterator is returned from FilterSetGasUsers and is used to iterate over the raw logs and unpacked data for SetGasUsers events raised by the MaasConfig contract. +type MaasConfigSetGasUsersIterator struct { + Event *MaasConfigSetGasUsers // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *MaasConfigSetGasUsersIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(MaasConfigSetGasUsers) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(MaasConfigSetGasUsers) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *MaasConfigSetGasUsersIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *MaasConfigSetGasUsersIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// MaasConfigSetGasUsers represents a SetGasUsers event raised by the MaasConfig contract. +type MaasConfigSetGasUsers struct { + Addrs []common.Address + AddOrRemove bool + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSetGasUsers is a free log retrieval operation binding the contract event 0xae3ffcd4711b2ae3218d54fe92ec1487fcd8b6db2c6033db7651da3c57e7cc45. +// +// Solidity: event SetGasUsers(address[] addrs, bool addOrRemove) +func (_MaasConfig *MaasConfigFilterer) FilterSetGasUsers(opts *bind.FilterOpts) (*MaasConfigSetGasUsersIterator, error) { + + logs, sub, err := _MaasConfig.contract.FilterLogs(opts, "SetGasUsers") + if err != nil { + return nil, err + } + return &MaasConfigSetGasUsersIterator{contract: _MaasConfig.contract, event: "SetGasUsers", logs: logs, sub: sub}, nil +} + +// WatchSetGasUsers is a free log subscription operation binding the contract event 0xae3ffcd4711b2ae3218d54fe92ec1487fcd8b6db2c6033db7651da3c57e7cc45. +// +// Solidity: event SetGasUsers(address[] addrs, bool addOrRemove) +func (_MaasConfig *MaasConfigFilterer) WatchSetGasUsers(opts *bind.WatchOpts, sink chan<- *MaasConfigSetGasUsers) (event.Subscription, error) { + + logs, sub, err := _MaasConfig.contract.WatchLogs(opts, "SetGasUsers") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(MaasConfigSetGasUsers) + if err := _MaasConfig.contract.UnpackLog(event, "SetGasUsers", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSetGasUsers is a log parse operation binding the contract event 0xae3ffcd4711b2ae3218d54fe92ec1487fcd8b6db2c6033db7651da3c57e7cc45. +// +// Solidity: event SetGasUsers(address[] addrs, bool addOrRemove) +func (_MaasConfig *MaasConfigFilterer) ParseSetGasUsers(log types.Log) (*MaasConfigSetGasUsers, error) { + event := new(MaasConfigSetGasUsers) + if err := _MaasConfig.contract.UnpackLog(event, "SetGasUsers", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/contracts/native/go_abi/neo3_state_manager_abi/neo3_state_manager_abi.go b/contracts/native/go_abi/neo3_state_manager_abi/neo3_state_manager_abi.go deleted file mode 100644 index 08c01670..00000000 --- a/contracts/native/go_abi/neo3_state_manager_abi/neo3_state_manager_abi.go +++ /dev/null @@ -1,607 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package neo3_state_manager_abi - -import ( - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -var ( - MethodApproveRegisterStateValidator = "approveRegisterStateValidator" - - MethodApproveRemoveStateValidator = "approveRemoveStateValidator" - - MethodGetCurrentStateValidator = "getCurrentStateValidator" - - MethodName = "name" - - MethodRegisterStateValidator = "registerStateValidator" - - MethodRemoveStateValidator = "removeStateValidator" -) - -// Neo3StateManagerABI is the input ABI used to generate the binding from. -const Neo3StateManagerABI = "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"ID\",\"type\":\"uint64\"}],\"name\":\"evtApproveRegisterStateValidator\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"ID\",\"type\":\"uint64\"}],\"name\":\"evtApproveRemoveStateValidator\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"ID\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"Address\",\"type\":\"address\"}],\"name\":\"approveRegisterStateValidator\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"ID\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"Address\",\"type\":\"address\"}],\"name\":\"approveRemoveStateValidator\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentStateValidator\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"Validator\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"Name\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"StateValidators\",\"type\":\"string[]\"},{\"internalType\":\"address\",\"name\":\"Address\",\"type\":\"address\"}],\"name\":\"registerStateValidator\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"StateValidators\",\"type\":\"string[]\"},{\"internalType\":\"address\",\"name\":\"Address\",\"type\":\"address\"}],\"name\":\"removeStateValidator\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" - -// Neo3StateManagerFuncSigs maps the 4-byte function signature to its string representation. -var Neo3StateManagerFuncSigs = map[string]string{ - "ca1c4d1b": "approveRegisterStateValidator(uint64,address)", - "3473fd55": "approveRemoveStateValidator(uint64,address)", - "770fa9ad": "getCurrentStateValidator()", - "06fdde03": "name()", - "f7531edd": "registerStateValidator(string[],address)", - "d62c2f61": "removeStateValidator(string[],address)", -} - -// Neo3StateManagerBin is the compiled bytecode used for deploying new contracts. -var Neo3StateManagerBin = "0x608060405234801561001057600080fd5b50610321806100206000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c806306fdde03146100675780633473fd551461007f578063770fa9ad14610067578063ca1c4d1b1461007f578063d62c2f61146100a5578063f7531edd146100a5575b600080fd5b6060604051610076919061028a565b60405180910390f35b61009561008d3660046101fb565b600092915050565b6040519015158152602001610076565b61009561008d3660046100cf565b80356001600160a01b03811681146100ca57600080fd5b919050565b60008060408084860312156100e357600080fd5b833567ffffffffffffffff808211156100fb57600080fd5b818601915086601f83011261010f57600080fd5b8135602082821115610123576101236102d5565b8160051b6101328282016102a4565b8381528281019086840183880185018d101561014d57600080fd5b600093505b858410156101dc5780358781111561016957600080fd5b8801603f81018e1361017a57600080fd5b858101358881111561018e5761018e6102d5565b6101a0601f8201601f191688016102a4565b8181528f8c8385010111156101b457600080fd5b818c840189830137600091810188019190915284525060019390930192918401918401610152565b5098506101ed9150508882016100b3565b955050505050509250929050565b6000806040838503121561020e57600080fd5b823567ffffffffffffffff8116811461022657600080fd5b9150610234602084016100b3565b90509250929050565b6000815180845260005b8181101561026357602081850181015186830182015201610247565b81811115610275576000602083870101525b50601f01601f19169290920160200192915050565b60208152600061029d602083018461023d565b9392505050565b604051601f8201601f1916810167ffffffffffffffff811182821017156102cd576102cd6102d5565b604052919050565b634e487b7160e01b600052604160045260246000fdfea26469706673582212202c6e8dc15980e12ec1b93cc0fd811e701b6b90ebd3fd4b8985934601617ca04e64736f6c63430008060033" - -// DeployNeo3StateManager deploys a new Ethereum contract, binding an instance of Neo3StateManager to it. -func DeployNeo3StateManager(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Neo3StateManager, error) { - parsed, err := abi.JSON(strings.NewReader(Neo3StateManagerABI)) - if err != nil { - return common.Address{}, nil, nil, err - } - - address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(Neo3StateManagerBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Neo3StateManager{Neo3StateManagerCaller: Neo3StateManagerCaller{contract: contract}, Neo3StateManagerTransactor: Neo3StateManagerTransactor{contract: contract}, Neo3StateManagerFilterer: Neo3StateManagerFilterer{contract: contract}}, nil -} - -// Neo3StateManager is an auto generated Go binding around an Ethereum contract. -type Neo3StateManager struct { - Neo3StateManagerCaller // Read-only binding to the contract - Neo3StateManagerTransactor // Write-only binding to the contract - Neo3StateManagerFilterer // Log filterer for contract events -} - -// Neo3StateManagerCaller is an auto generated read-only Go binding around an Ethereum contract. -type Neo3StateManagerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// Neo3StateManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type Neo3StateManagerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// Neo3StateManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type Neo3StateManagerFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// Neo3StateManagerSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type Neo3StateManagerSession struct { - Contract *Neo3StateManager // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// Neo3StateManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type Neo3StateManagerCallerSession struct { - Contract *Neo3StateManagerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// Neo3StateManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type Neo3StateManagerTransactorSession struct { - Contract *Neo3StateManagerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// Neo3StateManagerRaw is an auto generated low-level Go binding around an Ethereum contract. -type Neo3StateManagerRaw struct { - Contract *Neo3StateManager // Generic contract binding to access the raw methods on -} - -// Neo3StateManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type Neo3StateManagerCallerRaw struct { - Contract *Neo3StateManagerCaller // Generic read-only contract binding to access the raw methods on -} - -// Neo3StateManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type Neo3StateManagerTransactorRaw struct { - Contract *Neo3StateManagerTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewNeo3StateManager creates a new instance of Neo3StateManager, bound to a specific deployed contract. -func NewNeo3StateManager(address common.Address, backend bind.ContractBackend) (*Neo3StateManager, error) { - contract, err := bindNeo3StateManager(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Neo3StateManager{Neo3StateManagerCaller: Neo3StateManagerCaller{contract: contract}, Neo3StateManagerTransactor: Neo3StateManagerTransactor{contract: contract}, Neo3StateManagerFilterer: Neo3StateManagerFilterer{contract: contract}}, nil -} - -// NewNeo3StateManagerCaller creates a new read-only instance of Neo3StateManager, bound to a specific deployed contract. -func NewNeo3StateManagerCaller(address common.Address, caller bind.ContractCaller) (*Neo3StateManagerCaller, error) { - contract, err := bindNeo3StateManager(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &Neo3StateManagerCaller{contract: contract}, nil -} - -// NewNeo3StateManagerTransactor creates a new write-only instance of Neo3StateManager, bound to a specific deployed contract. -func NewNeo3StateManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*Neo3StateManagerTransactor, error) { - contract, err := bindNeo3StateManager(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &Neo3StateManagerTransactor{contract: contract}, nil -} - -// NewNeo3StateManagerFilterer creates a new log filterer instance of Neo3StateManager, bound to a specific deployed contract. -func NewNeo3StateManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*Neo3StateManagerFilterer, error) { - contract, err := bindNeo3StateManager(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &Neo3StateManagerFilterer{contract: contract}, nil -} - -// bindNeo3StateManager binds a generic wrapper to an already deployed contract. -func bindNeo3StateManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(Neo3StateManagerABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Neo3StateManager *Neo3StateManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Neo3StateManager.Contract.Neo3StateManagerCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Neo3StateManager *Neo3StateManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Neo3StateManager.Contract.Neo3StateManagerTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Neo3StateManager *Neo3StateManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Neo3StateManager.Contract.Neo3StateManagerTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Neo3StateManager *Neo3StateManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Neo3StateManager.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Neo3StateManager *Neo3StateManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Neo3StateManager.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Neo3StateManager *Neo3StateManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Neo3StateManager.Contract.contract.Transact(opts, method, params...) -} - -// ApproveRegisterStateValidator is a paid mutator transaction binding the contract method 0xca1c4d1b. -// -// Solidity: function approveRegisterStateValidator(uint64 ID, address Address) returns(bool success) -func (_Neo3StateManager *Neo3StateManagerTransactor) ApproveRegisterStateValidator(opts *bind.TransactOpts, ID uint64, Address common.Address) (*types.Transaction, error) { - return _Neo3StateManager.contract.Transact(opts, "approveRegisterStateValidator", ID, Address) -} - -// ApproveRegisterStateValidator is a paid mutator transaction binding the contract method 0xca1c4d1b. -// -// Solidity: function approveRegisterStateValidator(uint64 ID, address Address) returns(bool success) -func (_Neo3StateManager *Neo3StateManagerSession) ApproveRegisterStateValidator(ID uint64, Address common.Address) (*types.Transaction, error) { - return _Neo3StateManager.Contract.ApproveRegisterStateValidator(&_Neo3StateManager.TransactOpts, ID, Address) -} - -// ApproveRegisterStateValidator is a paid mutator transaction binding the contract method 0xca1c4d1b. -// -// Solidity: function approveRegisterStateValidator(uint64 ID, address Address) returns(bool success) -func (_Neo3StateManager *Neo3StateManagerTransactorSession) ApproveRegisterStateValidator(ID uint64, Address common.Address) (*types.Transaction, error) { - return _Neo3StateManager.Contract.ApproveRegisterStateValidator(&_Neo3StateManager.TransactOpts, ID, Address) -} - -// ApproveRemoveStateValidator is a paid mutator transaction binding the contract method 0x3473fd55. -// -// Solidity: function approveRemoveStateValidator(uint64 ID, address Address) returns(bool success) -func (_Neo3StateManager *Neo3StateManagerTransactor) ApproveRemoveStateValidator(opts *bind.TransactOpts, ID uint64, Address common.Address) (*types.Transaction, error) { - return _Neo3StateManager.contract.Transact(opts, "approveRemoveStateValidator", ID, Address) -} - -// ApproveRemoveStateValidator is a paid mutator transaction binding the contract method 0x3473fd55. -// -// Solidity: function approveRemoveStateValidator(uint64 ID, address Address) returns(bool success) -func (_Neo3StateManager *Neo3StateManagerSession) ApproveRemoveStateValidator(ID uint64, Address common.Address) (*types.Transaction, error) { - return _Neo3StateManager.Contract.ApproveRemoveStateValidator(&_Neo3StateManager.TransactOpts, ID, Address) -} - -// ApproveRemoveStateValidator is a paid mutator transaction binding the contract method 0x3473fd55. -// -// Solidity: function approveRemoveStateValidator(uint64 ID, address Address) returns(bool success) -func (_Neo3StateManager *Neo3StateManagerTransactorSession) ApproveRemoveStateValidator(ID uint64, Address common.Address) (*types.Transaction, error) { - return _Neo3StateManager.Contract.ApproveRemoveStateValidator(&_Neo3StateManager.TransactOpts, ID, Address) -} - -// GetCurrentStateValidator is a paid mutator transaction binding the contract method 0x770fa9ad. -// -// Solidity: function getCurrentStateValidator() returns(bytes Validator) -func (_Neo3StateManager *Neo3StateManagerTransactor) GetCurrentStateValidator(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Neo3StateManager.contract.Transact(opts, "getCurrentStateValidator") -} - -// GetCurrentStateValidator is a paid mutator transaction binding the contract method 0x770fa9ad. -// -// Solidity: function getCurrentStateValidator() returns(bytes Validator) -func (_Neo3StateManager *Neo3StateManagerSession) GetCurrentStateValidator() (*types.Transaction, error) { - return _Neo3StateManager.Contract.GetCurrentStateValidator(&_Neo3StateManager.TransactOpts) -} - -// GetCurrentStateValidator is a paid mutator transaction binding the contract method 0x770fa9ad. -// -// Solidity: function getCurrentStateValidator() returns(bytes Validator) -func (_Neo3StateManager *Neo3StateManagerTransactorSession) GetCurrentStateValidator() (*types.Transaction, error) { - return _Neo3StateManager.Contract.GetCurrentStateValidator(&_Neo3StateManager.TransactOpts) -} - -// Name is a paid mutator transaction binding the contract method 0x06fdde03. -// -// Solidity: function name() returns(string Name) -func (_Neo3StateManager *Neo3StateManagerTransactor) Name(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Neo3StateManager.contract.Transact(opts, "name") -} - -// Name is a paid mutator transaction binding the contract method 0x06fdde03. -// -// Solidity: function name() returns(string Name) -func (_Neo3StateManager *Neo3StateManagerSession) Name() (*types.Transaction, error) { - return _Neo3StateManager.Contract.Name(&_Neo3StateManager.TransactOpts) -} - -// Name is a paid mutator transaction binding the contract method 0x06fdde03. -// -// Solidity: function name() returns(string Name) -func (_Neo3StateManager *Neo3StateManagerTransactorSession) Name() (*types.Transaction, error) { - return _Neo3StateManager.Contract.Name(&_Neo3StateManager.TransactOpts) -} - -// RegisterStateValidator is a paid mutator transaction binding the contract method 0xf7531edd. -// -// Solidity: function registerStateValidator(string[] StateValidators, address Address) returns(bool success) -func (_Neo3StateManager *Neo3StateManagerTransactor) RegisterStateValidator(opts *bind.TransactOpts, StateValidators []string, Address common.Address) (*types.Transaction, error) { - return _Neo3StateManager.contract.Transact(opts, "registerStateValidator", StateValidators, Address) -} - -// RegisterStateValidator is a paid mutator transaction binding the contract method 0xf7531edd. -// -// Solidity: function registerStateValidator(string[] StateValidators, address Address) returns(bool success) -func (_Neo3StateManager *Neo3StateManagerSession) RegisterStateValidator(StateValidators []string, Address common.Address) (*types.Transaction, error) { - return _Neo3StateManager.Contract.RegisterStateValidator(&_Neo3StateManager.TransactOpts, StateValidators, Address) -} - -// RegisterStateValidator is a paid mutator transaction binding the contract method 0xf7531edd. -// -// Solidity: function registerStateValidator(string[] StateValidators, address Address) returns(bool success) -func (_Neo3StateManager *Neo3StateManagerTransactorSession) RegisterStateValidator(StateValidators []string, Address common.Address) (*types.Transaction, error) { - return _Neo3StateManager.Contract.RegisterStateValidator(&_Neo3StateManager.TransactOpts, StateValidators, Address) -} - -// RemoveStateValidator is a paid mutator transaction binding the contract method 0xd62c2f61. -// -// Solidity: function removeStateValidator(string[] StateValidators, address Address) returns(bool success) -func (_Neo3StateManager *Neo3StateManagerTransactor) RemoveStateValidator(opts *bind.TransactOpts, StateValidators []string, Address common.Address) (*types.Transaction, error) { - return _Neo3StateManager.contract.Transact(opts, "removeStateValidator", StateValidators, Address) -} - -// RemoveStateValidator is a paid mutator transaction binding the contract method 0xd62c2f61. -// -// Solidity: function removeStateValidator(string[] StateValidators, address Address) returns(bool success) -func (_Neo3StateManager *Neo3StateManagerSession) RemoveStateValidator(StateValidators []string, Address common.Address) (*types.Transaction, error) { - return _Neo3StateManager.Contract.RemoveStateValidator(&_Neo3StateManager.TransactOpts, StateValidators, Address) -} - -// RemoveStateValidator is a paid mutator transaction binding the contract method 0xd62c2f61. -// -// Solidity: function removeStateValidator(string[] StateValidators, address Address) returns(bool success) -func (_Neo3StateManager *Neo3StateManagerTransactorSession) RemoveStateValidator(StateValidators []string, Address common.Address) (*types.Transaction, error) { - return _Neo3StateManager.Contract.RemoveStateValidator(&_Neo3StateManager.TransactOpts, StateValidators, Address) -} - -// Neo3StateManagerApproveRegisterStateValidatorIterator is returned from FilterApproveRegisterStateValidator and is used to iterate over the raw logs and unpacked data for ApproveRegisterStateValidator events raised by the Neo3StateManager contract. -type Neo3StateManagerApproveRegisterStateValidatorIterator struct { - Event *Neo3StateManagerApproveRegisterStateValidator // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *Neo3StateManagerApproveRegisterStateValidatorIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(Neo3StateManagerApproveRegisterStateValidator) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(Neo3StateManagerApproveRegisterStateValidator) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *Neo3StateManagerApproveRegisterStateValidatorIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *Neo3StateManagerApproveRegisterStateValidatorIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// Neo3StateManagerApproveRegisterStateValidator represents a ApproveRegisterStateValidator event raised by the Neo3StateManager contract. -type Neo3StateManagerApproveRegisterStateValidator struct { - ID uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterApproveRegisterStateValidator is a free log retrieval operation binding the contract event 0xa2d1b53f6d5ea7964c14d81acde072ef679b771780c18a93206cd3319c6621d6. -// -// Solidity: event evtApproveRegisterStateValidator(uint64 ID) -func (_Neo3StateManager *Neo3StateManagerFilterer) FilterApproveRegisterStateValidator(opts *bind.FilterOpts) (*Neo3StateManagerApproveRegisterStateValidatorIterator, error) { - - logs, sub, err := _Neo3StateManager.contract.FilterLogs(opts, "evtApproveRegisterStateValidator") - if err != nil { - return nil, err - } - return &Neo3StateManagerApproveRegisterStateValidatorIterator{contract: _Neo3StateManager.contract, event: "evtApproveRegisterStateValidator", logs: logs, sub: sub}, nil -} - -// WatchApproveRegisterStateValidator is a free log subscription operation binding the contract event 0xa2d1b53f6d5ea7964c14d81acde072ef679b771780c18a93206cd3319c6621d6. -// -// Solidity: event evtApproveRegisterStateValidator(uint64 ID) -func (_Neo3StateManager *Neo3StateManagerFilterer) WatchApproveRegisterStateValidator(opts *bind.WatchOpts, sink chan<- *Neo3StateManagerApproveRegisterStateValidator) (event.Subscription, error) { - - logs, sub, err := _Neo3StateManager.contract.WatchLogs(opts, "evtApproveRegisterStateValidator") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(Neo3StateManagerApproveRegisterStateValidator) - if err := _Neo3StateManager.contract.UnpackLog(event, "evtApproveRegisterStateValidator", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseApproveRegisterStateValidator is a log parse operation binding the contract event 0xa2d1b53f6d5ea7964c14d81acde072ef679b771780c18a93206cd3319c6621d6. -// -// Solidity: event evtApproveRegisterStateValidator(uint64 ID) -func (_Neo3StateManager *Neo3StateManagerFilterer) ParseApproveRegisterStateValidator(log types.Log) (*Neo3StateManagerApproveRegisterStateValidator, error) { - event := new(Neo3StateManagerApproveRegisterStateValidator) - if err := _Neo3StateManager.contract.UnpackLog(event, "evtApproveRegisterStateValidator", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// Neo3StateManagerApproveRemoveStateValidatorIterator is returned from FilterApproveRemoveStateValidator and is used to iterate over the raw logs and unpacked data for ApproveRemoveStateValidator events raised by the Neo3StateManager contract. -type Neo3StateManagerApproveRemoveStateValidatorIterator struct { - Event *Neo3StateManagerApproveRemoveStateValidator // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *Neo3StateManagerApproveRemoveStateValidatorIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(Neo3StateManagerApproveRemoveStateValidator) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(Neo3StateManagerApproveRemoveStateValidator) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *Neo3StateManagerApproveRemoveStateValidatorIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *Neo3StateManagerApproveRemoveStateValidatorIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// Neo3StateManagerApproveRemoveStateValidator represents a ApproveRemoveStateValidator event raised by the Neo3StateManager contract. -type Neo3StateManagerApproveRemoveStateValidator struct { - ID uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterApproveRemoveStateValidator is a free log retrieval operation binding the contract event 0x32050489af2e3d6571e4c66ba0ca36ccf2b8feed7a7059d23aab90998d263604. -// -// Solidity: event evtApproveRemoveStateValidator(uint64 ID) -func (_Neo3StateManager *Neo3StateManagerFilterer) FilterApproveRemoveStateValidator(opts *bind.FilterOpts) (*Neo3StateManagerApproveRemoveStateValidatorIterator, error) { - - logs, sub, err := _Neo3StateManager.contract.FilterLogs(opts, "evtApproveRemoveStateValidator") - if err != nil { - return nil, err - } - return &Neo3StateManagerApproveRemoveStateValidatorIterator{contract: _Neo3StateManager.contract, event: "evtApproveRemoveStateValidator", logs: logs, sub: sub}, nil -} - -// WatchApproveRemoveStateValidator is a free log subscription operation binding the contract event 0x32050489af2e3d6571e4c66ba0ca36ccf2b8feed7a7059d23aab90998d263604. -// -// Solidity: event evtApproveRemoveStateValidator(uint64 ID) -func (_Neo3StateManager *Neo3StateManagerFilterer) WatchApproveRemoveStateValidator(opts *bind.WatchOpts, sink chan<- *Neo3StateManagerApproveRemoveStateValidator) (event.Subscription, error) { - - logs, sub, err := _Neo3StateManager.contract.WatchLogs(opts, "evtApproveRemoveStateValidator") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(Neo3StateManagerApproveRemoveStateValidator) - if err := _Neo3StateManager.contract.UnpackLog(event, "evtApproveRemoveStateValidator", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseApproveRemoveStateValidator is a log parse operation binding the contract event 0x32050489af2e3d6571e4c66ba0ca36ccf2b8feed7a7059d23aab90998d263604. -// -// Solidity: event evtApproveRemoveStateValidator(uint64 ID) -func (_Neo3StateManager *Neo3StateManagerFilterer) ParseApproveRemoveStateValidator(log types.Log) (*Neo3StateManagerApproveRemoveStateValidator, error) { - event := new(Neo3StateManagerApproveRemoveStateValidator) - if err := _Neo3StateManager.contract.UnpackLog(event, "evtApproveRemoveStateValidator", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} diff --git a/contracts/native/go_abi/node_manager_abi/node_manager_abi.go b/contracts/native/go_abi/node_manager_abi/node_manager_abi.go index 8eef4057..5cb11a05 100644 --- a/contracts/native/go_abi/node_manager_abi/node_manager_abi.go +++ b/contracts/native/go_abi/node_manager_abi/node_manager_abi.go @@ -35,8 +35,14 @@ var ( MethodGetChangingEpoch = "getChangingEpoch" + MethodGetChangingEpochJson = "getChangingEpochJson" + + MethodGetCurrentEpochJson = "getCurrentEpochJson" + MethodGetEpochByID = "getEpochByID" + MethodGetEpochListJson = "getEpochListJson" + MethodName = "name" MethodProof = "proof" @@ -51,18 +57,7 @@ var ( ) // INodeManagerABI is the input ABI used to generate the binding from. -const INodeManagerABI = "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"method\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"size\",\"type\":\"uint64\"}],\"name\":\"ConsensusSigned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"epoch\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"nextEpoch\",\"type\":\"bytes\"}],\"name\":\"EpochChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"epoch\",\"type\":\"bytes\"}],\"name\":\"Proposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"epochID\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"epochHash\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"votedNumber\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"groupSize\",\"type\":\"uint64\"}],\"name\":\"Voted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"epoch\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChangingEpoch\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"epochID\",\"type\":\"uint64\"}],\"name\":\"getEpochByID\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"epochID\",\"type\":\"uint64\"}],\"name\":\"proof\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"startHeight\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"peers\",\"type\":\"bytes\"}],\"name\":\"propose\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"epochID\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"epochHash\",\"type\":\"bytes\"}],\"name\":\"vote\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" - -// INodeManagerFuncSigs maps the 4-byte function signature to its string representation. -var INodeManagerFuncSigs = map[string]string{ - "900cf0cf": "epoch()", - "76b85cd9": "getChangingEpoch()", - "b9dda35e": "getEpochByID(uint64)", - "06fdde03": "name()", - "418f9899": "proof(uint64)", - "bcc12328": "propose(uint64,bytes)", - "08c16dbb": "vote(uint64,bytes)", -} +const INodeManagerABI = "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"method\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"size\",\"type\":\"uint64\"}],\"name\":\"ConsensusSigned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"epoch\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"nextEpoch\",\"type\":\"bytes\"}],\"name\":\"EpochChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"epoch\",\"type\":\"bytes\"}],\"name\":\"Proposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"epochID\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"epochHash\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"votedNumber\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"groupSize\",\"type\":\"uint64\"}],\"name\":\"Voted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"epoch\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChangingEpoch\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChangingEpochJson\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentEpochJson\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"epochID\",\"type\":\"uint64\"}],\"name\":\"getEpochByID\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"epochID\",\"type\":\"uint64\"}],\"name\":\"getEpochListJson\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"epochID\",\"type\":\"uint64\"}],\"name\":\"proof\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"startHeight\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"peers\",\"type\":\"bytes\"}],\"name\":\"propose\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"epochID\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"epochHash\",\"type\":\"bytes\"}],\"name\":\"vote\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" // INodeManager is an auto generated Go binding around an Ethereum contract. type INodeManager struct { @@ -268,6 +263,68 @@ func (_INodeManager *INodeManagerCallerSession) GetChangingEpoch() ([]byte, erro return _INodeManager.Contract.GetChangingEpoch(&_INodeManager.CallOpts) } +// GetChangingEpochJson is a free data retrieval call binding the contract method 0x47167d41. +// +// Solidity: function getChangingEpochJson() view returns(string) +func (_INodeManager *INodeManagerCaller) GetChangingEpochJson(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _INodeManager.contract.Call(opts, &out, "getChangingEpochJson") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// GetChangingEpochJson is a free data retrieval call binding the contract method 0x47167d41. +// +// Solidity: function getChangingEpochJson() view returns(string) +func (_INodeManager *INodeManagerSession) GetChangingEpochJson() (string, error) { + return _INodeManager.Contract.GetChangingEpochJson(&_INodeManager.CallOpts) +} + +// GetChangingEpochJson is a free data retrieval call binding the contract method 0x47167d41. +// +// Solidity: function getChangingEpochJson() view returns(string) +func (_INodeManager *INodeManagerCallerSession) GetChangingEpochJson() (string, error) { + return _INodeManager.Contract.GetChangingEpochJson(&_INodeManager.CallOpts) +} + +// GetCurrentEpochJson is a free data retrieval call binding the contract method 0x7d3d75d7. +// +// Solidity: function getCurrentEpochJson() view returns(string) +func (_INodeManager *INodeManagerCaller) GetCurrentEpochJson(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _INodeManager.contract.Call(opts, &out, "getCurrentEpochJson") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// GetCurrentEpochJson is a free data retrieval call binding the contract method 0x7d3d75d7. +// +// Solidity: function getCurrentEpochJson() view returns(string) +func (_INodeManager *INodeManagerSession) GetCurrentEpochJson() (string, error) { + return _INodeManager.Contract.GetCurrentEpochJson(&_INodeManager.CallOpts) +} + +// GetCurrentEpochJson is a free data retrieval call binding the contract method 0x7d3d75d7. +// +// Solidity: function getCurrentEpochJson() view returns(string) +func (_INodeManager *INodeManagerCallerSession) GetCurrentEpochJson() (string, error) { + return _INodeManager.Contract.GetCurrentEpochJson(&_INodeManager.CallOpts) +} + // GetEpochByID is a free data retrieval call binding the contract method 0xb9dda35e. // // Solidity: function getEpochByID(uint64 epochID) view returns(bytes) @@ -299,6 +356,37 @@ func (_INodeManager *INodeManagerCallerSession) GetEpochByID(epochID uint64) ([] return _INodeManager.Contract.GetEpochByID(&_INodeManager.CallOpts, epochID) } +// GetEpochListJson is a free data retrieval call binding the contract method 0x73d9f136. +// +// Solidity: function getEpochListJson(uint64 epochID) view returns(string) +func (_INodeManager *INodeManagerCaller) GetEpochListJson(opts *bind.CallOpts, epochID uint64) (string, error) { + var out []interface{} + err := _INodeManager.contract.Call(opts, &out, "getEpochListJson", epochID) + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// GetEpochListJson is a free data retrieval call binding the contract method 0x73d9f136. +// +// Solidity: function getEpochListJson(uint64 epochID) view returns(string) +func (_INodeManager *INodeManagerSession) GetEpochListJson(epochID uint64) (string, error) { + return _INodeManager.Contract.GetEpochListJson(&_INodeManager.CallOpts, epochID) +} + +// GetEpochListJson is a free data retrieval call binding the contract method 0x73d9f136. +// +// Solidity: function getEpochListJson(uint64 epochID) view returns(string) +func (_INodeManager *INodeManagerCallerSession) GetEpochListJson(epochID uint64) (string, error) { + return _INodeManager.Contract.GetEpochListJson(&_INodeManager.CallOpts, epochID) +} + // Name is a free data retrieval call binding the contract method 0x06fdde03. // // Solidity: function name() view returns(string) diff --git a/contracts/native/go_abi/relayer_manager_abi/relayer_manager_abi.go b/contracts/native/go_abi/relayer_manager_abi/relayer_manager_abi.go deleted file mode 100644 index c9cf9b96..00000000 --- a/contracts/native/go_abi/relayer_manager_abi/relayer_manager_abi.go +++ /dev/null @@ -1,851 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package relayer_manager_abi - -import ( - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -var ( - MethodApproveRegisterRelayer = "approveRegisterRelayer" - - MethodApproveRemoveRelayer = "approveRemoveRelayer" - - MethodName = "name" - - MethodRegisterRelayer = "registerRelayer" - - MethodRemoveRelayer = "removeRelayer" -) - -// RelayerManagerABI is the input ABI used to generate the binding from. -const RelayerManagerABI = "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"ID\",\"type\":\"uint64\"}],\"name\":\"evtApproveRegisterRelayer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"ID\",\"type\":\"uint64\"}],\"name\":\"evtApproveRemoveRelayer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"applyID\",\"type\":\"uint64\"}],\"name\":\"evtRegisterRelayer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"removeID\",\"type\":\"uint64\"}],\"name\":\"evtRemoveRelayer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"ID\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"Address\",\"type\":\"address\"}],\"name\":\"approveRegisterRelayer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"ID\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"Address\",\"type\":\"address\"}],\"name\":\"approveRemoveRelayer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"Name\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"AddressList\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"Address\",\"type\":\"address\"}],\"name\":\"registerRelayer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"AddressList\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"Address\",\"type\":\"address\"}],\"name\":\"removeRelayer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" - -// RelayerManagerFuncSigs maps the 4-byte function signature to its string representation. -var RelayerManagerFuncSigs = map[string]string{ - "07b8ca31": "approveRegisterRelayer(uint64,address)", - "2b1775dd": "approveRemoveRelayer(uint64,address)", - "06fdde03": "name()", - "d99802fe": "registerRelayer(address[],address)", - "0cffb52a": "removeRelayer(address[],address)", -} - -// RelayerManagerBin is the compiled bytecode used for deploying new contracts. -var RelayerManagerBin = "0x608060405234801561001057600080fd5b50610285806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806306fdde031461005c57806307b8ca31146100745780630cffb52a1461009a5780632b1775dd14610074578063d99802fe1461009a575b600080fd5b606060405161006b91906101e4565b60405180910390f35b61008a6100823660046101a2565b600092915050565b604051901515815260200161006b565b61008a6100823660046100c4565b80356001600160a01b03811681146100bf57600080fd5b919050565b600080604083850312156100d757600080fd5b823567ffffffffffffffff808211156100ef57600080fd5b818501915085601f83011261010357600080fd5b813560208282111561011757610117610239565b8160051b604051601f19603f8301168101818110868211171561013c5761013c610239565b604052838152828101945085830182870184018b101561015b57600080fd5b600096505b8487101561018557610171816100a8565b865260019690960195948301948301610160565b50965061019590508782016100a8565b9450505050509250929050565b600080604083850312156101b557600080fd5b823567ffffffffffffffff811681146101cd57600080fd5b91506101db602084016100a8565b90509250929050565b600060208083528351808285015260005b81811015610211578581018301518582016040015282016101f5565b81811115610223576000604083870101525b50601f01601f1916929092016040019392505050565b634e487b7160e01b600052604160045260246000fdfea2646970667358221220f8f573c9e4225c35f16c8b207ef9fe5a3541fabe38f3516118d08dbb43f7f78264736f6c63430008060033" - -// DeployRelayerManager deploys a new Ethereum contract, binding an instance of RelayerManager to it. -func DeployRelayerManager(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *RelayerManager, error) { - parsed, err := abi.JSON(strings.NewReader(RelayerManagerABI)) - if err != nil { - return common.Address{}, nil, nil, err - } - - address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(RelayerManagerBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &RelayerManager{RelayerManagerCaller: RelayerManagerCaller{contract: contract}, RelayerManagerTransactor: RelayerManagerTransactor{contract: contract}, RelayerManagerFilterer: RelayerManagerFilterer{contract: contract}}, nil -} - -// RelayerManager is an auto generated Go binding around an Ethereum contract. -type RelayerManager struct { - RelayerManagerCaller // Read-only binding to the contract - RelayerManagerTransactor // Write-only binding to the contract - RelayerManagerFilterer // Log filterer for contract events -} - -// RelayerManagerCaller is an auto generated read-only Go binding around an Ethereum contract. -type RelayerManagerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// RelayerManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type RelayerManagerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// RelayerManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type RelayerManagerFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// RelayerManagerSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type RelayerManagerSession struct { - Contract *RelayerManager // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// RelayerManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type RelayerManagerCallerSession struct { - Contract *RelayerManagerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// RelayerManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type RelayerManagerTransactorSession struct { - Contract *RelayerManagerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// RelayerManagerRaw is an auto generated low-level Go binding around an Ethereum contract. -type RelayerManagerRaw struct { - Contract *RelayerManager // Generic contract binding to access the raw methods on -} - -// RelayerManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type RelayerManagerCallerRaw struct { - Contract *RelayerManagerCaller // Generic read-only contract binding to access the raw methods on -} - -// RelayerManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type RelayerManagerTransactorRaw struct { - Contract *RelayerManagerTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewRelayerManager creates a new instance of RelayerManager, bound to a specific deployed contract. -func NewRelayerManager(address common.Address, backend bind.ContractBackend) (*RelayerManager, error) { - contract, err := bindRelayerManager(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &RelayerManager{RelayerManagerCaller: RelayerManagerCaller{contract: contract}, RelayerManagerTransactor: RelayerManagerTransactor{contract: contract}, RelayerManagerFilterer: RelayerManagerFilterer{contract: contract}}, nil -} - -// NewRelayerManagerCaller creates a new read-only instance of RelayerManager, bound to a specific deployed contract. -func NewRelayerManagerCaller(address common.Address, caller bind.ContractCaller) (*RelayerManagerCaller, error) { - contract, err := bindRelayerManager(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &RelayerManagerCaller{contract: contract}, nil -} - -// NewRelayerManagerTransactor creates a new write-only instance of RelayerManager, bound to a specific deployed contract. -func NewRelayerManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*RelayerManagerTransactor, error) { - contract, err := bindRelayerManager(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &RelayerManagerTransactor{contract: contract}, nil -} - -// NewRelayerManagerFilterer creates a new log filterer instance of RelayerManager, bound to a specific deployed contract. -func NewRelayerManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*RelayerManagerFilterer, error) { - contract, err := bindRelayerManager(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &RelayerManagerFilterer{contract: contract}, nil -} - -// bindRelayerManager binds a generic wrapper to an already deployed contract. -func bindRelayerManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(RelayerManagerABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_RelayerManager *RelayerManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _RelayerManager.Contract.RelayerManagerCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_RelayerManager *RelayerManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _RelayerManager.Contract.RelayerManagerTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_RelayerManager *RelayerManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _RelayerManager.Contract.RelayerManagerTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_RelayerManager *RelayerManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _RelayerManager.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_RelayerManager *RelayerManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _RelayerManager.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_RelayerManager *RelayerManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _RelayerManager.Contract.contract.Transact(opts, method, params...) -} - -// ApproveRegisterRelayer is a paid mutator transaction binding the contract method 0x07b8ca31. -// -// Solidity: function approveRegisterRelayer(uint64 ID, address Address) returns(bool success) -func (_RelayerManager *RelayerManagerTransactor) ApproveRegisterRelayer(opts *bind.TransactOpts, ID uint64, Address common.Address) (*types.Transaction, error) { - return _RelayerManager.contract.Transact(opts, "approveRegisterRelayer", ID, Address) -} - -// ApproveRegisterRelayer is a paid mutator transaction binding the contract method 0x07b8ca31. -// -// Solidity: function approveRegisterRelayer(uint64 ID, address Address) returns(bool success) -func (_RelayerManager *RelayerManagerSession) ApproveRegisterRelayer(ID uint64, Address common.Address) (*types.Transaction, error) { - return _RelayerManager.Contract.ApproveRegisterRelayer(&_RelayerManager.TransactOpts, ID, Address) -} - -// ApproveRegisterRelayer is a paid mutator transaction binding the contract method 0x07b8ca31. -// -// Solidity: function approveRegisterRelayer(uint64 ID, address Address) returns(bool success) -func (_RelayerManager *RelayerManagerTransactorSession) ApproveRegisterRelayer(ID uint64, Address common.Address) (*types.Transaction, error) { - return _RelayerManager.Contract.ApproveRegisterRelayer(&_RelayerManager.TransactOpts, ID, Address) -} - -// ApproveRemoveRelayer is a paid mutator transaction binding the contract method 0x2b1775dd. -// -// Solidity: function approveRemoveRelayer(uint64 ID, address Address) returns(bool success) -func (_RelayerManager *RelayerManagerTransactor) ApproveRemoveRelayer(opts *bind.TransactOpts, ID uint64, Address common.Address) (*types.Transaction, error) { - return _RelayerManager.contract.Transact(opts, "approveRemoveRelayer", ID, Address) -} - -// ApproveRemoveRelayer is a paid mutator transaction binding the contract method 0x2b1775dd. -// -// Solidity: function approveRemoveRelayer(uint64 ID, address Address) returns(bool success) -func (_RelayerManager *RelayerManagerSession) ApproveRemoveRelayer(ID uint64, Address common.Address) (*types.Transaction, error) { - return _RelayerManager.Contract.ApproveRemoveRelayer(&_RelayerManager.TransactOpts, ID, Address) -} - -// ApproveRemoveRelayer is a paid mutator transaction binding the contract method 0x2b1775dd. -// -// Solidity: function approveRemoveRelayer(uint64 ID, address Address) returns(bool success) -func (_RelayerManager *RelayerManagerTransactorSession) ApproveRemoveRelayer(ID uint64, Address common.Address) (*types.Transaction, error) { - return _RelayerManager.Contract.ApproveRemoveRelayer(&_RelayerManager.TransactOpts, ID, Address) -} - -// Name is a paid mutator transaction binding the contract method 0x06fdde03. -// -// Solidity: function name() returns(string Name) -func (_RelayerManager *RelayerManagerTransactor) Name(opts *bind.TransactOpts) (*types.Transaction, error) { - return _RelayerManager.contract.Transact(opts, "name") -} - -// Name is a paid mutator transaction binding the contract method 0x06fdde03. -// -// Solidity: function name() returns(string Name) -func (_RelayerManager *RelayerManagerSession) Name() (*types.Transaction, error) { - return _RelayerManager.Contract.Name(&_RelayerManager.TransactOpts) -} - -// Name is a paid mutator transaction binding the contract method 0x06fdde03. -// -// Solidity: function name() returns(string Name) -func (_RelayerManager *RelayerManagerTransactorSession) Name() (*types.Transaction, error) { - return _RelayerManager.Contract.Name(&_RelayerManager.TransactOpts) -} - -// RegisterRelayer is a paid mutator transaction binding the contract method 0xd99802fe. -// -// Solidity: function registerRelayer(address[] AddressList, address Address) returns(bool success) -func (_RelayerManager *RelayerManagerTransactor) RegisterRelayer(opts *bind.TransactOpts, AddressList []common.Address, Address common.Address) (*types.Transaction, error) { - return _RelayerManager.contract.Transact(opts, "registerRelayer", AddressList, Address) -} - -// RegisterRelayer is a paid mutator transaction binding the contract method 0xd99802fe. -// -// Solidity: function registerRelayer(address[] AddressList, address Address) returns(bool success) -func (_RelayerManager *RelayerManagerSession) RegisterRelayer(AddressList []common.Address, Address common.Address) (*types.Transaction, error) { - return _RelayerManager.Contract.RegisterRelayer(&_RelayerManager.TransactOpts, AddressList, Address) -} - -// RegisterRelayer is a paid mutator transaction binding the contract method 0xd99802fe. -// -// Solidity: function registerRelayer(address[] AddressList, address Address) returns(bool success) -func (_RelayerManager *RelayerManagerTransactorSession) RegisterRelayer(AddressList []common.Address, Address common.Address) (*types.Transaction, error) { - return _RelayerManager.Contract.RegisterRelayer(&_RelayerManager.TransactOpts, AddressList, Address) -} - -// RemoveRelayer is a paid mutator transaction binding the contract method 0x0cffb52a. -// -// Solidity: function removeRelayer(address[] AddressList, address Address) returns(bool success) -func (_RelayerManager *RelayerManagerTransactor) RemoveRelayer(opts *bind.TransactOpts, AddressList []common.Address, Address common.Address) (*types.Transaction, error) { - return _RelayerManager.contract.Transact(opts, "removeRelayer", AddressList, Address) -} - -// RemoveRelayer is a paid mutator transaction binding the contract method 0x0cffb52a. -// -// Solidity: function removeRelayer(address[] AddressList, address Address) returns(bool success) -func (_RelayerManager *RelayerManagerSession) RemoveRelayer(AddressList []common.Address, Address common.Address) (*types.Transaction, error) { - return _RelayerManager.Contract.RemoveRelayer(&_RelayerManager.TransactOpts, AddressList, Address) -} - -// RemoveRelayer is a paid mutator transaction binding the contract method 0x0cffb52a. -// -// Solidity: function removeRelayer(address[] AddressList, address Address) returns(bool success) -func (_RelayerManager *RelayerManagerTransactorSession) RemoveRelayer(AddressList []common.Address, Address common.Address) (*types.Transaction, error) { - return _RelayerManager.Contract.RemoveRelayer(&_RelayerManager.TransactOpts, AddressList, Address) -} - -// RelayerManagerApproveRegisterRelayerIterator is returned from FilterApproveRegisterRelayer and is used to iterate over the raw logs and unpacked data for ApproveRegisterRelayer events raised by the RelayerManager contract. -type RelayerManagerApproveRegisterRelayerIterator struct { - Event *RelayerManagerApproveRegisterRelayer // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *RelayerManagerApproveRegisterRelayerIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(RelayerManagerApproveRegisterRelayer) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(RelayerManagerApproveRegisterRelayer) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *RelayerManagerApproveRegisterRelayerIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *RelayerManagerApproveRegisterRelayerIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// RelayerManagerApproveRegisterRelayer represents a ApproveRegisterRelayer event raised by the RelayerManager contract. -type RelayerManagerApproveRegisterRelayer struct { - ID uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterApproveRegisterRelayer is a free log retrieval operation binding the contract event 0x85f1458b6de2aa7d6fb453821800c90d0ed717c565c2d5cdb73699b3ba657570. -// -// Solidity: event evtApproveRegisterRelayer(uint64 ID) -func (_RelayerManager *RelayerManagerFilterer) FilterApproveRegisterRelayer(opts *bind.FilterOpts) (*RelayerManagerApproveRegisterRelayerIterator, error) { - - logs, sub, err := _RelayerManager.contract.FilterLogs(opts, "evtApproveRegisterRelayer") - if err != nil { - return nil, err - } - return &RelayerManagerApproveRegisterRelayerIterator{contract: _RelayerManager.contract, event: "evtApproveRegisterRelayer", logs: logs, sub: sub}, nil -} - -// WatchApproveRegisterRelayer is a free log subscription operation binding the contract event 0x85f1458b6de2aa7d6fb453821800c90d0ed717c565c2d5cdb73699b3ba657570. -// -// Solidity: event evtApproveRegisterRelayer(uint64 ID) -func (_RelayerManager *RelayerManagerFilterer) WatchApproveRegisterRelayer(opts *bind.WatchOpts, sink chan<- *RelayerManagerApproveRegisterRelayer) (event.Subscription, error) { - - logs, sub, err := _RelayerManager.contract.WatchLogs(opts, "evtApproveRegisterRelayer") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(RelayerManagerApproveRegisterRelayer) - if err := _RelayerManager.contract.UnpackLog(event, "evtApproveRegisterRelayer", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseApproveRegisterRelayer is a log parse operation binding the contract event 0x85f1458b6de2aa7d6fb453821800c90d0ed717c565c2d5cdb73699b3ba657570. -// -// Solidity: event evtApproveRegisterRelayer(uint64 ID) -func (_RelayerManager *RelayerManagerFilterer) ParseApproveRegisterRelayer(log types.Log) (*RelayerManagerApproveRegisterRelayer, error) { - event := new(RelayerManagerApproveRegisterRelayer) - if err := _RelayerManager.contract.UnpackLog(event, "evtApproveRegisterRelayer", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// RelayerManagerApproveRemoveRelayerIterator is returned from FilterApproveRemoveRelayer and is used to iterate over the raw logs and unpacked data for ApproveRemoveRelayer events raised by the RelayerManager contract. -type RelayerManagerApproveRemoveRelayerIterator struct { - Event *RelayerManagerApproveRemoveRelayer // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *RelayerManagerApproveRemoveRelayerIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(RelayerManagerApproveRemoveRelayer) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(RelayerManagerApproveRemoveRelayer) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *RelayerManagerApproveRemoveRelayerIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *RelayerManagerApproveRemoveRelayerIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// RelayerManagerApproveRemoveRelayer represents a ApproveRemoveRelayer event raised by the RelayerManager contract. -type RelayerManagerApproveRemoveRelayer struct { - ID uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterApproveRemoveRelayer is a free log retrieval operation binding the contract event 0xff19e858c848163b5e0f8038dfb0870427c43f36f7446878ee73f9bd2ec491f4. -// -// Solidity: event evtApproveRemoveRelayer(uint64 ID) -func (_RelayerManager *RelayerManagerFilterer) FilterApproveRemoveRelayer(opts *bind.FilterOpts) (*RelayerManagerApproveRemoveRelayerIterator, error) { - - logs, sub, err := _RelayerManager.contract.FilterLogs(opts, "evtApproveRemoveRelayer") - if err != nil { - return nil, err - } - return &RelayerManagerApproveRemoveRelayerIterator{contract: _RelayerManager.contract, event: "evtApproveRemoveRelayer", logs: logs, sub: sub}, nil -} - -// WatchApproveRemoveRelayer is a free log subscription operation binding the contract event 0xff19e858c848163b5e0f8038dfb0870427c43f36f7446878ee73f9bd2ec491f4. -// -// Solidity: event evtApproveRemoveRelayer(uint64 ID) -func (_RelayerManager *RelayerManagerFilterer) WatchApproveRemoveRelayer(opts *bind.WatchOpts, sink chan<- *RelayerManagerApproveRemoveRelayer) (event.Subscription, error) { - - logs, sub, err := _RelayerManager.contract.WatchLogs(opts, "evtApproveRemoveRelayer") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(RelayerManagerApproveRemoveRelayer) - if err := _RelayerManager.contract.UnpackLog(event, "evtApproveRemoveRelayer", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseApproveRemoveRelayer is a log parse operation binding the contract event 0xff19e858c848163b5e0f8038dfb0870427c43f36f7446878ee73f9bd2ec491f4. -// -// Solidity: event evtApproveRemoveRelayer(uint64 ID) -func (_RelayerManager *RelayerManagerFilterer) ParseApproveRemoveRelayer(log types.Log) (*RelayerManagerApproveRemoveRelayer, error) { - event := new(RelayerManagerApproveRemoveRelayer) - if err := _RelayerManager.contract.UnpackLog(event, "evtApproveRemoveRelayer", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// RelayerManagerRegisterRelayerIterator is returned from FilterRegisterRelayer and is used to iterate over the raw logs and unpacked data for RegisterRelayer events raised by the RelayerManager contract. -type RelayerManagerRegisterRelayerIterator struct { - Event *RelayerManagerRegisterRelayer // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *RelayerManagerRegisterRelayerIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(RelayerManagerRegisterRelayer) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(RelayerManagerRegisterRelayer) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *RelayerManagerRegisterRelayerIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *RelayerManagerRegisterRelayerIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// RelayerManagerRegisterRelayer represents a RegisterRelayer event raised by the RelayerManager contract. -type RelayerManagerRegisterRelayer struct { - ApplyID uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterRegisterRelayer is a free log retrieval operation binding the contract event 0xcde26c3470cafd5b40f89e103f29443624c7648f3751a6fb8b56fb8b25059430. -// -// Solidity: event evtRegisterRelayer(uint64 applyID) -func (_RelayerManager *RelayerManagerFilterer) FilterRegisterRelayer(opts *bind.FilterOpts) (*RelayerManagerRegisterRelayerIterator, error) { - - logs, sub, err := _RelayerManager.contract.FilterLogs(opts, "evtRegisterRelayer") - if err != nil { - return nil, err - } - return &RelayerManagerRegisterRelayerIterator{contract: _RelayerManager.contract, event: "evtRegisterRelayer", logs: logs, sub: sub}, nil -} - -// WatchRegisterRelayer is a free log subscription operation binding the contract event 0xcde26c3470cafd5b40f89e103f29443624c7648f3751a6fb8b56fb8b25059430. -// -// Solidity: event evtRegisterRelayer(uint64 applyID) -func (_RelayerManager *RelayerManagerFilterer) WatchRegisterRelayer(opts *bind.WatchOpts, sink chan<- *RelayerManagerRegisterRelayer) (event.Subscription, error) { - - logs, sub, err := _RelayerManager.contract.WatchLogs(opts, "evtRegisterRelayer") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(RelayerManagerRegisterRelayer) - if err := _RelayerManager.contract.UnpackLog(event, "evtRegisterRelayer", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseRegisterRelayer is a log parse operation binding the contract event 0xcde26c3470cafd5b40f89e103f29443624c7648f3751a6fb8b56fb8b25059430. -// -// Solidity: event evtRegisterRelayer(uint64 applyID) -func (_RelayerManager *RelayerManagerFilterer) ParseRegisterRelayer(log types.Log) (*RelayerManagerRegisterRelayer, error) { - event := new(RelayerManagerRegisterRelayer) - if err := _RelayerManager.contract.UnpackLog(event, "evtRegisterRelayer", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// RelayerManagerRemoveRelayerIterator is returned from FilterRemoveRelayer and is used to iterate over the raw logs and unpacked data for RemoveRelayer events raised by the RelayerManager contract. -type RelayerManagerRemoveRelayerIterator struct { - Event *RelayerManagerRemoveRelayer // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *RelayerManagerRemoveRelayerIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(RelayerManagerRemoveRelayer) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(RelayerManagerRemoveRelayer) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *RelayerManagerRemoveRelayerIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *RelayerManagerRemoveRelayerIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// RelayerManagerRemoveRelayer represents a RemoveRelayer event raised by the RelayerManager contract. -type RelayerManagerRemoveRelayer struct { - RemoveID uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterRemoveRelayer is a free log retrieval operation binding the contract event 0x8f7667d2acd70ab373b61b6e8f28ca5259bfa2d53467f35f65bcf19041b5ba7d. -// -// Solidity: event evtRemoveRelayer(uint64 removeID) -func (_RelayerManager *RelayerManagerFilterer) FilterRemoveRelayer(opts *bind.FilterOpts) (*RelayerManagerRemoveRelayerIterator, error) { - - logs, sub, err := _RelayerManager.contract.FilterLogs(opts, "evtRemoveRelayer") - if err != nil { - return nil, err - } - return &RelayerManagerRemoveRelayerIterator{contract: _RelayerManager.contract, event: "evtRemoveRelayer", logs: logs, sub: sub}, nil -} - -// WatchRemoveRelayer is a free log subscription operation binding the contract event 0x8f7667d2acd70ab373b61b6e8f28ca5259bfa2d53467f35f65bcf19041b5ba7d. -// -// Solidity: event evtRemoveRelayer(uint64 removeID) -func (_RelayerManager *RelayerManagerFilterer) WatchRemoveRelayer(opts *bind.WatchOpts, sink chan<- *RelayerManagerRemoveRelayer) (event.Subscription, error) { - - logs, sub, err := _RelayerManager.contract.WatchLogs(opts, "evtRemoveRelayer") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(RelayerManagerRemoveRelayer) - if err := _RelayerManager.contract.UnpackLog(event, "evtRemoveRelayer", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseRemoveRelayer is a log parse operation binding the contract event 0x8f7667d2acd70ab373b61b6e8f28ca5259bfa2d53467f35f65bcf19041b5ba7d. -// -// Solidity: event evtRemoveRelayer(uint64 removeID) -func (_RelayerManager *RelayerManagerFilterer) ParseRemoveRelayer(log types.Log) (*RelayerManagerRemoveRelayer, error) { - event := new(RelayerManagerRemoveRelayer) - if err := _RelayerManager.contract.UnpackLog(event, "evtRemoveRelayer", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} diff --git a/contracts/native/go_abi/side_chain_manager_abi/side_chain_manager_abi.go b/contracts/native/go_abi/side_chain_manager_abi/side_chain_manager_abi.go deleted file mode 100644 index c75e640a..00000000 --- a/contracts/native/go_abi/side_chain_manager_abi/side_chain_manager_abi.go +++ /dev/null @@ -1,1500 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package side_chain_manager_abi - -import ( - "math/big" - "strings" - - ethereum "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -// side_chain_managerBtcTxParamDetial is an auto generated low-level Go binding around an user-defined struct. -type side_chain_managerBtcTxParamDetial struct { - PVersion uint64 - FeeRate uint64 - MinChange uint64 -} - -var ( - MethodApproveQuitSideChain = "approveQuitSideChain" - - MethodApproveRegisterSideChain = "approveRegisterSideChain" - - MethodApproveUpdateSideChain = "approveUpdateSideChain" - - MethodName = "name" - - MethodQuitSideChain = "quitSideChain" - - MethodRegisterRedeem = "registerRedeem" - - MethodRegisterSideChain = "registerSideChain" - - MethodSetBtcTxParam = "setBtcTxParam" - - MethodUpdateSideChain = "updateSideChain" -) - -// SideChainManagerABI is the input ABI used to generate the binding from. -const SideChainManagerABI = "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"ChainId\",\"type\":\"uint64\"}],\"name\":\"evtApproveQuitSideChain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"ChainId\",\"type\":\"uint64\"}],\"name\":\"evtApproveRegisterSideChain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"ChainId\",\"type\":\"uint64\"}],\"name\":\"evtApproveUpdateSideChain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"ChainId\",\"type\":\"uint64\"}],\"name\":\"evtQuitSideChain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"rk\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"ContractAddress\",\"type\":\"string\"}],\"name\":\"evtRegisterRedeem\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"ChainId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"Router\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"Name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"BlocksToWait\",\"type\":\"uint64\"}],\"name\":\"evtRegisterSideChain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"rk\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"RedeemChainId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"FeeRate\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"MinChange\",\"type\":\"uint64\"}],\"name\":\"evtSetBtcTxParam\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"ChainId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"Router\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"Name\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"BlocksToWait\",\"type\":\"uint64\"}],\"name\":\"evtUpdateSideChain\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"Chainid\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"Address\",\"type\":\"address\"}],\"name\":\"approveQuitSideChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"Chainid\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"Address\",\"type\":\"address\"}],\"name\":\"approveRegisterSideChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"Chainid\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"Address\",\"type\":\"address\"}],\"name\":\"approveUpdateSideChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"Name\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"Chainid\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"Address\",\"type\":\"address\"}],\"name\":\"quitSideChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"RedeemChainID\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"ContractChainID\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"Redeem\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"CVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"ContractAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"Signs\",\"type\":\"bytes[]\"}],\"name\":\"registerRedeem\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"Address\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"ChainId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"Router\",\"type\":\"uint64\"},{\"internalType\":\"string\",\"name\":\"Name\",\"type\":\"string\"},{\"internalType\":\"uint64\",\"name\":\"BlocksToWait\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"CCMCAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"ExtraInfo\",\"type\":\"bytes\"}],\"name\":\"registerSideChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"Redeem\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"RedeemChainId\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"Sigs\",\"type\":\"bytes[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"PVersion\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"FeeRate\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"MinChange\",\"type\":\"uint64\"}],\"internalType\":\"structside_chain_manager.BtcTxParamDetial\",\"name\":\"Detial\",\"type\":\"tuple\"}],\"name\":\"setBtcTxParam\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"Address\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"ChainId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"Router\",\"type\":\"uint64\"},{\"internalType\":\"string\",\"name\":\"Name\",\"type\":\"string\"},{\"internalType\":\"uint64\",\"name\":\"BlocksToWait\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"CCMCAddress\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"ExtraInfo\",\"type\":\"bytes\"}],\"name\":\"updateSideChain\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" - -// SideChainManagerFuncSigs maps the 4-byte function signature to its string representation. -var SideChainManagerFuncSigs = map[string]string{ - "6c8ac5c1": "approveQuitSideChain(uint64,address)", - "65764e16": "approveRegisterSideChain(uint64,address)", - "805b508e": "approveUpdateSideChain(uint64,address)", - "06fdde03": "name()", - "7460736e": "quitSideChain(uint64,address)", - "33e1d41a": "registerRedeem(uint64,uint64,bytes,uint64,bytes,bytes[])", - "ab7a2037": "registerSideChain(address,uint64,uint64,string,uint64,bytes,bytes)", - "ee9891e3": "setBtcTxParam(bytes,uint64,bytes[],(uint64,uint64,uint64))", - "f7782f81": "updateSideChain(address,uint64,uint64,string,uint64,bytes,bytes)", -} - -// SideChainManagerBin is the compiled bytecode used for deploying new contracts. -var SideChainManagerBin = "0x608060405234801561001057600080fd5b50610608806100206000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80637460736e116100665780637460736e146100da578063805b508e146100da578063ab7a2037146100f0578063ee9891e31461010b578063f7782f81146100f057600080fd5b806306fdde031461009857806333e1d41a146100b057806365764e16146100da5780636c8ac5c1146100da575b600080fd5b60606040516100a7919061050d565b60405180910390f35b6100ca6100be366004610454565b60009695505050505050565b60405190151581526020016100a7565b6100ca6100e8366004610421565b600092915050565b6100ca6100fe36600461027a565b6000979650505050505050565b6100ca61011936600461035c565b6000949350505050565b600067ffffffffffffffff83111561013d5761013d6105bc565b610150601f8401601f191660200161058b565b905082815283838301111561016457600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b038116811461019257600080fd5b919050565b600082601f8301126101a857600080fd5b8135602067ffffffffffffffff808311156101c5576101c56105bc565b8260051b6101d483820161058b565b8481528381019087850183890186018a10156101ef57600080fd5b60009350835b8781101561022c5781358681111561020b578586fd5b6102198c89838e010161023b565b85525092860192908601906001016101f5565b50909998505050505050505050565b600082601f83011261024c57600080fd5b61025b83833560208501610123565b9392505050565b803567ffffffffffffffff8116811461019257600080fd5b600080600080600080600060e0888a03121561029557600080fd5b61029e8861017b565b96506102ac60208901610262565b95506102ba60408901610262565b9450606088013567ffffffffffffffff808211156102d757600080fd5b818a0191508a601f8301126102eb57600080fd5b6102fa8b833560208501610123565b955061030860808b01610262565b945060a08a013591508082111561031e57600080fd5b61032a8b838c0161023b565b935060c08a013591508082111561034057600080fd5b5061034d8a828b0161023b565b91505092959891949750929550565b60008060008084860360c081121561037357600080fd5b853567ffffffffffffffff8082111561038b57600080fd5b61039789838a0161023b565b96506103a560208901610262565b955060408801359150808211156103bb57600080fd5b506103c888828901610197565b9350506060605f19820112156103dd57600080fd5b506103e6610562565b6103f260608701610262565b815261040060808701610262565b602082015261041160a08701610262565b6040820152939692955090935050565b6000806040838503121561043457600080fd5b61043d83610262565b915061044b6020840161017b565b90509250929050565b60008060008060008060c0878903121561046d57600080fd5b61047687610262565b955061048460208801610262565b9450604087013567ffffffffffffffff808211156104a157600080fd5b6104ad8a838b0161023b565b95506104bb60608a01610262565b945060808901359150808211156104d157600080fd5b6104dd8a838b0161023b565b935060a08901359150808211156104f357600080fd5b5061050089828a01610197565b9150509295509295509295565b600060208083528351808285015260005b8181101561053a5785810183015185820160400152820161051e565b8181111561054c576000604083870101525b50601f01601f1916929092016040019392505050565b6040516060810167ffffffffffffffff81118282101715610585576105856105bc565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156105b4576105b46105bc565b604052919050565b634e487b7160e01b600052604160045260246000fdfea26469706673582212201e30dd90c8f8c2bc2a8d03860a8d81c9f32d74209e8ba33de259f3bdaaaa078064736f6c63430008060033" - -// DeploySideChainManager deploys a new Ethereum contract, binding an instance of SideChainManager to it. -func DeploySideChainManager(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SideChainManager, error) { - parsed, err := abi.JSON(strings.NewReader(SideChainManagerABI)) - if err != nil { - return common.Address{}, nil, nil, err - } - - address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(SideChainManagerBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &SideChainManager{SideChainManagerCaller: SideChainManagerCaller{contract: contract}, SideChainManagerTransactor: SideChainManagerTransactor{contract: contract}, SideChainManagerFilterer: SideChainManagerFilterer{contract: contract}}, nil -} - -// SideChainManager is an auto generated Go binding around an Ethereum contract. -type SideChainManager struct { - SideChainManagerCaller // Read-only binding to the contract - SideChainManagerTransactor // Write-only binding to the contract - SideChainManagerFilterer // Log filterer for contract events -} - -// SideChainManagerCaller is an auto generated read-only Go binding around an Ethereum contract. -type SideChainManagerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// SideChainManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type SideChainManagerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// SideChainManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type SideChainManagerFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// SideChainManagerSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type SideChainManagerSession struct { - Contract *SideChainManager // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// SideChainManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type SideChainManagerCallerSession struct { - Contract *SideChainManagerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// SideChainManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type SideChainManagerTransactorSession struct { - Contract *SideChainManagerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// SideChainManagerRaw is an auto generated low-level Go binding around an Ethereum contract. -type SideChainManagerRaw struct { - Contract *SideChainManager // Generic contract binding to access the raw methods on -} - -// SideChainManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type SideChainManagerCallerRaw struct { - Contract *SideChainManagerCaller // Generic read-only contract binding to access the raw methods on -} - -// SideChainManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type SideChainManagerTransactorRaw struct { - Contract *SideChainManagerTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewSideChainManager creates a new instance of SideChainManager, bound to a specific deployed contract. -func NewSideChainManager(address common.Address, backend bind.ContractBackend) (*SideChainManager, error) { - contract, err := bindSideChainManager(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &SideChainManager{SideChainManagerCaller: SideChainManagerCaller{contract: contract}, SideChainManagerTransactor: SideChainManagerTransactor{contract: contract}, SideChainManagerFilterer: SideChainManagerFilterer{contract: contract}}, nil -} - -// NewSideChainManagerCaller creates a new read-only instance of SideChainManager, bound to a specific deployed contract. -func NewSideChainManagerCaller(address common.Address, caller bind.ContractCaller) (*SideChainManagerCaller, error) { - contract, err := bindSideChainManager(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &SideChainManagerCaller{contract: contract}, nil -} - -// NewSideChainManagerTransactor creates a new write-only instance of SideChainManager, bound to a specific deployed contract. -func NewSideChainManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*SideChainManagerTransactor, error) { - contract, err := bindSideChainManager(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &SideChainManagerTransactor{contract: contract}, nil -} - -// NewSideChainManagerFilterer creates a new log filterer instance of SideChainManager, bound to a specific deployed contract. -func NewSideChainManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*SideChainManagerFilterer, error) { - contract, err := bindSideChainManager(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &SideChainManagerFilterer{contract: contract}, nil -} - -// bindSideChainManager binds a generic wrapper to an already deployed contract. -func bindSideChainManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(SideChainManagerABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_SideChainManager *SideChainManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _SideChainManager.Contract.SideChainManagerCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_SideChainManager *SideChainManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _SideChainManager.Contract.SideChainManagerTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_SideChainManager *SideChainManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _SideChainManager.Contract.SideChainManagerTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_SideChainManager *SideChainManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _SideChainManager.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_SideChainManager *SideChainManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _SideChainManager.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_SideChainManager *SideChainManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _SideChainManager.Contract.contract.Transact(opts, method, params...) -} - -// ApproveQuitSideChain is a paid mutator transaction binding the contract method 0x6c8ac5c1. -// -// Solidity: function approveQuitSideChain(uint64 Chainid, address Address) returns(bool success) -func (_SideChainManager *SideChainManagerTransactor) ApproveQuitSideChain(opts *bind.TransactOpts, Chainid uint64, Address common.Address) (*types.Transaction, error) { - return _SideChainManager.contract.Transact(opts, "approveQuitSideChain", Chainid, Address) -} - -// ApproveQuitSideChain is a paid mutator transaction binding the contract method 0x6c8ac5c1. -// -// Solidity: function approveQuitSideChain(uint64 Chainid, address Address) returns(bool success) -func (_SideChainManager *SideChainManagerSession) ApproveQuitSideChain(Chainid uint64, Address common.Address) (*types.Transaction, error) { - return _SideChainManager.Contract.ApproveQuitSideChain(&_SideChainManager.TransactOpts, Chainid, Address) -} - -// ApproveQuitSideChain is a paid mutator transaction binding the contract method 0x6c8ac5c1. -// -// Solidity: function approveQuitSideChain(uint64 Chainid, address Address) returns(bool success) -func (_SideChainManager *SideChainManagerTransactorSession) ApproveQuitSideChain(Chainid uint64, Address common.Address) (*types.Transaction, error) { - return _SideChainManager.Contract.ApproveQuitSideChain(&_SideChainManager.TransactOpts, Chainid, Address) -} - -// ApproveRegisterSideChain is a paid mutator transaction binding the contract method 0x65764e16. -// -// Solidity: function approveRegisterSideChain(uint64 Chainid, address Address) returns(bool success) -func (_SideChainManager *SideChainManagerTransactor) ApproveRegisterSideChain(opts *bind.TransactOpts, Chainid uint64, Address common.Address) (*types.Transaction, error) { - return _SideChainManager.contract.Transact(opts, "approveRegisterSideChain", Chainid, Address) -} - -// ApproveRegisterSideChain is a paid mutator transaction binding the contract method 0x65764e16. -// -// Solidity: function approveRegisterSideChain(uint64 Chainid, address Address) returns(bool success) -func (_SideChainManager *SideChainManagerSession) ApproveRegisterSideChain(Chainid uint64, Address common.Address) (*types.Transaction, error) { - return _SideChainManager.Contract.ApproveRegisterSideChain(&_SideChainManager.TransactOpts, Chainid, Address) -} - -// ApproveRegisterSideChain is a paid mutator transaction binding the contract method 0x65764e16. -// -// Solidity: function approveRegisterSideChain(uint64 Chainid, address Address) returns(bool success) -func (_SideChainManager *SideChainManagerTransactorSession) ApproveRegisterSideChain(Chainid uint64, Address common.Address) (*types.Transaction, error) { - return _SideChainManager.Contract.ApproveRegisterSideChain(&_SideChainManager.TransactOpts, Chainid, Address) -} - -// ApproveUpdateSideChain is a paid mutator transaction binding the contract method 0x805b508e. -// -// Solidity: function approveUpdateSideChain(uint64 Chainid, address Address) returns(bool success) -func (_SideChainManager *SideChainManagerTransactor) ApproveUpdateSideChain(opts *bind.TransactOpts, Chainid uint64, Address common.Address) (*types.Transaction, error) { - return _SideChainManager.contract.Transact(opts, "approveUpdateSideChain", Chainid, Address) -} - -// ApproveUpdateSideChain is a paid mutator transaction binding the contract method 0x805b508e. -// -// Solidity: function approveUpdateSideChain(uint64 Chainid, address Address) returns(bool success) -func (_SideChainManager *SideChainManagerSession) ApproveUpdateSideChain(Chainid uint64, Address common.Address) (*types.Transaction, error) { - return _SideChainManager.Contract.ApproveUpdateSideChain(&_SideChainManager.TransactOpts, Chainid, Address) -} - -// ApproveUpdateSideChain is a paid mutator transaction binding the contract method 0x805b508e. -// -// Solidity: function approveUpdateSideChain(uint64 Chainid, address Address) returns(bool success) -func (_SideChainManager *SideChainManagerTransactorSession) ApproveUpdateSideChain(Chainid uint64, Address common.Address) (*types.Transaction, error) { - return _SideChainManager.Contract.ApproveUpdateSideChain(&_SideChainManager.TransactOpts, Chainid, Address) -} - -// Name is a paid mutator transaction binding the contract method 0x06fdde03. -// -// Solidity: function name() returns(string Name) -func (_SideChainManager *SideChainManagerTransactor) Name(opts *bind.TransactOpts) (*types.Transaction, error) { - return _SideChainManager.contract.Transact(opts, "name") -} - -// Name is a paid mutator transaction binding the contract method 0x06fdde03. -// -// Solidity: function name() returns(string Name) -func (_SideChainManager *SideChainManagerSession) Name() (*types.Transaction, error) { - return _SideChainManager.Contract.Name(&_SideChainManager.TransactOpts) -} - -// Name is a paid mutator transaction binding the contract method 0x06fdde03. -// -// Solidity: function name() returns(string Name) -func (_SideChainManager *SideChainManagerTransactorSession) Name() (*types.Transaction, error) { - return _SideChainManager.Contract.Name(&_SideChainManager.TransactOpts) -} - -// QuitSideChain is a paid mutator transaction binding the contract method 0x7460736e. -// -// Solidity: function quitSideChain(uint64 Chainid, address Address) returns(bool success) -func (_SideChainManager *SideChainManagerTransactor) QuitSideChain(opts *bind.TransactOpts, Chainid uint64, Address common.Address) (*types.Transaction, error) { - return _SideChainManager.contract.Transact(opts, "quitSideChain", Chainid, Address) -} - -// QuitSideChain is a paid mutator transaction binding the contract method 0x7460736e. -// -// Solidity: function quitSideChain(uint64 Chainid, address Address) returns(bool success) -func (_SideChainManager *SideChainManagerSession) QuitSideChain(Chainid uint64, Address common.Address) (*types.Transaction, error) { - return _SideChainManager.Contract.QuitSideChain(&_SideChainManager.TransactOpts, Chainid, Address) -} - -// QuitSideChain is a paid mutator transaction binding the contract method 0x7460736e. -// -// Solidity: function quitSideChain(uint64 Chainid, address Address) returns(bool success) -func (_SideChainManager *SideChainManagerTransactorSession) QuitSideChain(Chainid uint64, Address common.Address) (*types.Transaction, error) { - return _SideChainManager.Contract.QuitSideChain(&_SideChainManager.TransactOpts, Chainid, Address) -} - -// RegisterRedeem is a paid mutator transaction binding the contract method 0x33e1d41a. -// -// Solidity: function registerRedeem(uint64 RedeemChainID, uint64 ContractChainID, bytes Redeem, uint64 CVersion, bytes ContractAddress, bytes[] Signs) returns(bool success) -func (_SideChainManager *SideChainManagerTransactor) RegisterRedeem(opts *bind.TransactOpts, RedeemChainID uint64, ContractChainID uint64, Redeem []byte, CVersion uint64, ContractAddress []byte, Signs [][]byte) (*types.Transaction, error) { - return _SideChainManager.contract.Transact(opts, "registerRedeem", RedeemChainID, ContractChainID, Redeem, CVersion, ContractAddress, Signs) -} - -// RegisterRedeem is a paid mutator transaction binding the contract method 0x33e1d41a. -// -// Solidity: function registerRedeem(uint64 RedeemChainID, uint64 ContractChainID, bytes Redeem, uint64 CVersion, bytes ContractAddress, bytes[] Signs) returns(bool success) -func (_SideChainManager *SideChainManagerSession) RegisterRedeem(RedeemChainID uint64, ContractChainID uint64, Redeem []byte, CVersion uint64, ContractAddress []byte, Signs [][]byte) (*types.Transaction, error) { - return _SideChainManager.Contract.RegisterRedeem(&_SideChainManager.TransactOpts, RedeemChainID, ContractChainID, Redeem, CVersion, ContractAddress, Signs) -} - -// RegisterRedeem is a paid mutator transaction binding the contract method 0x33e1d41a. -// -// Solidity: function registerRedeem(uint64 RedeemChainID, uint64 ContractChainID, bytes Redeem, uint64 CVersion, bytes ContractAddress, bytes[] Signs) returns(bool success) -func (_SideChainManager *SideChainManagerTransactorSession) RegisterRedeem(RedeemChainID uint64, ContractChainID uint64, Redeem []byte, CVersion uint64, ContractAddress []byte, Signs [][]byte) (*types.Transaction, error) { - return _SideChainManager.Contract.RegisterRedeem(&_SideChainManager.TransactOpts, RedeemChainID, ContractChainID, Redeem, CVersion, ContractAddress, Signs) -} - -// RegisterSideChain is a paid mutator transaction binding the contract method 0xab7a2037. -// -// Solidity: function registerSideChain(address Address, uint64 ChainId, uint64 Router, string Name, uint64 BlocksToWait, bytes CCMCAddress, bytes ExtraInfo) returns(bool success) -func (_SideChainManager *SideChainManagerTransactor) RegisterSideChain(opts *bind.TransactOpts, Address common.Address, ChainId uint64, Router uint64, Name string, BlocksToWait uint64, CCMCAddress []byte, ExtraInfo []byte) (*types.Transaction, error) { - return _SideChainManager.contract.Transact(opts, "registerSideChain", Address, ChainId, Router, Name, BlocksToWait, CCMCAddress, ExtraInfo) -} - -// RegisterSideChain is a paid mutator transaction binding the contract method 0xab7a2037. -// -// Solidity: function registerSideChain(address Address, uint64 ChainId, uint64 Router, string Name, uint64 BlocksToWait, bytes CCMCAddress, bytes ExtraInfo) returns(bool success) -func (_SideChainManager *SideChainManagerSession) RegisterSideChain(Address common.Address, ChainId uint64, Router uint64, Name string, BlocksToWait uint64, CCMCAddress []byte, ExtraInfo []byte) (*types.Transaction, error) { - return _SideChainManager.Contract.RegisterSideChain(&_SideChainManager.TransactOpts, Address, ChainId, Router, Name, BlocksToWait, CCMCAddress, ExtraInfo) -} - -// RegisterSideChain is a paid mutator transaction binding the contract method 0xab7a2037. -// -// Solidity: function registerSideChain(address Address, uint64 ChainId, uint64 Router, string Name, uint64 BlocksToWait, bytes CCMCAddress, bytes ExtraInfo) returns(bool success) -func (_SideChainManager *SideChainManagerTransactorSession) RegisterSideChain(Address common.Address, ChainId uint64, Router uint64, Name string, BlocksToWait uint64, CCMCAddress []byte, ExtraInfo []byte) (*types.Transaction, error) { - return _SideChainManager.Contract.RegisterSideChain(&_SideChainManager.TransactOpts, Address, ChainId, Router, Name, BlocksToWait, CCMCAddress, ExtraInfo) -} - -// SetBtcTxParam is a paid mutator transaction binding the contract method 0xee9891e3. -// -// Solidity: function setBtcTxParam(bytes Redeem, uint64 RedeemChainId, bytes[] Sigs, (uint64,uint64,uint64) Detial) returns(bool success) -func (_SideChainManager *SideChainManagerTransactor) SetBtcTxParam(opts *bind.TransactOpts, Redeem []byte, RedeemChainId uint64, Sigs [][]byte, Detial side_chain_managerBtcTxParamDetial) (*types.Transaction, error) { - return _SideChainManager.contract.Transact(opts, "setBtcTxParam", Redeem, RedeemChainId, Sigs, Detial) -} - -// SetBtcTxParam is a paid mutator transaction binding the contract method 0xee9891e3. -// -// Solidity: function setBtcTxParam(bytes Redeem, uint64 RedeemChainId, bytes[] Sigs, (uint64,uint64,uint64) Detial) returns(bool success) -func (_SideChainManager *SideChainManagerSession) SetBtcTxParam(Redeem []byte, RedeemChainId uint64, Sigs [][]byte, Detial side_chain_managerBtcTxParamDetial) (*types.Transaction, error) { - return _SideChainManager.Contract.SetBtcTxParam(&_SideChainManager.TransactOpts, Redeem, RedeemChainId, Sigs, Detial) -} - -// SetBtcTxParam is a paid mutator transaction binding the contract method 0xee9891e3. -// -// Solidity: function setBtcTxParam(bytes Redeem, uint64 RedeemChainId, bytes[] Sigs, (uint64,uint64,uint64) Detial) returns(bool success) -func (_SideChainManager *SideChainManagerTransactorSession) SetBtcTxParam(Redeem []byte, RedeemChainId uint64, Sigs [][]byte, Detial side_chain_managerBtcTxParamDetial) (*types.Transaction, error) { - return _SideChainManager.Contract.SetBtcTxParam(&_SideChainManager.TransactOpts, Redeem, RedeemChainId, Sigs, Detial) -} - -// UpdateSideChain is a paid mutator transaction binding the contract method 0xf7782f81. -// -// Solidity: function updateSideChain(address Address, uint64 ChainId, uint64 Router, string Name, uint64 BlocksToWait, bytes CCMCAddress, bytes ExtraInfo) returns(bool success) -func (_SideChainManager *SideChainManagerTransactor) UpdateSideChain(opts *bind.TransactOpts, Address common.Address, ChainId uint64, Router uint64, Name string, BlocksToWait uint64, CCMCAddress []byte, ExtraInfo []byte) (*types.Transaction, error) { - return _SideChainManager.contract.Transact(opts, "updateSideChain", Address, ChainId, Router, Name, BlocksToWait, CCMCAddress, ExtraInfo) -} - -// UpdateSideChain is a paid mutator transaction binding the contract method 0xf7782f81. -// -// Solidity: function updateSideChain(address Address, uint64 ChainId, uint64 Router, string Name, uint64 BlocksToWait, bytes CCMCAddress, bytes ExtraInfo) returns(bool success) -func (_SideChainManager *SideChainManagerSession) UpdateSideChain(Address common.Address, ChainId uint64, Router uint64, Name string, BlocksToWait uint64, CCMCAddress []byte, ExtraInfo []byte) (*types.Transaction, error) { - return _SideChainManager.Contract.UpdateSideChain(&_SideChainManager.TransactOpts, Address, ChainId, Router, Name, BlocksToWait, CCMCAddress, ExtraInfo) -} - -// UpdateSideChain is a paid mutator transaction binding the contract method 0xf7782f81. -// -// Solidity: function updateSideChain(address Address, uint64 ChainId, uint64 Router, string Name, uint64 BlocksToWait, bytes CCMCAddress, bytes ExtraInfo) returns(bool success) -func (_SideChainManager *SideChainManagerTransactorSession) UpdateSideChain(Address common.Address, ChainId uint64, Router uint64, Name string, BlocksToWait uint64, CCMCAddress []byte, ExtraInfo []byte) (*types.Transaction, error) { - return _SideChainManager.Contract.UpdateSideChain(&_SideChainManager.TransactOpts, Address, ChainId, Router, Name, BlocksToWait, CCMCAddress, ExtraInfo) -} - -// SideChainManagerApproveQuitSideChainIterator is returned from FilterApproveQuitSideChain and is used to iterate over the raw logs and unpacked data for ApproveQuitSideChain events raised by the SideChainManager contract. -type SideChainManagerApproveQuitSideChainIterator struct { - Event *SideChainManagerApproveQuitSideChain // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *SideChainManagerApproveQuitSideChainIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(SideChainManagerApproveQuitSideChain) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(SideChainManagerApproveQuitSideChain) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *SideChainManagerApproveQuitSideChainIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *SideChainManagerApproveQuitSideChainIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// SideChainManagerApproveQuitSideChain represents a ApproveQuitSideChain event raised by the SideChainManager contract. -type SideChainManagerApproveQuitSideChain struct { - ChainId uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterApproveQuitSideChain is a free log retrieval operation binding the contract event 0x2d8d546abdecb5e9d71f9df93e8bb1e939c865274bf2e59be647e053909634a1. -// -// Solidity: event evtApproveQuitSideChain(uint64 ChainId) -func (_SideChainManager *SideChainManagerFilterer) FilterApproveQuitSideChain(opts *bind.FilterOpts) (*SideChainManagerApproveQuitSideChainIterator, error) { - - logs, sub, err := _SideChainManager.contract.FilterLogs(opts, "evtApproveQuitSideChain") - if err != nil { - return nil, err - } - return &SideChainManagerApproveQuitSideChainIterator{contract: _SideChainManager.contract, event: "evtApproveQuitSideChain", logs: logs, sub: sub}, nil -} - -// WatchApproveQuitSideChain is a free log subscription operation binding the contract event 0x2d8d546abdecb5e9d71f9df93e8bb1e939c865274bf2e59be647e053909634a1. -// -// Solidity: event evtApproveQuitSideChain(uint64 ChainId) -func (_SideChainManager *SideChainManagerFilterer) WatchApproveQuitSideChain(opts *bind.WatchOpts, sink chan<- *SideChainManagerApproveQuitSideChain) (event.Subscription, error) { - - logs, sub, err := _SideChainManager.contract.WatchLogs(opts, "evtApproveQuitSideChain") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(SideChainManagerApproveQuitSideChain) - if err := _SideChainManager.contract.UnpackLog(event, "evtApproveQuitSideChain", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseApproveQuitSideChain is a log parse operation binding the contract event 0x2d8d546abdecb5e9d71f9df93e8bb1e939c865274bf2e59be647e053909634a1. -// -// Solidity: event evtApproveQuitSideChain(uint64 ChainId) -func (_SideChainManager *SideChainManagerFilterer) ParseApproveQuitSideChain(log types.Log) (*SideChainManagerApproveQuitSideChain, error) { - event := new(SideChainManagerApproveQuitSideChain) - if err := _SideChainManager.contract.UnpackLog(event, "evtApproveQuitSideChain", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// SideChainManagerApproveRegisterSideChainIterator is returned from FilterApproveRegisterSideChain and is used to iterate over the raw logs and unpacked data for ApproveRegisterSideChain events raised by the SideChainManager contract. -type SideChainManagerApproveRegisterSideChainIterator struct { - Event *SideChainManagerApproveRegisterSideChain // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *SideChainManagerApproveRegisterSideChainIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(SideChainManagerApproveRegisterSideChain) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(SideChainManagerApproveRegisterSideChain) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *SideChainManagerApproveRegisterSideChainIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *SideChainManagerApproveRegisterSideChainIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// SideChainManagerApproveRegisterSideChain represents a ApproveRegisterSideChain event raised by the SideChainManager contract. -type SideChainManagerApproveRegisterSideChain struct { - ChainId uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterApproveRegisterSideChain is a free log retrieval operation binding the contract event 0x6517ffadca69f75ee51efa5c1e977750e009b25f0bd235ad2afc381ab9704e3e. -// -// Solidity: event evtApproveRegisterSideChain(uint64 ChainId) -func (_SideChainManager *SideChainManagerFilterer) FilterApproveRegisterSideChain(opts *bind.FilterOpts) (*SideChainManagerApproveRegisterSideChainIterator, error) { - - logs, sub, err := _SideChainManager.contract.FilterLogs(opts, "evtApproveRegisterSideChain") - if err != nil { - return nil, err - } - return &SideChainManagerApproveRegisterSideChainIterator{contract: _SideChainManager.contract, event: "evtApproveRegisterSideChain", logs: logs, sub: sub}, nil -} - -// WatchApproveRegisterSideChain is a free log subscription operation binding the contract event 0x6517ffadca69f75ee51efa5c1e977750e009b25f0bd235ad2afc381ab9704e3e. -// -// Solidity: event evtApproveRegisterSideChain(uint64 ChainId) -func (_SideChainManager *SideChainManagerFilterer) WatchApproveRegisterSideChain(opts *bind.WatchOpts, sink chan<- *SideChainManagerApproveRegisterSideChain) (event.Subscription, error) { - - logs, sub, err := _SideChainManager.contract.WatchLogs(opts, "evtApproveRegisterSideChain") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(SideChainManagerApproveRegisterSideChain) - if err := _SideChainManager.contract.UnpackLog(event, "evtApproveRegisterSideChain", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseApproveRegisterSideChain is a log parse operation binding the contract event 0x6517ffadca69f75ee51efa5c1e977750e009b25f0bd235ad2afc381ab9704e3e. -// -// Solidity: event evtApproveRegisterSideChain(uint64 ChainId) -func (_SideChainManager *SideChainManagerFilterer) ParseApproveRegisterSideChain(log types.Log) (*SideChainManagerApproveRegisterSideChain, error) { - event := new(SideChainManagerApproveRegisterSideChain) - if err := _SideChainManager.contract.UnpackLog(event, "evtApproveRegisterSideChain", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// SideChainManagerApproveUpdateSideChainIterator is returned from FilterApproveUpdateSideChain and is used to iterate over the raw logs and unpacked data for ApproveUpdateSideChain events raised by the SideChainManager contract. -type SideChainManagerApproveUpdateSideChainIterator struct { - Event *SideChainManagerApproveUpdateSideChain // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *SideChainManagerApproveUpdateSideChainIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(SideChainManagerApproveUpdateSideChain) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(SideChainManagerApproveUpdateSideChain) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *SideChainManagerApproveUpdateSideChainIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *SideChainManagerApproveUpdateSideChainIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// SideChainManagerApproveUpdateSideChain represents a ApproveUpdateSideChain event raised by the SideChainManager contract. -type SideChainManagerApproveUpdateSideChain struct { - ChainId uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterApproveUpdateSideChain is a free log retrieval operation binding the contract event 0x4c14575dec13d2259a0de2653a8dbbce76780e169975f171b841b9764259252d. -// -// Solidity: event evtApproveUpdateSideChain(uint64 ChainId) -func (_SideChainManager *SideChainManagerFilterer) FilterApproveUpdateSideChain(opts *bind.FilterOpts) (*SideChainManagerApproveUpdateSideChainIterator, error) { - - logs, sub, err := _SideChainManager.contract.FilterLogs(opts, "evtApproveUpdateSideChain") - if err != nil { - return nil, err - } - return &SideChainManagerApproveUpdateSideChainIterator{contract: _SideChainManager.contract, event: "evtApproveUpdateSideChain", logs: logs, sub: sub}, nil -} - -// WatchApproveUpdateSideChain is a free log subscription operation binding the contract event 0x4c14575dec13d2259a0de2653a8dbbce76780e169975f171b841b9764259252d. -// -// Solidity: event evtApproveUpdateSideChain(uint64 ChainId) -func (_SideChainManager *SideChainManagerFilterer) WatchApproveUpdateSideChain(opts *bind.WatchOpts, sink chan<- *SideChainManagerApproveUpdateSideChain) (event.Subscription, error) { - - logs, sub, err := _SideChainManager.contract.WatchLogs(opts, "evtApproveUpdateSideChain") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(SideChainManagerApproveUpdateSideChain) - if err := _SideChainManager.contract.UnpackLog(event, "evtApproveUpdateSideChain", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseApproveUpdateSideChain is a log parse operation binding the contract event 0x4c14575dec13d2259a0de2653a8dbbce76780e169975f171b841b9764259252d. -// -// Solidity: event evtApproveUpdateSideChain(uint64 ChainId) -func (_SideChainManager *SideChainManagerFilterer) ParseApproveUpdateSideChain(log types.Log) (*SideChainManagerApproveUpdateSideChain, error) { - event := new(SideChainManagerApproveUpdateSideChain) - if err := _SideChainManager.contract.UnpackLog(event, "evtApproveUpdateSideChain", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// SideChainManagerQuitSideChainIterator is returned from FilterQuitSideChain and is used to iterate over the raw logs and unpacked data for QuitSideChain events raised by the SideChainManager contract. -type SideChainManagerQuitSideChainIterator struct { - Event *SideChainManagerQuitSideChain // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *SideChainManagerQuitSideChainIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(SideChainManagerQuitSideChain) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(SideChainManagerQuitSideChain) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *SideChainManagerQuitSideChainIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *SideChainManagerQuitSideChainIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// SideChainManagerQuitSideChain represents a QuitSideChain event raised by the SideChainManager contract. -type SideChainManagerQuitSideChain struct { - ChainId uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterQuitSideChain is a free log retrieval operation binding the contract event 0x7bf563d05c6f1e91715904f8c9e53945100b40362d910f37e54bdc4989a685c9. -// -// Solidity: event evtQuitSideChain(uint64 ChainId) -func (_SideChainManager *SideChainManagerFilterer) FilterQuitSideChain(opts *bind.FilterOpts) (*SideChainManagerQuitSideChainIterator, error) { - - logs, sub, err := _SideChainManager.contract.FilterLogs(opts, "evtQuitSideChain") - if err != nil { - return nil, err - } - return &SideChainManagerQuitSideChainIterator{contract: _SideChainManager.contract, event: "evtQuitSideChain", logs: logs, sub: sub}, nil -} - -// WatchQuitSideChain is a free log subscription operation binding the contract event 0x7bf563d05c6f1e91715904f8c9e53945100b40362d910f37e54bdc4989a685c9. -// -// Solidity: event evtQuitSideChain(uint64 ChainId) -func (_SideChainManager *SideChainManagerFilterer) WatchQuitSideChain(opts *bind.WatchOpts, sink chan<- *SideChainManagerQuitSideChain) (event.Subscription, error) { - - logs, sub, err := _SideChainManager.contract.WatchLogs(opts, "evtQuitSideChain") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(SideChainManagerQuitSideChain) - if err := _SideChainManager.contract.UnpackLog(event, "evtQuitSideChain", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseQuitSideChain is a log parse operation binding the contract event 0x7bf563d05c6f1e91715904f8c9e53945100b40362d910f37e54bdc4989a685c9. -// -// Solidity: event evtQuitSideChain(uint64 ChainId) -func (_SideChainManager *SideChainManagerFilterer) ParseQuitSideChain(log types.Log) (*SideChainManagerQuitSideChain, error) { - event := new(SideChainManagerQuitSideChain) - if err := _SideChainManager.contract.UnpackLog(event, "evtQuitSideChain", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// SideChainManagerRegisterRedeemIterator is returned from FilterRegisterRedeem and is used to iterate over the raw logs and unpacked data for RegisterRedeem events raised by the SideChainManager contract. -type SideChainManagerRegisterRedeemIterator struct { - Event *SideChainManagerRegisterRedeem // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *SideChainManagerRegisterRedeemIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(SideChainManagerRegisterRedeem) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(SideChainManagerRegisterRedeem) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *SideChainManagerRegisterRedeemIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *SideChainManagerRegisterRedeemIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// SideChainManagerRegisterRedeem represents a RegisterRedeem event raised by the SideChainManager contract. -type SideChainManagerRegisterRedeem struct { - Rk string - ContractAddress string - Raw types.Log // Blockchain specific contextual infos -} - -// FilterRegisterRedeem is a free log retrieval operation binding the contract event 0x59fabb884927c5d2e368d355ea11674fd5974066f70ac78f9adab4f1e6a06a36. -// -// Solidity: event evtRegisterRedeem(string rk, string ContractAddress) -func (_SideChainManager *SideChainManagerFilterer) FilterRegisterRedeem(opts *bind.FilterOpts) (*SideChainManagerRegisterRedeemIterator, error) { - - logs, sub, err := _SideChainManager.contract.FilterLogs(opts, "evtRegisterRedeem") - if err != nil { - return nil, err - } - return &SideChainManagerRegisterRedeemIterator{contract: _SideChainManager.contract, event: "evtRegisterRedeem", logs: logs, sub: sub}, nil -} - -// WatchRegisterRedeem is a free log subscription operation binding the contract event 0x59fabb884927c5d2e368d355ea11674fd5974066f70ac78f9adab4f1e6a06a36. -// -// Solidity: event evtRegisterRedeem(string rk, string ContractAddress) -func (_SideChainManager *SideChainManagerFilterer) WatchRegisterRedeem(opts *bind.WatchOpts, sink chan<- *SideChainManagerRegisterRedeem) (event.Subscription, error) { - - logs, sub, err := _SideChainManager.contract.WatchLogs(opts, "evtRegisterRedeem") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(SideChainManagerRegisterRedeem) - if err := _SideChainManager.contract.UnpackLog(event, "evtRegisterRedeem", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseRegisterRedeem is a log parse operation binding the contract event 0x59fabb884927c5d2e368d355ea11674fd5974066f70ac78f9adab4f1e6a06a36. -// -// Solidity: event evtRegisterRedeem(string rk, string ContractAddress) -func (_SideChainManager *SideChainManagerFilterer) ParseRegisterRedeem(log types.Log) (*SideChainManagerRegisterRedeem, error) { - event := new(SideChainManagerRegisterRedeem) - if err := _SideChainManager.contract.UnpackLog(event, "evtRegisterRedeem", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// SideChainManagerRegisterSideChainIterator is returned from FilterRegisterSideChain and is used to iterate over the raw logs and unpacked data for RegisterSideChain events raised by the SideChainManager contract. -type SideChainManagerRegisterSideChainIterator struct { - Event *SideChainManagerRegisterSideChain // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *SideChainManagerRegisterSideChainIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(SideChainManagerRegisterSideChain) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(SideChainManagerRegisterSideChain) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *SideChainManagerRegisterSideChainIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *SideChainManagerRegisterSideChainIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// SideChainManagerRegisterSideChain represents a RegisterSideChain event raised by the SideChainManager contract. -type SideChainManagerRegisterSideChain struct { - ChainId uint64 - Router uint64 - Name string - BlocksToWait uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterRegisterSideChain is a free log retrieval operation binding the contract event 0x844fd8662935c80c93372c0cb9eb5fd6db52835a3078934d65f762a9bfd13ea2. -// -// Solidity: event evtRegisterSideChain(uint64 ChainId, uint64 Router, string Name, uint64 BlocksToWait) -func (_SideChainManager *SideChainManagerFilterer) FilterRegisterSideChain(opts *bind.FilterOpts) (*SideChainManagerRegisterSideChainIterator, error) { - - logs, sub, err := _SideChainManager.contract.FilterLogs(opts, "evtRegisterSideChain") - if err != nil { - return nil, err - } - return &SideChainManagerRegisterSideChainIterator{contract: _SideChainManager.contract, event: "evtRegisterSideChain", logs: logs, sub: sub}, nil -} - -// WatchRegisterSideChain is a free log subscription operation binding the contract event 0x844fd8662935c80c93372c0cb9eb5fd6db52835a3078934d65f762a9bfd13ea2. -// -// Solidity: event evtRegisterSideChain(uint64 ChainId, uint64 Router, string Name, uint64 BlocksToWait) -func (_SideChainManager *SideChainManagerFilterer) WatchRegisterSideChain(opts *bind.WatchOpts, sink chan<- *SideChainManagerRegisterSideChain) (event.Subscription, error) { - - logs, sub, err := _SideChainManager.contract.WatchLogs(opts, "evtRegisterSideChain") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(SideChainManagerRegisterSideChain) - if err := _SideChainManager.contract.UnpackLog(event, "evtRegisterSideChain", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseRegisterSideChain is a log parse operation binding the contract event 0x844fd8662935c80c93372c0cb9eb5fd6db52835a3078934d65f762a9bfd13ea2. -// -// Solidity: event evtRegisterSideChain(uint64 ChainId, uint64 Router, string Name, uint64 BlocksToWait) -func (_SideChainManager *SideChainManagerFilterer) ParseRegisterSideChain(log types.Log) (*SideChainManagerRegisterSideChain, error) { - event := new(SideChainManagerRegisterSideChain) - if err := _SideChainManager.contract.UnpackLog(event, "evtRegisterSideChain", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// SideChainManagerSetBtcTxParamIterator is returned from FilterSetBtcTxParam and is used to iterate over the raw logs and unpacked data for SetBtcTxParam events raised by the SideChainManager contract. -type SideChainManagerSetBtcTxParamIterator struct { - Event *SideChainManagerSetBtcTxParam // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *SideChainManagerSetBtcTxParamIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(SideChainManagerSetBtcTxParam) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(SideChainManagerSetBtcTxParam) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *SideChainManagerSetBtcTxParamIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *SideChainManagerSetBtcTxParamIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// SideChainManagerSetBtcTxParam represents a SetBtcTxParam event raised by the SideChainManager contract. -type SideChainManagerSetBtcTxParam struct { - Rk string - RedeemChainId uint64 - FeeRate uint64 - MinChange uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterSetBtcTxParam is a free log retrieval operation binding the contract event 0x9d437e9e204401edf24ac2844b216c7276e0350ec67ec35417a8ca070ddbde7b. -// -// Solidity: event evtSetBtcTxParam(string rk, uint64 RedeemChainId, uint64 FeeRate, uint64 MinChange) -func (_SideChainManager *SideChainManagerFilterer) FilterSetBtcTxParam(opts *bind.FilterOpts) (*SideChainManagerSetBtcTxParamIterator, error) { - - logs, sub, err := _SideChainManager.contract.FilterLogs(opts, "evtSetBtcTxParam") - if err != nil { - return nil, err - } - return &SideChainManagerSetBtcTxParamIterator{contract: _SideChainManager.contract, event: "evtSetBtcTxParam", logs: logs, sub: sub}, nil -} - -// WatchSetBtcTxParam is a free log subscription operation binding the contract event 0x9d437e9e204401edf24ac2844b216c7276e0350ec67ec35417a8ca070ddbde7b. -// -// Solidity: event evtSetBtcTxParam(string rk, uint64 RedeemChainId, uint64 FeeRate, uint64 MinChange) -func (_SideChainManager *SideChainManagerFilterer) WatchSetBtcTxParam(opts *bind.WatchOpts, sink chan<- *SideChainManagerSetBtcTxParam) (event.Subscription, error) { - - logs, sub, err := _SideChainManager.contract.WatchLogs(opts, "evtSetBtcTxParam") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(SideChainManagerSetBtcTxParam) - if err := _SideChainManager.contract.UnpackLog(event, "evtSetBtcTxParam", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseSetBtcTxParam is a log parse operation binding the contract event 0x9d437e9e204401edf24ac2844b216c7276e0350ec67ec35417a8ca070ddbde7b. -// -// Solidity: event evtSetBtcTxParam(string rk, uint64 RedeemChainId, uint64 FeeRate, uint64 MinChange) -func (_SideChainManager *SideChainManagerFilterer) ParseSetBtcTxParam(log types.Log) (*SideChainManagerSetBtcTxParam, error) { - event := new(SideChainManagerSetBtcTxParam) - if err := _SideChainManager.contract.UnpackLog(event, "evtSetBtcTxParam", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// SideChainManagerUpdateSideChainIterator is returned from FilterUpdateSideChain and is used to iterate over the raw logs and unpacked data for UpdateSideChain events raised by the SideChainManager contract. -type SideChainManagerUpdateSideChainIterator struct { - Event *SideChainManagerUpdateSideChain // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *SideChainManagerUpdateSideChainIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(SideChainManagerUpdateSideChain) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(SideChainManagerUpdateSideChain) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *SideChainManagerUpdateSideChainIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *SideChainManagerUpdateSideChainIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// SideChainManagerUpdateSideChain represents a UpdateSideChain event raised by the SideChainManager contract. -type SideChainManagerUpdateSideChain struct { - ChainId uint64 - Router uint64 - Name string - BlocksToWait uint64 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterUpdateSideChain is a free log retrieval operation binding the contract event 0xefc07386ca56a4a4f14c5dfb934a955331872da7cc24748a6ca78be8c1741bbe. -// -// Solidity: event evtUpdateSideChain(uint64 ChainId, uint64 Router, string Name, uint64 BlocksToWait) -func (_SideChainManager *SideChainManagerFilterer) FilterUpdateSideChain(opts *bind.FilterOpts) (*SideChainManagerUpdateSideChainIterator, error) { - - logs, sub, err := _SideChainManager.contract.FilterLogs(opts, "evtUpdateSideChain") - if err != nil { - return nil, err - } - return &SideChainManagerUpdateSideChainIterator{contract: _SideChainManager.contract, event: "evtUpdateSideChain", logs: logs, sub: sub}, nil -} - -// WatchUpdateSideChain is a free log subscription operation binding the contract event 0xefc07386ca56a4a4f14c5dfb934a955331872da7cc24748a6ca78be8c1741bbe. -// -// Solidity: event evtUpdateSideChain(uint64 ChainId, uint64 Router, string Name, uint64 BlocksToWait) -func (_SideChainManager *SideChainManagerFilterer) WatchUpdateSideChain(opts *bind.WatchOpts, sink chan<- *SideChainManagerUpdateSideChain) (event.Subscription, error) { - - logs, sub, err := _SideChainManager.contract.WatchLogs(opts, "evtUpdateSideChain") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(SideChainManagerUpdateSideChain) - if err := _SideChainManager.contract.UnpackLog(event, "evtUpdateSideChain", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseUpdateSideChain is a log parse operation binding the contract event 0xefc07386ca56a4a4f14c5dfb934a955331872da7cc24748a6ca78be8c1741bbe. -// -// Solidity: event evtUpdateSideChain(uint64 ChainId, uint64 Router, string Name, uint64 BlocksToWait) -func (_SideChainManager *SideChainManagerFilterer) ParseUpdateSideChain(log types.Log) (*SideChainManagerUpdateSideChain, error) { - event := new(SideChainManagerUpdateSideChain) - if err := _SideChainManager.contract.UnpackLog(event, "evtUpdateSideChain", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} diff --git a/contracts/native/governance/abi.go b/contracts/native/governance/abi.go deleted file mode 100644 index b309db41..00000000 --- a/contracts/native/governance/abi.go +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package governance - -import ( - "fmt" - "math/big" - "strings" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" -) - -const ( - EventAddValidator = "addValidator" -) - -const abijson = `[ - {"type":"function","constant":true,"name":"` + MethodContractName + `","inputs":[],"outputs":[{"name":"_name","type":"string"}],"payable":false,"stateMutability":"view"}, - {"type":"function","constant":true,"name":"` + MethodGetEpoch + `","inputs":[],"outputs":[{"name":"_epoch","type":"uint256"}],"payable":false,"stateMutability":"view"}, - {"type":"function","constant":true,"name":"` + MethodAddValidator + `","inputs":[{"name":"validator","type":"address"}],"outputs":[{"name":"succeed","type":"bool"}]}, - {"type":"function","constant":true,"name":"` + MethodGetValidators + `","inputs":[],"outputs":[{"name":"list","type":"address[]"}]}, - {"type":"event","anonymous":false,"name":"` + EventAddValidator + `","inputs":[{"indexed":false,"name":"validator","type":"address"},{"indexed":false,"name":"succeed","type":"bool"}]} -]` - -func GetABI() abi.ABI { - ab, err := abi.JSON(strings.NewReader(abijson)) - if err != nil { - panic(fmt.Sprintf("failed to load PLT abi json string: [%v]", err)) - } - return ab -} - -type MethodNameInput struct{} -type MethodNameOutput struct { - Name string -} - -type MethodEpochInput struct{} -type MethodEpochOutput struct { - Epoch *big.Int -} - -// validators -type MethodAddValidatorInput struct { - Validator common.Address -} -type MethodAddValidatorOutput struct { - Succeed bool -} - -type MethodGetValidatorsInput struct{} -type MethodGetValidatorsOutput struct { - List []common.Address -} diff --git a/contracts/native/governance/governance.go b/contracts/native/governance/governance.go deleted file mode 100644 index e451a875..00000000 --- a/contracts/native/governance/governance.go +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package governance - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/utils" -) - -// todo: design and implement. - -const contractName = "Zion governance" - -const ( - MethodContractName = "name" - MethodGetEpoch = "epoch" - MethodAddValidator = "addValidator" - MethodGetValidators = "validators" -) - -var ( - this = native.NativeContractAddrMap[native.NativeGovernance] - - gasTable = map[string]uint64{ - MethodContractName: 0, - MethodGetEpoch: 0, - MethodAddValidator: 100000, - MethodGetValidators: 0, - } - - ABI abi.ABI -) - -func InitGovernance() { - ABI = GetABI() - native.Contracts[this] = RegisterGovernanceContract -} - -func RegisterGovernanceContract(s *native.NativeContract) { - s.Prepare(&ABI, gasTable) - - s.Register(MethodContractName, Name) - s.Register(MethodGetEpoch, GetEpoch) - s.Register(MethodAddValidator, AddValidator) - s.Register(MethodGetValidators, GetValidators) -} - -func Name(s *native.NativeContract) ([]byte, error) { - return utils.PackOutputs(&ABI, MethodContractName, contractName) -} - -func GetEpoch(s *native.NativeContract) ([]byte, error) { - testEpoch := big.NewInt(1) - return utils.PackOutputs(&ABI, MethodGetEpoch, testEpoch) -} - -func AddValidator(s *native.NativeContract) ([]byte, error) { - ctx := s.ContractRef().CurrentContext() - params := &MethodAddValidatorInput{} - if err := utils.UnpackMethod(&ABI, MethodAddValidator, params, ctx.Payload); err != nil { - return nil, err - } - - emitAddValidator(s, params.Validator, true) - return utils.PackOutputs(&ABI, MethodAddValidator, true) -} - -// todo: genesis nodes as validators in the first epoch -func GetValidators(s *native.NativeContract) ([]byte, error) { - return nil, nil -} - -func emitAddValidator(s *native.NativeContract, validator common.Address, succeed bool) { - topics := make([]common.Hash, 2) - topics[0] = ABI.Events[EventAddValidator].ID - topics[1] = utils.Address2Hash(validator) - data := utils.Bool2Bytes(succeed) - emitter := utils.NewEventEmitter(this, s.ContractRef().BlockHeight().Uint64(), s.StateDB()) - emitter.Event(topics, data) -} diff --git a/contracts/native/governance/governance_test.go b/contracts/native/governance/governance_test.go deleted file mode 100644 index 05753126..00000000 --- a/contracts/native/governance/governance_test.go +++ /dev/null @@ -1,98 +0,0 @@ -package governance - -import ( - "math/big" - "os" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/core/state" - "github.com/stretchr/testify/assert" -) - -var ( - testStateDB *state.StateDB - testEnv *native.ContractRef - testGasSupply = uint64(100000) - - testCaller = common.HexToAddress("0xab7ada5c57b3e796ec589bfe84bea3cb7ae47b63") -) - -func TestMain(m *testing.M) { - testStateDB = utils.NewTestStateDB() - InitGovernance() - - blockNumber := big.NewInt(1) - - testEnv = native.NewContractRef(testStateDB, testCaller, testCaller, blockNumber, common.Hash{}, testGasSupply, nil) - - os.Exit(m.Run()) -} - -func TestName(t *testing.T) { - name := MethodContractName - payload, err := utils.PackMethod(&ABI, name) - assert.NoError(t, err) - - enc, gasLeft, err := testEnv.NativeCall(testCaller, this, payload) - assert.NoError(t, err) - - expectGasLeft := uint64(testEnv.GasLeft() - gasTable[name]) - assert.Equal(t, expectGasLeft, gasLeft) - - output := new(MethodNameOutput) - err = utils.UnpackOutputs(&ABI, name, output, enc) - assert.NoError(t, err) - assert.Equal(t, contractName, output.Name) - t.Logf("left gas %d", gasLeft) -} - -func TestEpoch(t *testing.T) { - name := MethodGetEpoch - - payload, err := utils.PackMethod(&ABI, name) - assert.NoError(t, err) - - enc, gasLeft, err := testEnv.NativeCall(testCaller, this, payload) - assert.NoError(t, err) - - expectGasLeft := uint64(testEnv.GasLeft()) - assert.Equal(t, expectGasLeft, gasLeft) - - output := new(MethodEpochOutput) - err = utils.UnpackOutputs(&ABI, name, output, enc) - assert.NoError(t, err) - - assert.Equal(t, uint64(1), output.Epoch.Uint64()) -} - -func TestAddValidator(t *testing.T) { - name := MethodAddValidator - - expectValidator := common.HexToAddress("0x12345") - payload, err := utils.PackMethod(&ABI, name, expectValidator) - assert.NoError(t, err) - - enc, gasLeft, err := testEnv.NativeCall(testCaller, this, payload) - assert.NoError(t, err) - - expectGasLeft := uint64(testEnv.GasLeft()) - assert.Equal(t, expectGasLeft, gasLeft) - - output := new(MethodAddValidatorOutput) - err = utils.UnpackOutputs(&ABI, name, output, enc) - assert.NoError(t, err) - assert.Equal(t, true, output.Succeed) - - hash := testEnv.StateDB().BlockHash() - logs := testEnv.StateDB().GetLogs(hash) - assert.Equal(t, len(logs), 1) - - event := logs[0] - assert.Equal(t, 2, len(event.Topics)) - assert.Equal(t, ABI.Events[EventAddValidator].ID, event.Topics[0]) - assert.Equal(t, expectValidator, utils.Hash2Address(event.Topics[1])) - assert.Equal(t, utils.Bool2Bytes(true), event.Data) -} diff --git a/contracts/native/governance/maas_config/abi.go b/contracts/native/governance/maas_config/abi.go new file mode 100644 index 00000000..cbfec5d6 --- /dev/null +++ b/contracts/native/governance/maas_config/abi.go @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2021 The Zion Authors + * This file is part of The Zion library. + * + * The Zion is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Zion is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The Zion. If not, see . + */ + +package maas_config + +import ( + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/contracts/native/utils" +) + +const contractName = "maas config" + +const ( + + // abi + MaasConfigABI = "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"doBlock\",\"type\":\"bool\"}],\"name\":\"BlockAccount\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"ChangeOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"doEnable\",\"type\":\"bool\"}],\"name\":\"EnableGasManage\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"addrs\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"addOrRemove\",\"type\":\"bool\"}],\"name\":\"SetAdmins\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isManager\",\"type\":\"bool\"}],\"name\":\"SetGasManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"addrs\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"addOrRemove\",\"type\":\"bool\"}],\"name\":\"SetGasUsers\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"doBlock\",\"type\":\"bool\"}],\"name\":\"blockAccount\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"changeOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"doEnable\",\"type\":\"bool\"}],\"name\":\"enableGasManage\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminList\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlacklist\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasManagerList\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getGasUserList\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"isAdmin\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"isBlocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isGasManageEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"isGasManager\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"isGasUser\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"addrs\",\"type\":\"address[]\"},{\"internalType\":\"bool\",\"name\":\"addOrRemove\",\"type\":\"bool\"}],\"name\":\"setAdmins\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"isManager\",\"type\":\"bool\"}],\"name\":\"setGasManager\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"addrs\",\"type\":\"address[]\"},{\"internalType\":\"bool\",\"name\":\"addOrRemove\",\"type\":\"bool\"}],\"name\":\"setGasUsers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" + + // method name + MethodName = "name" + MethodChangeOwner = "changeOwner" + MethodGetOwner = "getOwner" + MethodBlockAccount = "blockAccount" + MethodIsBlocked = "isBlocked" + MethodGetBlacklist = "getBlacklist" + + MethodEnableGasManage = "enableGasManage" + MethodIsGasManageEnabled = "isGasManageEnabled" + MethodSetGasManager = "setGasManager" + MethodIsGasManager = "isGasManager" + MethodGetGasManagerList = "getGasManagerList" + + MethodSetGasUsers = "setGasUsers" + MethodIsGasUser = "isGasUser" + MethodGetGasUserList = "getGasUserList" + + MethodSetAdmins = "setAdmins" + MethodIsAdmin = "isAdmin" + MethodGetAdminList = "getAdminList" + + EventChangeOwner = "ChangeOwner" + EventBlockAccount = "BlockAccount" + EventEnableGasManage = "EnableGasManage" + EventSetGasManager = "SetGasManager" + EventSetGasUsers = "SetGasUsers" + EventSetAdmins = "SetAdmins" +) + +func InitABI() { + ab, err := abi.JSON(strings.NewReader(MaasConfigABI)) + if err != nil { + panic(fmt.Sprintf("failed to load abi json string: [%v]", err)) + } + ABI = &ab +} + +var ( + ABI *abi.ABI + this = utils.MaasConfigContractAddress +) + +type MethodContractNameOutput struct { + Name string +} + +func (m *MethodContractNameOutput) Encode() ([]byte, error) { + m.Name = contractName + return utils.PackOutputs(ABI, MethodName, m.Name) +} +func (m *MethodContractNameOutput) Decode(payload []byte) error { + return utils.UnpackOutputs(ABI, MethodName, m, payload) +} + +type MethodBoolOutput struct { + Success bool +} + +func (m *MethodBoolOutput) Encode(methodName string) ([]byte, error) { + return utils.PackOutputs(ABI, methodName, m.Success) +} + +func (m *MethodBoolOutput) Decode(payload []byte, methodName string) error { + return utils.UnpackOutputs(ABI, methodName, m, payload) +} + +type MethodAddressOutput struct { + Addr common.Address +} + +func (m *MethodAddressOutput) Encode(methodName string) ([]byte, error) { + return utils.PackOutputs(ABI, methodName, m.Addr) +} + +func (m *MethodAddressOutput) Decode(payload []byte, methodName string) error { + return utils.UnpackOutputs(ABI, methodName, m, payload) +} + +type MethodChangeOwnerInput struct { + Addr common.Address +} + +func (m *MethodChangeOwnerInput) Encode() ([]byte, error) { + return utils.PackMethod(ABI, MethodChangeOwner, m.Addr) +} + +func (m *MethodChangeOwnerInput) Decode(payload []byte) error { + var data struct { + Addr common.Address + } + if err := utils.UnpackMethod(ABI, MethodChangeOwner, &data, payload); err != nil { + return err + } + m.Addr = data.Addr + return nil +} + +type MethodBlockAccountInput struct { + Addr common.Address + DoBlock bool +} + +func (m *MethodBlockAccountInput) Encode() ([]byte, error) { + return utils.PackMethod(ABI, MethodBlockAccount, m.Addr, m.DoBlock) +} + +func (m *MethodBlockAccountInput) Decode(payload []byte) error { + var data struct { + Addr common.Address + DoBlock bool + } + if err := utils.UnpackMethod(ABI, MethodBlockAccount, &data, payload); err != nil { + return err + } + m.Addr = data.Addr + m.DoBlock = data.DoBlock + return nil +} + +type MethodIsBlockedInput struct { + Addr common.Address +} + +func (m *MethodIsBlockedInput) Encode() ([]byte, error) { + return utils.PackMethod(ABI, MethodIsBlocked, m.Addr) +} + +func (m *MethodIsBlockedInput) Decode(payload []byte) error { + var data struct { + Addr common.Address + } + if err := utils.UnpackMethod(ABI, MethodIsBlocked, &data, payload); err != nil { + return err + } + m.Addr = data.Addr + return nil +} + +type MethodStringOutput struct { + Result string +} + +func (m *MethodStringOutput) Encode(methodName string) ([]byte, error) { + return utils.PackOutputs(ABI, methodName, m.Result) +} + +func (m *MethodStringOutput) Decode(payload []byte, methodName string) error { + return utils.UnpackOutputs(ABI, methodName, m, payload) +} + +type MethodEnableGasManageInput struct { + DoEnable bool +} + +func (m *MethodEnableGasManageInput) Encode() ([]byte, error) { + return utils.PackMethod(ABI, MethodEnableGasManage, m.DoEnable) +} + +func (m *MethodEnableGasManageInput) Decode(payload []byte) error { + return utils.UnpackMethod(ABI, MethodEnableGasManage, m, payload) +} + +type MethodSetGasManagerInput struct { + Addr common.Address + IsManager bool +} + +func (m *MethodSetGasManagerInput) Encode() ([]byte, error) { + return utils.PackMethod(ABI, MethodSetGasManager, m.Addr, m.IsManager) +} + +func (m *MethodSetGasManagerInput) Decode(payload []byte) error { + return utils.UnpackMethod(ABI, MethodSetGasManager, m, payload) +} + +type MethodIsGasManagerInput struct { + Addr common.Address +} + +func (m *MethodIsGasManagerInput) Encode() ([]byte, error) { + return utils.PackMethod(ABI, MethodIsGasManager, m.Addr) +} + +func (m *MethodIsGasManagerInput) Decode(payload []byte) error { + return utils.UnpackMethod(ABI, MethodIsGasManager, m, payload) +} + +type MethodSetGasUsersInput struct { + Addrs []common.Address + AddOrRemove bool +} + +func (m *MethodSetGasUsersInput) Encode() ([]byte, error) { + return utils.PackMethod(ABI, MethodSetGasUsers, m.Addrs, m.AddOrRemove) +} + +func (m *MethodSetGasUsersInput) Decode(payload []byte) error { + return utils.UnpackMethod(ABI, MethodSetGasUsers, m, payload) +} + +type MethodIsGasUserInput struct { + Addr common.Address +} + +func (m *MethodIsGasUserInput) Encode() ([]byte, error) { + return utils.PackMethod(ABI, MethodIsGasUser, m.Addr) +} + +func (m *MethodIsGasUserInput) Decode(payload []byte) error { + return utils.UnpackMethod(ABI, MethodIsGasUser, m, payload) +} + +type MethodSetAdminsInput struct { + Addrs []common.Address + AddOrRemove bool +} + +func (m *MethodSetAdminsInput) Encode() ([]byte, error) { + return utils.PackMethod(ABI, MethodSetAdmins, m.Addrs, m.AddOrRemove) +} + +func (m *MethodSetAdminsInput) Decode(payload []byte) error { + return utils.UnpackMethod(ABI, MethodSetAdmins, m, payload) +} + +type MethodIsAdminInput struct { + Addr common.Address +} + +func (m *MethodIsAdminInput) Encode() ([]byte, error) { + return utils.PackMethod(ABI, MethodIsAdmin, m.Addr) +} + +func (m *MethodIsAdminInput) Decode(payload []byte) error { + return utils.UnpackMethod(ABI, MethodIsAdmin, m, payload) +} diff --git a/contracts/native/governance/maas_config/abi_test.go b/contracts/native/governance/maas_config/abi_test.go new file mode 100644 index 00000000..640f75d8 --- /dev/null +++ b/contracts/native/governance/maas_config/abi_test.go @@ -0,0 +1,277 @@ +package maas_config + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/contracts/native/utils" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/assert" +) + +func TestABIShowJonString(t *testing.T) { + t.Log(MaasConfigABI) + for name, v := range ABI.Methods { + t.Logf("method %s, id %s", name, hexutil.Encode(v.ID)) + } + t.Log("\n") +} + +var testAddresses = []common.Address{ + common.HexToAddress("0x2D3913c12ACa0E4A2278f829Fb78A682123c0125"), + common.HexToAddress("0x2D3913c12ACa0E4A2278f829Fb78A682123c0126"), + common.HexToAddress("0x2D3913c12ACa0E4A2278f829Fb78A682123c0127"), + common.HexToAddress("0x2D3913c12ACa0E4A2278f829Fb78A682123c0128"), + common.HexToAddress("0x2D3913c12ACa0E4A2278f829Fb78A682123c0129"), +} + +func TestABIMethodContractName(t *testing.T) { + + enc, err := utils.PackOutputs(ABI, MethodName, contractName) + assert.NoError(t, err) + params := new(MethodContractNameOutput) + assert.NoError(t, utils.UnpackOutputs(ABI, MethodName, params, enc)) + assert.Equal(t, contractName, params.Name) +} + +func TestABIMethodChangeOwnerInput(t *testing.T) { + expect := &MethodChangeOwnerInput{Addr: testAddresses[0]} + enc, err := expect.Encode() + assert.NoError(t, err) + methodId := hexutil.Encode(crypto.Keccak256([]byte("changeOwner(address)"))[:4]) + assert.Equal(t, methodId, hexutil.Encode(enc)[:10]) + got := new(MethodChangeOwnerInput) + assert.NoError(t, got.Decode(enc)) + assert.Equal(t, expect, got) +} + +func TestABIMethodChangeOwnerOutput(t *testing.T) { + var cases = []struct { + Result bool + }{ + { + Result: true, + }, + { + Result: false, + }, + } + + for _, testCase := range cases { + output := &MethodBoolOutput{Success: testCase.Result} + enc, err := output.Encode(MethodChangeOwner) + assert.NoError(t, err) + + got := new(MethodBoolOutput) + err = got.Decode(enc, MethodChangeOwner) + assert.NoError(t, err) + + assert.Equal(t, output, got) + } +} + +func TestABIMethodGetOwnerOutput(t *testing.T) { + var cases = []struct { + Addr common.Address + }{ + { + Addr: testAddresses[0], + }, + { + Addr: testAddresses[1], + }, + } + + for _, testCase := range cases { + output := &MethodAddressOutput{Addr: testCase.Addr} + enc, err := output.Encode(MethodGetOwner) + assert.NoError(t, err) + + got := new(MethodAddressOutput) + err = got.Decode(enc, MethodGetOwner) + assert.NoError(t, err) + + assert.Equal(t, output, got) + } +} + +func TestMethodBlockAccountInput(t *testing.T) { + var cases = []struct { + Addr common.Address + DoBlock bool + }{ + { + Addr: testAddresses[0], + DoBlock: false, + }, + { + Addr: testAddresses[1], + DoBlock: true, + }, + } + + for _, testCase := range cases { + output := &MethodBlockAccountInput{Addr: testCase.Addr, DoBlock: testCase.DoBlock} + enc, err := output.Encode() + assert.NoError(t, err) + + methodId := hexutil.Encode(crypto.Keccak256([]byte("blockAccount(address,bool)"))[:4]) + assert.Equal(t, methodId, hexutil.Encode(enc)[:10]) + + got := new(MethodBlockAccountInput) + err = got.Decode(enc) + assert.NoError(t, err) + assert.Equal(t, got, output) + } +} + +func TestMethodBlockAccountOutput(t *testing.T) { + var cases = []struct { + Success bool + }{ + {true}, + {false}, + } + + for _, testCase := range cases { + output := &MethodBoolOutput{Success: testCase.Success} + enc, err := output.Encode(MethodBlockAccount) + assert.NoError(t, err) + + got := new(MethodBoolOutput) + err = got.Decode(enc, MethodBlockAccount) + assert.NoError(t, err) + + assert.Equal(t, got, output) + } +} + +func TestMethodIsBlockedInput(t *testing.T) { + var cases = []struct{ Addr common.Address }{ + {testAddresses[1]}, + {testAddresses[0]}, + } + + for _, testCase := range cases { + input := &MethodIsBlockedInput{testCase.Addr} + enc, err := input.Encode() + assert.NoError(t, err) + + methodId := hexutil.Encode(crypto.Keccak256([]byte("isBlocked(address)"))[:4]) + assert.Equal(t, methodId, hexutil.Encode(enc)[:10]) + + got := new(MethodIsBlockedInput) + err = got.Decode(enc) + assert.NoError(t, err) + assert.Equal(t, got, input) + } +} + +func TestMethodIsBlockedOutput(t *testing.T) { + var cases = []struct{ Success bool }{ + {true}, + {false}, + } + + for _, testCase := range cases { + output := &MethodBoolOutput{testCase.Success} + enc, err := output.Encode(MethodIsBlocked) + assert.NoError(t, err) + + got := new(MethodBoolOutput) + err = got.Decode(enc, MethodIsBlocked) + assert.NoError(t, err) + assert.Equal(t, got, output) + } +} + +func TestMethodGetBlacklistOutput(t *testing.T) { + var cases = []struct{ Result string }{ + {"Success"}, + {"Fail"}, + } + + for _, testCase := range cases { + output := &MethodStringOutput{testCase.Result} + enc, err := output.Encode(MethodGetBlacklist) + assert.NoError(t, err) + + got := new(MethodStringOutput) + err = got.Decode(enc, MethodGetBlacklist) + assert.NoError(t, err) + assert.Equal(t, got, output) + } +} + +func TestMethodEnableGasManageInput(t *testing.T) { + var cases = []struct{ DoEnable bool }{ + {true}, + {false}, + } + + for _, testCase := range cases { + input := &MethodEnableGasManageInput{testCase.DoEnable} + enc, err := input.Encode() + assert.NoError(t, err) + + methodId := hexutil.Encode(crypto.Keccak256([]byte(MethodEnableGasManage + "(bool)"))[:4]) + assert.Equal(t, methodId, hexutil.Encode(enc)[:10]) + + got := new(MethodEnableGasManageInput) + err = got.Decode(enc) + assert.NoError(t, err) + assert.Equal(t, got, input) + } +} + +func TestMethodSetGasManagerInput(t *testing.T) { + var cases = []struct { + Addr common.Address + IsWhite bool + }{ + { + Addr: testAddresses[0], + IsWhite: false, + }, + { + Addr: testAddresses[1], + IsWhite: true, + }, + } + + for _, testCase := range cases { + input := &MethodSetGasManagerInput{testCase.Addr, testCase.IsWhite} + enc, err := input.Encode() + assert.NoError(t, err) + + methodId := hexutil.Encode(crypto.Keccak256([]byte(MethodSetGasManager + "(address,bool)"))[:4]) + assert.Equal(t, methodId, hexutil.Encode(enc)[:10]) + + got := new(MethodSetGasManagerInput) + err = got.Decode(enc) + assert.NoError(t, err) + assert.Equal(t, got, input) + } +} + +func TestMethodIsGasManagerInput(t *testing.T) { + var cases = []struct{ Addr common.Address }{ + {testAddresses[1]}, + {testAddresses[0]}, + } + + for _, testCase := range cases { + input := &MethodIsGasManagerInput{testCase.Addr} + enc, err := input.Encode() + assert.NoError(t, err) + + methodId := hexutil.Encode(crypto.Keccak256([]byte(MethodIsGasManager + "(address)"))[:4]) + assert.Equal(t, methodId, hexutil.Encode(enc)[:10]) + + got := new(MethodIsGasManagerInput) + err = got.Decode(enc) + assert.NoError(t, err) + assert.Equal(t, got, input) + } +} diff --git a/contracts/native/governance/maas_config/config.go b/contracts/native/governance/maas_config/config.go new file mode 100644 index 00000000..060b88a8 --- /dev/null +++ b/contracts/native/governance/maas_config/config.go @@ -0,0 +1,527 @@ +/* + * Copyright (C) 2021 The Zion Authors + * This file is part of The Zion library. + * + * The Zion is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Zion is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The Zion. If not, see . + */ + +package maas_config + +import ( + "encoding/json" + "errors" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/contracts/native" + "github.com/ethereum/go-ethereum/contracts/native/contract" + "github.com/ethereum/go-ethereum/contracts/native/utils" + "github.com/ethereum/go-ethereum/log" +) + +var ( + gasTable = map[string]uint64{ + MethodName: 0, + MethodChangeOwner: 30000, + MethodGetOwner: 0, + MethodBlockAccount: 30000, + MethodIsBlocked: 0, + MethodGetBlacklist: 0, + + MethodEnableGasManage: 30000, + MethodSetGasManager: 30000, + MethodIsGasManageEnabled: 0, + MethodIsGasManager: 0, + MethodGetGasManagerList: 0, + + MethodSetGasUsers: 30000, + MethodIsGasUser: 0, + MethodGetGasUserList: 0, + + MethodSetAdmins: 30000, + MethodIsAdmin: 0, + MethodGetAdminList: 0, + } +) + +func InitMaasConfig() { + InitABI() + native.Contracts[this] = RegisterMaasConfigContract +} + +func RegisterMaasConfigContract(s *native.NativeContract) { + s.Prepare(ABI, gasTable) + + s.Register(MethodName, Name) + s.Register(MethodChangeOwner, ChangeOwner) + s.Register(MethodGetOwner, GetOwner) + + s.Register(MethodBlockAccount, BlockAccount) + s.Register(MethodIsBlocked, IsBlocked) + s.Register(MethodGetBlacklist, GetBlacklist) + + s.Register(MethodEnableGasManage, EnableGasManage) + s.Register(MethodSetGasManager, SetGasManager) + s.Register(MethodIsGasManageEnabled, IsGasManageEnabled) + s.Register(MethodIsGasManager, IsGasManager) + s.Register(MethodGetGasManagerList, GetGasManagerList) + + s.Register(MethodSetGasUsers, SetGasUsers) + s.Register(MethodIsGasUser, IsGasUser) + s.Register(MethodGetGasUserList, GetGasUserList) + + s.Register(MethodSetAdmins, SetAdmins) + s.Register(MethodIsAdmin, IsAdmin) + s.Register(MethodGetAdminList, GetAdminList) +} + +func Name(s *native.NativeContract) ([]byte, error) { + return new(MethodContractNameOutput).Encode() +} + +// change owner +func ChangeOwner(s *native.NativeContract) ([]byte, error) { + ctx := s.ContractRef().CurrentContext() + caller := ctx.Caller + + // check caller == origin + if err := contract.ValidateOwner(s, caller); err != nil { + return utils.ByteFailed, errors.New("caller is not equal to origin") + } + + // check owner + currentOwner := getOwner(s) + if currentOwner != common.EmptyAddress && caller != currentOwner { + return utils.ByteFailed, errors.New("invalid authority for owner") + } + + // decode input + input := new(MethodChangeOwnerInput) + if err := input.Decode(ctx.Payload); err != nil { + log.Trace("ChangeOwner", "decode input failed", err) + return utils.ByteFailed, errors.New("invalid input") + } + + // verify new owner address + m := getAddressMap(s, blacklistKey) + _, ok := m[input.Addr] + if ok { + err := errors.New("new owner address in blacklist") + log.Trace("ChangeOwner", "invalid new owner", err) + return utils.ByteFailed, err + } + + // store owner + set(s, ownerKey, input.Addr.Bytes()) + + // emit event log + if err := s.AddNotify(ABI, []string{EventChangeOwner}, common.BytesToHash(currentOwner.Bytes()), common.BytesToHash(input.Addr.Bytes())); err != nil { + log.Trace("ChangeOwner", "emit event log failed", err) + return utils.ByteFailed, errors.New("emit EventChangeOwner error") + } + + return utils.ByteSuccess, nil +} + +// get owner +func GetOwner(s *native.NativeContract) ([]byte, error) { + output := &MethodAddressOutput{Addr: getOwner(s)} + return output.Encode(MethodGetOwner) +} + +func getOwner(s *native.NativeContract) common.Address { + // get value + value, _ := get(s, ownerKey) + if len(value) == 0 { + return common.EmptyAddress + } + return common.BytesToAddress(value) +} + +func checkOwner(s *native.NativeContract) error { + caller := s.ContractRef().CurrentContext().Caller + origin := s.ContractRef().TxOrigin() + if caller != origin { + return errors.New("caller is not equal to origin") + } + + if origin != getOwner(s) { + return errors.New("invalid authority for owner") + } + return nil +} + +func isAdmin(s *native.NativeContract) bool { + origin := s.ContractRef().TxOrigin() + m := getAddressMap(s, gasAdminListKey) + _, ok := m[origin] + return ok +} + +func checkOwnerOrAdmin(s *native.NativeContract) error { + caller := s.ContractRef().CurrentContext().Caller + origin := s.ContractRef().TxOrigin() + if caller != origin { + return errors.New("caller is not equal to origin") + } + + if origin != getOwner(s) && !isAdmin(s) { + return errors.New("invalid authority for owner or admin") + } + return nil +} + +// block account(add account to blacklist map) or unblock account +func BlockAccount(s *native.NativeContract) ([]byte, error) { + ctx := s.ContractRef().CurrentContext() + + // check owner + if err := checkOwner(s); err != nil { + return utils.ByteFailed, err + } + + // decode input + input := new(MethodBlockAccountInput) + if err := input.Decode(ctx.Payload); err != nil { + log.Trace("blockAccount", "decode input failed", err) + return utils.ByteFailed, errors.New("invalid input") + } + + currentOwner := getOwner(s) + if input.Addr == currentOwner { + err := errors.New("block owner is forbidden") + log.Trace("blockAccount", "block owner is forbidden", err) + return utils.ByteFailed, err + } + + m := getAddressMap(s, blacklistKey) + if input.DoBlock { + m[input.Addr] = struct{}{} + } else { + delete(m, input.Addr) + } + + value, err := json.Marshal(m) + if err != nil { + log.Trace("blockAccount", "encode value failed", err) + return utils.ByteFailed, errors.New("encode value failed") + } + set(s, blacklistKey, value) + + // emit event log + if err := s.AddNotify(ABI, []string{EventBlockAccount}, common.BytesToHash(input.Addr.Bytes()), input.DoBlock); err != nil { + log.Trace("blockAccount", "emit event log failed", err) + return utils.ByteFailed, errors.New("emit EventBlockAccount error") + } + + return utils.ByteSuccess, nil +} + +func getAddressMap(s *native.NativeContract, key []byte) map[common.Address]struct{} { + value, _ := get(s, key) + m := make(map[common.Address]struct{}) + if len(value) > 0 { + if err := json.Unmarshal(value, &m); err != nil { + log.Trace("getAddressMap", "decode value failed", err) + } + } + return m +} + +// check if account is blocked +func IsBlocked(s *native.NativeContract) ([]byte, error) { + ctx := s.ContractRef().CurrentContext() + + // decode input + input := new(MethodIsBlockedInput) + if err := input.Decode(ctx.Payload); err != nil { + log.Trace("IsBlocked", "decode input failed", err) + return utils.ByteFailed, errors.New("invalid input") + } + + // get value + m := getAddressMap(s, blacklistKey) + _, ok := m[input.Addr] + output := &MethodBoolOutput{Success: ok} + + return output.Encode(MethodIsBlocked) +} + +// get blacklist json +func GetBlacklist(s *native.NativeContract) ([]byte, error) { + // get value + m := getAddressMap(s, blacklistKey) + list := make([]common.Address, 0, len(m)) + for key := range m { + list = append(list, key) + } + result, _ := json.Marshal(list) + output := &MethodStringOutput{Result: string(result)} + return output.Encode(MethodGetBlacklist) +} + +// enable gas manage +func EnableGasManage(s *native.NativeContract) ([]byte, error) { + ctx := s.ContractRef().CurrentContext() + + // check owner + if err := checkOwner(s); err != nil { + return utils.ByteFailed, err + } + + // decode input + input := new(MethodEnableGasManageInput) + if err := input.Decode(ctx.Payload); err != nil { + log.Trace("EnableGasManage", "decode input failed", err) + return utils.ByteFailed, errors.New("invalid input") + } + + // set enable status + if input.DoEnable { + set(s, gasManageEnableKey, utils.BYTE_TRUE) + } else { + del(s, gasManageEnableKey) + } + + // emit event log + if err := s.AddNotify(ABI, []string{EventEnableGasManage}, input.DoEnable); err != nil { + log.Trace("EnableGasManage", "emit event log failed", err) + return utils.ByteFailed, errors.New("emit EventEnableGasManage error") + } + + return utils.ByteSuccess, nil +} + +// check if gas manage is enabled +func IsGasManageEnabled(s *native.NativeContract) ([]byte, error) { + // get value + value, _ := get(s, gasManageEnableKey) + output := &MethodBoolOutput{Success: len(value) > 0} + return output.Encode(MethodIsGasManageEnabled) +} + +// set gas manager address +func SetGasManager(s *native.NativeContract) ([]byte, error) { + ctx := s.ContractRef().CurrentContext() + + // check owner + if err := checkOwner(s); err != nil { + return utils.ByteFailed, err + } + + // decode input + input := new(MethodSetGasManagerInput) + if err := input.Decode(ctx.Payload); err != nil { + log.Trace("SetGasManager", "decode input failed", err) + return utils.ByteFailed, errors.New("invalid input") + } + + m := getAddressMap(s, gasManagerListKey) + if input.IsManager { + m[input.Addr] = struct{}{} + } else { + delete(m, input.Addr) + } + + value, err := json.Marshal(m) + if err != nil { + log.Trace("SetGasManager", "encode value failed", err) + return utils.ByteFailed, errors.New("encode value failed") + } + set(s, gasManagerListKey, value) + + // emit event log + if err := s.AddNotify(ABI, []string{EventSetGasManager}, common.BytesToHash(input.Addr.Bytes()), input.IsManager); err != nil { + log.Trace("SetGasManager", "emit event log failed", err) + return utils.ByteFailed, errors.New("emit EventSetGasManager error") + } + + return utils.ByteSuccess, nil +} + +// check if address is in gas manager list +func IsGasManager(s *native.NativeContract) ([]byte, error) { + ctx := s.ContractRef().CurrentContext() + + // decode input + input := new(MethodIsGasManagerInput) + if err := input.Decode(ctx.Payload); err != nil { + log.Trace("IsGasManager", "decode input failed", err) + return utils.ByteFailed, errors.New("invalid input") + } + + // get value + m := getAddressMap(s, gasManagerListKey) + _, ok := m[input.Addr] + output := &MethodBoolOutput{Success: ok} + + return output.Encode(MethodIsGasManager) +} + +// get gas manager list json +func GetGasManagerList(s *native.NativeContract) ([]byte, error) { + // get value + m := getAddressMap(s, gasManagerListKey) + list := make([]common.Address, 0, len(m)) + for key := range m { + list = append(list, key) + } + result, _ := json.Marshal(list) + output := &MethodStringOutput{Result: string(result)} + return output.Encode(MethodGetGasManagerList) +} + +// set gas users +func SetGasUsers(s *native.NativeContract) ([]byte, error) { + ctx := s.ContractRef().CurrentContext() + + // check owner + if err := checkOwnerOrAdmin(s); err != nil { + return utils.ByteFailed, err + } + + // decode input + input := new(MethodSetGasUsersInput) + if err := input.Decode(ctx.Payload); err != nil { + log.Trace("SetGasUsers", "decode input failed", err) + return utils.ByteFailed, errors.New("invalid input") + } + + m := getAddressMap(s, gasUserListKey) + for _, v := range input.Addrs { + if input.AddOrRemove { + m[v] = struct{}{} + } else { + delete(m, v) + } + } + + value, err := json.Marshal(m) + if err != nil { + log.Trace("SetGasUsers", "encode value failed", err) + return utils.ByteFailed, errors.New("encode value failed") + } + set(s, gasUserListKey, value) + + // emit event log + if err := s.AddNotify(ABI, []string{EventSetGasUsers}, input.Addrs, input.AddOrRemove); err != nil { + log.Trace("SetGasUsers", "emit event log failed", err) + return utils.ByteFailed, errors.New("emit EventSetGasUsers error") + } + + return utils.ByteSuccess, nil +} + +// check if address is in gas user list +func IsGasUser(s *native.NativeContract) ([]byte, error) { + ctx := s.ContractRef().CurrentContext() + + // decode input + input := new(MethodIsGasUserInput) + if err := input.Decode(ctx.Payload); err != nil { + log.Trace("IsGasUser", "decode input failed", err) + return utils.ByteFailed, errors.New("invalid input") + } + + // get value + m := getAddressMap(s, gasUserListKey) + _, ok := m[input.Addr] + output := &MethodBoolOutput{Success: ok} + + return output.Encode(MethodIsGasUser) +} + +// get gas user list json +func GetGasUserList(s *native.NativeContract) ([]byte, error) { + // get value + m := getAddressMap(s, gasUserListKey) + list := make([]common.Address, 0, len(m)) + for key := range m { + list = append(list, key) + } + result, _ := json.Marshal(list) + output := &MethodStringOutput{Result: string(result)} + return output.Encode(MethodGetGasUserList) +} + +// set admins +func SetAdmins(s *native.NativeContract) ([]byte, error) { + ctx := s.ContractRef().CurrentContext() + + // check owner + if err := checkOwner(s); err != nil { + return utils.ByteFailed, err + } + + // decode input + input := new(MethodSetAdminsInput) + if err := input.Decode(ctx.Payload); err != nil { + log.Trace("SetAdmins", "decode input failed", err) + return utils.ByteFailed, errors.New("invalid input") + } + + m := getAddressMap(s, gasAdminListKey) + for _, v := range input.Addrs { + if input.AddOrRemove { + m[v] = struct{}{} + } else { + delete(m, v) + } + } + + value, err := json.Marshal(m) + if err != nil { + log.Trace("SetAdmins", "encode value failed", err) + return utils.ByteFailed, errors.New("encode value failed") + } + set(s, gasAdminListKey, value) + + // emit event log + if err := s.AddNotify(ABI, []string{EventSetAdmins}, input.Addrs, input.AddOrRemove); err != nil { + log.Trace("SetAdmins", "emit event log failed", err) + return utils.ByteFailed, errors.New("emit EventSetAdmins error") + } + + return utils.ByteSuccess, nil +} + +// check if address is in admin list +func IsAdmin(s *native.NativeContract) ([]byte, error) { + ctx := s.ContractRef().CurrentContext() + + // decode input + input := new(MethodIsAdminInput) + if err := input.Decode(ctx.Payload); err != nil { + log.Trace("IsAdmin", "decode input failed", err) + return utils.ByteFailed, errors.New("invalid input") + } + + // get value + m := getAddressMap(s, gasAdminListKey) + _, ok := m[input.Addr] + output := &MethodBoolOutput{Success: ok} + + return output.Encode(MethodIsAdmin) +} + +// get admin list json +func GetAdminList(s *native.NativeContract) ([]byte, error) { + m := getAddressMap(s, gasAdminListKey) + list := make([]common.Address, 0, len(m)) + for key := range m { + list = append(list, key) + } + result, _ := json.Marshal(list) + output := &MethodStringOutput{Result: string(result)} + return output.Encode(MethodGetAdminList) +} diff --git a/contracts/native/governance/maas_config/config_test.go b/contracts/native/governance/maas_config/config_test.go new file mode 100644 index 00000000..8da8f87a --- /dev/null +++ b/contracts/native/governance/maas_config/config_test.go @@ -0,0 +1,517 @@ +package maas_config + +import ( + "crypto/rand" + "encoding/json" + "errors" + "math/big" + "os" + "strconv" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/contracts/native" + "github.com/ethereum/go-ethereum/contracts/native/utils" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/stretchr/testify/assert" +) + +func TestMain(m *testing.M) { + InitMaasConfig() + os.Exit(m.Run()) +} + +var ( + testStateDB *state.StateDB + testEmptyCtx *native.NativeContract + + testSupplyGas uint64 = 100000000000000000 + testCaller common.Address +) + +func generateNativeContractRef(origin common.Address, blockNum int) *native.ContractRef { + token := make([]byte, common.HashLength) + rand.Read(token) + hash := common.BytesToHash(token) + return native.NewContractRef(testStateDB, origin, origin, big.NewInt(int64(blockNum)), hash, testSupplyGas, nil) +} + +func generateNativeContract(origin common.Address, blockNum int) *native.NativeContract { + ref := generateNativeContractRef(origin, blockNum) + return native.NewNativeContract(testStateDB, ref) +} + +func resetTestContext() { + db := rawdb.NewMemoryDatabase() + testStateDB, _ = state.New(common.Hash{}, state.NewDatabase(db), nil) + testEmptyCtx = native.NewNativeContract(testStateDB, nil) + testCaller = testAddresses[0] +} + +func TestChangeAndGetOwner(t *testing.T) { + type TestCase struct { + Payload []byte + BeforeHandler func(c *TestCase, ctx *native.NativeContract) + AfterHandler func(c *TestCase, ctx *native.NativeContract) + Expect error + ReturnData bool + } + + cases := []*TestCase{ + { + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + input := &MethodChangeOwnerInput{Addr: testAddresses[0]} + c.Payload, _ = input.Encode() + }, + Expect: nil, + ReturnData: true, + }, + { + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + payload, err := utils.PackMethod(ABI, MethodGetOwner) + assert.NoError(t, err) + c.Payload = payload + }, + Expect: nil, + }, + } + + resetTestContext() + ctx := generateNativeContract(testCaller, 3) + + for k, v := range cases { + if v.BeforeHandler != nil { + v.BeforeHandler(v, ctx) + } + result, _, err := ctx.ContractRef().NativeCall(testCaller, this, v.Payload) + assert.Equal(t, v.Expect, err) + if k == 0 { + res, err := strconv.ParseBool(string(result)) + assert.NoError(t, err) + t.Log("changeOwner result: ", res) + assert.Equal(t, v.ReturnData, res) + } + if k == 1 { + t.Log("getOwner result: ", hexutil.Encode(result)) + assert.Equal(t, common.HexToAddress(common.Bytes2Hex(result)), testAddresses[0]) + } + if v.AfterHandler != nil { + v.AfterHandler(v, ctx) + } + } +} + +func setDefaultOwner(ctx *native.NativeContract) { + input := &MethodChangeOwnerInput{Addr: testAddresses[0]} + payload, _ := input.Encode() + result, _, err := ctx.ContractRef().NativeCall(testCaller, this, payload) + if err != nil { + panic(err) + } + res, _ := strconv.ParseBool(string(result)) + if !res { + panic("setDefaultOwner error") + } +} + +func TestMethodBlockAccount(t *testing.T) { + type TestCase struct { + BlockNum int + Payload []byte + BeforeHandler func(c *TestCase, ctx *native.NativeContract) + AfterHandler func(c *TestCase, ctx *native.NativeContract) + ReturnData []byte + Expect error + } + cases := []*TestCase{ + { + BlockNum: 3, + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + input := &MethodBlockAccountInput{Addr: testAddresses[3], DoBlock: true} + c.Payload, _ = input.Encode() + }, + ReturnData: []byte{'0'}, + Expect: errors.New("invalid authority for owner"), + }, + { + BlockNum: 3, + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + setDefaultOwner(ctx) + input := &MethodBlockAccountInput{Addr: testAddresses[3], DoBlock: true} + c.Payload, _ = input.Encode() + }, + ReturnData: []byte{'1'}, + Expect: nil, + }, + { + BlockNum: 3, + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + setDefaultOwner(ctx) + input := &MethodBlockAccountInput{Addr: testAddresses[3], DoBlock: false} + c.Payload, _ = input.Encode() + }, + ReturnData: []byte{'1'}, + Expect: nil, + }, + { + BlockNum: 3, + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + setDefaultOwner(ctx) + input := &MethodBlockAccountInput{Addr: testAddresses[4], DoBlock: false} + c.Payload, _ = input.Encode() + }, + ReturnData: []byte{'1'}, + Expect: nil, + }, + } + + resetTestContext() + for _, v := range cases { + ctx := generateNativeContract(testCaller, v.BlockNum) + + if v.BeforeHandler != nil { + v.BeforeHandler(v, ctx) + } + result, _, err := ctx.ContractRef().NativeCall(testCaller, this, v.Payload) + assert.Equal(t, v.Expect, err) + t.Log("blockAccount result: ", string(result)) + assert.Equal(t, v.ReturnData, result) + if v.AfterHandler != nil { + v.AfterHandler(v, ctx) + } + } +} + +func blockTestAccount(ctx *native.NativeContract) { + input := &MethodBlockAccountInput{Addr: testAddresses[3], DoBlock: true} + payload, _ := input.Encode() + result, _, err := ctx.ContractRef().NativeCall(testCaller, this, payload) + if err != nil || result[0] != utils.ByteSuccess[0] { + panic("blockTestAccount err: " + err.Error()) + } +} + +func TestMethodGetBlacklist(t *testing.T) { + type TestCase struct { + BlockNum int + Payload []byte + BeforeHandler func(c *TestCase, ctx *native.NativeContract) + AfterHandler func(c *TestCase, ctx *native.NativeContract) + BlackList []common.Address + Expect error + } + + cases := []*TestCase{ + { + BlockNum: 3, + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + c.Payload, _ = utils.PackMethod(ABI, MethodGetBlacklist) + }, + BlackList: []common.Address{}, + Expect: nil, + }, + { + BlockNum: 3, + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + setDefaultOwner(ctx) + blockTestAccount(ctx) + c.Payload, _ = utils.PackMethod(ABI, MethodGetBlacklist) + }, + BlackList: []common.Address{testAddresses[3]}, + Expect: nil, + }, + } + + for _, v := range cases { + resetTestContext() + ctx := generateNativeContract(testCaller, v.BlockNum) + if v.BeforeHandler != nil { + v.BeforeHandler(v, ctx) + } + result, _, err := ctx.ContractRef().NativeCall(testCaller, this, v.Payload) + assert.Equal(t, v.Expect, err) + + got := new(MethodStringOutput) + err = got.Decode(result, MethodGetBlacklist) + assert.NoError(t, err) + list := make([]common.Address, 1) + json.Unmarshal([]byte(got.Result), &list) + t.Log("blackList result: ", list) + assert.Equal(t, list, v.BlackList) + if v.AfterHandler != nil { + v.AfterHandler(v, ctx) + } + } +} + +func TestMethodIsBlocked(t *testing.T) { + type TestCase struct { + BlockNum int + Payload []byte + BeforeHandler func(c *TestCase, ctx *native.NativeContract) + AfterHandler func(c *TestCase, ctx *native.NativeContract) + ReturnData bool + Expect error + } + + cases := []*TestCase{ + { + BlockNum: 3, + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + input := &MethodIsBlockedInput{Addr: testAddresses[3]} + c.Payload, _ = input.Encode() + }, + ReturnData: false, + Expect: nil, + }, + { + BlockNum: 3, + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + setDefaultOwner(ctx) + blockTestAccount(ctx) + input := &MethodIsBlockedInput{Addr: testAddresses[3]} + c.Payload, _ = input.Encode() + }, + ReturnData: true, + Expect: nil, + }, + } + + for _, v := range cases { + resetTestContext() + ctx := generateNativeContract(testCaller, v.BlockNum) + if v.BeforeHandler != nil { + v.BeforeHandler(v, ctx) + } + result, _, err := ctx.ContractRef().NativeCall(testCaller, this, v.Payload) + assert.Equal(t, v.Expect, err) + got := new(MethodBoolOutput) + got.Decode(result, MethodIsBlocked) + t.Log("isBlocked result: ", got.Success) + assert.Equal(t, got.Success, v.ReturnData) + if v.AfterHandler != nil { + v.AfterHandler(v, ctx) + } + } +} + +func TestMethodName(t *testing.T) { + type TestCase struct { + BlockNum int + Payload []byte + BeforeHandler func(c *TestCase, ctx *native.NativeContract) + AfterHandler func(c *TestCase, ctx *native.NativeContract) + ReturnData string + Expect error + } + + cases := []*TestCase{ + { + BlockNum: 3, + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + c.Payload, _ = utils.PackMethod(ABI, MethodName) + }, + ReturnData: contractName, + Expect: nil, + }, + } + + for _, v := range cases { + resetTestContext() + ctx := generateNativeContract(testCaller, v.BlockNum) + if v.BeforeHandler != nil { + v.BeforeHandler(v, ctx) + } + result, _, err := ctx.ContractRef().NativeCall(testCaller, this, v.Payload) + assert.Equal(t, v.Expect, err) + got := new(MethodContractNameOutput) + got.Decode(result) + t.Log("name result: ", got.Name) + assert.Equal(t, got.Name, v.ReturnData) + if v.AfterHandler != nil { + v.AfterHandler(v, ctx) + } + } +} + +func encodeMethodBoolOutput(result bool, methodName string) []byte { + enc, _ := (&MethodBoolOutput{result}).Encode(methodName) + return enc +} + +func encodeMethodStringOutput(result string, methodName string) []byte { + enc, _ := (&MethodStringOutput{result}).Encode(methodName) + return enc +} + +func TestMethodSetGasManager(t *testing.T) { + type TestCase struct { + BlockNum int + Payload []byte + BeforeHandler func(c *TestCase, ctx *native.NativeContract) + AfterHandler func(c *TestCase, ctx *native.NativeContract) + ReturnData []byte + Expect error + } + cases := []*TestCase{ + { + BlockNum: 3, + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + input := &MethodSetGasManagerInput{Addr: testAddresses[3], IsManager: true} + c.Payload, _ = input.Encode() + }, + ReturnData: []byte{'0'}, + Expect: errors.New("invalid authority for owner"), + }, + { + BlockNum: 3, + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + setDefaultOwner(ctx) + input := &MethodSetGasManagerInput{Addr: testAddresses[3], IsManager: true} + c.Payload, _ = input.Encode() + }, + ReturnData: []byte{'1'}, + Expect: nil, + }, + { + BlockNum: 3, + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + input := &MethodIsGasManagerInput{Addr: testAddresses[3]} + c.Payload, _ = input.Encode() + }, + ReturnData: encodeMethodBoolOutput(true, MethodIsGasManager), + Expect: nil, + }, + { + BlockNum: 3, + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + c.Payload, _ = utils.PackMethod(ABI, MethodGetGasManagerList) + }, + ReturnData: encodeMethodStringOutput("[\""+strings.ToLower(testAddresses[3].String())+"\"]", MethodGetGasManagerList), + Expect: nil, + }, + { + BlockNum: 3, + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + setDefaultOwner(ctx) + input := &MethodSetGasManagerInput{Addr: testAddresses[3], IsManager: false} + c.Payload, _ = input.Encode() + }, + ReturnData: []byte{'1'}, + Expect: nil, + }, + { + BlockNum: 3, + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + input := &MethodIsGasManagerInput{Addr: testAddresses[3]} + c.Payload, _ = input.Encode() + }, + ReturnData: encodeMethodBoolOutput(false, MethodIsGasManager), + Expect: nil, + }, + { + BlockNum: 3, + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + c.Payload, _ = utils.PackMethod(ABI, MethodGetGasManagerList) + }, + ReturnData: encodeMethodStringOutput("[]", MethodGetGasManagerList), + Expect: nil, + }, + } + + resetTestContext() + for _, v := range cases { + ctx := generateNativeContract(testCaller, v.BlockNum) + + if v.BeforeHandler != nil { + v.BeforeHandler(v, ctx) + } + result, _, err := ctx.ContractRef().NativeCall(testCaller, this, v.Payload) + assert.Equal(t, v.Expect, err) + assert.Equal(t, v.ReturnData, result) + if v.AfterHandler != nil { + v.AfterHandler(v, ctx) + } + } +} + +func TestMethodEnableGasManage(t *testing.T) { + type TestCase struct { + Payload []byte + BeforeHandler func(c *TestCase, ctx *native.NativeContract) + AfterHandler func(c *TestCase, ctx *native.NativeContract) + Expect error + ReturnData []byte + } + + cases := []*TestCase{ + { + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + payload, err := utils.PackMethod(ABI, MethodIsGasManageEnabled) + assert.NoError(t, err) + c.Payload = payload + }, + ReturnData: encodeMethodBoolOutput(false, MethodIsGasManageEnabled), + Expect: nil, + }, + { + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + input := &MethodEnableGasManageInput{DoEnable: true} + c.Payload, _ = input.Encode() + }, + ReturnData: []byte{'0'}, + Expect: errors.New("invalid authority for owner"), + }, + { + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + setDefaultOwner(ctx) + input := &MethodEnableGasManageInput{DoEnable: true} + c.Payload, _ = input.Encode() + }, + Expect: nil, + ReturnData: []byte{'1'}, + }, + { + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + payload, err := utils.PackMethod(ABI, MethodIsGasManageEnabled) + assert.NoError(t, err) + c.Payload = payload + }, + ReturnData: encodeMethodBoolOutput(true, MethodIsGasManageEnabled), + Expect: nil, + }, + { + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + setDefaultOwner(ctx) + input := &MethodEnableGasManageInput{DoEnable: false} + c.Payload, _ = input.Encode() + }, + Expect: nil, + ReturnData: []byte{'1'}, + }, + { + BeforeHandler: func(c *TestCase, ctx *native.NativeContract) { + payload, err := utils.PackMethod(ABI, MethodIsGasManageEnabled) + assert.NoError(t, err) + c.Payload = payload + }, + ReturnData: encodeMethodBoolOutput(false, MethodIsGasManageEnabled), + Expect: nil, + }, + } + + resetTestContext() + ctx := generateNativeContract(testCaller, 3) + + for _, v := range cases { + if v.BeforeHandler != nil { + v.BeforeHandler(v, ctx) + } + result, _, err := ctx.ContractRef().NativeCall(testCaller, this, v.Payload) + assert.Equal(t, v.Expect, err) + assert.Equal(t, v.ReturnData, result) + } +} diff --git a/contracts/native/governance/maas_config/storage.go b/contracts/native/governance/maas_config/storage.go new file mode 100644 index 00000000..d4c4462f --- /dev/null +++ b/contracts/native/governance/maas_config/storage.go @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2021 The Zion Authors + * This file is part of The Zion library. + * + * The Zion is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Zion is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The Zion. If not, see . + */ + +package maas_config + +import ( + "github.com/ethereum/go-ethereum/contracts/native" + "github.com/ethereum/go-ethereum/contracts/native/utils" + "github.com/ethereum/go-ethereum/core/state" +) + +// storage key prefix +const ( + BLACKLIST = "blacklist" + OWNER = "owner" + NODE_WHITE_ENABLE = "node_white_enable" + GAS_MANAGE_ENABLE = "gas_manage_enable" + NODE_WHITELIST = "node_whitelist" + GAS_MANAGER_LIST = "gas_manager_list" + GAS_USER_LIST = "gas_user_list" + GAS_ADMIN_LIST = "gas_admin_list" +) + +var ( + blacklistKey = utils.ConcatKey(this, []byte(BLACKLIST)) + ownerKey = utils.ConcatKey(this, []byte(OWNER)) + gasManageEnableKey = utils.ConcatKey(this, []byte(GAS_MANAGE_ENABLE)) + gasManagerListKey = utils.ConcatKey(this, []byte(GAS_MANAGER_LIST)) + gasUserListKey = utils.ConcatKey(this, []byte(GAS_USER_LIST)) + gasAdminListKey = utils.ConcatKey(this, []byte(GAS_ADMIN_LIST)) +) + +// ==================================================================== +// +// storage basic operations +// +// ==================================================================== + +func get(s *native.NativeContract, key []byte) ([]byte, error) { + return customGet(s.GetCacheDB(), key) +} + +func set(s *native.NativeContract, key, value []byte) { + customSet(s.GetCacheDB(), key, value) +} + +func del(s *native.NativeContract, key []byte) { + customDel(s.GetCacheDB(), key) +} + +func customGet(db *state.CacheDB, key []byte) ([]byte, error) { + value, err := db.Get(key) + if err != nil { + return nil, err + // } else if value == nil || len(value) == 0 { + // return nil, ErrEof + } else { + return value, nil + } +} + +func customSet(db *state.CacheDB, key, value []byte) { + db.Put(key, value) +} + +func customDel(db *state.CacheDB, key []byte) { + db.Delete(key) +} diff --git a/contracts/native/governance/maas_config/storage_test.go b/contracts/native/governance/maas_config/storage_test.go new file mode 100644 index 00000000..d2c51b5f --- /dev/null +++ b/contracts/native/governance/maas_config/storage_test.go @@ -0,0 +1,107 @@ +package maas_config + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestSetAndGet(t *testing.T) { + resetTestContext() + type TestCase struct { + Key []byte + Value []byte + expect error + } + + cases := []TestCase{ + { + Key: ownerKey, + Value: []byte("0x2D3913c12ACa0E4A2278f829Fb78A682123c0129"), + expect: nil, + }, + { + Key: []byte("testKey"), + Value: []byte("testValue"), + expect: errors.New("CacheDB should only be used for native contract storage"), + }, + { + Key: []byte("0x2D3913c12ACa0E4A2278f829Fb78A682123c0129"), + Value: []byte("testValue"), + expect: nil, + }, + } + for _, testCase := range cases { + key := testCase.Key + value := testCase.Value + defer func() { + if err := recover(); err != nil { + assert.Equal(t, err, testCase.expect.Error()) + t.Log("error:", err) + } + }() + set(testEmptyCtx, key, value) + res, err := get(testEmptyCtx, key) + assert.NoError(t, err) + t.Log(string(res)) + assert.Equal(t, testCase.Value, res) + } +} + +func TestSetDelAndGet(t *testing.T) { + resetTestContext() + type TestCase struct { + Key []byte + Value []byte + BeforeHandler func(testCase *TestCase) + AfterHandler func(testCase *TestCase) + expect error + } + + cases := []TestCase{ + { + Key: ownerKey, + Value: []byte("0x2D3913c12ACa0E4A2278f829Fb78A682123c0129"), + BeforeHandler: func(testCase *TestCase) { + key := testCase.Key + value := testCase.Value + set(testEmptyCtx, key, value) + }, + AfterHandler: func(testCase *TestCase) { + key := testCase.Key + res, err := get(testEmptyCtx, key) + assert.NoError(t, err) + t.Log(string(res)) + assert.Equal(t, res, testCase.Value) + del(testEmptyCtx, key) + res, err = get(testEmptyCtx, key) + assert.NoError(t, err) + t.Log(string(res)) + assert.Equal(t, res, []byte(nil)) + }, + expect: nil, + }, + { + Key: []byte("testKey"), + Value: []byte("testValue"), + BeforeHandler: func(testCase *TestCase) { + set(testEmptyCtx, testCase.Key, testCase.Value) + }, + AfterHandler: nil, + expect: errors.New("CacheDB should only be used for native contract storage"), + }, + } + + for _, testCase := range cases { + defer func() { + if err := recover(); err != nil { + assert.Equal(t, err, testCase.expect.Error()) + t.Log("error:", err) + } + }() + testCase.BeforeHandler(&testCase) + testCase.AfterHandler(&testCase) + } + +} diff --git a/contracts/native/governance/neo3_state_manager/abi.go b/contracts/native/governance/neo3_state_manager/abi.go deleted file mode 100644 index 53957aef..00000000 --- a/contracts/native/governance/neo3_state_manager/abi.go +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package neo3_state_manager - -import ( - "fmt" - "strings" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" -) - -const ( - EventApproveRegisterStateValidator = "approveRegisterStateValidator" - EventApproveRemoveStateValidator = "approveRemoveStateValidator" -) - -const abijson = `[ - {"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"ID","type":"uint64"}],"name":"` + EventApproveRegisterStateValidator + `","type":"event"}, - {"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"ID","type":"uint64"}],"name":"` + EventApproveRemoveStateValidator + `","type":"event"}, - {"inputs":[{"internalType":"uint64","name":"ID","type":"uint64"},{"internalType":"address","name":"Address","type":"address"}],"name":"` + MethodApproveRegisterStateValidator + `","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"}, - {"inputs":[{"internalType":"uint64","name":"ID","type":"uint64"},{"internalType":"address","name":"Address","type":"address"}],"name":"` + MethodApproveRemoveStateValidator + `","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"}, - {"inputs":[],"name":"` + MethodContractName + `","outputs":[{"internalType":"string","name":"Name","type":"string"}],"stateMutability":"nonpayable","type":"function"}, - {"inputs":[],"name":"` + MethodGetCurrentStateValidator + `","outputs":[{"internalType":"bytes","name":"Validator","type":"bytes"}],"stateMutability":"nonpayable","type":"function"}, - {"inputs":[{"internalType":"string[]","name":"StateValidators","type":"string[]"},{"internalType":"address","name":"Address","type":"address"}],"name":"` + MethodRegisterStateValidator + `","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"}, - {"inputs":[{"internalType":"string[]","name":"StateValidators","type":"string[]"},{"internalType":"address","name":"Address","type":"address"}],"name":"` + MethodRemoveStateValidator + `","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"} -]` - -func GetABI() *abi.ABI { - ab, err := abi.JSON(strings.NewReader(abijson)) - if err != nil { - panic(fmt.Sprintf("failed to load abi json string: [%v]", err)) - } - return &ab -} - -type StateValidatorListParam struct { - StateValidators []string // public key strings in encoded format, each is 33 bytes in []byte - Address common.Address // for check witness? -} - -type ApproveStateValidatorParam struct { - ID uint64 // StateValidatorApproveID - Address common.Address // for check witness? -} diff --git a/contracts/native/governance/neo3_state_manager/neo3_state_manager.go b/contracts/native/governance/neo3_state_manager/neo3_state_manager.go deleted file mode 100644 index 288b8baa..00000000 --- a/contracts/native/governance/neo3_state_manager/neo3_state_manager.go +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package neo3_state_manager - -import ( - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/utils" -) - -const contractName = "neo3 state manager" - -const ( - MethodContractName = "name" - MethodGetCurrentStateValidator = "getCurrentStateValidator" - MethodRegisterStateValidator = "registerStateValidator" - MethodApproveRegisterStateValidator = "approveRegisterStateValidator" - MethodRemoveStateValidator = "removeStateValidator" - MethodApproveRemoveStateValidator = "approveRemoveStateValidator" -) - -var ( - this = native.NativeContractAddrMap[native.NativeNeo3StateManager] - gasTable = map[string]uint64{ - MethodContractName: 0, - MethodGetCurrentStateValidator: 0, - MethodRegisterStateValidator: 100000, - MethodApproveRegisterStateValidator: 0, - MethodRemoveStateValidator: 0, - MethodApproveRemoveStateValidator: 0, - } - - ABI *abi.ABI -) - -func InitNeo3StateManager() { - ABI = GetABI() - native.Contracts[this] = RegisterNeo3StateManagerContract -} - -func RegisterNeo3StateManagerContract(s *native.NativeContract) { - s.Prepare(ABI, gasTable) - - s.Register(MethodContractName, Name) - s.Register(MethodGetCurrentStateValidator, GetCurrentStateValidator) - s.Register(MethodRegisterStateValidator, RegisterStateValidator) - s.Register(MethodApproveRegisterStateValidator, ApproveRegisterStateValidator) - s.Register(MethodRemoveStateValidator, RemoveStateValidator) - s.Register(MethodApproveRemoveStateValidator, ApproveRemoveStateValidator) -} - -func Name(s *native.NativeContract) ([]byte, error) { - return utils.PackOutputs(ABI, MethodContractName, contractName) -} - -func GetCurrentStateValidator(s *native.NativeContract) ([]byte, error) { - - return utils.PackOutputs(ABI, MethodGetCurrentStateValidator, []byte{}) -} - -func RegisterStateValidator(s *native.NativeContract) ([]byte, error) { - ctx := s.ContractRef().CurrentContext() - params := &StateValidatorListParam{} - if err := utils.UnpackMethod(ABI, MethodRegisterStateValidator, params, ctx.Payload); err != nil { - return nil, err - } - - return utils.PackOutputs(ABI, MethodRegisterStateValidator, true) -} - -func ApproveRegisterStateValidator(s *native.NativeContract) ([]byte, error) { - ctx := s.ContractRef().CurrentContext() - params := &ApproveStateValidatorParam{} - if err := utils.UnpackMethod(ABI, MethodApproveRegisterStateValidator, params, ctx.Payload); err != nil { - return nil, err - } - - return utils.PackOutputs(ABI, MethodApproveRegisterStateValidator, true) -} - -func RemoveStateValidator(s *native.NativeContract) ([]byte, error) { - ctx := s.ContractRef().CurrentContext() - params := &StateValidatorListParam{} - if err := utils.UnpackMethod(ABI, MethodRemoveStateValidator, params, ctx.Payload); err != nil { - return nil, err - } - - return utils.PackOutputs(ABI, MethodRemoveStateValidator, true) -} - -func ApproveRemoveStateValidator(s *native.NativeContract) ([]byte, error) { - ctx := s.ContractRef().CurrentContext() - params := &ApproveStateValidatorParam{} - if err := utils.UnpackMethod(ABI, MethodApproveRemoveStateValidator, params, ctx.Payload); err != nil { - return nil, err - } - - return utils.PackOutputs(ABI, MethodApproveRemoveStateValidator, true) -} diff --git a/contracts/native/governance/node_manager/abi.go b/contracts/native/governance/node_manager/abi.go index 8de082c3..402fe4f6 100644 --- a/contracts/native/governance/node_manager/abi.go +++ b/contracts/native/governance/node_manager/abi.go @@ -248,3 +248,33 @@ func emitEpochChange(s *native.NativeContract, curEpoch, nextEpoch *EpochInfo) e func emitConsensusSign(s *native.NativeContract, sign *ConsensusSign, signer common.Address, num int) error { return s.AddNotify(ABI, []string{EventConsensusSigned}, sign.Method, sign.Input, signer, uint64(num)) } + +type MethodGetEpochListJsonInput struct { + EpochID uint64 +} + +func (m *MethodGetEpochListJsonInput) Encode() ([]byte, error) { + return utils.PackMethod(ABI, MethodGetEpochListJson, m.EpochID) +} +func (m *MethodGetEpochListJsonInput) Decode(payload []byte) error { + var data struct { + EpochID uint64 + } + if err := utils.UnpackMethod(ABI, MethodGetEpochListJson, &data, payload); err != nil { + return err + } + m.EpochID = data.EpochID + return nil +} + +type MethodGetJsonOutput struct { + Result string +} + +func (m *MethodGetJsonOutput) Encode(methodName string) ([]byte, error) { + return utils.PackOutputs(ABI, methodName, m.Result) +} + +func (m *MethodGetJsonOutput) Decode(payload []byte, methodName string) error { + return utils.UnpackOutputs(ABI, methodName, m, payload) +} diff --git a/contracts/native/governance/node_manager/abi_test.go b/contracts/native/governance/node_manager/abi_test.go index eddbaa03..c0c3e9e8 100644 --- a/contracts/native/governance/node_manager/abi_test.go +++ b/contracts/native/governance/node_manager/abi_test.go @@ -180,3 +180,30 @@ func TestABIMethodProofOutput(t *testing.T) { assert.Equal(t, expect, got) } + +func TestABIMethodGetEpochListJsonInput(t *testing.T) { + expect := new(MethodGetEpochListJsonInput) + expect.EpochID = uint64(9932) + enc, err := expect.Encode() + assert.NoError(t, err) + + got := new(MethodGetEpochListJsonInput) + assert.NoError(t, got.Decode(enc)) + + assert.Equal(t, expect, got) +} + +func TestABIMethodGetJsonOutput(t *testing.T) { + expect := new(MethodGetJsonOutput) + epochID := uint64(2) + peers := generateTestPeers(7) + epoch := &EpochInfo{ID: epochID, Proposer: peers.List[0].Address, Peers: peers, StartHeight: 60} + expect.Result = epoch.Json() + enc, err := expect.Encode(MethodGetEpochListJson) + assert.NoError(t, err) + + got := new(MethodGetJsonOutput) + assert.NoError(t, got.Decode(enc, MethodGetEpochListJson)) + + assert.Equal(t, expect, got) +} diff --git a/contracts/native/governance/node_manager/manager.go b/contracts/native/governance/node_manager/manager.go index a3996e2a..0cdef1fc 100644 --- a/contracts/native/governance/node_manager/manager.go +++ b/contracts/native/governance/node_manager/manager.go @@ -21,6 +21,7 @@ package node_manager import ( "fmt" "sort" + "strings" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -48,6 +49,10 @@ var ( MethodGetEpochByID: 0, MethodProof: 0, MethodGetChangingEpoch: 0, + + MethodGetChangingEpochJson: 0, + MethodGetCurrentEpochJson: 0, + MethodGetEpochListJson: 0, } ) @@ -83,6 +88,10 @@ func RegisterNodeManagerContract(s *native.NativeContract) { s.Register(MethodGetEpochByID, GetEpochByID) s.Register(MethodProof, GetEpochProof) s.Register(MethodGetChangingEpoch, GetChangingEpoch) + + s.Register(MethodGetChangingEpochJson, GetChangingEpochJson) + s.Register(MethodGetCurrentEpochJson, GetCurrentEpochJson) + s.Register(MethodGetEpochListJson, GetEpochListJson) } func Name(s *native.NativeContract) ([]byte, error) { @@ -378,20 +387,10 @@ func GetEpochWithStateDB(db *state.StateDB) (*EpochInfo, error) { } func GetChangingEpoch(s *native.NativeContract) ([]byte, error) { - curEpochHash, err := getCurrentEpochHash(s) - if err != nil { - return utils.ByteFailed, err - } - epoch, err := getEpoch(s, curEpochHash) + epoch, err := getChangingEpoch(s) if err != nil { return utils.ByteFailed, err } - - height := s.ContractRef().BlockHeight().Uint64() - if height > epoch.StartHeight { - log.Warn("getChangingEpoch", "epoch changing invalidation, start height", epoch.StartHeight, "current height", height) - return utils.ByteFailed, fmt.Errorf("epoch invalid") - } output := &MethodEpochOutput{Epoch: epoch} return output.Encode() } @@ -416,6 +415,53 @@ func GetEpochByID(s *native.NativeContract) ([]byte, error) { return output.Encode() } +func GetEpochListJson(s *native.NativeContract) ([]byte, error) { + ctx := s.ContractRef().CurrentContext() + + // decode input + input := new(MethodGetEpochListJsonInput) + if err := input.Decode(ctx.Payload); err != nil { + log.Trace("GetEpochListJson", "decode input failed", err) + return utils.ByteFailed, ErrInvalidInput + } + + epochList, err := getEpochListByID(s, input.EpochID) + if err != nil { + log.Trace("GetEpochListJson", "get history epoch failed", err) + return utils.ByteFailed, ErrEpochNotExist + } + var str strings.Builder + str.WriteString("[") + for i, v := range epochList { + str.WriteString(v.Json()) + if i != len(epochList)-1 { + str.WriteString(",") + } + } + str.WriteString("]") + output := MethodGetJsonOutput{Result: str.String()} + return output.Encode(MethodGetEpochListJson) +} + +func GetCurrentEpochJson(s *native.NativeContract) ([]byte, error) { + epoch, err := getCurrentEpoch(s) + if err != nil { + log.Trace("epoch", "get current epoch failed", err) + return utils.ByteFailed, ErrEpochNotExist + } + output := &MethodGetJsonOutput{Result: epoch.Json()} + return output.Encode(MethodGetCurrentEpochJson) +} + +func GetChangingEpochJson(s *native.NativeContract) ([]byte, error) { + epoch, err := getChangingEpoch(s) + if err != nil { + return utils.ByteFailed, err + } + output := &MethodGetJsonOutput{Result: epoch.Json()} + return output.Encode(MethodGetChangingEpochJson) +} + func GetEpochProof(s *native.NativeContract) ([]byte, error) { ctx := s.ContractRef().CurrentContext() diff --git a/contracts/native/governance/node_manager/manager_test.go b/contracts/native/governance/node_manager/manager_test.go index 3a970003..a8f6d42a 100644 --- a/contracts/native/governance/node_manager/manager_test.go +++ b/contracts/native/governance/node_manager/manager_test.go @@ -20,6 +20,7 @@ package node_manager import ( "crypto/rand" + "encoding/json" "math/big" "os" "sort" @@ -28,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/contracts/native" + "github.com/ethereum/go-ethereum/contracts/native/go_abi/node_manager_abi" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/crypto" @@ -528,6 +530,17 @@ func TestProposalPassed(t *testing.T) { curEpoch, err = getEpoch(ctx, epoch.Hash()) assert.NoError(t, err) assert.Equal(t, ProposalStatusPassed, curEpoch.Status) + + // get changing epoch + changingInput := &MethodGetChangingEpochInput{} + changingEpochPayload, err := changingInput.Encode() + assert.Nil(t, err) + ctx = generateNativeContract(common.EmptyAddress, int(proposalStartHeight-1)) + enc, _, err := ctx.ContractRef().NativeCall(common.EmptyAddress, this, changingEpochPayload) + changingOutPut := &MethodEpochOutput{} + changingOutPut.Decode(enc) + assert.NoError(t, err) + assert.Equal(t, curEpoch.Hash(), changingOutPut.Epoch.Hash()) } func TestDirtyJob(t *testing.T) { @@ -608,6 +621,48 @@ func TestGetEpochByID(t *testing.T) { assert.Equal(t, epoch.Hash(), output.Epoch.Hash()) } +func TestGetEpochListJson(t *testing.T) { + resetTestContext() + + s := testEmptyCtx + epochID := uint64(2) + peers := generateTestPeers(12) + voters := []common.Address{peers.List[2].Address, peers.List[3].Address} + + // store last epoch + lastEpoch := &EpochInfo{ID: epochID - 1, Proposer: peers.List[0].Address, Peers: peers, StartHeight: 60} + assert.NoError(t, storeEpoch(s, lastEpoch)) + assert.NoError(t, storeProposal(s, lastEpoch.ID, lastEpoch.Hash())) + + // store current useless epoch and votes + eps := []*EpochInfo{ + {ID: epochID, Proposer: peers.List[0].Address, Peers: &Peers{List: peers.List[:5]}, StartHeight: 270}, + {ID: epochID, Proposer: peers.List[1].Address, Peers: &Peers{List: peers.List[:6]}, StartHeight: 290}, + } + for i, v := range eps { + assert.NoError(t, storeEpoch(s, v)) + assert.NoError(t, storeProposal(s, v.ID, v.Hash())) + assert.NoError(t, storeVote(s, v.Hash(), voters[i])) + storeVoteTo(s, v.ID, voters[i], v.Hash()) + } + + input := new(MethodGetEpochListJsonInput) + input.EpochID = epochID + payload, err := input.Encode() + assert.NoError(t, err) + ctx := generateNativeContract(common.EmptyAddress, int(61)) + enc, _, err := ctx.ContractRef().NativeCall(common.EmptyAddress, this, payload) + assert.NoError(t, err) + + output := new(MethodGetJsonOutput) + assert.NoError(t, output.Decode(enc, node_manager_abi.MethodGetEpochListJson)) + var outputEpochs []*EpochInfo + assert.NoError(t, json.Unmarshal([]byte(output.Result), &outputEpochs)) + assert.Equal(t, eps[0].Hash(), outputEpochs[0].Hash()) + assert.Equal(t, eps[1].Hash(), outputEpochs[1].Hash()) + assert.Equal(t, 2, len(outputEpochs)) +} + func TestGetProofByID(t *testing.T) { resetTestContext() diff --git a/contracts/native/governance/node_manager/types.go b/contracts/native/governance/node_manager/types.go index 85d8b95f..57800b96 100644 --- a/contracts/native/governance/node_manager/types.go +++ b/contracts/native/governance/node_manager/types.go @@ -19,6 +19,7 @@ package node_manager import ( + "encoding/json" "fmt" "io" "math" @@ -163,6 +164,26 @@ func (m *EpochInfo) String() string { m.Hash().Hex(), m.ID, pstr, m.StartHeight, m.Proposer.Hex(), m.Status.String()) } +func (m *EpochInfo) Json() string { + var epoch = struct { + ID uint64 + Peers *Peers + StartHeight uint64 + Proposer common.Address + Status ProposalStatusType + Hash common.Hash + }{ + ID: m.ID, + Peers: m.Peers, + StartHeight: m.StartHeight, + Proposer: m.Proposer, + Status: m.Status, + Hash: m.Hash(), + } + bytes, _ := json.Marshal(epoch) + return string(bytes) +} + func (m *EpochInfo) Hash() common.Hash { if hash := m.hash.Load(); hash != nil { return hash.(common.Hash) diff --git a/contracts/native/governance/node_manager/utils.go b/contracts/native/governance/node_manager/utils.go index 0f61877e..5a44be68 100644 --- a/contracts/native/governance/node_manager/utils.go +++ b/contracts/native/governance/node_manager/utils.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/contracts/native" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" ) func getCurrentEpoch(s *native.NativeContract) (*EpochInfo, error) { @@ -72,6 +73,47 @@ func getEffectiveEpochByID(s *native.NativeContract, epochID uint64) (*EpochInfo return getEpoch(s, lastEpochHash) } +func getEpochListByID(s *native.NativeContract, epochID uint64) ([]*EpochInfo, error) { + if epochID < StartEpochID { + return nil, fmt.Errorf("epoch %d not exist", epochID) + } + list, err := getProposals(s, epochID) + if err != nil { + return nil, fmt.Errorf("epoch %d has no proposal, err: %v", epochID, err) + } + if len(list) == 0 { + return nil, fmt.Errorf("epoch %d has no proposal", epochID) + } + var epochList []*EpochInfo + for _, v := range list { + item, err := getEpoch(s, v) + if err != nil { + return nil, fmt.Errorf("proposal %d not exists, err: %v", v, err) + } + epochList = append(epochList, item) + } + + return epochList, nil +} + +func getChangingEpoch(s *native.NativeContract) (*EpochInfo, error) { + curEpochHash, err := getCurrentEpochHash(s) + if err != nil { + return nil, err + } + epoch, err := getEpoch(s, curEpochHash) + if err != nil { + return nil, err + } + + height := s.ContractRef().BlockHeight().Uint64() + if height > epoch.StartHeight { + log.Warn("getChangingEpoch", "epoch changing invalidation, start height", epoch.StartHeight, "current height", height) + return nil, fmt.Errorf("epoch invalid") + } + return epoch, nil +} + func CheckAuthority(origin, caller common.Address, epoch *EpochInfo) error { if epoch == nil || epoch.Peers == nil || epoch.Peers.List == nil { return fmt.Errorf("invalid epoch") diff --git a/contracts/native/governance/relayer_manager/abi.go b/contracts/native/governance/relayer_manager/abi.go deleted file mode 100644 index 4d7dbf14..00000000 --- a/contracts/native/governance/relayer_manager/abi.go +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package relayer_manager - -import ( - "fmt" - "strings" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native/go_abi/relayer_manager_abi" - polycomm "github.com/polynetwork/poly/common" -) - -var ( - EventRegisterRelayer = relayer_manager_abi.MethodRegisterRelayer - EventApproveRegisterRelayer = relayer_manager_abi.MethodApproveRegisterRelayer - EventRemoveRelayer = relayer_manager_abi.MethodRemoveRelayer - EventApproveRemoveRelayer = relayer_manager_abi.MethodApproveRemoveRelayer -) - -func GetABI() *abi.ABI { - ab, err := abi.JSON(strings.NewReader(relayer_manager_abi.RelayerManagerABI)) - if err != nil { - panic(fmt.Sprintf("failed to load abi json string: [%v]", err)) - } - return &ab -} - -type RelayerListParam struct { - AddressList []common.Address - Address common.Address -} - -func (this *RelayerListParam) Serialization(sink *polycomm.ZeroCopySink) { - sink.WriteVarUint(uint64(len(this.AddressList))) - for _, v := range this.AddressList { - sink.WriteVarBytes(v[:]) - } - sink.WriteVarBytes(this.Address[:]) -} - -func (this *RelayerListParam) Deserialization(source *polycomm.ZeroCopySource) error { - n, eof := source.NextVarUint() - if eof { - return fmt.Errorf("source.NextVarUint, deserialize AddressList length error") - } - addressList := make([]common.Address, 0) - for i := 0; uint64(i) < n; i++ { - address, eof := source.NextVarBytes() - if eof { - return fmt.Errorf("source.NextVarBytes, deserialize address error") - } - addr, err := common.AddressParseFromBytes(address) - if err != nil { - return fmt.Errorf("common.AddressParseFromBytes, deserialize address error: %s", err) - } - addressList = append(addressList, addr) - } - - address, eof := source.NextVarBytes() - if eof { - return fmt.Errorf("source.NextVarBytes, deserialize address error") - } - addr, err := common.AddressParseFromBytes(address) - if err != nil { - return fmt.Errorf("common.AddressParseFromBytes, deserialize address error: %s", err) - } - this.AddressList = addressList - this.Address = addr - return nil -} - -type ApproveRelayerParam struct { - ID uint64 - Address common.Address -} diff --git a/contracts/native/governance/relayer_manager/relayer_manager.go b/contracts/native/governance/relayer_manager/relayer_manager.go deleted file mode 100644 index 626ea80c..00000000 --- a/contracts/native/governance/relayer_manager/relayer_manager.go +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package relayer_manager - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/contract" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - "github.com/ethereum/go-ethereum/contracts/native/utils" -) - -const contractName = "relayer manager" - -const ( - //function name - MethodContractName = "name" - MethodRegisterRelayer = "registerRelayer" - MethodApproveRegisterRelayer = "approveRegisterRelayer" - MethodRemoveRelayer = "removeRelayer" - MethodApproveRemoveRelayer = "approveRemoveRelayer" - - //key prefix - RELAYER = "relayer" - RELAYER_APPLY = "relayerApply" - RELAYER_REMOVE = "relayerRemove" - APPLY_ID = "applyID" - REMOVE_ID = "removeID" -) - -var ( - this = native.NativeContractAddrMap[native.NativeRelayerManager] - gasTable = map[string]uint64{ - MethodContractName: 0, - MethodRegisterRelayer: 0, - MethodApproveRegisterRelayer: 100000, - MethodRemoveRelayer: 0, - MethodApproveRemoveRelayer: 0, - } - - ABI *abi.ABI -) - -func InitRelayerManager() { - ABI = GetABI() - native.Contracts[this] = RegisterRelayerManagerContract -} - -func RegisterRelayerManagerContract(s *native.NativeContract) { - s.Prepare(ABI, gasTable) - - s.Register(MethodContractName, Name) - s.Register(MethodRegisterRelayer, RegisterRelayer) - s.Register(MethodApproveRegisterRelayer, ApproveRegisterRelayer) - s.Register(MethodRemoveRelayer, RemoveRelayer) - s.Register(MethodApproveRemoveRelayer, ApproveRemoveRelayer) -} - -func Name(s *native.NativeContract) ([]byte, error) { - return utils.PackOutputs(ABI, MethodContractName, contractName) -} - -func RegisterRelayer(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &RelayerListParam{} - if err := utils.UnpackMethod(ABI, MethodRegisterRelayer, params, ctx.Payload); err != nil { - return nil, err - } - - //check witness - err := contract.ValidateOwner(native, params.Address) - if err != nil { - return nil, fmt.Errorf("RegisterSideChain, checkWitness error: %v", err) - } - - if err := putRelayerApply(native, params); err != nil { - return nil, fmt.Errorf("RegisterRelayer, putRelayer error: %v", err) - } - - return utils.PackOutputs(ABI, MethodRegisterRelayer, true) -} - -func ApproveRegisterRelayer(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &ApproveRelayerParam{} - if err := utils.UnpackMethod(ABI, MethodApproveRegisterRelayer, params, ctx.Payload); err != nil { - return nil, err - } - - //check witness - err := contract.ValidateOwner(native, params.Address) - if err != nil { - return nil, fmt.Errorf("RegisterSideChain, checkWitness error: %v", err) - } - - relayerListParam, err := getRelayerApply(native, params.ID) - if err != nil { - return nil, fmt.Errorf("ApproveRegisterRelayer, getRelayerApply error: %v", err) - } - - //check consensus signs - ok, err := node_manager.CheckConsensusSigns(native, MethodApproveRegisterRelayer, utils.GetUint64Bytes(params.ID), params.Address) - if err != nil { - return nil, fmt.Errorf("ApproveRegisterRelayer, CheckConsensusSigns error: %v", err) - } - if !ok { - return utils.PackOutputs(ABI, MethodApproveRegisterRelayer, true) - } - - for _, address := range relayerListParam.AddressList { - err = putRelayer(native, address) - if err != nil { - return nil, fmt.Errorf("ApproveRegisterRelayer, putRelayer error: %v", err) - } - } - - native.GetCacheDB().Delete(utils.ConcatKey(utils.RelayerManagerContractAddress, []byte(RELAYER_APPLY), utils.GetUint64Bytes(params.ID))) - - err = native.AddNotify(ABI, []string{EventApproveRegisterRelayer}, params.ID) - if err != nil { - return nil, fmt.Errorf("ApproveRegisterRelayer, AddNotify error: %v", err) - } - return utils.PackOutputs(ABI, MethodApproveRegisterRelayer, true) -} - -func RemoveRelayer(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &RelayerListParam{} - if err := utils.UnpackMethod(ABI, MethodRemoveRelayer, params, ctx.Payload); err != nil { - return nil, err - } - - //check witness - err := contract.ValidateOwner(native, params.Address) - if err != nil { - return nil, fmt.Errorf("RegisterSideChain, checkWitness error: %v", err) - } - - err = putRelayerRemove(native, params) - if err != nil { - return nil, fmt.Errorf("RemoveRelayer, putRelayer error: %v", err) - } - - return utils.PackOutputs(ABI, MethodRemoveRelayer, true) -} - -func ApproveRemoveRelayer(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &ApproveRelayerParam{} - if err := utils.UnpackMethod(ABI, MethodApproveRemoveRelayer, params, ctx.Payload); err != nil { - return nil, err - } - - //check witness - err := contract.ValidateOwner(native, params.Address) - if err != nil { - return nil, fmt.Errorf("RegisterSideChain, checkWitness error: %v", err) - } - - relayerListParam, err := getRelayerRemove(native, params.ID) - if err != nil { - return nil, fmt.Errorf("ApproveRemoveRelayer, getRelayerRemove error: %v", err) - } - - //check consensus signs - ok, err := node_manager.CheckConsensusSigns(native, MethodApproveRemoveRelayer, utils.GetUint64Bytes(params.ID), params.Address) - if err != nil { - return nil, fmt.Errorf("ApproveRemoveRelayer, CheckConsensusSigns error: %v", err) - } - if !ok { - return utils.PackOutputs(ABI, MethodApproveRemoveRelayer, true) - } - - for _, address := range relayerListParam.AddressList { - native.GetCacheDB().Delete(utils.ConcatKey(utils.RelayerManagerContractAddress, []byte(RELAYER), address[:])) - } - err = native.AddNotify(ABI, []string{EventApproveRemoveRelayer}, params.ID) - if err != nil { - return nil, fmt.Errorf("ApproveRemoveRelayer, AddNotify error: %v", err) - } - - return utils.PackOutputs(ABI, MethodApproveRemoveRelayer, true) -} diff --git a/contracts/native/governance/relayer_manager/relayer_manager_test.go b/contracts/native/governance/relayer_manager/relayer_manager_test.go deleted file mode 100644 index 8a696479..00000000 --- a/contracts/native/governance/relayer_manager/relayer_manager_test.go +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package relayer_manager - -import ( - "crypto/ecdsa" - "encoding/hex" - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/crypto" - polycomm "github.com/polynetwork/poly/common" - cstates "github.com/polynetwork/poly/core/states" - "github.com/stretchr/testify/assert" -) - -func init() { - InitRelayerManager() - node_manager.InitNodeManager() - db := rawdb.NewMemoryDatabase() - sdb, _ = state.New(common.Hash{}, state.NewDatabase(db), nil) - - cacheDB := (*state.CacheDB)(sdb) - putPeerMapPoolAndView(cacheDB) -} - -func putPeerMapPoolAndView(db *state.CacheDB) { - key, _ := crypto.GenerateKey() - acct = &key.PublicKey - - peerPoolMap := new(node_manager.PeerPoolMap) - peerPoolMap.PeerPoolMap = make(map[string]*node_manager.PeerPoolItem) - pkStr := hex.EncodeToString(crypto.FromECDSAPub(acct)) - peerPoolMap.PeerPoolMap[pkStr] = &node_manager.PeerPoolItem{ - Index: uint32(0), - PeerPubkey: pkStr, - Address: crypto.PubkeyToAddress(*acct), - Status: node_manager.ConsensusStatus, - } - view := uint32(0) - viewBytes := utils.GetUint32Bytes(view) - sink := polycomm.NewZeroCopySink(nil) - peerPoolMap.Serialization(sink) - db.Put(utils.ConcatKey(utils.NodeManagerContractAddress, []byte(node_manager.PEER_POOL), viewBytes), cstates.GenRawStorageItem(sink.Bytes())) - - sink.Reset() - - govView := node_manager.GovernanceView{ - View: view, - } - govView.Serialization(sink) - db.Put(utils.ConcatKey(utils.NodeManagerContractAddress, []byte(node_manager.GOVERNANCE_VIEW)), cstates.GenRawStorageItem(sink.Bytes())) -} - -var ( - sdb *state.StateDB - acct *ecdsa.PublicKey -) - -func TestRegisterRelayer(t *testing.T) { - { - params := new(RelayerListParam) - params.AddressList = []common.Address{{1, 2, 4, 6}, {1, 4, 5, 7}, {1, 3, 5, 7, 9}} - - input, err := utils.PackMethodWithStruct(ABI, MethodRegisterRelayer, params) - assert.Nil(t, err) - - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, common.Address{}, common.Address{}, blockNumber, common.Hash{}, gasTable[MethodRegisterRelayer]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(common.Address{}, utils.RelayerManagerContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(ABI, MethodRegisterRelayer, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - - contract := native.NewNativeContract(sdb, contractRef) - relayerListParam, err := getRelayerApply(contract, 0) - assert.Nil(t, err) - assert.Equal(t, params, relayerListParam) - } - - // none consensus acct should not be able to approve register relayer - { - caller := crypto.PubkeyToAddress(*acct) - param := new(ApproveRelayerParam) - param.ID = 0 - param.Address = caller - - input, err := utils.PackMethodWithStruct(ABI, MethodApproveRegisterRelayer, param) - assert.Nil(t, err) - - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, gasTable[MethodApproveRegisterRelayer]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.RelayerManagerContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(ABI, MethodApproveRegisterRelayer, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - - contract := native.NewNativeContract(sdb, contractRef) - ok, err := node_manager.CheckConsensusSigns(contract, MethodApproveRegisterRelayer, utils.GetUint64Bytes(0), caller) - assert.Nil(t, err) - assert.Equal(t, true, ok) - } - -} - -func TestRemoveRelayer(t *testing.T) { - { - params := new(RelayerListParam) - params.AddressList = []common.Address{{1, 2, 4, 6}, {1, 4, 5, 7}} - - input, err := utils.PackMethodWithStruct(ABI, MethodRemoveRelayer, params) - assert.Nil(t, err) - - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, common.Address{}, common.Address{}, blockNumber, common.Hash{}, gasTable[MethodRemoveRelayer]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(common.Address{}, utils.RelayerManagerContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(ABI, MethodRemoveRelayer, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - - contract := native.NewNativeContract(sdb, contractRef) - relayerListParam, err := getRelayerRemove(contract, 0) - assert.Nil(t, err) - assert.Equal(t, params, relayerListParam) - } - - { - caller := crypto.PubkeyToAddress(*acct) - param := new(ApproveRelayerParam) - param.ID = 0 - param.Address = caller - - input, err := utils.PackMethodWithStruct(ABI, MethodApproveRemoveRelayer, param) - assert.Nil(t, err) - - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, gasTable[MethodApproveRemoveRelayer]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.RelayerManagerContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(ABI, MethodApproveRemoveRelayer, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - - contract := native.NewNativeContract(sdb, contractRef) - ok, err := node_manager.CheckConsensusSigns(contract, MethodApproveRemoveRelayer, utils.GetUint64Bytes(0), caller) - assert.Nil(t, err) - assert.Equal(t, true, ok) - } -} diff --git a/contracts/native/governance/relayer_manager/utils.go b/contracts/native/governance/relayer_manager/utils.go deleted file mode 100644 index 3a5854c1..00000000 --- a/contracts/native/governance/relayer_manager/utils.go +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package relayer_manager - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/utils" - polycomm "github.com/polynetwork/poly/common" - cstates "github.com/polynetwork/poly/core/states" -) - -func putRelayer(native *native.NativeContract, relayer common.Address) error { - contract := utils.RelayerManagerContractAddress - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(RELAYER), relayer[:]), cstates.GenRawStorageItem(relayer[:])) - return nil -} - -func putRelayerApply(native *native.NativeContract, relayerListParam *RelayerListParam) error { - contract := utils.RelayerManagerContractAddress - applyID, err := getApplyID(native) - if err != nil { - return fmt.Errorf("putRelayerApply, getApplyID error: %v", err) - } - newApplyID := applyID + 1 - err = putApplyID(native, newApplyID) - if err != nil { - return fmt.Errorf("putRelayerApply, putApplyID error: %v", err) - } - sink := polycomm.NewZeroCopySink(nil) - relayerListParam.Serialization(sink) - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(RELAYER_APPLY), utils.GetUint64Bytes(applyID)), - cstates.GenRawStorageItem(sink.Bytes())) - - err = native.AddNotify(ABI, []string{EventRegisterRelayer}, applyID) - if err != nil { - return fmt.Errorf("putRelayerApply, AddNotify error: %v", err) - } - return nil -} - -func getApplyID(native *native.NativeContract) (uint64, error) { - contract := utils.RelayerManagerContractAddress - applyIDStore, err := native.GetCacheDB().Get(utils.ConcatKey(contract, []byte(APPLY_ID))) - if err != nil { - return 0, fmt.Errorf("getApplyID, get applyIDStore error: %v", err) - } - var applyID uint64 = 0 - if applyIDStore != nil { - applyIDBytes, err := cstates.GetValueFromRawStorageItem(applyIDStore) - if err != nil { - return 0, fmt.Errorf("getApplyID, deserialize from raw storage item err:%v", err) - } - applyID = utils.GetBytesUint64(applyIDBytes) - } - return applyID, nil -} - -func putApplyID(native *native.NativeContract, applyID uint64) error { - contract := utils.RelayerManagerContractAddress - applyIDByte := utils.GetUint64Bytes(applyID) - - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(APPLY_ID)), cstates.GenRawStorageItem(applyIDByte)) - return nil -} - -func getRelayerApply(native *native.NativeContract, applyID uint64) (*RelayerListParam, error) { - contract := utils.RelayerManagerContractAddress - relayerListParamStore, err := native.GetCacheDB().Get(utils.ConcatKey(contract, []byte(RELAYER_APPLY), utils.GetUint64Bytes(applyID))) - if err != nil { - return nil, fmt.Errorf("getRelayerApply, get relayerListParamStore error: %v", err) - } - if relayerListParamStore == nil { - return nil, fmt.Errorf("getRelayerApply, can't find any record") - } - relayerListParam := new(RelayerListParam) - relayerListParamBytes, err := cstates.GetValueFromRawStorageItem(relayerListParamStore) - if err != nil { - return nil, fmt.Errorf("getRelayerApply, deserialize from raw storage item err:%v", err) - } - err = relayerListParam.Deserialization(polycomm.NewZeroCopySource(relayerListParamBytes)) - if err != nil { - return nil, fmt.Errorf("getRelayerApply, relayerListParam.Deserialization fail:%v", err) - } - return relayerListParam, nil -} - -func putRelayerRemove(native *native.NativeContract, relayerListParam *RelayerListParam) error { - contract := utils.RelayerManagerContractAddress - removeID, err := getRemoveID(native) - if err != nil { - return fmt.Errorf("putRelayerRemove, getRemoveID error: %v", err) - } - newRemoveID := removeID + 1 - err = putRemoveID(native, newRemoveID) - if err != nil { - return fmt.Errorf("putRelayerRemove, putRemoveID error: %v", err) - } - sink := polycomm.NewZeroCopySink(nil) - relayerListParam.Serialization(sink) - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(RELAYER_REMOVE), utils.GetUint64Bytes(removeID)), - cstates.GenRawStorageItem(sink.Bytes())) - - err = native.AddNotify(ABI, []string{EventRemoveRelayer}, removeID) - if err != nil { - return fmt.Errorf("putRelayerRemove, AddNotify error: %v", err) - } - return nil -} - -func getRemoveID(native *native.NativeContract) (uint64, error) { - contract := utils.RelayerManagerContractAddress - removeIDStore, err := native.GetCacheDB().Get(utils.ConcatKey(contract, []byte(REMOVE_ID))) - if err != nil { - return 0, fmt.Errorf("getRemoveID, get removeIDStore error: %v", err) - } - var removeID uint64 = 0 - if removeIDStore != nil { - removeIDBytes, err := cstates.GetValueFromRawStorageItem(removeIDStore) - if err != nil { - return 0, fmt.Errorf("getRemoveID, deserialize from raw storage item err:%v", err) - } - removeID = utils.GetBytesUint64(removeIDBytes) - } - return removeID, nil -} - -func putRemoveID(native *native.NativeContract, removeID uint64) error { - contract := utils.RelayerManagerContractAddress - removeIDByte := utils.GetUint64Bytes(removeID) - - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(REMOVE_ID)), cstates.GenRawStorageItem(removeIDByte)) - return nil -} - -func getRelayerRemove(native *native.NativeContract, removeID uint64) (*RelayerListParam, error) { - contract := utils.RelayerManagerContractAddress - relayerListParamStore, err := native.GetCacheDB().Get(utils.ConcatKey(contract, []byte(RELAYER_REMOVE), utils.GetUint64Bytes(removeID))) - if err != nil { - return nil, fmt.Errorf("getRelayerRemove, get relayerListParamStore error: %v", err) - } - if relayerListParamStore == nil { - return nil, fmt.Errorf("getRelayerRemove, can't find any record") - } - relayerListParam := new(RelayerListParam) - relayerListParamBytes, err := cstates.GetValueFromRawStorageItem(relayerListParamStore) - if err != nil { - return nil, fmt.Errorf("getRelayerRemove, deserialize from raw storage item err:%v", err) - } - err = relayerListParam.Deserialization(polycomm.NewZeroCopySource(relayerListParamBytes)) - if err != nil { - return nil, fmt.Errorf("getRelayerRemove, Deserialization fail:%v", err) - } - return relayerListParam, nil -} diff --git a/contracts/native/governance/side_chain_manager/abi.go b/contracts/native/governance/side_chain_manager/abi.go deleted file mode 100644 index a69bb873..00000000 --- a/contracts/native/governance/side_chain_manager/abi.go +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package side_chain_manager - -import ( - "fmt" - "strings" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native/go_abi/side_chain_manager_abi" - polycomm "github.com/polynetwork/poly/common" -) - -var ( - EventRegisterSideChain = side_chain_manager_abi.MethodRegisterSideChain - EventApproveRegisterSideChain = side_chain_manager_abi.MethodApproveRegisterSideChain - EventUpdateSideChain = side_chain_manager_abi.MethodUpdateSideChain - EventApproveUpdateSideChain = side_chain_manager_abi.MethodApproveUpdateSideChain - EventQuitSideChain = side_chain_manager_abi.MethodQuitSideChain - EventApproveQuitSideChain = side_chain_manager_abi.MethodApproveQuitSideChain - EventRegisterRedeem = side_chain_manager_abi.MethodRegisterRedeem -) - -func GetABI() *abi.ABI { - ab, err := abi.JSON(strings.NewReader(side_chain_manager_abi.SideChainManagerABI)) - if err != nil { - panic(fmt.Sprintf("failed to load abi json string: [%v]", err)) - } - return &ab -} - -type RegisterSideChainParam struct { - Address common.Address - ChainId uint64 - Router uint64 - Name string - BlocksToWait uint64 - CCMCAddress []byte - ExtraInfo []byte -} - -type ChainidParam struct { - Chainid uint64 - Address common.Address -} - -type RegisterRedeemParam struct { - RedeemChainID uint64 - ContractChainID uint64 - Redeem []byte - CVersion uint64 - ContractAddress []byte - Signs [][]byte -} - -type BtcTxParam struct { - Redeem []byte - RedeemChainId uint64 - Sigs [][]byte - Detial *BtcTxParamDetial -} - -type BtcTxParamDetial struct { - PVersion uint64 - FeeRate uint64 - MinChange uint64 -} - -func (this *BtcTxParamDetial) Serialization(sink *polycomm.ZeroCopySink) { - sink.WriteVarUint(this.PVersion) - sink.WriteVarUint(this.FeeRate) - sink.WriteVarUint(this.MinChange) -} - -func (this *BtcTxParamDetial) Deserialization(source *polycomm.ZeroCopySource) error { - var eof bool - this.PVersion, eof = source.NextVarUint() - if eof { - return fmt.Errorf("BtcTxParamDetial deserialize version error") - } - this.FeeRate, eof = source.NextVarUint() - if eof { - return fmt.Errorf("BtcTxParamDetial deserialize fee rate error") - } - this.MinChange, eof = source.NextVarUint() - if eof { - return fmt.Errorf("BtcTxParamDetial deserialize min-change error") - } - return nil -} diff --git a/contracts/native/governance/side_chain_manager/side_chain_manager.go b/contracts/native/governance/side_chain_manager/side_chain_manager.go deleted file mode 100644 index 2315637e..00000000 --- a/contracts/native/governance/side_chain_manager/side_chain_manager.go +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package side_chain_manager - -import ( - "encoding/hex" - "fmt" - - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcutil" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/contract" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/polynetwork/poly/common" -) - -const contractName = "side chain manager" - -const ( - //function name - MethodContractName = "name" - MethodRegisterSideChain = "registerSideChain" - MethodApproveRegisterSideChain = "approveRegisterSideChain" - MethodUpdateSideChain = "updateSideChain" - MethodApproveUpdateSideChain = "approveUpdateSideChain" - MethodQuitSideChain = "quitSideChain" - MethodApproveQuitSideChain = "approveQuitSideChain" - MethodRegisterRedeem = "registerRedeem" - MethodSetBtcTxParam = "setBtcTxParam" - - //key prefix - SIDE_CHAIN_APPLY = "sideChainApply" - UPDATE_SIDE_CHAIN_REQUEST = "updateSideChainRequest" - QUIT_SIDE_CHAIN_REQUEST = "quitSideChainRequest" - SIDE_CHAIN = "sideChain" - REDEEM_BIND = "redeemBind" - BIND_SIGN_INFO = "bindSignInfo" - BTC_TX_PARAM = "btcTxParam" - REDEEM_SCRIPT = "redeemScript" -) - -var ( - this = native.NativeContractAddrMap[native.NativeSideChainManager] - gasTable = map[string]uint64{ - // MethodContractName: 0, - MethodRegisterSideChain: 0, - MethodApproveRegisterSideChain: 100000, - MethodUpdateSideChain: 0, - MethodApproveUpdateSideChain: 0, - MethodQuitSideChain: 0, - MethodApproveQuitSideChain: 0, - MethodRegisterRedeem: 0, - MethodSetBtcTxParam: 0, - } - - ABI *abi.ABI -) - -func InitSideChainManager() { - ABI = GetABI() - native.Contracts[this] = RegisterSideChainManagerContract -} - -func RegisterSideChainManagerContract(s *native.NativeContract) { - s.Prepare(ABI, gasTable) - - // s.Register(MethodContractName, Name) - s.Register(MethodRegisterSideChain, RegisterSideChain) - s.Register(MethodApproveRegisterSideChain, ApproveRegisterSideChain) - s.Register(MethodUpdateSideChain, UpdateSideChain) - s.Register(MethodApproveUpdateSideChain, ApproveUpdateSideChain) - s.Register(MethodQuitSideChain, QuitSideChain) - s.Register(MethodApproveQuitSideChain, ApproveQuitSideChain) - s.Register(MethodRegisterRedeem, RegisterRedeem) - s.Register(MethodSetBtcTxParam, SetBtcTxParam) -} - -func Name(s *native.NativeContract) ([]byte, error) { - return utils.PackOutputs(ABI, MethodContractName, contractName) -} - -func RegisterSideChain(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &RegisterSideChainParam{} - if err := utils.UnpackMethod(ABI, MethodRegisterSideChain, params, ctx.Payload); err != nil { - return nil, err - } - - //check witness - err := contract.ValidateOwner(native, params.Address) - if err != nil { - return nil, fmt.Errorf("RegisterSideChain, checkWitness error: %v", err) - } - registerSideChain, err := GetSideChainApply(native, params.ChainId) - if err != nil { - return nil, fmt.Errorf("RegisterSideChain, getRegisterSideChain error: %v", err) - } - if registerSideChain != nil { - return nil, fmt.Errorf("RegisterSideChain, chainid already requested") - } - sideChain, err := GetSideChain(native, params.ChainId) - if err != nil { - return nil, fmt.Errorf("RegisterSideChain, getSideChain error: %v", err) - } - if sideChain != nil { - return nil, fmt.Errorf("RegisterSideChain, chainid already registered") - } - - sideChain = &SideChain{ - Address: params.Address, - ChainId: params.ChainId, - Router: params.Router, - Name: params.Name, - BlocksToWait: params.BlocksToWait, - CCMCAddress: params.CCMCAddress, - ExtraInfo: params.ExtraInfo, - } - err = putSideChainApply(native, sideChain) - if err != nil { - return nil, fmt.Errorf("RegisterSideChain, putRegisterSideChain error: %v", err) - } - - err = native.AddNotify(ABI, []string{EventRegisterSideChain}, params.ChainId, params.Router, params.Name, params.BlocksToWait) - if err != nil { - return nil, fmt.Errorf("RegisterSideChain, AddNotify error: %v", err) - } - return utils.PackOutputs(ABI, MethodRegisterSideChain, true) -} - -func ApproveRegisterSideChain(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &ChainidParam{} - if err := utils.UnpackMethod(ABI, MethodApproveRegisterSideChain, params, ctx.Payload); err != nil { - return nil, err - } - - //check witness - err := contract.ValidateOwner(native, params.Address) - if err != nil { - return nil, fmt.Errorf("ApproveRegisterSideChain, checkWitness error: %v", err) - } - - registerSideChain, err := GetSideChainApply(native, params.Chainid) - if err != nil { - return nil, fmt.Errorf("ApproveRegisterSideChain, getRegisterSideChain error: %v", err) - } - if registerSideChain == nil { - return nil, fmt.Errorf("ApproveRegisterSideChain, chainid is not requested") - } - - ok, err := node_manager.CheckConsensusSigns(native, MethodApproveRegisterSideChain, utils.GetUint64Bytes(params.Chainid), - params.Address) - if err != nil { - return nil, fmt.Errorf("ApproveRegisterSideChain, CheckConsensusSigns error: %v", err) - } - if !ok { - return utils.PackOutputs(ABI, MethodApproveRegisterSideChain, true) - } - - err = PutSideChain(native, registerSideChain) - if err != nil { - return nil, fmt.Errorf("ApproveRegisterSideChain, putSideChain error: %v", err) - } - - native.GetCacheDB().Delete(utils.ConcatKey(utils.SideChainManagerContractAddress, []byte(SIDE_CHAIN_APPLY), utils.GetUint64Bytes(params.Chainid))) - err = native.AddNotify(ABI, []string{EventApproveRegisterSideChain}, params.Chainid) - if err != nil { - return nil, fmt.Errorf("ApproveRegisterSideChain, AddNotify error: %v", err) - } - return utils.PackOutputs(ABI, MethodApproveRegisterSideChain, true) -} - -func UpdateSideChain(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &RegisterSideChainParam{} - if err := utils.UnpackMethod(ABI, MethodUpdateSideChain, params, ctx.Payload); err != nil { - return nil, err - } - - //check witness - err := contract.ValidateOwner(native, params.Address) - if err != nil { - return nil, fmt.Errorf("RegisterSideChain, checkWitness error: %v", err) - } - - sideChain, err := GetSideChain(native, params.ChainId) - if err != nil { - return nil, fmt.Errorf("UpdateSideChain, getSideChain error: %v", err) - } - if sideChain == nil { - return nil, fmt.Errorf("UpdateSideChain, side chain is not registered") - } - if sideChain.Address != params.Address { - return nil, fmt.Errorf("UpdateSideChain, side chain owner is wrong") - } - updateSideChain := &SideChain{ - Address: params.Address, - ChainId: params.ChainId, - Router: params.Router, - Name: params.Name, - BlocksToWait: params.BlocksToWait, - CCMCAddress: params.CCMCAddress, - ExtraInfo: params.ExtraInfo, - } - err = putUpdateSideChain(native, updateSideChain) - if err != nil { - return nil, fmt.Errorf("UpdateSideChain, putUpdateSideChain error: %v", err) - } - err = native.AddNotify(ABI, []string{EventUpdateSideChain}, params.ChainId, params.Router, params.Name, params.BlocksToWait) - if err != nil { - return nil, fmt.Errorf("UpdateSideChain, AddNotify error: %v", err) - } - - return utils.PackOutputs(ABI, MethodUpdateSideChain, true) -} - -func ApproveUpdateSideChain(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &ChainidParam{} - if err := utils.UnpackMethod(ABI, MethodApproveUpdateSideChain, params, ctx.Payload); err != nil { - return nil, err - } - - //check witness - err := contract.ValidateOwner(native, params.Address) - if err != nil { - return nil, fmt.Errorf("ApproveUpdateSideChain, checkWitness error: %v", err) - } - sideChain, err := getUpdateSideChain(native, params.Chainid) - if err != nil { - return nil, fmt.Errorf("ApproveUpdateSideChain, getUpdateSideChain error: %v", err) - } - if sideChain == nil { - return nil, fmt.Errorf("ApproveUpdateSideChain, chainid is not requested update") - } - - //check consensus signs - ok, err := node_manager.CheckConsensusSigns(native, MethodApproveUpdateSideChain, utils.GetUint64Bytes(params.Chainid), - params.Address) - if err != nil { - return nil, fmt.Errorf("ApproveUpdateSideChain, CheckConsensusSigns error: %v", err) - } - if !ok { - utils.PackOutputs(ABI, MethodApproveUpdateSideChain, true) - } - - err = PutSideChain(native, sideChain) - if err != nil { - return nil, fmt.Errorf("ApproveUpdateSideChain, putSideChain error: %v", err) - } - - chainidByte := utils.GetUint64Bytes(params.Chainid) - native.GetCacheDB().Delete(utils.ConcatKey(utils.SideChainManagerContractAddress, []byte(UPDATE_SIDE_CHAIN_REQUEST), chainidByte)) - - err = native.AddNotify(ABI, []string{EventApproveUpdateSideChain}, params.Chainid) - if err != nil { - return nil, fmt.Errorf("ApproveUpdateSideChain, AddNotify error: %v", err) - } - - return utils.PackOutputs(ABI, MethodApproveUpdateSideChain, true) -} - -func QuitSideChain(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &ChainidParam{} - if err := utils.UnpackMethod(ABI, MethodQuitSideChain, params, ctx.Payload); err != nil { - return nil, err - } - - //check witness - err := contract.ValidateOwner(native, params.Address) - if err != nil { - return nil, fmt.Errorf("ApproveUpdateSideChain, checkWitness error: %v", err) - } - - sideChain, err := GetSideChain(native, params.Chainid) - if err != nil { - return nil, fmt.Errorf("QuitSideChain, getSideChain error: %v", err) - } - if sideChain == nil { - return nil, fmt.Errorf("QuitSideChain, side chain is not registered") - } - if sideChain.Address != params.Address { - return nil, fmt.Errorf("QuitSideChain, side chain owner is wrong") - } - err = putQuitSideChain(native, params.Chainid) - if err != nil { - return nil, fmt.Errorf("QuitSideChain, putUpdateSideChain error: %v", err) - } - - err = native.AddNotify(ABI, []string{EventQuitSideChain}, params.Chainid) - if err != nil { - return nil, fmt.Errorf("QuitSideChain, AddNotify error: %v", err) - } - return utils.PackOutputs(ABI, MethodQuitSideChain, true) -} - -func ApproveQuitSideChain(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &ChainidParam{} - if err := utils.UnpackMethod(ABI, MethodApproveQuitSideChain, params, ctx.Payload); err != nil { - return nil, err - } - - //check witness - err := contract.ValidateOwner(native, params.Address) - if err != nil { - return nil, fmt.Errorf("ApproveQuitSideChain, checkWitness error: %v", err) - } - - err = getQuitSideChain(native, params.Chainid) - if err != nil { - return nil, fmt.Errorf("ApproveQuitSideChain, getQuitSideChain error: %v", err) - } - - //check consensus signs - ok, err := node_manager.CheckConsensusSigns(native, MethodQuitSideChain, utils.GetUint64Bytes(params.Chainid), - params.Address) - if err != nil { - return nil, fmt.Errorf("ApproveQuitSideChain, CheckConsensusSigns error: %v", err) - } - if !ok { - return utils.PackOutputs(ABI, MethodApproveQuitSideChain, true) - } - - chainidByte := utils.GetUint64Bytes(params.Chainid) - native.GetCacheDB().Delete(utils.ConcatKey(utils.SideChainManagerContractAddress, []byte(MethodQuitSideChain), chainidByte)) - native.GetCacheDB().Delete(utils.ConcatKey(utils.SideChainManagerContractAddress, []byte(SIDE_CHAIN), chainidByte)) - - err = native.AddNotify(ABI, []string{EventApproveQuitSideChain}, params.Chainid) - if err != nil { - return nil, fmt.Errorf("ApproveQuitSideChain, AddNotify error: %v", err) - } - return utils.PackOutputs(ABI, MethodApproveQuitSideChain, true) -} - -func RegisterRedeem(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &RegisterRedeemParam{} - if err := utils.UnpackMethod(ABI, MethodRegisterRedeem, params, ctx.Payload); err != nil { - return nil, err - } - - ty, addrs, m, err := txscript.ExtractPkScriptAddrs(params.Redeem, netParam) - if err != nil { - return nil, fmt.Errorf("RegisterRedeem, failed to extract addrs: %v", err) - } - if ty != txscript.MultiSigTy { - return nil, fmt.Errorf("RegisterRedeem, wrong type of redeem: %s", ty.String()) - } - rk := btcutil.Hash160(params.Redeem) - - contract, err := GetContractBind(native, params.RedeemChainID, params.ContractChainID, rk) - if err != nil { - return nil, fmt.Errorf("RegisterRedeem, failed to get contract and version: %v", err) - } - if contract != nil && contract.Ver+1 != params.CVersion { - return nil, fmt.Errorf("RegisterRedeem, previous version is %d and your version should "+ - "be %d not %d", contract.Ver, contract.Ver+1, params.CVersion) - } - verified, err := verifyRedeemRegister(params, addrs) - if err != nil { - return nil, fmt.Errorf("RegisterRedeem, failed to verify: %v", err) - } - key := append(append(append(rk, utils.GetUint64Bytes(params.RedeemChainID)...), - params.ContractAddress...), utils.GetUint64Bytes(params.ContractChainID)...) - bindSignInfo, err := getBindSignInfo(native, key) - if err != nil { - return nil, fmt.Errorf("RegisterRedeem, getBindSignInfo error: %v", err) - } - for k, v := range verified { - bindSignInfo.BindSignInfo[k] = v - } - err = putBindSignInfo(native, key, bindSignInfo) - if err != nil { - return nil, fmt.Errorf("RegisterRedeem, failed to putBindSignInfo: %v", err) - } - - if len(bindSignInfo.BindSignInfo) >= m { - err = putContractBind(native, params.RedeemChainID, params.ContractChainID, rk, params.ContractAddress, params.CVersion) - if err != nil { - return nil, fmt.Errorf("RegisterRedeem, putContractBind error: %v", err) - } - if err = putBtcRedeemScript(native, hex.EncodeToString(rk), params.Redeem, params.RedeemChainID); err != nil { - return nil, fmt.Errorf("RegisterRedeem, failed to save redeemscript %v with key %v, error: %v", hex.EncodeToString(params.Redeem), rk, err) - } - err = native.AddNotify(ABI, []string{EventRegisterRedeem}, hex.EncodeToString(rk), hex.EncodeToString(params.ContractAddress)) - if err != nil { - return nil, fmt.Errorf("RegisterRedeem, AddNotify error: %v", err) - } - } - - return utils.PackOutputs(ABI, MethodRegisterRedeem, true) -} - -func SetBtcTxParam(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &BtcTxParam{} - if err := utils.UnpackMethod(ABI, MethodRegisterRedeem, params, ctx.Payload); err != nil { - return nil, err - } - - if params.Detial.FeeRate == 0 { - return nil, fmt.Errorf("SetBtcTxParam, fee rate can't be zero") - } - if params.Detial.MinChange < 2000 { - return nil, fmt.Errorf("SetBtcTxParam, min-change can't less than 2000") - } - cls, addrs, m, err := txscript.ExtractPkScriptAddrs(params.Redeem, netParam) - if err != nil { - return nil, fmt.Errorf("SetBtcTxParam, extract addrs from redeem %v", err) - } - if cls != txscript.MultiSigTy { - return nil, fmt.Errorf("SetBtcTxParam, redeem script is not multisig script: %s", cls.String()) - } - rk := btcutil.Hash160(params.Redeem) - prev, err := GetBtcTxParam(native, rk, params.RedeemChainId) - if err != nil { - return nil, fmt.Errorf("SetBtcTxParam, get previous param error: %v", err) - } - if prev != nil && params.Detial.PVersion != prev.PVersion+1 { - return nil, fmt.Errorf("SetBtcTxParam, previous version is %d and your version should "+ - "be %d not %d", prev.PVersion, prev.PVersion+1, params.Detial.PVersion) - } - sink := common.NewZeroCopySink(nil) - params.Detial.Serialization(sink) - key := append(append(rk, utils.GetUint64Bytes(params.RedeemChainId)...), sink.Bytes()...) - info, err := getBindSignInfo(native, key) - if err != nil { - return nil, fmt.Errorf("SetBtcTxParam, getBindSignInfo error: %v", err) - } - if len(info.BindSignInfo) >= m { - return nil, fmt.Errorf("SetBtcTxParam, the signatures are already enough") - } - verified, err := verifyBtcTxParam(params, addrs) - if err != nil { - return nil, fmt.Errorf("SetBtcTxParam, failed to verify: %v", err) - } - for k, v := range verified { - info.BindSignInfo[k] = v - } - if err = putBindSignInfo(native, key, info); err != nil { - return nil, fmt.Errorf("SetBtcTxParam, failed to put bindSignInfo: %v", err) - } - if len(info.BindSignInfo) >= m { - if err = putBtcTxParam(native, rk, params.RedeemChainId, params.Detial); err != nil { - return nil, fmt.Errorf("SetBtcTxParam, failed to put btcTxParam: %v", err) - } - native.AddNotify( - ABI, []string{MethodRegisterRedeem}, hex.EncodeToString(rk), params.RedeemChainId, - params.Detial.FeeRate, params.Detial.MinChange) - } - - return utils.PackOutputs(ABI, MethodRegisterRedeem, true) -} diff --git a/contracts/native/governance/side_chain_manager/side_chain_manager_test.go b/contracts/native/governance/side_chain_manager/side_chain_manager_test.go deleted file mode 100644 index b797f5b0..00000000 --- a/contracts/native/governance/side_chain_manager/side_chain_manager_test.go +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package side_chain_manager - -import ( - "encoding/hex" - "math/big" - "testing" - - "crypto/ecdsa" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/crypto" - polycomm "github.com/polynetwork/poly/common" - cstates "github.com/polynetwork/poly/core/states" - "github.com/stretchr/testify/assert" -) - -func init() { - InitSideChainManager() - node_manager.InitNodeManager() - db := rawdb.NewMemoryDatabase() - sdb, _ = state.New(common.Hash{}, state.NewDatabase(db), nil) - - cacheDB := (*state.CacheDB)(sdb) - putPeerMapPoolAndView(cacheDB) -} - -func putPeerMapPoolAndView(db *state.CacheDB) { - key, _ := crypto.GenerateKey() - acct = &key.PublicKey - - peerPoolMap := new(node_manager.PeerPoolMap) - peerPoolMap.PeerPoolMap = make(map[string]*node_manager.PeerPoolItem) - pkStr := hex.EncodeToString(crypto.FromECDSAPub(acct)) - peerPoolMap.PeerPoolMap[pkStr] = &node_manager.PeerPoolItem{ - Index: uint32(0), - PeerPubkey: pkStr, - Address: crypto.PubkeyToAddress(*acct), - Status: node_manager.ConsensusStatus, - } - view := uint32(0) - viewBytes := utils.GetUint32Bytes(view) - sink := polycomm.NewZeroCopySink(nil) - peerPoolMap.Serialization(sink) - db.Put(utils.ConcatKey(utils.NodeManagerContractAddress, []byte(node_manager.PEER_POOL), viewBytes), cstates.GenRawStorageItem(sink.Bytes())) - - sink.Reset() - - govView := node_manager.GovernanceView{ - View: view, - } - govView.Serialization(sink) - db.Put(utils.ConcatKey(utils.NodeManagerContractAddress, []byte(node_manager.GOVERNANCE_VIEW)), cstates.GenRawStorageItem(sink.Bytes())) -} - -var ( - sdb *state.StateDB - acct *ecdsa.PublicKey -) - -func TestRegisterSideChainManager(t *testing.T) { - param := new(RegisterSideChainParam) - param.BlocksToWait = 4 - param.ChainId = 8 - param.Name = "mychain" - param.Router = 3 - - input, err := utils.PackMethodWithStruct(ABI, MethodRegisterSideChain, param) - assert.Nil(t, err) - - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, common.Address{}, common.Address{}, blockNumber, common.Hash{}, gasTable[MethodRegisterSideChain]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(common.Address{}, utils.SideChainManagerContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(ABI, MethodRegisterSideChain, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - - contract := native.NewNativeContract(sdb, contractRef) - sideChain, err := GetSideChainApply(contract, 8) - assert.Equal(t, sideChain.Name, "mychain") - assert.Nil(t, err) - - _, _, err = contractRef.NativeCall(common.Address{}, utils.SideChainManagerContractAddress, input) - assert.NotNil(t, err) -} - -func TestApproveRegisterSideChain(t *testing.T) { - - TestRegisterSideChainManager(t) - - caller := crypto.PubkeyToAddress(*acct) - param := new(ChainidParam) - param.Chainid = 8 - param.Address = caller - - input, err := utils.PackMethodWithStruct(ABI, MethodApproveRegisterSideChain, param) - assert.Nil(t, err) - - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, gasTable[MethodApproveRegisterSideChain]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.SideChainManagerContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(ABI, MethodApproveRegisterSideChain, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) -} - -func TestUpdateSideChain(t *testing.T) { - TestApproveRegisterSideChain(t) - - param := new(RegisterSideChainParam) - param.Address = common.Address{} - param.BlocksToWait = 10 - param.ChainId = 8 - param.Name = "own" - param.Router = 3 - - input, err := utils.PackMethodWithStruct(ABI, MethodUpdateSideChain, param) - assert.Nil(t, err) - - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, common.Address{}, common.Address{}, blockNumber, common.Hash{}, gasTable[MethodUpdateSideChain]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(common.Address{}, utils.SideChainManagerContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(ABI, MethodUpdateSideChain, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) -} - -func TestApproveUpdateSideChain(t *testing.T) { - TestUpdateSideChain(t) - - caller := crypto.PubkeyToAddress(*acct) - - param := new(ChainidParam) - param.Chainid = 8 - param.Address = caller - - input, err := utils.PackMethodWithStruct(ABI, MethodApproveUpdateSideChain, param) - assert.Nil(t, err) - - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, gasTable[MethodApproveUpdateSideChain]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.SideChainManagerContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(ABI, MethodApproveUpdateSideChain, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - - contract := native.NewNativeContract(sdb, contractRef) - sideChain, err := GetSideChain(contract, 8) - assert.Equal(t, sideChain.Name, "own") - assert.Nil(t, err) -} diff --git a/contracts/native/governance/side_chain_manager/states.go b/contracts/native/governance/side_chain_manager/states.go deleted file mode 100644 index 50dc6a38..00000000 --- a/contracts/native/governance/side_chain_manager/states.go +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package side_chain_manager - -import ( - "fmt" - "sort" - - ethcomm "github.com/ethereum/go-ethereum/common" - "github.com/polynetwork/poly/common" -) - -type SideChain struct { - Address ethcomm.Address - ChainId uint64 - Router uint64 - Name string - BlocksToWait uint64 - CCMCAddress []byte - ExtraInfo []byte -} - -func (this *SideChain) Serialization(sink *common.ZeroCopySink) error { - sink.WriteVarBytes(this.Address[:]) - sink.WriteVarUint(this.ChainId) - sink.WriteVarUint(this.Router) - sink.WriteVarBytes([]byte(this.Name)) - sink.WriteVarUint(this.BlocksToWait) - sink.WriteVarBytes(this.CCMCAddress) - sink.WriteVarBytes(this.ExtraInfo) - return nil -} - -func (this *SideChain) Deserialization(source *common.ZeroCopySource) error { - address, eof := source.NextVarBytes() - if eof { - return fmt.Errorf("utils.NextVarBytes, deserialize address error") - } - addr, err := common.AddressParseFromBytes(address) - if err != nil { - return fmt.Errorf("common.AddressParseFromBytes, deserialize address error: %s", err) - } - chainId, eof := source.NextVarUint() - if eof { - return fmt.Errorf("source.NextVarUint, deserialize chainid error") - } - router, eof := source.NextVarUint() - if eof { - return fmt.Errorf("source.NextVarUint, deserialize router error") - } - name, eof := source.NextString() - if eof { - return fmt.Errorf("source.NextString, deserialize name error") - } - blocksToWait, eof := source.NextVarUint() - if eof { - return fmt.Errorf("source.NextVarUint, deserialize blocksToWait error") - } - CCMCAddress, eof := source.NextVarBytes() - if eof { - return fmt.Errorf("source.NextVarBytes, deserialize CCMCAddress error") - } - ExtraInfo, eof := source.NextVarBytes() - if eof { - return fmt.Errorf("source.NextVarBytes, deserialize ExtraInfo error") - } - - this.Address = ethcomm.Address(addr) - this.ChainId = chainId - this.Router = router - this.Name = name - this.BlocksToWait = blocksToWait - this.CCMCAddress = CCMCAddress - this.ExtraInfo = ExtraInfo - return nil -} - -type BindSignInfo struct { - BindSignInfo map[string][]byte -} - -func (this *BindSignInfo) Serialization(sink *common.ZeroCopySink) { - sink.WriteVarUint(uint64(len(this.BindSignInfo))) - var BindSignInfoList []string - for k := range this.BindSignInfo { - BindSignInfoList = append(BindSignInfoList, k) - } - sort.SliceStable(BindSignInfoList, func(i, j int) bool { - return BindSignInfoList[i] > BindSignInfoList[j] - }) - for _, k := range BindSignInfoList { - sink.WriteString(k) - sink.WriteVarBytes(this.BindSignInfo[k]) - } -} - -func (this *BindSignInfo) Deserialization(source *common.ZeroCopySource) error { - n, eof := source.NextVarUint() - if eof { - return fmt.Errorf("BindSignInfo deserialize MultiSignInfo length error") - } - bindSignInfo := make(map[string][]byte) - for i := 0; uint64(i) < n; i++ { - k, eof := source.NextString() - if eof { - return fmt.Errorf("BindSignInfo deserialize public key error") - } - v, eof := source.NextVarBytes() - if eof { - return fmt.Errorf("BindSignInfo deserialize byte error") - } - bindSignInfo[k] = v - } - this.BindSignInfo = bindSignInfo - return nil -} - -type ContractBinded struct { - Contract []byte - Ver uint64 -} - -func (this *ContractBinded) Serialization(sink *common.ZeroCopySink) { - sink.WriteVarBytes(this.Contract) - sink.WriteUint64(this.Ver) -} - -func (this *ContractBinded) Deserialization(source *common.ZeroCopySource) error { - var eof bool - this.Contract, eof = source.NextVarBytes() - if eof { - return fmt.Errorf("BindContract deserialize contract error") - } - this.Ver, eof = source.NextUint64() - if eof { - return fmt.Errorf("BindContract deserialize version error") - } - return nil -} diff --git a/contracts/native/governance/side_chain_manager/utils.go b/contracts/native/governance/side_chain_manager/utils.go deleted file mode 100644 index 4c77d2cd..00000000 --- a/contracts/native/governance/side_chain_manager/utils.go +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package side_chain_manager - -import ( - "fmt" - - "github.com/btcsuite/btcd/btcec" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/txscript" - "github.com/btcsuite/btcutil" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/polynetwork/poly/common" - cstates "github.com/polynetwork/poly/core/states" -) - -var netParam = &chaincfg.TestNet3Params - -func GetSideChainApply(native *native.NativeContract, chanid uint64) (*SideChain, error) { - contract := utils.SideChainManagerContractAddress - chainidByte := utils.GetUint64Bytes(chanid) - - sideChainStore, err := native.GetCacheDB().Get(utils.ConcatKey(contract, []byte(SIDE_CHAIN_APPLY), - chainidByte)) - if err != nil { - return nil, fmt.Errorf("getRegisterSideChain,get registerSideChainRequestStore error: %v", err) - } - sideChain := new(SideChain) - if sideChainStore != nil { - sideChainBytes, err := cstates.GetValueFromRawStorageItem(sideChainStore) - if err != nil { - return nil, fmt.Errorf("getRegisterSideChain, deserialize from raw storage item err:%v", err) - } - if err := sideChain.Deserialization(common.NewZeroCopySource(sideChainBytes)); err != nil { - return nil, fmt.Errorf("getRegisterSideChain, deserialize sideChain error: %v", err) - } - return sideChain, nil - } else { - return nil, nil - } -} - -func putSideChainApply(native *native.NativeContract, sideChain *SideChain) error { - contract := utils.SideChainManagerContractAddress - chainidByte := utils.GetUint64Bytes(sideChain.ChainId) - - sink := common.NewZeroCopySink(nil) - err := sideChain.Serialization(sink) - if err != nil { - return fmt.Errorf("putRegisterSideChain, sideChain.Serialization error: %v", err) - } - - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(SIDE_CHAIN_APPLY), chainidByte), - cstates.GenRawStorageItem(sink.Bytes())) - return nil -} - -func GetSideChain(native *native.NativeContract, chainID uint64) (*SideChain, error) { - contract := utils.SideChainManagerContractAddress - chainIDByte := utils.GetUint64Bytes(chainID) - - sideChainStore, err := native.GetCacheDB().Get(utils.ConcatKey(contract, []byte(SIDE_CHAIN), - chainIDByte)) - if err != nil { - return nil, fmt.Errorf("getSideChain,get registerSideChainRequestStore error: %v", err) - } - sideChain := new(SideChain) - if sideChainStore != nil { - sideChainBytes, err := cstates.GetValueFromRawStorageItem(sideChainStore) - if err != nil { - return nil, fmt.Errorf("getSideChain, deserialize from raw storage item err:%v", err) - } - if err := sideChain.Deserialization(common.NewZeroCopySource(sideChainBytes)); err != nil { - return nil, fmt.Errorf("getSideChain, deserialize sideChain error: %v", err) - } - return sideChain, nil - } - return nil, nil - -} - -func PutSideChain(native *native.NativeContract, sideChain *SideChain) error { - contract := utils.SideChainManagerContractAddress - chainidByte := utils.GetUint64Bytes(sideChain.ChainId) - - sink := common.NewZeroCopySink(nil) - err := sideChain.Serialization(sink) - if err != nil { - return fmt.Errorf("putSideChain, sideChain.Serialization error: %v", err) - } - - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(SIDE_CHAIN), chainidByte), - cstates.GenRawStorageItem(sink.Bytes())) - return nil -} - -func getUpdateSideChain(native *native.NativeContract, chanid uint64) (*SideChain, error) { - contract := utils.SideChainManagerContractAddress - chainidByte := utils.GetUint64Bytes(chanid) - - sideChainStore, err := native.GetCacheDB().Get(utils.ConcatKey(contract, []byte(UPDATE_SIDE_CHAIN_REQUEST), - chainidByte)) - if err != nil { - return nil, fmt.Errorf("getUpdateSideChain,get registerSideChainRequestStore error: %v", err) - } - sideChain := new(SideChain) - if sideChainStore != nil { - sideChainBytes, err := cstates.GetValueFromRawStorageItem(sideChainStore) - if err != nil { - return nil, fmt.Errorf("getUpdateSideChain, deserialize from raw storage item err:%v", err) - } - if err := sideChain.Deserialization(common.NewZeroCopySource(sideChainBytes)); err != nil { - return nil, fmt.Errorf("getUpdateSideChain, deserialize sideChain error: %v", err) - } - return sideChain, nil - } else { - return nil, nil - } -} - -func putUpdateSideChain(native *native.NativeContract, sideChain *SideChain) error { - contract := utils.SideChainManagerContractAddress - chainidByte := utils.GetUint64Bytes(sideChain.ChainId) - - sink := common.NewZeroCopySink(nil) - err := sideChain.Serialization(sink) - if err != nil { - return fmt.Errorf("putUpdateSideChain, sideChain.Serialization error: %v", err) - } - - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(UPDATE_SIDE_CHAIN_REQUEST), chainidByte), - cstates.GenRawStorageItem(sink.Bytes())) - return nil -} - -func getQuitSideChain(native *native.NativeContract, chainid uint64) error { - contract := utils.SideChainManagerContractAddress - chainidByte := utils.GetUint64Bytes(chainid) - - chainIDStore, err := native.GetCacheDB().Get(utils.ConcatKey(contract, []byte(QUIT_SIDE_CHAIN_REQUEST), - chainidByte)) - if err != nil { - return fmt.Errorf("getQuitSideChain, get registerSideChainRequestStore error: %v", err) - } - if chainIDStore != nil { - return nil - } - return fmt.Errorf("getQuitSideChain, no record") -} - -func putQuitSideChain(native *native.NativeContract, chainid uint64) error { - contract := utils.SideChainManagerContractAddress - chainidByte := utils.GetUint64Bytes(chainid) - - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(QUIT_SIDE_CHAIN_REQUEST), chainidByte), - cstates.GenRawStorageItem(chainidByte)) - return nil -} - -func GetContractBind(native *native.NativeContract, redeemChainID, contractChainID uint64, - redeemKey []byte) (*ContractBinded, error) { - contract := utils.SideChainManagerContractAddress - redeemChainIDByte := utils.GetUint64Bytes(redeemChainID) - contractChainIDByte := utils.GetUint64Bytes(contractChainID) - contractBindStore, err := native.GetCacheDB().Get(utils.ConcatKey(contract, []byte(REDEEM_BIND), - redeemChainIDByte, contractChainIDByte, redeemKey)) - if err != nil { - return nil, fmt.Errorf("GetContractBind, get contractBindStore error: %v", err) - } - if contractBindStore != nil { - val, err := cstates.GetValueFromRawStorageItem(contractBindStore) - if err != nil { - return nil, fmt.Errorf("GetContractBind, deserialize from raw storage item err:%v", err) - } - cb := &ContractBinded{} - err = cb.Deserialization(common.NewZeroCopySource(val)) - if err != nil { - return nil, fmt.Errorf("GetContractBind, deserialize BindContract err:%v", err) - } - return cb, nil - } else { - return nil, nil - } - -} - -func putContractBind(native *native.NativeContract, redeemChainID, contractChainID uint64, - redeemKey, contractAddress []byte, cver uint64) error { - contract := utils.SideChainManagerContractAddress - redeemChainIDByte := utils.GetUint64Bytes(redeemChainID) - contractChainIDByte := utils.GetUint64Bytes(contractChainID) - bc := &ContractBinded{ - Contract: contractAddress, - Ver: cver, - } - sink := common.NewZeroCopySink(nil) - bc.Serialization(sink) - - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(REDEEM_BIND), - redeemChainIDByte, contractChainIDByte, redeemKey), cstates.GenRawStorageItem(sink.Bytes())) - return nil -} - -func putBindSignInfo(native *native.NativeContract, message []byte, multiSignInfo *BindSignInfo) error { - key := utils.ConcatKey(utils.SideChainManagerContractAddress, []byte(BIND_SIGN_INFO), message) - sink := common.NewZeroCopySink(nil) - multiSignInfo.Serialization(sink) - native.GetCacheDB().Put(key, cstates.GenRawStorageItem(sink.Bytes())) - return nil -} - -func getBindSignInfo(native *native.NativeContract, message []byte) (*BindSignInfo, error) { - key := utils.ConcatKey(utils.SideChainManagerContractAddress, []byte(BIND_SIGN_INFO), message) - bindSignInfoStore, err := native.GetCacheDB().Get(key) - if err != nil { - return nil, fmt.Errorf("getBtcMultiSignInfo, get multiSignInfoStore error: %v", err) - } - - bindSignInfo := &BindSignInfo{ - BindSignInfo: make(map[string][]byte), - } - if bindSignInfoStore != nil { - bindSignInfoBytes, err := cstates.GetValueFromRawStorageItem(bindSignInfoStore) - if err != nil { - return nil, fmt.Errorf("getBtcMultiSignInfo, deserialize from raw storage item err:%v", err) - } - err = bindSignInfo.Deserialization(common.NewZeroCopySource(bindSignInfoBytes)) - if err != nil { - return nil, fmt.Errorf("getBtcMultiSignInfo, deserialize multiSignInfo err:%v", err) - } - } - return bindSignInfo, nil -} - -func putBtcTxParam(native *native.NativeContract, redeemKey []byte, redeemChainId uint64, detail *BtcTxParamDetial) error { - redeemChainIdBytes := utils.GetUint64Bytes(redeemChainId) - sink := common.NewZeroCopySink(nil) - detail.Serialization(sink) - native.GetCacheDB().Put(utils.ConcatKey(utils.SideChainManagerContractAddress, []byte(BTC_TX_PARAM), redeemKey, - redeemChainIdBytes), cstates.GenRawStorageItem(sink.Bytes())) - return nil -} - -func GetBtcTxParam(native *native.NativeContract, redeemKey []byte, redeemChainId uint64) (*BtcTxParamDetial, error) { - redeemChainIdBytes := utils.GetUint64Bytes(redeemChainId) - store, err := native.GetCacheDB().Get(utils.ConcatKey(utils.SideChainManagerContractAddress, []byte(BTC_TX_PARAM), redeemKey, - redeemChainIdBytes)) - if err != nil { - return nil, fmt.Errorf("GetBtcTxParam, get btcTxParam error: %v", err) - } - if store != nil { - detialBytes, err := cstates.GetValueFromRawStorageItem(store) - if err != nil { - return nil, fmt.Errorf("GetBtcTxParam, deserialize from raw storage item error: %v", err) - } - detial := &BtcTxParamDetial{} - err = detial.Deserialization(common.NewZeroCopySource(detialBytes)) - if err != nil { - return nil, fmt.Errorf("GetBtcTxParam, deserialize BtcTxParam error: %v", err) - } - return detial, nil - } - return nil, nil -} - -func verifyRedeemRegister(param *RegisterRedeemParam, addrs []btcutil.Address) (map[string][]byte, error) { - r := make([]byte, len(param.Redeem)) - copy(r, param.Redeem) - cverBytes := utils.GetUint64Bytes(param.CVersion) - fromChainId := utils.GetUint64Bytes(param.RedeemChainID) - toChainId := utils.GetUint64Bytes(param.ContractChainID) - hash := btcutil.Hash160(append(append(append(append(r, fromChainId...), param.ContractAddress...), - toChainId...), cverBytes...)) - return verify(param.Signs, addrs, hash) -} - -func verifyBtcTxParam(param *BtcTxParam, addrs []btcutil.Address) (map[string][]byte, error) { - r := make([]byte, len(param.Redeem)) - copy(r, param.Redeem) - fromChainId := utils.GetUint64Bytes(param.RedeemChainId) - frBytes := utils.GetUint64Bytes(param.Detial.FeeRate) - mcBytes := utils.GetUint64Bytes(param.Detial.MinChange) - verBytes := utils.GetUint64Bytes(param.Detial.PVersion) - hash := btcutil.Hash160(append(append(append(append(r, fromChainId...), frBytes...), mcBytes...), verBytes...)) - return verify(param.Sigs, addrs, hash) -} - -func verify(sigs [][]byte, addrs []btcutil.Address, hash []byte) (map[string][]byte, error) { - res := make(map[string][]byte) - for i, sig := range sigs { - if len(sig) < 1 { - return nil, fmt.Errorf("length of no.%d sig is less than 1", i) - } - pSig, err := btcec.ParseDERSignature(sig, btcec.S256()) - if err != nil { - return nil, fmt.Errorf("failed to parse no.%d sig: %v", i, err) - } - for _, addr := range addrs { - if pSig.Verify(hash, addr.(*btcutil.AddressPubKey).PubKey()) { - res[addr.EncodeAddress()] = sig - } - } - } - if len(res) == 0 { - return nil, fmt.Errorf("no sigs is verified") - } - return res, nil -} - -func putBtcRedeemScript(native *native.NativeContract, redeemScriptKey string, redeemScriptBytes []byte, redeemChainId uint64) error { - chainIDBytes := utils.GetUint64Bytes(redeemChainId) - key := utils.ConcatKey(utils.SideChainManagerContractAddress, []byte(REDEEM_SCRIPT), chainIDBytes, []byte(redeemScriptKey)) - - cls := txscript.GetScriptClass(redeemScriptBytes) - if cls.String() != "multisig" { - return fmt.Errorf("putBtcRedeemScript, wrong type of redeem: %s", cls) - } - native.GetCacheDB().Put(key, cstates.GenRawStorageItem(redeemScriptBytes)) - return nil -} - -func GetBtcRedeemScriptBytes(native *native.NativeContract, redeemScriptKey string, redeemChainId uint64) ([]byte, error) { - chainIDBytes := utils.GetUint64Bytes(redeemChainId) - key := utils.ConcatKey(utils.SideChainManagerContractAddress, []byte(REDEEM_SCRIPT), chainIDBytes, []byte(redeemScriptKey)) - redeemStore, err := native.GetCacheDB().Get(key) - if err != nil { - return nil, fmt.Errorf("getBtcRedeemScript, get btcProofStore error: %v", err) - } - if redeemStore == nil { - return nil, fmt.Errorf("getBtcRedeemScript, can not find any records") - } - redeemBytes, err := cstates.GetValueFromRawStorageItem(redeemStore) - if err != nil { - return nil, fmt.Errorf("getBtcRedeemScript, deserialize from raw storage item err:%v", err) - } - return redeemBytes, nil -} diff --git a/contracts/native/header_sync/bsc/header_sync.go b/contracts/native/header_sync/bsc/header_sync.go deleted file mode 100644 index 1a6754c0..00000000 --- a/contracts/native/header_sync/bsc/header_sync.go +++ /dev/null @@ -1,848 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package bsc - -import ( - "encoding/json" - "errors" - "fmt" - "io" - "math/big" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - scom "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth/types" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rlp" - cstates "github.com/polynetwork/poly/core/states" - "golang.org/x/crypto/sha3" -) - -// Handler ... -type Handler struct { -} - -// NewHandler ... -func NewHandler() *Handler { - return &Handler{} -} - -// GenesisHeader ... -type GenesisHeader struct { - Header types.Header - PrevValidators []HeightAndValidators -} - -// HeightAndValidators ... -type HeightAndValidators struct { - Height *big.Int - Validators []common.Address - Hash *common.Hash -} - -// HeaderWithDifficultySum ... -type HeaderWithDifficultySum struct { - Header *types.Header `json:"header"` - DifficultySum *big.Int `json:"difficultySum"` - EpochParentHash *common.Hash `json:"epochParentHash"` -} - -// ExtraInfo ... -type ExtraInfo struct { - ChainID *big.Int // for bsc -} - -// Context ... -type Context struct { - ExtraInfo ExtraInfo - ChainID uint64 -} - -// HeaderWithChainID ... -type HeaderWithChainID struct { - Header *HeaderWithDifficultySum - ChainID uint64 -} - -var ( - inMemoryHeaders = 400 - inMemoryGenesis = 40 - extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity - extraSeal = crypto.SignatureLength // Fixed number of extra-data suffix bytes reserved for signer seal - uncleHash = types.CalcUncleHash(nil) // Always Keccak256(RLP([])) as uncles are meaningless outside of PoW. - diffInTurn = big.NewInt(2) // Block difficulty for in-turn signatures - diffNoTurn = big.NewInt(1) // Block difficulty for out-of-turn signatures - - GasLimitBoundDivisor uint64 = 256 // The bound divisor of the gas limit, used in update calculations. -) - -// SyncGenesisHeader ... -func (h *Handler) SyncGenesisHeader(native *native.NativeContract) (err error) { - ctx := native.ContractRef().CurrentContext() - params := &scom.SyncGenesisHeaderParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodSyncGenesisHeader, params, ctx.Payload); err != nil { - return fmt.Errorf("SyncGenesisHeader, contract params deserialize error: %v", err) - } - - // Get current epoch operator - ok, err := node_manager.CheckConsensusSigns(native, scom.MethodSyncGenesisHeader, ctx.Payload, native.ContractRef().MsgSender()) - if err != nil { - return fmt.Errorf("SyncGenesisHeader, CheckConsensusSigns error: %v", err) - } - if !ok { - return nil - } - - // can only store once - stored, err := isGenesisStored(native, params) - if err != nil { - return fmt.Errorf("bsc Handler SyncGenesisHeader, isGenesisStored error: %v", err) - } - if stored { - return fmt.Errorf("bsc Handler SyncGenesisHeader, genesis had been initialized") - } - - var genesis GenesisHeader - err = json.Unmarshal(params.GenesisHeader, &genesis) - if err != nil { - return fmt.Errorf("bsc Handler SyncGenesisHeader, deserialize GenesisHeader err: %v", err) - } - - signersBytes := len(genesis.Header.Extra) - extraVanity - extraSeal - if signersBytes == 0 || signersBytes%common.AddressLength != 0 { - return fmt.Errorf("invalid signer list, signersBytes:%d", signersBytes) - } - - if len(genesis.PrevValidators) != 1 { - return fmt.Errorf("invalid PrevValidators") - } - if genesis.Header.Number.Cmp(genesis.PrevValidators[0].Height) <= 0 { - return fmt.Errorf("invalid height orders") - } - validators, err := ParseValidators(genesis.Header.Extra[extraVanity : extraVanity+signersBytes]) - if err != nil { - return - } - genesis.PrevValidators = append([]HeightAndValidators{ - {Height: genesis.Header.Number, Validators: validators}, - }, genesis.PrevValidators...) - - err = storeGenesis(native, params, &genesis) - if err != nil { - return fmt.Errorf("bsc Handler SyncGenesisHeader, storeGenesis error: %v", err) - } - - return -} - -// SyncBlockHeader ... -func (h *Handler) SyncBlockHeader(native *native.NativeContract) error { - headerParams := &scom.SyncBlockHeaderParam{} - { - ctx := native.ContractRef().CurrentContext() - if err := utils.UnpackMethod(scom.ABI, scom.MethodSyncBlockHeader, headerParams, ctx.Payload); err != nil { - return err - } - } - - side, err := side_chain_manager.GetSideChain(native, headerParams.ChainID) - if err != nil { - return fmt.Errorf("bsc Handler SyncBlockHeader, GetSideChain error: %v", err) - } - var extraInfo ExtraInfo - err = json.Unmarshal(side.ExtraInfo, &extraInfo) - if err != nil { - return fmt.Errorf("bsc Handler SyncBlockHeader, ExtraInfo Unmarshal error: %v", err) - } - - ctx := &Context{ExtraInfo: extraInfo, ChainID: headerParams.ChainID} - - for _, v := range headerParams.Headers { - var header types.Header - err := json.Unmarshal(v, &header) - if err != nil { - return fmt.Errorf("bsc Handler SyncBlockHeader, deserialize header err: %v", err) - } - headerHash := header.Hash() - - exist, err := isHeaderExist(native, headerHash, ctx) - if err != nil { - return fmt.Errorf("bsc Handler SyncBlockHeader, isHeaderExist headerHash err: %v", err) - } - if exist { - log.Warnf("bsc Handler SyncBlockHeader, header has exist. Header: %s", string(v)) - continue - } - - parentExist, err := isHeaderExist(native, header.ParentHash, ctx) - if err != nil { - return fmt.Errorf("bsc Handler SyncBlockHeader, isHeaderExist ParentHash err: %v", err) - } - if !parentExist { - return fmt.Errorf("bsc Handler SyncBlockHeader, parent header not exist. Header: %s", string(v)) - } - - signer, err := verifySignature(native, &header, ctx) - if err != nil { - return fmt.Errorf("bsc Handler SyncBlockHeader, verifySignature err: %v", err) - } - - // get prev epochs, also checking recent limit - phv, pphv, lastSeenHeight, err := getPrevHeightAndValidators(native, &header, ctx) - if err != nil { - return fmt.Errorf("bsc Handler SyncBlockHeader, getPrevHeightAndValidators err: %v", err) - } - - var ( - inTurnHV *HeightAndValidators - ) - - diffWithLastEpoch := big.NewInt(0).Sub(header.Number, phv.Height).Int64() - if diffWithLastEpoch <= int64(len(pphv.Validators)/2) { - // pphv is in effect - inTurnHV = pphv - } else { - // phv is in effect - inTurnHV = phv - } - - if lastSeenHeight > 0 { - limit := int64(len(inTurnHV.Validators) / 2) - if header.Number.Int64() <= lastSeenHeight+limit { - return fmt.Errorf("bsc Handler SyncBlockHeader, RecentlySigned, lastSeenHeight:%d currentHeight:%d #V:%d", lastSeenHeight, header.Number.Int64(), len(inTurnHV.Validators)) - } - } - - indexInTurn := int(header.Number.Uint64()) % len(inTurnHV.Validators) - if indexInTurn < 0 { - return fmt.Errorf("indexInTurn is negative:%d inTurnHV.Height:%d header.Number:%d", indexInTurn, inTurnHV.Height.Int64(), header.Number.Int64()) - } - valid := false - for idx, v := range inTurnHV.Validators { - if v == signer { - valid = true - if indexInTurn == idx { - if header.Difficulty.Cmp(diffInTurn) != 0 { - return fmt.Errorf("invalid difficulty, got %v expect %v index:%v", header.Difficulty.Int64(), diffInTurn.Int64(), int(indexInTurn)%len(inTurnHV.Validators)) - } - } else { - if header.Difficulty.Cmp(diffNoTurn) != 0 { - return fmt.Errorf("invalid difficulty, got %v expect %v index:%v", header.Difficulty.Int64(), diffNoTurn.Int64(), int(indexInTurn)%len(inTurnHV.Validators)) - } - } - } - } - if !valid { - return fmt.Errorf("bsc Handler SyncBlockHeader, invalid signer") - } - - err = addHeader(native, &header, phv, ctx) - if err != nil { - return fmt.Errorf("bsc Handler SyncBlockHeader, addHeader err: %v", err) - } - - scom.NotifyPutHeader(native, headerParams.ChainID, header.Number.Uint64(), header.Hash().Hex()) - } - return nil -} - -// SyncCrossChainMsg ... -func (h *Handler) SyncCrossChainMsg(native *native.NativeContract) error { - return nil -} - -func isHeaderExist(native *native.NativeContract, headerHash common.Hash, ctx *Context) (bool, error) { - headerStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(ctx.ChainID), headerHash.Bytes())) - if err != nil { - return false, fmt.Errorf("bsc Handler isHeaderExist error: %v", err) - } - - return headerStore != nil, nil -} - -func verifySignature(native *native.NativeContract, header *types.Header, ctx *Context) (signer common.Address, err error) { - return verifyHeader(native, header, ctx) -} - -func verifyHeader(native *native.NativeContract, header *types.Header, ctx *Context) (signer common.Address, err error) { - - // Don't waste time checking blocks from the future - if header.Time > uint64(time.Now().Unix()) { - err = errors.New("block in the future") - return - } - - // Check that the extra-data contains both the vanity and signature - if len(header.Extra) < extraVanity { - err = errors.New("extra-data 32 byte vanity prefix missing") - return - } - if len(header.Extra) < extraVanity+extraSeal { - err = errors.New("extra-data 65 byte signature suffix missing") - return - } - - // Ensure that the extra-data contains a signer list on checkpoint, but none otherwise - signersBytes := len(header.Extra) - extraVanity - extraSeal - - if signersBytes%common.AddressLength != 0 { - err = errors.New("invalid signer list") - return - } - - // Ensure that the mix digest is zero as we don't have fork protection currently - if header.MixDigest != (common.Hash{}) { - err = errors.New("non-zero mix digest") - return - } - - // Ensure that the block doesn't contain any uncles which are meaningless in PoA - if header.UncleHash != uncleHash { - err = errors.New("non empty uncle hash") - return - } - - // Ensure that the block's difficulty is meaningful (may not be correct at this point) - if header.Difficulty == nil || (header.Difficulty.Cmp(diffInTurn) != 0 && header.Difficulty.Cmp(diffNoTurn) != 0) { - err = errors.New("invalid difficulty") - return - } - - // All basic checks passed, verify cascading fields - return verifyCascadingFields(native, header, ctx) -} - -func verifyCascadingFields(native *native.NativeContract, header *types.Header, ctx *Context) (signer common.Address, err error) { - - number := header.Number.Uint64() - - parent, err := getHeader(native, header.ParentHash, ctx.ChainID) - if err != nil { - return - } - - if parent.Header.Number.Uint64() != number-1 { - err = errors.New("unknown ancestor") - return - } - - // Verify that the gas limit is <= 2^63-1 - capacity := uint64(0x7fffffffffffffff) - if header.GasLimit > capacity { - err = fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, capacity) - return - } - // Verify that the gasUsed is <= gasLimit - if header.GasUsed > header.GasLimit { - err = fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit) - return - } - - // Verify that the gas limit remains within allowed bounds - diff := int64(parent.Header.GasLimit) - int64(header.GasLimit) - if diff < 0 { - diff *= -1 - } - limit := parent.Header.GasLimit / GasLimitBoundDivisor - - if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit { - err = fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.Header.GasLimit, limit) - return - } - - return verifySeal(native, header, ctx) -} - -// for test -var mockSigner common.Address - -func verifySeal(native *native.NativeContract, header *types.Header, ctx *Context) (signer common.Address, err error) { - // Verifying the genesis block is not supported - number := header.Number.Uint64() - if number == 0 { - err = errors.New("unknown block") - return - } - - if mockSigner != (common.Address{}) { - return mockSigner, nil - } - // Resolve the authorization key and check against validators - signer, err = ecrecover(header, ctx.ExtraInfo.ChainID) - if err != nil { - return - } - - if signer != header.Coinbase { - err = errors.New("coinbase do not match with signature") - return - } - - return -} - -// ecrecover extracts the Ethereum account address from a signed header. -func ecrecover(header *types.Header, chainID *big.Int) (common.Address, error) { - // Retrieve the signature from the header extra-data - if len(header.Extra) < extraSeal { - return common.Address{}, errors.New("extra-data 65 byte signature suffix missing") - } - signature := header.Extra[len(header.Extra)-extraSeal:] - - // Recover the public key and the Ethereum address - pubkey, err := crypto.Ecrecover(SealHash(header, chainID).Bytes(), signature) - if err != nil { - return common.Address{}, err - } - var signer common.Address - copy(signer[:], crypto.Keccak256(pubkey[1:])[12:]) - - return signer, nil -} - -// SealHash returns the hash of a block prior to it being sealed. -func SealHash(header *types.Header, chainID *big.Int) (hash common.Hash) { - hasher := sha3.NewLegacyKeccak256() - encodeSigHeader(hasher, header, chainID) - hasher.Sum(hash[:0]) - return hash -} - -func encodeSigHeader(w io.Writer, header *types.Header, chainID *big.Int) { - err := rlp.Encode(w, []interface{}{ - chainID, - header.ParentHash, - header.UncleHash, - header.Coinbase, - header.Root, - header.TxHash, - header.ReceiptHash, - header.Bloom, - header.Difficulty, - header.Number, - header.GasLimit, - header.GasUsed, - header.Time, - header.Extra[:len(header.Extra)-65], // this will panic if extra is too short, should check before calling encodeSigHeader - header.MixDigest, - header.Nonce, - }) - if err != nil { - panic("can't encode: " + err.Error()) - } -} - -func isGenesisStored(native *native.NativeContract, params *scom.SyncGenesisHeaderParam) (stored bool, err error) { - genesis, err := getGenesis(native, params.ChainID) - if err != nil { - return - } - - stored = genesis != nil - return -} - -func getGenesis(native *native.NativeContract, chainID uint64) (genesisHeader *GenesisHeader, err error) { - - genesisBytes, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.GENESIS_HEADER), utils.GetUint64Bytes(chainID))) - if err != nil { - err = fmt.Errorf("getGenesis, GetCacheDB err:%v", err) - return - } - - if genesisBytes == nil { - return - } - - genesisBytes, err = cstates.GetValueFromRawStorageItem(genesisBytes) - if err != nil { - err = fmt.Errorf("getGenesis, GetValueFromRawStorageItem err:%v", err) - return - } - - { - genesisHeader = &GenesisHeader{} - err = json.Unmarshal(genesisBytes, &genesisHeader) - if err != nil { - err = fmt.Errorf("getGenesis, json.Unmarshal err:%v", err) - return - } - } - - return -} - -func storeGenesis(native *native.NativeContract, params *scom.SyncGenesisHeaderParam, genesisHeader *GenesisHeader) (err error) { - - genesisBytes, err := json.Marshal(genesisHeader) - if err != nil { - return - } - - native.GetCacheDB().Put( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.GENESIS_HEADER), utils.GetUint64Bytes(params.ChainID)), - cstates.GenRawStorageItem(genesisBytes)) - - headerWithSum := &HeaderWithDifficultySum{Header: &genesisHeader.Header, DifficultySum: genesisHeader.Header.Difficulty} - - err = putHeaderWithSum(native, params.ChainID, headerWithSum) - if err != nil { - return - } - - putCanonicalHeight(native, params.ChainID, genesisHeader.Header.Number.Uint64()) - putCanonicalHash(native, params.ChainID, genesisHeader.Header.Number.Uint64(), genesisHeader.Header.Hash()) - - scom.NotifyPutHeader(native, params.ChainID, genesisHeader.Header.Number.Uint64(), genesisHeader.Header.Hash().Hex()) - return -} - -// ParseValidators ... -func ParseValidators(validatorsBytes []byte) ([]common.Address, error) { - if len(validatorsBytes)%common.AddressLength != 0 { - return nil, errors.New("invalid validators bytes") - } - n := len(validatorsBytes) / common.AddressLength - result := make([]common.Address, n) - for i := 0; i < n; i++ { - address := make([]byte, common.AddressLength) - copy(address, validatorsBytes[i*common.AddressLength:(i+1)*common.AddressLength]) - result[i] = common.BytesToAddress(address) - } - return result, nil -} - -func putHeaderWithSum(native *native.NativeContract, chainID uint64, headerWithSum *HeaderWithDifficultySum) (err error) { - - headerBytes, err := json.Marshal(headerWithSum) - if err != nil { - return - } - - native.GetCacheDB().Put( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), headerWithSum.Header.Hash().Bytes()), - cstates.GenRawStorageItem(headerBytes)) - return -} - -func putCanonicalHeight(native *native.NativeContract, chainID uint64, height uint64) { - native.GetCacheDB().Put( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.CURRENT_HEADER_HEIGHT), utils.GetUint64Bytes(chainID)), - cstates.GenRawStorageItem(utils.GetUint64Bytes(uint64(height)))) -} - -func putCanonicalHash(native *native.NativeContract, chainID uint64, height uint64, hash common.Hash) { - native.GetCacheDB().Put(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(height)), - cstates.GenRawStorageItem(hash.Bytes())) -} - -func addHeader(native *native.NativeContract, header *types.Header, phv *HeightAndValidators, ctx *Context) (err error) { - - parentHeader, err := getHeader(native, header.ParentHash, ctx.ChainID) - if err != nil { - return - } - - cheight, err := GetCanonicalHeight(native, ctx.ChainID) - if err != nil { - return - } - cheader, err := GetCanonicalHeader(native, ctx.ChainID, cheight) - if err != nil { - return - } - if cheader == nil { - err = fmt.Errorf("getCanonicalHeader returns nil") - return - } - - localTd := cheader.DifficultySum - externTd := new(big.Int).Add(header.Difficulty, parentHeader.DifficultySum) - - headerWithSum := &HeaderWithDifficultySum{Header: header, DifficultySum: externTd, EpochParentHash: phv.Hash} - err = putHeaderWithSum(native, ctx.ChainID, headerWithSum) - if err != nil { - return - } - - if externTd.Cmp(localTd) > 0 { - // Delete any canonical number assignments above the new head - var headerWithSum *HeaderWithDifficultySum - for i := header.Number.Uint64() + 1; ; i++ { - headerWithSum, err = GetCanonicalHeader(native, ctx.ChainID, i) - if err != nil { - return - } - if headerWithSum == nil { - break - } - - deleteCanonicalHash(native, ctx.ChainID, i) - } - - // Overwrite any stale canonical number assignments - var ( - hash common.Hash - headHeader *HeaderWithDifficultySum - ) - cheight := header.Number.Uint64() - 1 - headHash := header.ParentHash - - for { - hash, err = getCanonicalHash(native, ctx.ChainID, cheight) - if err != nil { - return - } - if hash == headHash { - break - } - - putCanonicalHash(native, ctx.ChainID, cheight, headHash) - headHeader, err = getHeader(native, headHash, ctx.ChainID) - if err != nil { - return - } - headHash = headHeader.Header.ParentHash - cheight-- - } - - // Extend the canonical chain with the new header - putCanonicalHash(native, ctx.ChainID, header.Number.Uint64(), header.Hash()) - putCanonicalHeight(native, ctx.ChainID, header.Number.Uint64()) - } - - return nil -} - -func getPrevHeightAndValidators(native *native.NativeContract, header *types.Header, ctx *Context) (phv, pphv *HeightAndValidators, lastSeenHeight int64, err error) { - - genesis, err := getGenesis(native, ctx.ChainID) - if err != nil { - err = fmt.Errorf("bsc Handler getGenesis error: %v", err) - return - } - - if genesis == nil { - err = fmt.Errorf("bsc Handler genesis not set") - return - } - - genesisHeaderHash := genesis.Header.Hash() - if header.Hash() == genesisHeaderHash { - err = fmt.Errorf("genesis header should not be synced again") - return - } - - lastSeenHeight = -1 - targetCoinbase := header.Coinbase - if header.ParentHash == genesisHeaderHash { - if genesis.Header.Coinbase == targetCoinbase { - lastSeenHeight = genesis.Header.Number.Int64() - } - - phv = &genesis.PrevValidators[0] - phv.Hash = &genesisHeaderHash - pphv = &genesis.PrevValidators[1] - return - } - - prevHeaderWithSum, err := getHeader(native, header.ParentHash, ctx.ChainID) - if err != nil { - err = fmt.Errorf("bsc Handler getHeader error: %v", err) - return - } - - if prevHeaderWithSum.Header.Coinbase == targetCoinbase { - lastSeenHeight = prevHeaderWithSum.Header.Number.Int64() - } else { - nextRecentParentHash := prevHeaderWithSum.Header.ParentHash - defer func() { - if err == nil { - maxV := len(phv.Validators) - if maxV < len(pphv.Validators) { - maxV = len(pphv.Validators) - } - maxLimit := maxV / 2 - for i := 0; i < maxLimit-1; i++ { - prevHeaderWithSum, err := getHeader(native, nextRecentParentHash, ctx.ChainID) - if err != nil { - err = fmt.Errorf("bsc Handler getHeader error: %v", err) - return - } - if prevHeaderWithSum.Header.Coinbase == targetCoinbase { - lastSeenHeight = prevHeaderWithSum.Header.Number.Int64() - return - } - - if nextRecentParentHash == genesisHeaderHash { - return - } - nextRecentParentHash = prevHeaderWithSum.Header.ParentHash - } - } - }() - } - - var ( - validators []common.Address - nextParentHash common.Hash - ) - - currentPV := &phv - - for { - - if len(prevHeaderWithSum.Header.Extra) > extraVanity+extraSeal { - validators, err = ParseValidators(prevHeaderWithSum.Header.Extra[extraVanity : len(prevHeaderWithSum.Header.Extra)-extraSeal]) - if err != nil { - err = fmt.Errorf("bsc Handler ParseValidators error: %v", err) - return - } - *currentPV = &HeightAndValidators{ - Height: prevHeaderWithSum.Header.Number, - Validators: validators, - } - switch *currentPV { - case phv: - hash := prevHeaderWithSum.Header.Hash() - phv.Hash = &hash - currentPV = &pphv - case pphv: - return - default: - err = fmt.Errorf("bug in bsc Handler") - return - } - } - - nextParentHash = prevHeaderWithSum.Header.ParentHash - if prevHeaderWithSum.EpochParentHash != nil { - nextParentHash = *prevHeaderWithSum.EpochParentHash - } - - if nextParentHash == genesisHeaderHash { - switch *currentPV { - case phv: - phv = &genesis.PrevValidators[0] - phv.Hash = &genesisHeaderHash - pphv = &genesis.PrevValidators[1] - case pphv: - pphv = &genesis.PrevValidators[0] - default: - err = fmt.Errorf("bug in bsc Handler") - return - } - return - } - - prevHeaderWithSum, err = getHeader(native, nextParentHash, ctx.ChainID) - if err != nil { - err = fmt.Errorf("bsc Handler getHeader error: %v", err) - return - } - - } -} - -func getHeader(native *native.NativeContract, hash common.Hash, chainID uint64) (headerWithSum *HeaderWithDifficultySum, err error) { - - headerStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), hash.Bytes())) - if err != nil { - return nil, fmt.Errorf("bsc Handler getHeader error: %v", err) - } - if headerStore == nil { - return nil, fmt.Errorf("bsc Handler getHeader, can not find any header records") - } - storeBytes, err := cstates.GetValueFromRawStorageItem(headerStore) - if err != nil { - return nil, fmt.Errorf("bsc Handler getHeader, deserialize headerBytes from raw storage item err:%v", err) - } - headerWithSum = &HeaderWithDifficultySum{} - if err := json.Unmarshal(storeBytes, &headerWithSum); err != nil { - return nil, fmt.Errorf("bsc Handler getHeader, deserialize header error: %v", err) - } - - return -} - -// GetCanonicalHeight ... -func GetCanonicalHeight(native *native.NativeContract, chainID uint64) (height uint64, err error) { - heightStore, err := native.GetCacheDB().Get( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.CURRENT_HEADER_HEIGHT), utils.GetUint64Bytes(chainID))) - if err != nil { - err = fmt.Errorf("bsc Handler GetCanonicalHeight err:%v", err) - return - } - - storeBytes, err := cstates.GetValueFromRawStorageItem(heightStore) - if err != nil { - err = fmt.Errorf("bsc Handler GetCanonicalHeight, GetValueFromRawStorageItem err:%v", err) - return - } - - height = utils.GetBytesUint64(storeBytes) - return -} - -// GetCanonicalHeader ... -func GetCanonicalHeader(native *native.NativeContract, chainID uint64, height uint64) (headerWithSum *HeaderWithDifficultySum, err error) { - hash, err := getCanonicalHash(native, chainID, height) - if err != nil { - return - } - - if hash == (common.Hash{}) { - return - } - - headerWithSum, err = getHeader(native, hash, chainID) - return -} - -func getCanonicalHash(native *native.NativeContract, chainID uint64, height uint64) (hash common.Hash, err error) { - hashBytesStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(height))) - if err != nil { - return - } - - if hashBytesStore == nil { - return - } - - hashBytes, err := cstates.GetValueFromRawStorageItem(hashBytesStore) - if err != nil { - err = fmt.Errorf("bsc Handler getCanonicalHash, GetValueFromRawStorageItem err:%v", err) - return - } - - hash = common.BytesToHash(hashBytes) - return -} - -func deleteCanonicalHash(native *native.NativeContract, chainID uint64, height uint64) { - native.GetCacheDB().Delete(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(height))) -} diff --git a/contracts/native/header_sync/common/abi.go b/contracts/native/header_sync/common/abi.go deleted file mode 100644 index 9c519fd3..00000000 --- a/contracts/native/header_sync/common/abi.go +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package common - -import ( - "fmt" - "strings" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/contracts/native/go_abi/header_sync_abi" -) - -var ( - MethodContractName = header_sync_abi.MethodName - MethodSyncGenesisHeader = header_sync_abi.MethodSyncGenesisHeader - MethodSyncBlockHeader = header_sync_abi.MethodSyncBlockHeader - MethodSyncCrossChainMsg = header_sync_abi.MethodSyncCrossChainMsg -) - -var GasTable = map[string]uint64{ - MethodContractName: 0, - MethodSyncGenesisHeader: 0, - MethodSyncBlockHeader: 1000, - MethodSyncCrossChainMsg: 0, -} - -func GetABI() *abi.ABI { - ab, err := abi.JSON(strings.NewReader(header_sync_abi.HeaderSyncABI)) - if err != nil { - panic(fmt.Sprintf("failed to load abi json string: [%v]", err)) - } - return &ab -} - -var ABI *abi.ABI diff --git a/contracts/native/header_sync/common/param.go b/contracts/native/header_sync/common/param.go deleted file mode 100644 index 470fa4e6..00000000 --- a/contracts/native/header_sync/common/param.go +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package common - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - polycomm "github.com/polynetwork/poly/common" -) - -const ( - //key prefix - CROSS_CHAIN_MSG = "crossChainMsg" - CURRENT_MSG_HEIGHT = "currentMsgHeight" - BLOCK_HEADER = "blockHeader" - CURRENT_HEADER_HEIGHT = "currentHeaderHeight" - HEADER_INDEX = "headerIndex" - CONSENSUS_PEER = "consensusPeer" - CONSENSUS_PEER_BLOCK_HEIGHT = "consensusPeerBlockHeight" - KEY_HEIGHTS = "keyHeights" - ETH_CACHE = "ethCaches" - GENESIS_HEADER = "genesisHeader" - MAIN_CHAIN = "mainChain" - EPOCH_SWITCH = "epochSwitch" - SYNC_HEADER_NAME_EVENT = "syncHeader" - SYNC_CROSSCHAIN_MSG = "syncCrossChainMsg" - POLYGON_SPAN = "polygonSpan" -) - -type HeaderSyncHandler interface { - SyncGenesisHeader(service *native.NativeContract) error - SyncBlockHeader(service *native.NativeContract) error - SyncCrossChainMsg(service *native.NativeContract) error -} - -type SyncGenesisHeaderParam struct { - ChainID uint64 - GenesisHeader []byte -} - -func (this *SyncGenesisHeaderParam) Serialization(sink *polycomm.ZeroCopySink) { - sink.WriteUint64(this.ChainID) - sink.WriteVarBytes(this.GenesisHeader) -} - -func (this *SyncGenesisHeaderParam) Deserialization(source *polycomm.ZeroCopySource) error { - chainID, eof := source.NextUint64() - if eof { - return fmt.Errorf("SyncGenesisHeaderParam deserialize chainID error") - } - genesisHeader, eof := source.NextVarBytes() - if eof { - return fmt.Errorf("utils.DecodeVarBytes, deserialize genesisHeader count error") - } - this.ChainID = chainID - this.GenesisHeader = genesisHeader - return nil -} - -type SyncBlockHeaderParam struct { - ChainID uint64 - Address common.Address - Headers [][]byte -} - -func (this *SyncBlockHeaderParam) Serialization(sink *polycomm.ZeroCopySink) { - sink.WriteUint64(this.ChainID) - sink.WriteAddress(polycomm.Address(this.Address)) - sink.WriteUint64(uint64(len(this.Headers))) - for _, v := range this.Headers { - sink.WriteVarBytes(v) - } -} - -func (this *SyncBlockHeaderParam) Deserialization(source *polycomm.ZeroCopySource) error { - chainID, eof := source.NextUint64() - if eof { - return fmt.Errorf("SyncGenesisHeaderParam deserialize chainID error") - } - address, eof := source.NextAddress() - if eof { - return fmt.Errorf("utils.DecodeAddress, deserialize address error") - } - n, eof := source.NextUint64() - if eof { - return fmt.Errorf("utils.DecodeVarUint, deserialize header count error") - } - var headers [][]byte - for i := 0; uint64(i) < n; i++ { - header, eof := source.NextVarBytes() - if eof { - - return fmt.Errorf("utils.DecodeVarBytes, deserialize header error") - } - headers = append(headers, header) - } - this.ChainID = chainID - this.Address = common.Address(address) - this.Headers = headers - return nil -} - -type SyncCrossChainMsgParam struct { - ChainID uint64 - Address common.Address - CrossChainMsgs [][]byte -} - -func (this *SyncCrossChainMsgParam) Serialization(sink *polycomm.ZeroCopySink) { - sink.WriteUint64(this.ChainID) - sink.WriteAddress(polycomm.Address(this.Address)) - sink.WriteUint64(uint64(len(this.CrossChainMsgs))) - for _, v := range this.CrossChainMsgs { - sink.WriteVarBytes(v) - } -} - -func (this *SyncCrossChainMsgParam) Deserialization(source *polycomm.ZeroCopySource) error { - chainID, eof := source.NextUint64() - if eof { - return fmt.Errorf("SyncGenesisHeaderParam deserialize chainID error") - } - address, eof := source.NextAddress() - if eof { - return fmt.Errorf("utils.DecodeAddress, deserialize address error") - } - n, eof := source.NextUint64() - if eof { - return fmt.Errorf("utils.DecodeVarUint, deserialize header count error") - } - var crossChainMsgs [][]byte - for i := 0; uint64(i) < n; i++ { - crossChainMsg, eof := source.NextVarBytes() - if eof { - - return fmt.Errorf("utils.DecodeVarBytes, deserialize crossChainMsg error") - } - crossChainMsgs = append(crossChainMsgs, crossChainMsg) - } - this.ChainID = chainID - this.Address = common.Address(address) - this.CrossChainMsgs = crossChainMsgs - return nil -} - -func NotifyPutHeader(native *native.NativeContract, chainID uint64, height uint64, blockHash string) { - - err := native.AddNotify(ABI, []string{SYNC_HEADER_NAME_EVENT}, chainID, height, blockHash, native.ContractRef().BlockHeight()) - if err != nil { - panic(fmt.Sprintf("NotifyPutHeader failed: %v", err)) - } -} diff --git a/contracts/native/header_sync/common/param_test.go b/contracts/native/header_sync/common/param_test.go deleted file mode 100644 index 479916e5..00000000 --- a/contracts/native/header_sync/common/param_test.go +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ - -package common - -import ( - "testing" - - polycomm "github.com/polynetwork/poly/common" - "github.com/stretchr/testify/assert" -) - -func TestSyncGenesisHeaderParam(t *testing.T) { - param := SyncGenesisHeaderParam{ - ChainID: 123, - GenesisHeader: []byte{1, 2, 3}, - } - - sink := polycomm.NewZeroCopySink(nil) - param.Serialization(sink) - - var p SyncGenesisHeaderParam - err := p.Deserialization(polycomm.NewZeroCopySource(sink.Bytes())) - assert.NoError(t, err) - - assert.Equal(t, p, param) -} - -func TestSyncBlockHeaderParam(t *testing.T) { - p := SyncBlockHeaderParam{ - ChainID: 123, - Headers: [][]byte{{1, 2, 3}}, - } - - sink := polycomm.NewZeroCopySink(nil) - p.Serialization(sink) - - var param SyncBlockHeaderParam - err := param.Deserialization(polycomm.NewZeroCopySource(sink.Bytes())) - - assert.NoError(t, err) - - assert.Equal(t, p, param) -} diff --git a/contracts/native/header_sync/cosmos/header_sync.go b/contracts/native/header_sync/cosmos/header_sync.go deleted file mode 100644 index f141ba67..00000000 --- a/contracts/native/header_sync/cosmos/header_sync.go +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2020 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ - -package cosmos - -import ( - "bytes" - "fmt" - "github.com/cosmos/cosmos-sdk/codec" - - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - scom "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/log" - "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/multisig" - "github.com/tendermint/tendermint/crypto/secp256k1" -) - -type CosmosHandler struct{} - -func NewCosmosHandler() *CosmosHandler { - return &CosmosHandler{} -} - -func newCDC() *codec.Codec { - cdc := codec.New() - - cdc.RegisterInterface((*crypto.PubKey)(nil), nil) - cdc.RegisterConcrete(ed25519.PubKeyEd25519{}, ed25519.PubKeyAminoName, nil) - cdc.RegisterConcrete(secp256k1.PubKeySecp256k1{}, secp256k1.PubKeyAminoName, nil) - cdc.RegisterConcrete(multisig.PubKeyMultisigThreshold{}, multisig.PubKeyMultisigThresholdAminoRoute, nil) - - cdc.RegisterInterface((*crypto.PrivKey)(nil), nil) - cdc.RegisterConcrete(ed25519.PrivKeyEd25519{}, ed25519.PrivKeyAminoName, nil) - cdc.RegisterConcrete(secp256k1.PrivKeySecp256k1{}, secp256k1.PrivKeyAminoName, nil) - return cdc -} - -func (this *CosmosHandler) SyncGenesisHeader(native *native.NativeContract) error { - ctx := native.ContractRef().CurrentContext() - param := &scom.SyncGenesisHeaderParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodSyncGenesisHeader, param, ctx.Payload); err != nil { - return fmt.Errorf("SyncGenesisHeader, contract params deserialize error: %v", err) - } - - // Get current epoch operator - ok, err := node_manager.CheckConsensusSigns(native, scom.MethodSyncGenesisHeader, ctx.Payload, native.ContractRef().MsgSender()) - if err != nil { - return fmt.Errorf("SyncGenesisHeader, CheckConsensusSigns error: %v", err) - } - if !ok { - return nil - } - - // get genesis header from input parameters - cdc := newCDC() - var header CosmosHeader - err = cdc.UnmarshalBinaryBare(param.GenesisHeader, &header) - if err != nil { - return fmt.Errorf("CosmosHandler SyncGenesisHeader: %s", err) - } - // check if has genesis header - info, err := GetEpochSwitchInfo(native, param.ChainID) - if err == nil && info != nil { - return fmt.Errorf("CosmosHandler SyncGenesisHeader, genesis header had been initialized") - } - PutEpochSwitchInfo(native, param.ChainID, &CosmosEpochSwitchInfo{ - Height: header.Header.Height, - NextValidatorsHash: header.Header.NextValidatorsHash, - ChainID: header.Header.ChainID, - BlockHash: header.Header.Hash(), - }) - return nil -} - -func (this *CosmosHandler) SyncBlockHeader(native *native.NativeContract) error { - params := &scom.SyncBlockHeaderParam{} - - ctx := native.ContractRef().CurrentContext() - if err := utils.UnpackMethod(scom.ABI, scom.MethodSyncBlockHeader, params, ctx.Payload); err != nil { - return err - } - - cdc := newCDC() - cnt := 0 - info, err := GetEpochSwitchInfo(native, params.ChainID) - if err != nil { - return fmt.Errorf("SyncBlockHeader, get epoch switching height failed: %v", err) - } - for _, v := range params.Headers { - var myHeader CosmosHeader - err := cdc.UnmarshalBinaryBare(v, &myHeader) - if err != nil { - return fmt.Errorf("SyncBlockHeader failed to unmarshal header: %v", err) - } - if bytes.Equal(myHeader.Header.NextValidatorsHash, myHeader.Header.ValidatorsHash) { - continue - } - if info.Height >= myHeader.Header.Height { - log.Debugf("SyncBlockHeader, height %d is lower or equal than epoch switching height %d", - myHeader.Header.Height, info.Height) - continue - } - if err = VerifyCosmosHeader(&myHeader, info); err != nil { - return fmt.Errorf("SyncBlockHeader, failed to verify header: %v", err) - } - info.NextValidatorsHash = myHeader.Header.NextValidatorsHash - info.Height = myHeader.Header.Height - info.BlockHash = myHeader.Header.Hash() - cnt++ - } - if cnt == 0 { - return fmt.Errorf("no header you commited is useful") - } - PutEpochSwitchInfo(native, params.ChainID, info) - return nil -} - -func (this *CosmosHandler) SyncCrossChainMsg(native *native.NativeContract) error { - return nil -} diff --git a/contracts/native/header_sync/cosmos/states.go b/contracts/native/header_sync/cosmos/states.go deleted file mode 100644 index 46d6f249..00000000 --- a/contracts/native/header_sync/cosmos/states.go +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package cosmos - -import ( - "fmt" - - "github.com/polynetwork/poly/common" - "github.com/tendermint/tendermint/libs/bytes" - "github.com/tendermint/tendermint/types" -) - -type CosmosEpochSwitchInfo struct { - // The height where validators set changed last time. Poly only accept - // header and proof signed by new validators. That means the header - // can not be lower than this height. - Height int64 - - // Hash of the block at `Height`. Poly don't save the whole header. - // So we can identify the content of this block by `BlockHash`. - BlockHash bytes.HexBytes - - // The hash of new validators set which used to verify validators set - // committed with proof. - NextValidatorsHash bytes.HexBytes - - // The cosmos chain-id of this chain basing Cosmos-sdk. - ChainID string -} - -func (info *CosmosEpochSwitchInfo) Serialization(sink *common.ZeroCopySink) { - sink.WriteInt64(info.Height) - sink.WriteVarBytes(info.BlockHash) - sink.WriteVarBytes(info.NextValidatorsHash) - sink.WriteString(info.ChainID) -} - -func (info *CosmosEpochSwitchInfo) Deserialization(source *common.ZeroCopySource) error { - var eof bool - info.Height, eof = source.NextInt64() - if eof { - return fmt.Errorf("deserialize height of CosmosEpochSwitchInfo failed") - } - info.BlockHash, eof = source.NextVarBytes() - if eof { - return fmt.Errorf("deserialize BlockHash of CosmosEpochSwitchInfo failed") - } - info.NextValidatorsHash, eof = source.NextVarBytes() - if eof { - return fmt.Errorf("deserialize NextValidatorsHash of CosmosEpochSwitchInfo failed") - } - info.ChainID, eof = source.NextString() - if eof { - return fmt.Errorf("deserialize ChainID of CosmosEpochSwitchInfo failed") - } - return nil -} - -type CosmosHeader struct { - Header types.Header - Commit *types.Commit - Valsets []*types.Validator -} diff --git a/contracts/native/header_sync/cosmos/utils.go b/contracts/native/header_sync/cosmos/utils.go deleted file mode 100644 index 575a8ddc..00000000 --- a/contracts/native/header_sync/cosmos/utils.go +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2020 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ - -package cosmos - -import ( - "bytes" - "encoding/hex" - "fmt" - "github.com/polynetwork/poly/common" - - "github.com/ethereum/go-ethereum/contracts/native" - cstates "github.com/polynetwork/poly/core/states" - - hscommon "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/tendermint/tendermint/types" -) - -func notifyEpochSwitchInfo(native *native.NativeContract, chainID uint64, info *CosmosEpochSwitchInfo) { - hscommon.NotifyPutHeader(native, chainID, uint64(info.Height), info.BlockHash.String()) -} - -func GetEpochSwitchInfo(service *native.NativeContract, chainId uint64) (*CosmosEpochSwitchInfo, error) { - val, err := service.GetCacheDB().Get( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(hscommon.EPOCH_SWITCH), utils.GetUint64Bytes(chainId))) - if err != nil { - return nil, fmt.Errorf("failed to get epoch switching height: %v", err) - } - raw, err := cstates.GetValueFromRawStorageItem(val) - if err != nil { - return nil, fmt.Errorf("deserialize bytes from raw storage item err: %v", err) - } - info := &CosmosEpochSwitchInfo{} - if err = info.Deserialization(common.NewZeroCopySource(raw)); err != nil { - return nil, fmt.Errorf("failed to deserialize CosmosEpochSwitchInfo: %v", err) - } - return info, nil -} - -func PutEpochSwitchInfo(service *native.NativeContract, chainId uint64, info *CosmosEpochSwitchInfo) { - sink := common.NewZeroCopySink(nil) - info.Serialization(sink) - service.GetCacheDB().Put( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(hscommon.EPOCH_SWITCH), utils.GetUint64Bytes(chainId)), - cstates.GenRawStorageItem(sink.Bytes())) - notifyEpochSwitchInfo(service, chainId, info) -} - -func VerifyCosmosHeader(myHeader *CosmosHeader, info *CosmosEpochSwitchInfo) error { - // now verify this header - valset := types.NewValidatorSet(myHeader.Valsets) - if !bytes.Equal(info.NextValidatorsHash, valset.Hash()) { - return fmt.Errorf("VerifyCosmosHeader, block validator is not right, next validator hash: %s, "+ - "validator set hash: %s", info.NextValidatorsHash.String(), hex.EncodeToString(valset.Hash())) - } - if !bytes.Equal(myHeader.Header.ValidatorsHash, valset.Hash()) { - return fmt.Errorf("VerifyCosmosHeader, block validator is not right!, header validator hash: %s, "+ - "validator set hash: %s", myHeader.Header.ValidatorsHash.String(), hex.EncodeToString(valset.Hash())) - } - if myHeader.Commit.GetHeight() != myHeader.Header.Height { - return fmt.Errorf("VerifyCosmosHeader, commit height is not right! commit height: %d, "+ - "header height: %d", myHeader.Commit.GetHeight(), myHeader.Header.Height) - } - if !bytes.Equal(myHeader.Commit.BlockID.Hash, myHeader.Header.Hash()) { - return fmt.Errorf("VerifyCosmosHeader, commit hash is not right!, commit block hash: %s,"+ - " header hash: %s", myHeader.Commit.BlockID.Hash.String(), hex.EncodeToString(valset.Hash())) - } - if err := myHeader.Commit.ValidateBasic(); err != nil { - return fmt.Errorf("VerifyCosmosHeader, commit is not right! err: %s", err.Error()) - } - if valset.Size() != len(myHeader.Commit.Signatures) { - return fmt.Errorf("VerifyCosmosHeader, the size of precommits is not right!") - } - talliedVotingPower := int64(0) - for idx, commitSig := range myHeader.Commit.Signatures { - if commitSig.Absent() { - continue // OK, some precommits can be missing. - } - _, val := valset.GetByIndex(idx) - // Validate signature. - precommitSignBytes := myHeader.Commit.VoteSignBytes(info.ChainID, idx) - if !val.PubKey.VerifyBytes(precommitSignBytes, commitSig.Signature) { - return fmt.Errorf("VerifyCosmosHeader, Invalid commit -- invalid signature: %v", commitSig) - } - // Good precommit! - if myHeader.Commit.BlockID.Equals(commitSig.BlockID(myHeader.Commit.BlockID)) { - talliedVotingPower += val.VotingPower - } - } - if talliedVotingPower <= valset.TotalVotingPower()*2/3 { - return fmt.Errorf("VerifyCosmosHeader, voteing power is not enough!") - } - - return nil -} diff --git a/contracts/native/header_sync/entrance.go b/contracts/native/header_sync/entrance.go deleted file mode 100644 index 90d6a435..00000000 --- a/contracts/native/header_sync/entrance.go +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package header_sync - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/bsc" - hscommon "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/cosmos" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/heco" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/msc" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/okex" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/polygon" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/quorum" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/zilliqa" - "github.com/ethereum/go-ethereum/contracts/native/utils" -) - -const contractName = "header sync" - -var ( - this = native.NativeContractAddrMap[native.NativeSyncHeader] -) - -func InitHeaderSync() { - native.Contracts[this] = RegisterHeaderSyncContract - hscommon.ABI = hscommon.GetABI() -} - -func RegisterHeaderSyncContract(s *native.NativeContract) { - s.Prepare(hscommon.ABI, hscommon.GasTable) - - s.Register(hscommon.MethodContractName, Name) - s.Register(hscommon.MethodSyncGenesisHeader, SyncGenesisHeader) - s.Register(hscommon.MethodSyncBlockHeader, SyncBlockHeader) - s.Register(hscommon.MethodSyncCrossChainMsg, SyncCrossChainMsg) -} - -func Name(s *native.NativeContract) ([]byte, error) { - return utils.PackOutputs(hscommon.ABI, hscommon.MethodContractName, contractName) -} - -func SyncGenesisHeader(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &hscommon.SyncGenesisHeaderParam{} - if err := utils.UnpackMethod(hscommon.ABI, hscommon.MethodSyncGenesisHeader, params, ctx.Payload); err != nil { - return nil, err - } - chainID := params.ChainID - - //check if chainid exist - sideChain, err := side_chain_manager.GetSideChain(native, chainID) - if err != nil { - return nil, fmt.Errorf("SyncGenesisHeader, side_chain_manager.GetSideChain error: %v", err) - } - if sideChain == nil { - return nil, fmt.Errorf("SyncGenesisHeader, side chain is not registered") - } - - handler, err := GetChainHandler(sideChain.Router) - if err != nil { - return nil, err - } - - err = handler.SyncGenesisHeader(native) - if err != nil { - return nil, err - } - - return utils.PackOutputs(hscommon.ABI, hscommon.MethodSyncGenesisHeader, true) -} - -func SyncBlockHeader(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &hscommon.SyncBlockHeaderParam{} - if err := utils.UnpackMethod(hscommon.ABI, hscommon.MethodSyncBlockHeader, params, ctx.Payload); err != nil { - return nil, err - } - - chainID := params.ChainID - //check if chainid exist - sideChain, err := side_chain_manager.GetSideChain(native, chainID) - if err != nil { - return nil, fmt.Errorf("SyncGenesisHeader, side_chain_manager.GetSideChain error: %v", err) - } - if sideChain == nil { - return nil, fmt.Errorf("SyncGenesisHeader, side chain is not registered") - } - - handler, err := GetChainHandler(sideChain.Router) - if err != nil { - return nil, err - } - - err = handler.SyncBlockHeader(native) - if err != nil { - return nil, err - } - - return utils.PackOutputs(hscommon.ABI, hscommon.MethodSyncBlockHeader, true) -} - -func SyncCrossChainMsg(native *native.NativeContract) ([]byte, error) { - ctx := native.ContractRef().CurrentContext() - params := &hscommon.SyncCrossChainMsgParam{} - if err := utils.UnpackMethod(hscommon.ABI, hscommon.MethodSyncCrossChainMsg, params, ctx.Payload); err != nil { - return nil, err - } - - chainID := params.ChainID - //check if chainid exist - sideChain, err := side_chain_manager.GetSideChain(native, chainID) - if err != nil { - return nil, fmt.Errorf("SyncGenesisHeader, side_chain_manager.GetSideChain error: %v", err) - } - if sideChain == nil { - return nil, fmt.Errorf("SyncGenesisHeader, side chain is not registered") - } - - handler, err := GetChainHandler(sideChain.Router) - if err != nil { - return nil, err - } - - err = handler.SyncCrossChainMsg(native) - if err != nil { - return nil, err - } - - return utils.PackOutputs(hscommon.ABI, hscommon.MethodSyncCrossChainMsg, true) -} - -func GetChainHandler(router uint64) (hscommon.HeaderSyncHandler, error) { - switch router { - case utils.BSC_ROUTER: - return bsc.NewHandler(), nil - case utils.ETH_ROUTER: - return eth.NewETHHandler(), nil - case utils.HECO_ROUTER: - return heco.NewHecoHandler(), nil - case utils.MSC_ROUTER: - return msc.NewHandler(), nil - case utils.OKEX_ROUTER: - return okex.NewHandler(), nil - case utils.QUORUM_ROUTER: - return quorum.NewQuorumHandler(), nil - case utils.POLYGON_HEIMDALL_ROUTER: - return polygon.NewHeimdallHandler(), nil - case utils.POLYGON_BOR_ROUTER: - return polygon.NewBorHandler(), nil - case utils.COSMOS_ROUTER: - return cosmos.NewCosmosHandler(), nil - case utils.ZILLIQA_ROUTER: - return zilliqa.NewHandler(), nil - default: - return nil, fmt.Errorf("not a supported router:%d", router) - } -} diff --git a/contracts/native/header_sync/entrance_cosmos_test.go b/contracts/native/header_sync/entrance_cosmos_test.go deleted file mode 100644 index 32d118e8..00000000 --- a/contracts/native/header_sync/entrance_cosmos_test.go +++ /dev/null @@ -1,525 +0,0 @@ -/* - * Copyright (C) 2020 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ - -package header_sync - -import ( - "crypto/ecdsa" - "encoding/hex" - "encoding/json" - "fmt" - "math/big" - "reflect" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/polynetwork/poly/common" - - "github.com/ethereum/go-ethereum/contracts/native" - - scom "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/cosmos" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/zilliqa" - - "github.com/ethereum/go-ethereum/contracts/native/utils" - - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - - "strings" - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/ethereum/go-ethereum/contracts/native/cross_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/governance" - "github.com/ethereum/go-ethereum/contracts/native/governance/neo3_state_manager" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - "github.com/ethereum/go-ethereum/contracts/native/governance/relayer_manager" - - "github.com/ethereum/go-ethereum/crypto" - cstates "github.com/polynetwork/poly/core/states" -) - -const ( - SUCCESS = iota - GENESIS_PARAM_ERROR - GENESIS_INITIALIZED - SYNCBLOCK_PARAM_ERROR - SYNCBLOCK_ORPHAN - DIFFICULTY_ERROR - NONCE_ERROR - OPERATOR_ERROR - UNKNOWN -) - -var ( - sdb *state.StateDB - acct *ecdsa.PublicKey - caller ethcommon.Address - contractRef *native.ContractRef -) - -func init() { - governance.InitGovernance() - InitHeaderSync() - cross_chain_manager.InitCrossChainManager() - neo3_state_manager.InitNeo3StateManager() - node_manager.InitNodeManager() - relayer_manager.InitRelayerManager() - side_chain_manager.InitSideChainManager() - - db := rawdb.NewMemoryDatabase() - sdb, _ = state.New(ethcommon.Hash{}, state.NewDatabase(db), nil) - - cacheDB := (*state.CacheDB)(sdb) - - blockNumber := big.NewInt(1) - key, _ := crypto.GenerateKey() - acct = &key.PublicKey - caller = crypto.PubkeyToAddress(*acct) - putPeerMapPoolAndView(cacheDB) - contractRef = native.NewContractRef(sdb, caller, caller, blockNumber, ethcommon.Hash{}, 60000000, nil) -} - -func putPeerMapPoolAndView(db *state.CacheDB) { - /* key, _ := crypto.GenerateKey() - acct = &key.PublicKey - - caller = crypto.PubkeyToAddress(*acct) */ - - peerPoolMap := new(node_manager.PeerPoolMap) - peerPoolMap.PeerPoolMap = make(map[string]*node_manager.PeerPoolItem) - pkStr := hex.EncodeToString(crypto.FromECDSAPub(acct)) - peerPoolMap.PeerPoolMap[pkStr] = &node_manager.PeerPoolItem{ - Index: uint32(0), - PeerPubkey: pkStr, - Address: crypto.PubkeyToAddress(*acct), - Status: node_manager.ConsensusStatus, - } - view := uint32(0) - viewBytes := utils.GetUint32Bytes(view) - sink := common.NewZeroCopySink(nil) - peerPoolMap.Serialization(sink) - db.Put(utils.ConcatKey(utils.NodeManagerContractAddress, []byte(node_manager.PEER_POOL), viewBytes), cstates.GenRawStorageItem(sink.Bytes())) - - sink.Reset() - - govView := node_manager.GovernanceView{ - View: view, - } - govView.Serialization(sink) - db.Put(utils.ConcatKey(utils.NodeManagerContractAddress, []byte(node_manager.GOVERNANCE_VIEW)), cstates.GenRawStorageItem(sink.Bytes())) -} - -func typeOfError(e error) int { - if e == nil { - return SUCCESS - } - errDesc := e.Error() - if strings.Contains(errDesc, "genesis header had been initialized") { - return GENESIS_INITIALIZED - } else if strings.Contains(errDesc, "deserialize header err:") { - return GENESIS_PARAM_ERROR - } else if strings.Contains(errDesc, "deserialize header err:") { - return SYNCBLOCK_PARAM_ERROR - } else if strings.Contains(errDesc, "get the parent block failed. Error:") { - return SYNCBLOCK_ORPHAN - } else if strings.Contains(errDesc, "invalid difficulty:") { - return DIFFICULTY_ERROR - } else if strings.Contains(errDesc, "verify header error:") { - return NONCE_ERROR - } - return UNKNOWN -} - -func RegisterSideChainManager(contractRef *native.ContractRef, chainId uint64) { - param := new(side_chain_manager.RegisterSideChainParam) - param.BlocksToWait = 4 - param.ChainId = chainId - param.Name = "mychain" - param.Router = 3 - param.Address = caller - - extraInfo := zilliqa.ExtraInfo{NumOfGuardList: 1} - b, _ := json.Marshal(extraInfo) - param.ExtraInfo = b - - input, err := utils.PackMethodWithStruct(side_chain_manager.GetABI(), side_chain_manager.MethodRegisterSideChain, param) - if err != nil { - panic(err) - } - - _, _, err = contractRef.NativeCall(caller, utils.SideChainManagerContractAddress, input) - - if err != nil { - // panic(err) - } -} - -func NewNative(name string, param interface{}) (*native.NativeContract, error) { - if scom.ABI == nil { - scom.ABI = scom.GetABI() - } - - input, err := utils.PackMethodWithStruct(scom.GetABI(), name, param) - if err != nil { - return nil, err - } - - contractRef.PushContext(&native.Context{ - Caller: caller, - ContractAddress: utils.HeaderSyncContractAddress, - Payload: input, - }) - - c := native.NewNativeContract(sdb, contractRef) - - chainId := reflect.Indirect(reflect.ValueOf(param)).FieldByName("ChainID").Uint() - RegisterSideChainManager(contractRef, uint64(chainId)) - - /* - input, err := utils.PackMethodWithStruct(scom.GetABI(), name, param) - if err != nil { - return nil, err - } - - ret, leftOverGas, err := contractRef.NativeCall(ethcommon.Address{}, utils.HeaderSyncContractAddress, input) - if err != nil { - return nil, err - } - fmt.Printf("ret: %s, gas: %d", hex.EncodeToString(ret), leftOverGas) */ - return c, nil - - //result, err := utils.PackOutputs(header_sync.ABI, header_sync.MethodSyncBlockHeader, true) - //_ = result -} - -func TestSyncGenesisHeader(t *testing.T) { - header10000, _ := hex.DecodeString("0aa8020a02080a120774657374696e6718904e220c08eae29ff70510ffc5bfd5022a480a20a952550d320e34bd910fdf47d4b0d1b9b2c691d0432ebe5c2f25174c484663781224080112206fc745af7c59194f8e841a4e8bf89e6b7e873d1dfb807829deafc1093fcbe33e3220e728973f68379b28c499cfa4a6234a79ca6e7579290fa0c5013a65ce7af69db2422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a2021b3a41b885e7248c813ee0290f540cd6a1227d21e263a875497a6aa7972e4ec72146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b70108904e1a480a20d7147608a68aa6e72f26d196dd5ea13ab1e580eee72cb1d84b3e6e49c5a5ffd3122408011220e9dc35792711de4bb8b19ecb7ce888cbd0835bec6b16d7dfc33fe4667bccb8092268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08efe29ff70510cd98fefe022240e3807de6d7d219a0c2ca6187b6a447711de395f8a51053ed7fde07f522b1977987411d74128a31a03c0df91790b10596776fe5381363706086ca4086cb96ca061a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = 5 - param.GenesisHeader = header10000 - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - native, err := NewNative(scom.MethodSyncGenesisHeader, param) - if err != nil { - fmt.Printf("NewNative err: %v", err) - return - } - cosmosHandler := cosmos.NewCosmosHandler() - err = cosmosHandler.SyncGenesisHeader(native) - if err != nil { - fmt.Printf("SyncGenesisHeader err: %s", err.Error()) - } - assert.Equal(t, SUCCESS, typeOfError(err)) - - info, err := cosmos.GetEpochSwitchInfo(native, param.ChainID) - if err != nil { - fmt.Printf("GetEpochSwitchInfo err: %v", err) - } - assert.Equal(t, info != nil, true) - assert.Equal(t, uint64(info.Height), uint64(10000)) -} - -func TestSyncBlockHeader(t *testing.T) { - cosmosHandler := cosmos.NewCosmosHandler() - var native *native.NativeContract - { - header10000, _ := hex.DecodeString("0aa8020a02080a120774657374696e6718904e220c08eae29ff70510ffc5bfd5022a480a20a952550d320e34bd910fdf47d4b0d1b9b2c691d0432ebe5c2f25174c484663781224080112206fc745af7c59194f8e841a4e8bf89e6b7e873d1dfb807829deafc1093fcbe33e3220e728973f68379b28c499cfa4a6234a79ca6e7579290fa0c5013a65ce7af69db2422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a2021b3a41b885e7248c813ee0290f540cd6a1227d21e263a875497a6aa7972e4ec72146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b70108904e1a480a20d7147608a68aa6e72f26d196dd5ea13ab1e580eee72cb1d84b3e6e49c5a5ffd3122408011220e9dc35792711de4bb8b19ecb7ce888cbd0835bec6b16d7dfc33fe4667bccb8092268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08efe29ff70510cd98fefe022240e3807de6d7d219a0c2ca6187b6a447711de395f8a51053ed7fde07f522b1977987411d74128a31a03c0df91790b10596776fe5381363706086ca4086cb96ca061a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = 5 - param.GenesisHeader = header10000 - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - native, _ = NewNative(scom.MethodSyncGenesisHeader, param) - err := cosmosHandler.SyncGenesisHeader(native) - if err != nil { - fmt.Printf("err: %s", err.Error()) - } - assert.Equal(t, SUCCESS, typeOfError(err)) - - info, _ := cosmos.GetEpochSwitchInfo(native, param.ChainID) - assert.Equal(t, info != nil, true) - assert.Equal(t, uint64(info.Height), uint64(10000)) - } - { - header10001, _ := hex.DecodeString("0aa8020a02080a120774657374696e6718914e220c08efe29ff70510cd98fefe022a480a20d7147608a68aa6e72f26d196dd5ea13ab1e580eee72cb1d84b3e6e49c5a5ffd3122408011220e9dc35792711de4bb8b19ecb7ce888cbd0835bec6b16d7dfc33fe4667bccb80932200622a4189db86c59caf2e5c993001125147821024fa1b4483ab8bfd9a5ab516c422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a200cee95b828cd74a3078db7c6e3ef8e75c282edf5396b525b831309632edc7a4a72146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b70108914e1a480a208e0b7bb3f66dc7e215ffbf77c9971cfd12742bf495bbc92b38b6fdbf0a9c235f122408011220b27ce0ec06318b860c6b66b3a6ed10c49034532aaf159de509278cbf949969412268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08f4e29ff70510edfbe0a603224012da471ec08ccd347b40f5c505054bc49b28dea720cb38e84c80a6fcb3042148a374e1a179b3b20064dc35aead710a6e8600a8e3b0e0823384801129924725061a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - header10002, _ := hex.DecodeString("0aa8020a02080a120774657374696e6718924e220c08f4e29ff70510edfbe0a6032a480a208e0b7bb3f66dc7e215ffbf77c9971cfd12742bf495bbc92b38b6fdbf0a9c235f122408011220b27ce0ec06318b860c6b66b3a6ed10c49034532aaf159de509278cbf9499694132203bd019d6ef8763f689bd053b3d5d96c99d096456e862af5dff0382c8dfab9483422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a20e22606949c1bf971360a980bf85a0cc9ec7753ad02f4258f1998a4194ba78a2872146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b70108924e1a480a20ee52cb572507c078193a7e1eba63b4ff50f3f3cd2d91e77d9a1da13764ae87b512240801122090bc1b8a3706428b1ea03f8d4466c71832f8c2f0affaa604d67ef726e2d46e8b2268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08f9e29ff70510bebbd6d40322406254e69b1a46a928a0815afe9a0175d7f7f2831fe2b166a4e9c9c4f58668d69abbd6638eef817fd2a06b6f03334272e636b576017a66956895c60fda73a2e5091a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - param := new(scom.SyncBlockHeaderParam) - param.ChainID = 5 - param.Headers = append(param.Headers, header10001) - param.Headers = append(param.Headers, header10002) - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - native, err := NewNative(scom.MethodSyncBlockHeader, param) - if err != nil { - fmt.Printf("%v", err) - } - assert.Nil(t, err) - err = cosmosHandler.SyncBlockHeader(native) - // no header you commited is useful - assert.Error(t, err) - } -} - -/* - insert a new block -*/ -func TestSyncBlockHeader2(t *testing.T) { - cosmosHandler := cosmos.NewCosmosHandler() - { - header10000, _ := hex.DecodeString("0aa8020a02080a120774657374696e6718904e220c08eae29ff70510ffc5bfd5022a480a20a952550d320e34bd910fdf47d4b0d1b9b2c691d0432ebe5c2f25174c484663781224080112206fc745af7c59194f8e841a4e8bf89e6b7e873d1dfb807829deafc1093fcbe33e3220e728973f68379b28c499cfa4a6234a79ca6e7579290fa0c5013a65ce7af69db2422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a2021b3a41b885e7248c813ee0290f540cd6a1227d21e263a875497a6aa7972e4ec72146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b70108904e1a480a20d7147608a68aa6e72f26d196dd5ea13ab1e580eee72cb1d84b3e6e49c5a5ffd3122408011220e9dc35792711de4bb8b19ecb7ce888cbd0835bec6b16d7dfc33fe4667bccb8092268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08efe29ff70510cd98fefe022240e3807de6d7d219a0c2ca6187b6a447711de395f8a51053ed7fde07f522b1977987411d74128a31a03c0df91790b10596776fe5381363706086ca4086cb96ca061a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = 5 - param.GenesisHeader = header10000 - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - native, _ := NewNative(scom.MethodSyncGenesisHeader, param) - err := cosmosHandler.SyncGenesisHeader(native) - if err != nil { - fmt.Printf("err: %s", err.Error()) - } - assert.Equal(t, SUCCESS, typeOfError(err)) - - info, _ := cosmos.GetEpochSwitchInfo(native, param.ChainID) - assert.Equal(t, info != nil, true) - assert.Equal(t, uint64(info.Height), uint64(10000)) - } - { - header10010, _ := hex.DecodeString("0aa8020a02080a120774657374696e67189a4e220c089de39ff70510ddf7abe5022a480a20520e78552c565e47a32fae7d923e61e33565a1518952cfadd767d0cc763c1ba5122408011220f65f6b4edd4b7f52bd0ac8bec534a646d68d152021a391b387169a169194635232201450e9e06022e395b9176448a4718f2c1f161ce3cfd501205245f19686038765422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a200f4cb2e3e6b3437ff1810c3420884ffbe13a8826c2830d7bec2c586c95a33f1572146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b701089a4e1a480a2064852da2991661fbd8d4f5e6789450b57662248ca4b996f640b327564c7c84601224080112209537acb3f8eebab33b949353ca450207614152c7df471b3aff1ffb683f78939c2268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08a2e39ff70510a5fe848d032240bdbb92c73dd1bd5a61ebc72099b76d3d934573a5a54196a04e87e010964864d34e2a2a42ada217c5c9be210adc1cd0b2091c32fb9525fdabfb247fd7660466001a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - header10011, _ := hex.DecodeString("0aa8020a02080a120774657374696e67189b4e220c08a2e39ff70510a5fe848d032a480a2064852da2991661fbd8d4f5e6789450b57662248ca4b996f640b327564c7c84601224080112209537acb3f8eebab33b949353ca450207614152c7df471b3aff1ffb683f78939c322055b77f9a764871721521ff6aeb920fe01bc440446712b483866cd4d09944839e422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a20b4cf9c1ec8e800ee5e201678c25580124ea8ae1e3dc7c4128d67b92ac876522f72146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b701089b4e1a480a20dd5ee8ddd3d21d365aa11153d8e83367140de92e4ccfabd999e97f093b83d388122408011220d3ee12d83dbba28047922ee735604065bbf18286ab770262327e92aed9d7662b2268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08a7e39ff70510ecbbe6b903224048b1c9b7b32bdc0ecc11cb491dcd23f621bb799969221dae82e28645d229310eac1e3cde1aae6056b395d75b4d3adc96190c3cc40dc1ecaa2e431f4d5b78620b1a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - param := new(scom.SyncBlockHeaderParam) - param.ChainID = 5 - param.Headers = append(param.Headers, header10010) - param.Headers = append(param.Headers, header10011) - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - native, _ := NewNative(scom.MethodSyncBlockHeader, param) - err := cosmosHandler.SyncBlockHeader(native) - assert.Error(t, err) - - //height, _ := getCurrentHeight(native, param.ChainID) - //assert.Equal(t, uint64(height), uint64(10011)) - } - { - header10001, _ := hex.DecodeString("0aa8020a02080a120774657374696e6718914e220c08efe29ff70510cd98fefe022a480a20d7147608a68aa6e72f26d196dd5ea13ab1e580eee72cb1d84b3e6e49c5a5ffd3122408011220e9dc35792711de4bb8b19ecb7ce888cbd0835bec6b16d7dfc33fe4667bccb80932200622a4189db86c59caf2e5c993001125147821024fa1b4483ab8bfd9a5ab516c422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a200cee95b828cd74a3078db7c6e3ef8e75c282edf5396b525b831309632edc7a4a72146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b70108914e1a480a208e0b7bb3f66dc7e215ffbf77c9971cfd12742bf495bbc92b38b6fdbf0a9c235f122408011220b27ce0ec06318b860c6b66b3a6ed10c49034532aaf159de509278cbf949969412268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08f4e29ff70510edfbe0a603224012da471ec08ccd347b40f5c505054bc49b28dea720cb38e84c80a6fcb3042148a374e1a179b3b20064dc35aead710a6e8600a8e3b0e0823384801129924725061a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - header10002, _ := hex.DecodeString("0aa8020a02080a120774657374696e6718924e220c08f4e29ff70510edfbe0a6032a480a208e0b7bb3f66dc7e215ffbf77c9971cfd12742bf495bbc92b38b6fdbf0a9c235f122408011220b27ce0ec06318b860c6b66b3a6ed10c49034532aaf159de509278cbf9499694132203bd019d6ef8763f689bd053b3d5d96c99d096456e862af5dff0382c8dfab9483422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a20e22606949c1bf971360a980bf85a0cc9ec7753ad02f4258f1998a4194ba78a2872146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b70108924e1a480a20ee52cb572507c078193a7e1eba63b4ff50f3f3cd2d91e77d9a1da13764ae87b512240801122090bc1b8a3706428b1ea03f8d4466c71832f8c2f0affaa604d67ef726e2d46e8b2268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08f9e29ff70510bebbd6d40322406254e69b1a46a928a0815afe9a0175d7f7f2831fe2b166a4e9c9c4f58668d69abbd6638eef817fd2a06b6f03334272e636b576017a66956895c60fda73a2e5091a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - param := new(scom.SyncBlockHeaderParam) - param.ChainID = 5 - param.Headers = append(param.Headers, header10001) - param.Headers = append(param.Headers, header10002) - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - native, _ := NewNative(scom.MethodSyncBlockHeader, param) - err := cosmosHandler.SyncBlockHeader(native) - if err != nil { - fmt.Printf("err: %s", err.Error()) - } - assert.Error(t, err) - - //height, _ := getCurrentHeight(native, param.ChainID) - //assert.Equal(t, uint64(height), uint64(10011)) - } -} - -/* - sync block before genensis -*/ -func TestSyncBlockHeader3(t *testing.T) { - cosmosHandler := cosmos.NewCosmosHandler() - - { - header10000, _ := hex.DecodeString("0aa8020a02080a120774657374696e6718904e220c08eae29ff70510ffc5bfd5022a480a20a952550d320e34bd910fdf47d4b0d1b9b2c691d0432ebe5c2f25174c484663781224080112206fc745af7c59194f8e841a4e8bf89e6b7e873d1dfb807829deafc1093fcbe33e3220e728973f68379b28c499cfa4a6234a79ca6e7579290fa0c5013a65ce7af69db2422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a2021b3a41b885e7248c813ee0290f540cd6a1227d21e263a875497a6aa7972e4ec72146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b70108904e1a480a20d7147608a68aa6e72f26d196dd5ea13ab1e580eee72cb1d84b3e6e49c5a5ffd3122408011220e9dc35792711de4bb8b19ecb7ce888cbd0835bec6b16d7dfc33fe4667bccb8092268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08efe29ff70510cd98fefe022240e3807de6d7d219a0c2ca6187b6a447711de395f8a51053ed7fde07f522b1977987411d74128a31a03c0df91790b10596776fe5381363706086ca4086cb96ca061a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = 5 - param.GenesisHeader = header10000 - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - native, _ := NewNative(scom.MethodSyncGenesisHeader, param) - err := cosmosHandler.SyncGenesisHeader(native) - if err != nil { - fmt.Printf("err: %s", err.Error()) - } - assert.Equal(t, SUCCESS, typeOfError(err)) - - //has, _ := hasGenesis(native, param.ChainID) - //assert.Equal(t, has, true) - // - //height, _ := getCurrentHeight(native, param.ChainID) - //assert.Equal(t, uint64(height), uint64(10000)) - } - { - header9999, _ := hex.DecodeString("0aa8020a02080a120774657374696e67188f4e220c08e5e29ff70510abdb8ea7022a480a20727d85a7eb9a24c6fa1916456049197ba51046f84ee7270a00996f09206402fa1224080112206b044fe89ef52ac7977a9bd2569d49b47b3a5d895244fcb283fc875220fb5e063220a70dd9071d2ecac99ce7eeb462c7e56bcc99fab3cb52dd45cfe2502313777f55422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a209658cd0c9251c2514753fd85c0ebf649f8bec6bf885813dccbada1a575b2156c72146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b701088f4e1a480a20a952550d320e34bd910fdf47d4b0d1b9b2c691d0432ebe5c2f25174c484663781224080112206fc745af7c59194f8e841a4e8bf89e6b7e873d1dfb807829deafc1093fcbe33e2268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08eae29ff70510ffc5bfd5022240912bf904c00e06e8e922459179ee611d13082a10efefeb08ff238dae6d5f0c4f25034e70079c48709c1d3c0849a4fc2470743e871982dc860a94f2a68d07520c1a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - param := new(scom.SyncBlockHeaderParam) - param.ChainID = 5 - param.Headers = append(param.Headers, header9999) - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - native, _ := NewNative(scom.MethodSyncBlockHeader, param) - err := cosmosHandler.SyncBlockHeader(native) - assert.Error(t, err) - } -} - -func TestSyncBlockHeaderTwice(t *testing.T) { - cosmosHandler := cosmos.NewCosmosHandler() - - { - header10000, _ := hex.DecodeString("0aa8020a02080a120774657374696e6718904e220c08eae29ff70510ffc5bfd5022a480a20a952550d320e34bd910fdf47d4b0d1b9b2c691d0432ebe5c2f25174c484663781224080112206fc745af7c59194f8e841a4e8bf89e6b7e873d1dfb807829deafc1093fcbe33e3220e728973f68379b28c499cfa4a6234a79ca6e7579290fa0c5013a65ce7af69db2422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a2021b3a41b885e7248c813ee0290f540cd6a1227d21e263a875497a6aa7972e4ec72146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b70108904e1a480a20d7147608a68aa6e72f26d196dd5ea13ab1e580eee72cb1d84b3e6e49c5a5ffd3122408011220e9dc35792711de4bb8b19ecb7ce888cbd0835bec6b16d7dfc33fe4667bccb8092268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08efe29ff70510cd98fefe022240e3807de6d7d219a0c2ca6187b6a447711de395f8a51053ed7fde07f522b1977987411d74128a31a03c0df91790b10596776fe5381363706086ca4086cb96ca061a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = 5 - param.GenesisHeader = header10000 - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - native, _ := NewNative(scom.MethodSyncGenesisHeader, param) - err := cosmosHandler.SyncGenesisHeader(native) - if err != nil { - fmt.Printf("err: %s", err.Error()) - } - assert.Nil(t, err) - - //has, _ := hasGenesis(native, param.ChainID) - //assert.Equal(t, has, true) - // - //height, _ := getCurrentHeight(native, param.ChainID) - //assert.Equal(t, uint64(height), uint64(10000)) - } - { - header10011, _ := hex.DecodeString("0aa8020a02080a120774657374696e67189b4e220c08a2e39ff70510a5fe848d032a480a2064852da2991661fbd8d4f5e6789450b57662248ca4b996f640b327564c7c84601224080112209537acb3f8eebab33b949353ca450207614152c7df471b3aff1ffb683f78939c322055b77f9a764871721521ff6aeb920fe01bc440446712b483866cd4d09944839e422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a20b4cf9c1ec8e800ee5e201678c25580124ea8ae1e3dc7c4128d67b92ac876522f72146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b701089b4e1a480a20dd5ee8ddd3d21d365aa11153d8e83367140de92e4ccfabd999e97f093b83d388122408011220d3ee12d83dbba28047922ee735604065bbf18286ab770262327e92aed9d7662b2268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08a7e39ff70510ecbbe6b903224048b1c9b7b32bdc0ecc11cb491dcd23f621bb799969221dae82e28645d229310eac1e3cde1aae6056b395d75b4d3adc96190c3cc40dc1ecaa2e431f4d5b78620b1a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - header10010, _ := hex.DecodeString("0aa8020a02080a120774657374696e67189a4e220c089de39ff70510ddf7abe5022a480a20520e78552c565e47a32fae7d923e61e33565a1518952cfadd767d0cc763c1ba5122408011220f65f6b4edd4b7f52bd0ac8bec534a646d68d152021a391b387169a169194635232201450e9e06022e395b9176448a4718f2c1f161ce3cfd501205245f19686038765422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a200f4cb2e3e6b3437ff1810c3420884ffbe13a8826c2830d7bec2c586c95a33f1572146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b701089a4e1a480a2064852da2991661fbd8d4f5e6789450b57662248ca4b996f640b327564c7c84601224080112209537acb3f8eebab33b949353ca450207614152c7df471b3aff1ffb683f78939c2268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08a2e39ff70510a5fe848d032240bdbb92c73dd1bd5a61ebc72099b76d3d934573a5a54196a04e87e010964864d34e2a2a42ada217c5c9be210adc1cd0b2091c32fb9525fdabfb247fd7660466001a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - param := new(scom.SyncBlockHeaderParam) - param.ChainID = 5 - - param.Headers = append(param.Headers, header10010) - param.Headers = append(param.Headers, header10011) - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - native, _ := NewNative(scom.MethodSyncBlockHeader, param) - err := cosmosHandler.SyncBlockHeader(native) - if err != nil { - fmt.Printf("err: %s", err.Error()) - } - assert.Error(t, err) - - //height, _ := getCurrentHeight(native, param.ChainID) - //assert.Equal(t, uint64(height), uint64(10011)) - } - { - header10011, _ := hex.DecodeString("0aa8020a02080a120774657374696e67189b4e220c08a2e39ff70510a5fe848d032a480a2064852da2991661fbd8d4f5e6789450b57662248ca4b996f640b327564c7c84601224080112209537acb3f8eebab33b949353ca450207614152c7df471b3aff1ffb683f78939c322055b77f9a764871721521ff6aeb920fe01bc440446712b483866cd4d09944839e422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a20b4cf9c1ec8e800ee5e201678c25580124ea8ae1e3dc7c4128d67b92ac876522f72146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b701089b4e1a480a20dd5ee8ddd3d21d365aa11153d8e83367140de92e4ccfabd999e97f093b83d388122408011220d3ee12d83dbba28047922ee735604065bbf18286ab770262327e92aed9d7662b2268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08a7e39ff70510ecbbe6b903224048b1c9b7b32bdc0ecc11cb491dcd23f621bb799969221dae82e28645d229310eac1e3cde1aae6056b395d75b4d3adc96190c3cc40dc1ecaa2e431f4d5b78620b1a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - header10012, _ := hex.DecodeString("0aa8020a02080a120774657374696e67189c4e220c08a7e39ff70510ecbbe6b9032a480a20dd5ee8ddd3d21d365aa11153d8e83367140de92e4ccfabd999e97f093b83d388122408011220d3ee12d83dbba28047922ee735604065bbf18286ab770262327e92aed9d7662b32202496df827069967ea78dd93d07e6389e95abadd81cb5bd53cb9048b73a7ae0f2422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a206a1f58abdc0c358ed42023b6da978c6baa7c748f2534f42cec212c5ddeddd16172146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b601089c4e1a480a20744cf79eec130b744c9325ee44eb74661cfbe090989ee27af6a6856750ff41751224080112204a684ab601bb25ede19c18622513ecd95637dff4ef6270a1cec154e35a939a212267080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0b08ade39ff70510e9cad70b2240d448c0de45611b935f1f4d37ca33cafa174c9eebdc074febdf70eaac9fc384bf669369c46ed279b18f5bd7a73999d4ae46c382204947f019fa3fca1ea9d0dc021a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - param := new(scom.SyncBlockHeaderParam) - param.ChainID = 5 - - param.Headers = append(param.Headers, header10011) - param.Headers = append(param.Headers, header10012) - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - native, _ := NewNative(scom.MethodSyncBlockHeader, param) - err := cosmosHandler.SyncBlockHeader(native) - if err != nil { - fmt.Printf("err: %s", err.Error()) - } - assert.Error(t, err) - - //height, _ := getCurrentHeight(native, param.ChainID) - //assert.Equal(t, uint64(height), uint64(10012)) - } -} - -func TestSyncBlockHeaderUnorder(t *testing.T) { - cosmosHandler := cosmos.NewCosmosHandler() - - { - header10000, _ := hex.DecodeString("0aa8020a02080a120774657374696e6718904e220c08eae29ff70510ffc5bfd5022a480a20a952550d320e34bd910fdf47d4b0d1b9b2c691d0432ebe5c2f25174c484663781224080112206fc745af7c59194f8e841a4e8bf89e6b7e873d1dfb807829deafc1093fcbe33e3220e728973f68379b28c499cfa4a6234a79ca6e7579290fa0c5013a65ce7af69db2422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a2021b3a41b885e7248c813ee0290f540cd6a1227d21e263a875497a6aa7972e4ec72146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b70108904e1a480a20d7147608a68aa6e72f26d196dd5ea13ab1e580eee72cb1d84b3e6e49c5a5ffd3122408011220e9dc35792711de4bb8b19ecb7ce888cbd0835bec6b16d7dfc33fe4667bccb8092268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08efe29ff70510cd98fefe022240e3807de6d7d219a0c2ca6187b6a447711de395f8a51053ed7fde07f522b1977987411d74128a31a03c0df91790b10596776fe5381363706086ca4086cb96ca061a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = 5 - param.GenesisHeader = header10000 - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - native, _ := NewNative(scom.MethodSyncGenesisHeader, param) - err := cosmosHandler.SyncGenesisHeader(native) - if err != nil { - fmt.Printf("err: %s", err.Error()) - } - assert.Equal(t, SUCCESS, typeOfError(err)) - - //has, _ := hasGenesis(native, param.ChainID) - //assert.Equal(t, has, true) - // - //height, _ := getCurrentHeight(native, param.ChainID) - //assert.Equal(t, uint64(height), uint64(10000)) - } - { - header10010, _ := hex.DecodeString("0aa8020a02080a120774657374696e67189a4e220c089de39ff70510ddf7abe5022a480a20520e78552c565e47a32fae7d923e61e33565a1518952cfadd767d0cc763c1ba5122408011220f65f6b4edd4b7f52bd0ac8bec534a646d68d152021a391b387169a169194635232201450e9e06022e395b9176448a4718f2c1f161ce3cfd501205245f19686038765422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a200f4cb2e3e6b3437ff1810c3420884ffbe13a8826c2830d7bec2c586c95a33f1572146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b701089a4e1a480a2064852da2991661fbd8d4f5e6789450b57662248ca4b996f640b327564c7c84601224080112209537acb3f8eebab33b949353ca450207614152c7df471b3aff1ffb683f78939c2268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08a2e39ff70510a5fe848d032240bdbb92c73dd1bd5a61ebc72099b76d3d934573a5a54196a04e87e010964864d34e2a2a42ada217c5c9be210adc1cd0b2091c32fb9525fdabfb247fd7660466001a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - header10011, _ := hex.DecodeString("0aa8020a02080a120774657374696e67189b4e220c08a2e39ff70510a5fe848d032a480a2064852da2991661fbd8d4f5e6789450b57662248ca4b996f640b327564c7c84601224080112209537acb3f8eebab33b949353ca450207614152c7df471b3aff1ffb683f78939c322055b77f9a764871721521ff6aeb920fe01bc440446712b483866cd4d09944839e422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a20b4cf9c1ec8e800ee5e201678c25580124ea8ae1e3dc7c4128d67b92ac876522f72146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b701089b4e1a480a20dd5ee8ddd3d21d365aa11153d8e83367140de92e4ccfabd999e97f093b83d388122408011220d3ee12d83dbba28047922ee735604065bbf18286ab770262327e92aed9d7662b2268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08a7e39ff70510ecbbe6b903224048b1c9b7b32bdc0ecc11cb491dcd23f621bb799969221dae82e28645d229310eac1e3cde1aae6056b395d75b4d3adc96190c3cc40dc1ecaa2e431f4d5b78620b1a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - param := new(scom.SyncBlockHeaderParam) - param.ChainID = 5 - - param.Headers = append(param.Headers, header10010) - param.Headers = append(param.Headers, header10011) - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - native, _ := NewNative(scom.MethodSyncBlockHeader, param) - err := cosmosHandler.SyncBlockHeader(native) - if err != nil { - fmt.Printf("err: %s", err.Error()) - } - assert.Error(t, err) - - //height, _ := getCurrentHeight(native, param.ChainID) - //assert.Equal(t, uint64(height), uint64(10011)) - } - { - header10012, _ := hex.DecodeString("0aa8020a02080a120774657374696e67189c4e220c08a7e39ff70510ecbbe6b9032a480a20dd5ee8ddd3d21d365aa11153d8e83367140de92e4ccfabd999e97f093b83d388122408011220d3ee12d83dbba28047922ee735604065bbf18286ab770262327e92aed9d7662b32202496df827069967ea78dd93d07e6389e95abadd81cb5bd53cb9048b73a7ae0f2422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a206a1f58abdc0c358ed42023b6da978c6baa7c748f2534f42cec212c5ddeddd16172146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b601089c4e1a480a20744cf79eec130b744c9325ee44eb74661cfbe090989ee27af6a6856750ff41751224080112204a684ab601bb25ede19c18622513ecd95637dff4ef6270a1cec154e35a939a212267080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0b08ade39ff70510e9cad70b2240d448c0de45611b935f1f4d37ca33cafa174c9eebdc074febdf70eaac9fc384bf669369c46ed279b18f5bd7a73999d4ae46c382204947f019fa3fca1ea9d0dc021a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - header10011, _ := hex.DecodeString("0aa8020a02080a120774657374696e67189b4e220c08a2e39ff70510a5fe848d032a480a2064852da2991661fbd8d4f5e6789450b57662248ca4b996f640b327564c7c84601224080112209537acb3f8eebab33b949353ca450207614152c7df471b3aff1ffb683f78939c322055b77f9a764871721521ff6aeb920fe01bc440446712b483866cd4d09944839e422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a20b4cf9c1ec8e800ee5e201678c25580124ea8ae1e3dc7c4128d67b92ac876522f72146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b701089b4e1a480a20dd5ee8ddd3d21d365aa11153d8e83367140de92e4ccfabd999e97f093b83d388122408011220d3ee12d83dbba28047922ee735604065bbf18286ab770262327e92aed9d7662b2268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c08a7e39ff70510ecbbe6b903224048b1c9b7b32bdc0ecc11cb491dcd23f621bb799969221dae82e28645d229310eac1e3cde1aae6056b395d75b4d3adc96190c3cc40dc1ecaa2e431f4d5b78620b1a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - header10008, _ := hex.DecodeString("0aa8020a02080a120774657374696e6718984e220c0893e39ff70510bc93c689022a480a2014a45a0bde0573b04e03e9510a9e5b892d900803daf0296b0304c7172b865e2f122408011220d6e71ceeb4cc3ba6e5969eb127f5978a520c65501fc7a05c0ec79207b832bb1c32202e5974d3a2e211545c3648129248bd17317c8b34e456c2fceebadcb83ee9d76b422058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883794a2058df3ad01815e689d296705e219563932f8edd3637c1cd8f4a785906ca8883795220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a202e13fd7f9843a72be774ecfcd93e2dfc6ece88af940606398c7d7dfc1aadf7ba72146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812b70108984e1a480a20785bf8c3118aca98f1afa8138efed02c9e56056b4081b0aa99199f9e40590f1112240801122017d6baffe9414cafd8c348b42e13899a561faf72d49d9493b23711d43ed480dd2268080212146ff75a0ce1ed3596eb34a107bcfc1bebd1ea94781a0c0898e39ff70510a1bb83be02224064ef0539008ed04defb72325818b79aca8a1aac9ec68e82c32177d6b28f37ee6d4b45576877da5ce734fb3f031f45156dfed366401024f88596dbfa9c47bd1041a3f0a146ff75a0ce1ed3596eb34a107bcfc1bebd1ea947812251624de6420760145874ef07a40698eea7afdf7d89719c76c96a5517ac2cf1162bb2e0a70a21864") - param := new(scom.SyncBlockHeaderParam) - param.ChainID = 5 - - param.Headers = append(param.Headers, header10012) - param.Headers = append(param.Headers, header10011) - param.Headers = append(param.Headers, header10008) - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - native, _ := NewNative(scom.MethodSyncBlockHeader, param) - err := cosmosHandler.SyncBlockHeader(native) - if err != nil { - fmt.Printf("err: %s", err.Error()) - } - assert.Error(t, err) - - //height, _ := getCurrentHeight(native, param.ChainID) - //assert.Equal(t, uint64(height), uint64(10012)) - } -} diff --git a/contracts/native/header_sync/entrance_zilliqa_test.go b/contracts/native/header_sync/entrance_zilliqa_test.go deleted file mode 100644 index 4780a2c4..00000000 --- a/contracts/native/header_sync/entrance_zilliqa_test.go +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright (C) 2020 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ - -package header_sync - -import ( - "encoding/json" - "fmt" - "math/big" - - "github.com/polynetwork/poly/common" - - "github.com/ethereum/go-ethereum/contracts/native" - - scom "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/zilliqa" - - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/Zilliqa/gozilliqa-sdk/core" - ziutil "github.com/Zilliqa/gozilliqa-sdk/util" -) - -const ZILChainID = 9 - -func getLatestHeight(native *native.NativeContract) uint64 { - height, _ := zilliqa.GetCurrentTxHeaderHeight(native, ZILChainID) - return height -} - -func getHeaderHashByHeight(native *native.NativeContract, height uint64) []byte { - block, _ := zilliqa.GetTxHeaderByHeight(native, height, ZILChainID) - return block.BlockHash[:] -} - -func TestSyncGenesisHeaderZilliqa(t *testing.T) { - txBlock1Raw := "{\"BlockHash\":[56,40,135,50,178,230,126,194,104,230,177,166,241,195,181,119,72,230,177,102,171,121,58,163,41,139,18,92,138,231,108,39],\"Cosigs\":{\"CS1\":{\"R\":79461090997780129048034156976579207017607593312295382854180954812611062499786,\"S\":91742597770497613815760351313815911030151335677216474693626678776993533665077},\"B1\":[true,true,true,true,true,true,true,false,false,false],\"CS2\":{\"R\":22513373955460225598459727159582327633978685137898384968505490930737451385826,\"S\":69259600331273345477024713698850194580163873601064291944707625774006410868491},\"B2\":[true,true,false,true,true,true,true,true,false,false]},\"Timestamp\":1614851084113383,\"BlockHeader\":{\"BlockHeaderBase\":{\"Version\":1,\"CommitteeHash\":[144,78,35,242,84,150,244,171,215,191,207,200,228,18,4,75,188,156,242,96,234,28,171,227,90,127,173,150,197,48,76,231],\"PrevHash\":[25,71,113,139,67,29,37,221,101,194,38,247,159,62,10,156,201,106,148,136,153,218,179,66,41,147,222,241,73,74,156,149]},\"GasLimit\":90000,\"GasUsed\":0,\"Rewards\":0,\"BlockNum\":1,\"HashSet\":{\"StateRootHash\":[171,57,165,166,188,170,165,153,119,109,69,231,171,86,24,230,64,155,13,154,233,104,156,53,214,30,42,57,70,180,219,46],\"DeltaHash\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"MbInfoHash\":[59,61,191,206,53,105,23,193,9,0,195,32,41,52,29,157,182,192,2,221,165,75,6,239,121,24,166,25,78,63,43,201]},\"NumTxs\":0,\"MinerPubKey\":\"0x02105342331FCD7CA95648DF8C5373C596982544F35E90849B1E619DFC59F03D48\",\"DSBlockNum\":1}}" - var txblock core.TxBlock - json.Unmarshal([]byte(txBlock1Raw), &txblock) - dsBlock1Raw := "{\"BlockHash\":[110,156,68,14,64,80,203,185,47,33,51,251,33,253,134,144,165,106,177,248,40,162,95,175,149,198,226,104,42,133,141,147],\"Cosigs\":{\"CS1\":{\"R\":82378159645007731822019453933480162750953116703416061439006821187696821549829,\"S\":76062990255435928402343339335249009291551400166495738641213601543709385329901},\"B1\":[true,true,true,false,true,true,true,true,false,false],\"CS2\":{\"R\":93854453672214038567945187798065701969482439716186198113435402044731863802032,\"S\":99194416943091049405554646407147384870804679504363691825129226286226313434999},\"B2\":[true,true,true,true,true,true,false,false,true,false]},\"Timestamp\":1614851053611705,\"BlockHeader\":{\"BlockHeaderBase\":{\"Version\":2,\"CommitteeHash\":[168,148,171,148,251,117,232,182,248,255,95,207,117,54,148,68,162,158,59,213,12,56,135,233,222,70,197,78,138,205,243,168],\"PrevHash\":[15,0,233,211,23,83,0,252,40,120,18,210,1,237,207,191,203,129,101,128,150,6,84,85,149,191,83,112,12,82,70,72]},\"DsDifficulty\":5,\"Difficulty\":3,\"LeaderPubKey\":\"0x02105342331FCD7CA95648DF8C5373C596982544F35E90849B1E619DFC59F03D48\",\"BlockNum\":1,\"EpochNum\":1,\"GasPrice\":\"2000000000\",\"SwInfo\":{\"ZilliqaMajorVersion\":0,\"ZilliqaMinorVersion\":0,\"ZilliqaFixVersion\":0,\"ZilliqaUpgradeDS\":0,\"ZilliqaCommit\":0,\"ScillaMajorVersion\":0,\"ScillaMinorVersion\":0,\"ScillaFixVersion\":0,\"ScillaUpgradeDS\":0,\"ScillaCommit\":0},\"PoWDSWinners\":{\"0x0374A5CA5D76BEE5A1DE132AE72184AB084D23EC7A4867CCD562C58405BBB663E2\":{\"IpAddress\":3672036406,\"ListenPortHost\":33133,\"HostName\":\"\"}},\"RemoveDSNodePubKeys\":null,\"DSBlockHashSet\":{\"ShadingHash\":\"0VOZ8Rwe5L9/H5LD5FtSOWf9XK5dSilsYmSbzoF7Bjo=\",\"ReservedField\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},\"GovDSShardVotesMap\":{}},\"PrevDSHash\":\"0000000000000000000000000000000000000000000000000000000000000000\"}" - var dsblock core.DsBlock - json.Unmarshal([]byte(dsBlock1Raw), &dsblock) - ipaddr, _ := new(big.Int).SetString("3672036406", 10) - initComm := []core.PairOfNode{ - { - PubKey: "02105342331FCD7CA95648DF8C5373C596982544F35E90849B1E619DFC59F03D48", - }, - { - PubKey: "021D439D1CCCAE17C3D6E855BC78E96438C808D16D1CBF8D7ABD391E41CEE9B1BF", - }, - { - PubKey: "021EDDE95598F5F59708D2E728E00EDB2ECF278C16BD389384320B1AF998DCC2FD", - }, - { - PubKey: "02445FE498E7FBB240BDF9185EB5E7642AF1AF36852D1E132E198A222FBAC617A0", - }, - { - PubKey: "0256EC4BC62FB56C83A3F6160E67499A9E381CF7A613EBF34B9ECDB9E64171DDF4", - }, - { - PubKey: "0264D991762D81DD6557BCB33EC8AA3F621B4CB790852F2231C864921387B76862", - }, - { - PubKey: "027A00916BDD3CF954ED13A0494BFB73FF95BF28C54004F2749F1A8E8CC1AB5B3D", - }, - { - PubKey: "0297C693FBEBAF397CBDE616F605920EF70D7F6E5EC8DD82E71AE1E812E5E0B303", - }, - { - PubKey: "02AE5ADF63E9161000713987B5EBB490B5E6B57CF5B7F9799B4AB907BA19D468F6", - }, - { - PubKey: "0374A5CA5D76BEE5A1DE132AE72184AB084D23EC7A4867CCD562C58405BBB663E2", - Peer: core.Peer{ - IpAddress: ipaddr, - ListenPortHost: 33133, - }, - }, - } - txBlockAndDsComm := &zilliqa.TxBlockAndDsComm{ - TxBlock: &txblock, - DsBlock: &dsblock, - DsComm: initComm, - } - txBlockAndDsCommRaw, _ := json.Marshal(txBlockAndDsComm) - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = ZILChainID - param.GenesisHeader = txBlockAndDsCommRaw - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - n, err := NewNative(scom.MethodSyncGenesisHeader, param) - if err != nil { - fmt.Printf("NewNative err: %v", err) - return - } - zilHeader := zilliqa.NewHandler() - - err1 := zilHeader.SyncGenesisHeader(n) - assert.Equal(t, SUCCESS, typeOfError(err1)) - - height := getLatestHeight(n) - assert.Equal(t, uint64(1), height) - - headerHash := getHeaderHashByHeight(n, height) - // [56,40,135,50,178,230,126,194,104,230,177,166,241,195,181,119,72,230,177,102,171,121,58,163,41,139,18,92,138,231,108,39] - assert.Equal(t, "38288732b2e67ec268e6b1a6f1c3b57748e6b166ab793aa3298b125c8ae76c27", ziutil.EncodeHex(headerHash)) -} - -func TestSyncGenesisHeaderNoOperator(t *testing.T) { - txBlock1Raw := "{\"BlockHash\":[56,40,135,50,178,230,126,194,104,230,177,166,241,195,181,119,72,230,177,102,171,121,58,163,41,139,18,92,138,231,108,39],\"Cosigs\":{\"CS1\":{\"R\":79461090997780129048034156976579207017607593312295382854180954812611062499786,\"S\":91742597770497613815760351313815911030151335677216474693626678776993533665077},\"B1\":[true,true,true,true,true,true,true,false,false,false],\"CS2\":{\"R\":22513373955460225598459727159582327633978685137898384968505490930737451385826,\"S\":69259600331273345477024713698850194580163873601064291944707625774006410868491},\"B2\":[true,true,false,true,true,true,true,true,false,false]},\"Timestamp\":1614851084113383,\"BlockHeader\":{\"BlockHeaderBase\":{\"Version\":1,\"CommitteeHash\":[144,78,35,242,84,150,244,171,215,191,207,200,228,18,4,75,188,156,242,96,234,28,171,227,90,127,173,150,197,48,76,231],\"PrevHash\":[25,71,113,139,67,29,37,221,101,194,38,247,159,62,10,156,201,106,148,136,153,218,179,66,41,147,222,241,73,74,156,149]},\"GasLimit\":90000,\"GasUsed\":0,\"Rewards\":0,\"BlockNum\":1,\"HashSet\":{\"StateRootHash\":[171,57,165,166,188,170,165,153,119,109,69,231,171,86,24,230,64,155,13,154,233,104,156,53,214,30,42,57,70,180,219,46],\"DeltaHash\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"MbInfoHash\":[59,61,191,206,53,105,23,193,9,0,195,32,41,52,29,157,182,192,2,221,165,75,6,239,121,24,166,25,78,63,43,201]},\"NumTxs\":0,\"MinerPubKey\":\"0x02105342331FCD7CA95648DF8C5373C596982544F35E90849B1E619DFC59F03D48\",\"DSBlockNum\":1}}" - var txblock core.TxBlock - json.Unmarshal([]byte(txBlock1Raw), &txblock) - dsBlock1Raw := "{\"BlockHash\":[110,156,68,14,64,80,203,185,47,33,51,251,33,253,134,144,165,106,177,248,40,162,95,175,149,198,226,104,42,133,141,147],\"Cosigs\":{\"CS1\":{\"R\":82378159645007731822019453933480162750953116703416061439006821187696821549829,\"S\":76062990255435928402343339335249009291551400166495738641213601543709385329901},\"B1\":[true,true,true,false,true,true,true,true,false,false],\"CS2\":{\"R\":93854453672214038567945187798065701969482439716186198113435402044731863802032,\"S\":99194416943091049405554646407147384870804679504363691825129226286226313434999},\"B2\":[true,true,true,true,true,true,false,false,true,false]},\"Timestamp\":1614851053611705,\"BlockHeader\":{\"BlockHeaderBase\":{\"Version\":2,\"CommitteeHash\":[168,148,171,148,251,117,232,182,248,255,95,207,117,54,148,68,162,158,59,213,12,56,135,233,222,70,197,78,138,205,243,168],\"PrevHash\":[15,0,233,211,23,83,0,252,40,120,18,210,1,237,207,191,203,129,101,128,150,6,84,85,149,191,83,112,12,82,70,72]},\"DsDifficulty\":5,\"Difficulty\":3,\"LeaderPubKey\":\"0x02105342331FCD7CA95648DF8C5373C596982544F35E90849B1E619DFC59F03D48\",\"BlockNum\":1,\"EpochNum\":1,\"GasPrice\":\"2000000000\",\"SwInfo\":{\"ZilliqaMajorVersion\":0,\"ZilliqaMinorVersion\":0,\"ZilliqaFixVersion\":0,\"ZilliqaUpgradeDS\":0,\"ZilliqaCommit\":0,\"ScillaMajorVersion\":0,\"ScillaMinorVersion\":0,\"ScillaFixVersion\":0,\"ScillaUpgradeDS\":0,\"ScillaCommit\":0},\"PoWDSWinners\":{\"0x0374A5CA5D76BEE5A1DE132AE72184AB084D23EC7A4867CCD562C58405BBB663E2\":{\"IpAddress\":3672036406,\"ListenPortHost\":33133,\"HostName\":\"\"}},\"RemoveDSNodePubKeys\":null,\"DSBlockHashSet\":{\"ShadingHash\":\"0VOZ8Rwe5L9/H5LD5FtSOWf9XK5dSilsYmSbzoF7Bjo=\",\"ReservedField\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},\"GovDSShardVotesMap\":{}},\"PrevDSHash\":\"0000000000000000000000000000000000000000000000000000000000000000\"}" - var dsblock core.DsBlock - json.Unmarshal([]byte(dsBlock1Raw), &dsblock) - ipaddr, _ := new(big.Int).SetString("3672036406", 10) - initComm := []core.PairOfNode{ - { - PubKey: "02105342331FCD7CA95648DF8C5373C596982544F35E90849B1E619DFC59F03D48", - }, - { - PubKey: "021D439D1CCCAE17C3D6E855BC78E96438C808D16D1CBF8D7ABD391E41CEE9B1BF", - }, - { - PubKey: "021EDDE95598F5F59708D2E728E00EDB2ECF278C16BD389384320B1AF998DCC2FD", - }, - { - PubKey: "02445FE498E7FBB240BDF9185EB5E7642AF1AF36852D1E132E198A222FBAC617A0", - }, - { - PubKey: "0256EC4BC62FB56C83A3F6160E67499A9E381CF7A613EBF34B9ECDB9E64171DDF4", - }, - { - PubKey: "0264D991762D81DD6557BCB33EC8AA3F621B4CB790852F2231C864921387B76862", - }, - { - PubKey: "027A00916BDD3CF954ED13A0494BFB73FF95BF28C54004F2749F1A8E8CC1AB5B3D", - }, - { - PubKey: "0297C693FBEBAF397CBDE616F605920EF70D7F6E5EC8DD82E71AE1E812E5E0B303", - }, - { - PubKey: "02AE5ADF63E9161000713987B5EBB490B5E6B57CF5B7F9799B4AB907BA19D468F6", - }, - { - PubKey: "0374A5CA5D76BEE5A1DE132AE72184AB084D23EC7A4867CCD562C58405BBB663E2", - Peer: core.Peer{ - IpAddress: ipaddr, - ListenPortHost: 33133, - }, - }, - } - txBlockAndDsComm := &zilliqa.TxBlockAndDsComm{ - TxBlock: &txblock, - DsBlock: &dsblock, - DsComm: initComm, - } - txBlockAndDsCommRaw, _ := json.Marshal(txBlockAndDsComm) - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = ZILChainID - param.GenesisHeader = txBlockAndDsCommRaw - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - n, _ := NewNative(scom.MethodSyncGenesisHeader, param) - - zilHeader := zilliqa.NewHandler() - err2 := zilHeader.SyncGenesisHeader(n) - assert.Equal(t, 0, typeOfError(err2), err2) - -} - -func TestSyncGenesisHeaderTwice(t *testing.T) { - txBlock1Raw := "{\"BlockHash\":[56,40,135,50,178,230,126,194,104,230,177,166,241,195,181,119,72,230,177,102,171,121,58,163,41,139,18,92,138,231,108,39],\"Cosigs\":{\"CS1\":{\"R\":79461090997780129048034156976579207017607593312295382854180954812611062499786,\"S\":91742597770497613815760351313815911030151335677216474693626678776993533665077},\"B1\":[true,true,true,true,true,true,true,false,false,false],\"CS2\":{\"R\":22513373955460225598459727159582327633978685137898384968505490930737451385826,\"S\":69259600331273345477024713698850194580163873601064291944707625774006410868491},\"B2\":[true,true,false,true,true,true,true,true,false,false]},\"Timestamp\":1614851084113383,\"BlockHeader\":{\"BlockHeaderBase\":{\"Version\":1,\"CommitteeHash\":[144,78,35,242,84,150,244,171,215,191,207,200,228,18,4,75,188,156,242,96,234,28,171,227,90,127,173,150,197,48,76,231],\"PrevHash\":[25,71,113,139,67,29,37,221,101,194,38,247,159,62,10,156,201,106,148,136,153,218,179,66,41,147,222,241,73,74,156,149]},\"GasLimit\":90000,\"GasUsed\":0,\"Rewards\":0,\"BlockNum\":1,\"HashSet\":{\"StateRootHash\":[171,57,165,166,188,170,165,153,119,109,69,231,171,86,24,230,64,155,13,154,233,104,156,53,214,30,42,57,70,180,219,46],\"DeltaHash\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"MbInfoHash\":[59,61,191,206,53,105,23,193,9,0,195,32,41,52,29,157,182,192,2,221,165,75,6,239,121,24,166,25,78,63,43,201]},\"NumTxs\":0,\"MinerPubKey\":\"0x02105342331FCD7CA95648DF8C5373C596982544F35E90849B1E619DFC59F03D48\",\"DSBlockNum\":1}}" - var txblock core.TxBlock - json.Unmarshal([]byte(txBlock1Raw), &txblock) - dsBlock1Raw := "{\"BlockHash\":[110,156,68,14,64,80,203,185,47,33,51,251,33,253,134,144,165,106,177,248,40,162,95,175,149,198,226,104,42,133,141,147],\"Cosigs\":{\"CS1\":{\"R\":82378159645007731822019453933480162750953116703416061439006821187696821549829,\"S\":76062990255435928402343339335249009291551400166495738641213601543709385329901},\"B1\":[true,true,true,false,true,true,true,true,false,false],\"CS2\":{\"R\":93854453672214038567945187798065701969482439716186198113435402044731863802032,\"S\":99194416943091049405554646407147384870804679504363691825129226286226313434999},\"B2\":[true,true,true,true,true,true,false,false,true,false]},\"Timestamp\":1614851053611705,\"BlockHeader\":{\"BlockHeaderBase\":{\"Version\":2,\"CommitteeHash\":[168,148,171,148,251,117,232,182,248,255,95,207,117,54,148,68,162,158,59,213,12,56,135,233,222,70,197,78,138,205,243,168],\"PrevHash\":[15,0,233,211,23,83,0,252,40,120,18,210,1,237,207,191,203,129,101,128,150,6,84,85,149,191,83,112,12,82,70,72]},\"DsDifficulty\":5,\"Difficulty\":3,\"LeaderPubKey\":\"0x02105342331FCD7CA95648DF8C5373C596982544F35E90849B1E619DFC59F03D48\",\"BlockNum\":1,\"EpochNum\":1,\"GasPrice\":\"2000000000\",\"SwInfo\":{\"ZilliqaMajorVersion\":0,\"ZilliqaMinorVersion\":0,\"ZilliqaFixVersion\":0,\"ZilliqaUpgradeDS\":0,\"ZilliqaCommit\":0,\"ScillaMajorVersion\":0,\"ScillaMinorVersion\":0,\"ScillaFixVersion\":0,\"ScillaUpgradeDS\":0,\"ScillaCommit\":0},\"PoWDSWinners\":{\"0x0374A5CA5D76BEE5A1DE132AE72184AB084D23EC7A4867CCD562C58405BBB663E2\":{\"IpAddress\":3672036406,\"ListenPortHost\":33133,\"HostName\":\"\"}},\"RemoveDSNodePubKeys\":null,\"DSBlockHashSet\":{\"ShadingHash\":\"0VOZ8Rwe5L9/H5LD5FtSOWf9XK5dSilsYmSbzoF7Bjo=\",\"ReservedField\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},\"GovDSShardVotesMap\":{}},\"PrevDSHash\":\"0000000000000000000000000000000000000000000000000000000000000000\"}" - var dsblock core.DsBlock - json.Unmarshal([]byte(dsBlock1Raw), &dsblock) - ipaddr, _ := new(big.Int).SetString("3672036406", 10) - initComm := []core.PairOfNode{ - { - PubKey: "02105342331FCD7CA95648DF8C5373C596982544F35E90849B1E619DFC59F03D48", - }, - { - PubKey: "021D439D1CCCAE17C3D6E855BC78E96438C808D16D1CBF8D7ABD391E41CEE9B1BF", - }, - { - PubKey: "021EDDE95598F5F59708D2E728E00EDB2ECF278C16BD389384320B1AF998DCC2FD", - }, - { - PubKey: "02445FE498E7FBB240BDF9185EB5E7642AF1AF36852D1E132E198A222FBAC617A0", - }, - { - PubKey: "0256EC4BC62FB56C83A3F6160E67499A9E381CF7A613EBF34B9ECDB9E64171DDF4", - }, - { - PubKey: "0264D991762D81DD6557BCB33EC8AA3F621B4CB790852F2231C864921387B76862", - }, - { - PubKey: "027A00916BDD3CF954ED13A0494BFB73FF95BF28C54004F2749F1A8E8CC1AB5B3D", - }, - { - PubKey: "0297C693FBEBAF397CBDE616F605920EF70D7F6E5EC8DD82E71AE1E812E5E0B303", - }, - { - PubKey: "02AE5ADF63E9161000713987B5EBB490B5E6B57CF5B7F9799B4AB907BA19D468F6", - }, - { - PubKey: "0374A5CA5D76BEE5A1DE132AE72184AB084D23EC7A4867CCD562C58405BBB663E2", - Peer: core.Peer{ - IpAddress: ipaddr, - ListenPortHost: 33133, - }, - }, - } - txBlockAndDsComm := &zilliqa.TxBlockAndDsComm{ - TxBlock: &txblock, - DsBlock: &dsblock, - DsComm: initComm, - } - txBlockAndDsCommRaw, _ := json.Marshal(txBlockAndDsComm) - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = ZILChainID - param.GenesisHeader = txBlockAndDsCommRaw - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - n, _ := NewNative(scom.MethodSyncGenesisHeader, param) - zilHeader := zilliqa.NewHandler() - - err1 := zilHeader.SyncGenesisHeader(n) - assert.Equal(t, SUCCESS, typeOfError(err1)) - - err2 := zilHeader.SyncGenesisHeader(n) - assert.Equal(t, GENESIS_INITIALIZED, typeOfError(err2), err2) -} - -func TestSyncGenesisHeader_ParamError(t *testing.T) { - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = ZILChainID - param.GenesisHeader = nil - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - n, _ := NewNative(scom.MethodSyncGenesisHeader, param) - handler := zilliqa.NewHandler() - err := handler.SyncGenesisHeader(n) - assert.Equal(t, 1, typeOfError(err), err) -} - -func TestSyncBlockHeaderZilliqa(t *testing.T) { - txBlock1Raw := "{\"BlockHash\":[198,196,187,223,41,2,55,74,137,181,32,30,60,41,236,89,143,130,134,130,199,97,214,179,226,175,234,58,19,164,21,52],\"Cosigs\":{\"CS1\":{\"R\":58109336629118555449396504414874375430355183929502199153641350911913486744966,\"S\":42834457765405144810525740276961270055984409438037147774867951849264678802245},\"B1\":[true,true,false,true,false,true,true,true,true,false],\"CS2\":{\"R\":12041111728720404404134849913346487651892647150712666255963719399528392436985,\"S\":34374222978675334172262022327625814503512146074096743130855290756370657189473},\"B2\":[true,true,false,true,true,false,false,true,true,true]},\"Timestamp\":1616482651266233,\"BlockHeader\":{\"BlockHeaderBase\":{\"Version\":1,\"CommitteeHash\":[144,78,35,242,84,150,244,171,215,191,207,200,228,18,4,75,188,156,242,96,234,28,171,227,90,127,173,150,197,48,76,231],\"PrevHash\":[25,71,113,139,67,29,37,221,101,194,38,247,159,62,10,156,201,106,148,136,153,218,179,66,41,147,222,241,73,74,156,149]},\"GasLimit\":90000,\"GasUsed\":0,\"Rewards\":0,\"BlockNum\":1,\"HashSet\":{\"StateRootHash\":[171,57,165,166,188,170,165,153,119,109,69,231,171,86,24,230,64,155,13,154,233,104,156,53,214,30,42,57,70,180,219,46],\"DeltaHash\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"MbInfoHash\":[170,83,56,79,227,227,163,152,41,49,93,157,81,186,108,199,250,219,201,151,94,128,26,160,224,4,229,187,42,118,189,9]},\"NumTxs\":0,\"MinerPubKey\":\"0x02105342331FCD7CA95648DF8C5373C596982544F35E90849B1E619DFC59F03D48\",\"DSBlockNum\":1}}" - var txblock core.TxBlock - json.Unmarshal([]byte(txBlock1Raw), &txblock) - dsBlock1Raw := "{\"BlockHash\":[177,178,21,5,74,140,129,216,72,9,242,219,69,149,147,174,103,170,87,54,134,43,203,3,127,204,249,87,253,161,41,201],\"Cosigs\":{\"CS1\":{\"R\":99613788632020474433702045650540466738849941380038721642420319455252563066652,\"S\":83470010795651631914604412622099137695720109919902885425706313763948963023929},\"B1\":[true,true,false,true,true,true,false,true,true,false],\"CS2\":{\"R\":58439812583250820485652115586977725380594874340399000353204907104397745535732,\"S\":73713840044045713358947710673991983098670518727699349081038715495574564253106},\"B2\":[true,true,false,true,true,false,false,true,true,true]},\"Timestamp\":1616482624411339,\"BlockHeader\":{\"BlockHeaderBase\":{\"Version\":2,\"CommitteeHash\":[168,148,171,148,251,117,232,182,248,255,95,207,117,54,148,68,162,158,59,213,12,56,135,233,222,70,197,78,138,205,243,168],\"PrevHash\":[15,0,233,211,23,83,0,252,40,120,18,210,1,237,207,191,203,129,101,128,150,6,84,85,149,191,83,112,12,82,70,72]},\"DsDifficulty\":5,\"Difficulty\":3,\"LeaderPubKey\":\"0x02105342331FCD7CA95648DF8C5373C596982544F35E90849B1E619DFC59F03D48\",\"BlockNum\":1,\"EpochNum\":1,\"GasPrice\":\"2000000000\",\"SwInfo\":{\"ZilliqaMajorVersion\":0,\"ZilliqaMinorVersion\":0,\"ZilliqaFixVersion\":0,\"ZilliqaUpgradeDS\":0,\"ZilliqaCommit\":0,\"ScillaMajorVersion\":0,\"ScillaMinorVersion\":0,\"ScillaFixVersion\":0,\"ScillaUpgradeDS\":0,\"ScillaCommit\":0},\"PoWDSWinners\":{\"0x0374A5CA5D76BEE5A1DE132AE72184AB084D23EC7A4867CCD562C58405BBB663E2\":{\"IpAddress\":925292578,\"ListenPortHost\":33133,\"HostName\":\"\"}},\"RemoveDSNodePubKeys\":null,\"DSBlockHashSet\":{\"ShardingHash\":\"FIDBeRfj8PyS3ukv4SocHJvBU7jUVr3WMQAQ69AM0zc=\",\"ReservedField\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},\"GovDSShardVotesMap\":{}},\"PrevDSHash\":\"0000000000000000000000000000000000000000000000000000000000000000\"}" - var dsblock core.DsBlock - json.Unmarshal([]byte(dsBlock1Raw), &dsblock) - ipaddr, _ := new(big.Int).SetString("3672036406", 10) - initComm := []core.PairOfNode{ - { - PubKey: "02105342331FCD7CA95648DF8C5373C596982544F35E90849B1E619DFC59F03D48", - }, - { - PubKey: "021D439D1CCCAE17C3D6E855BC78E96438C808D16D1CBF8D7ABD391E41CEE9B1BF", - }, - { - PubKey: "021EDDE95598F5F59708D2E728E00EDB2ECF278C16BD389384320B1AF998DCC2FD", - }, - { - PubKey: "02445FE498E7FBB240BDF9185EB5E7642AF1AF36852D1E132E198A222FBAC617A0", - }, - { - PubKey: "0256EC4BC62FB56C83A3F6160E67499A9E381CF7A613EBF34B9ECDB9E64171DDF4", - }, - { - PubKey: "0264D991762D81DD6557BCB33EC8AA3F621B4CB790852F2231C864921387B76862", - }, - { - PubKey: "027A00916BDD3CF954ED13A0494BFB73FF95BF28C54004F2749F1A8E8CC1AB5B3D", - }, - { - PubKey: "0297C693FBEBAF397CBDE616F605920EF70D7F6E5EC8DD82E71AE1E812E5E0B303", - }, - { - PubKey: "02AE5ADF63E9161000713987B5EBB490B5E6B57CF5B7F9799B4AB907BA19D468F6", - }, - { - PubKey: "0374A5CA5D76BEE5A1DE132AE72184AB084D23EC7A4867CCD562C58405BBB663E2", - Peer: core.Peer{ - IpAddress: ipaddr, - ListenPortHost: 33133, - }, - }, - } - txBlockAndDsComm := &zilliqa.TxBlockAndDsComm{ - TxBlock: &txblock, - DsBlock: &dsblock, - DsComm: initComm, - } - txBlockAndDsCommRaw, _ := json.Marshal(txBlockAndDsComm) - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = ZILChainID - param.GenesisHeader = txBlockAndDsCommRaw - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - n, _ := NewNative(scom.MethodSyncGenesisHeader, param) - zilHeader := zilliqa.NewHandler() - - err1 := zilHeader.SyncGenesisHeader(n) - assert.Equal(t, SUCCESS, typeOfError(err1)) - - { - tx2 := "{\"BlockHash\":[5,87,218,152,215,172,201,175,55,221,20,70,163,232,62,179,31,70,219,106,39,12,57,65,166,164,185,70,178,176,19,48],\"Cosigs\":{\"CS1\":{\"R\":54597451652952888417512946896303661396013826296460113603832920706139092087649,\"S\":56753266975166847184238555659989691929088341907435508947769762570338628362173},\"B1\":[true,false,false,true,true,true,true,true,true,false],\"CS2\":{\"R\":36326739996437912010421129351156669175821362361052250000373139287527937181625,\"S\":9944649594228203414556601877828781023829377587493680071256874426779118191398},\"B2\":[true,true,false,true,false,true,true,true,true,false]},\"Timestamp\":1616482675522072,\"BlockHeader\":{\"BlockHeaderBase\":{\"Version\":1,\"CommitteeHash\":[144,78,35,242,84,150,244,171,215,191,207,200,228,18,4,75,188,156,242,96,234,28,171,227,90,127,173,150,197,48,76,231],\"PrevHash\":[198,196,187,223,41,2,55,74,137,181,32,30,60,41,236,89,143,130,134,130,199,97,214,179,226,175,234,58,19,164,21,52]},\"GasLimit\":90000,\"GasUsed\":0,\"Rewards\":0,\"BlockNum\":2,\"HashSet\":{\"StateRootHash\":[171,57,165,166,188,170,165,153,119,109,69,231,171,86,24,230,64,155,13,154,233,104,156,53,214,30,42,57,70,180,219,46],\"DeltaHash\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"MbInfoHash\":[163,85,71,96,47,189,89,66,122,29,134,216,243,88,210,43,84,46,72,158,100,216,185,56,173,27,135,178,92,63,149,83]},\"NumTxs\":0,\"MinerPubKey\":\"0x02105342331FCD7CA95648DF8C5373C596982544F35E90849B1E619DFC59F03D48\",\"DSBlockNum\":1}}" - var txBlock2 core.TxBlock - json.Unmarshal([]byte(tx2), &txBlock2) - txHeader2 := core.TxBlockOrDsBlock{ - DsBlock: nil, - TxBlock: &txBlock2, - } - txBlock2Raw, _ := json.Marshal(txHeader2) - - ds2 := "{\"BlockHash\":[110,207,125,63,163,252,161,211,95,229,133,37,19,210,42,0,211,57,9,191,98,56,112,173,74,208,143,22,135,137,45,90],\"Cosigs\":{\"CS1\":{\"R\":56502596102891709708736445865299726564263544940681323864604659561497267761793,\"S\":86725324460902515960412953201928687760351444425711626037301532154266414263256},\"B1\":[true,true,false,true,true,false,true,true,true,false],\"CS2\":{\"R\":55156965666244021617738656401179199952957114058974483696365972510155680247153,\"S\":97015393337678150234175522258654584855566438697571288263384422102882529172951},\"B2\":[true,true,false,false,true,false,true,true,true,true]},\"Timestamp\":1616482787090369,\"BlockHeader\":{\"BlockHeaderBase\":{\"Version\":2,\"CommitteeHash\":[144,78,35,242,84,150,244,171,215,191,207,200,228,18,4,75,188,156,242,96,234,28,171,227,90,127,173,150,197,48,76,231],\"PrevHash\":[177,178,21,5,74,140,129,216,72,9,242,219,69,149,147,174,103,170,87,54,134,43,203,3,127,204,249,87,253,161,41,201]},\"DsDifficulty\":5,\"Difficulty\":3,\"LeaderPubKey\":\"0x02105342331FCD7CA95648DF8C5373C596982544F35E90849B1E619DFC59F03D48\",\"BlockNum\":2,\"EpochNum\":5,\"GasPrice\":\"2000000000\",\"SwInfo\":{\"ZilliqaMajorVersion\":0,\"ZilliqaMinorVersion\":0,\"ZilliqaFixVersion\":0,\"ZilliqaUpgradeDS\":0,\"ZilliqaCommit\":0,\"ScillaMajorVersion\":0,\"ScillaMinorVersion\":0,\"ScillaFixVersion\":0,\"ScillaUpgradeDS\":0,\"ScillaCommit\":0},\"PoWDSWinners\":{\"0x02D3CB3FFC8DDE2A55AC29D013CEB5636806C6FC61C5AF077B6313DC636027A602\":{\"IpAddress\":259309366,\"ListenPortHost\":33133,\"HostName\":\"\"}},\"RemoveDSNodePubKeys\":[\"0x0374A5CA5D76BEE5A1DE132AE72184AB084D23EC7A4867CCD562C58405BBB663E2\"],\"DSBlockHashSet\":{\"ShardingHash\":\"WwDIqGn9lP8QgWTR/0KGtTxNjIaZ8xVe0rp2L6fKsxc=\",\"ReservedField\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},\"GovDSShardVotesMap\":{}},\"PrevDSHash\":\"b1b215054a8c81d84809f2db459593ae67aa5736862bcb037fccf957fda129c9\"}" - var dsBlock core.DsBlock - json.Unmarshal([]byte(ds2), &dsBlock) - dxBlock2 := core.TxBlockOrDsBlock{ - DsBlock: &dsBlock, - TxBlock: nil, - } - dsBlock2Raw, _ := json.Marshal(dxBlock2) - - ds3 := "{\"BlockHash\":[25,151,250,148,87,47,225,9,116,157,156,163,68,58,44,34,97,3,83,194,52,57,28,201,114,10,152,50,150,113,183,121],\"Cosigs\":{\"CS1\":{\"R\":12650252898742473466070092531844492202946771590557956991986987650625381182918,\"S\":15349085518327498393804839729572844141829718816896857218630306999619783152127},\"B1\":[true,true,false,true,true,true,true,false,true,false],\"CS2\":{\"R\":113536827174274976233000287455547736881926014915104046926508153941651626663559,\"S\":68201912123518469640310854201194472136490911262515861617597461185837243642676},\"B2\":[true,true,false,true,true,true,false,true,true,false]},\"Timestamp\":1616482966502387,\"BlockHeader\":{\"BlockHeaderBase\":{\"Version\":2,\"CommitteeHash\":[168,148,171,148,251,117,232,182,248,255,95,207,117,54,148,68,162,158,59,213,12,56,135,233,222,70,197,78,138,205,243,168],\"PrevHash\":[110,207,125,63,163,252,161,211,95,229,133,37,19,210,42,0,211,57,9,191,98,56,112,173,74,208,143,22,135,137,45,90]},\"DsDifficulty\":5,\"Difficulty\":3,\"LeaderPubKey\":\"0x02AE5ADF63E9161000713987B5EBB490B5E6B57CF5B7F9799B4AB907BA19D468F6\",\"BlockNum\":3,\"EpochNum\":10,\"GasPrice\":\"2000000000\",\"SwInfo\":{\"ZilliqaMajorVersion\":0,\"ZilliqaMinorVersion\":0,\"ZilliqaFixVersion\":0,\"ZilliqaUpgradeDS\":0,\"ZilliqaCommit\":0,\"ScillaMajorVersion\":0,\"ScillaMinorVersion\":0,\"ScillaFixVersion\":0,\"ScillaUpgradeDS\":0,\"ScillaCommit\":0},\"PoWDSWinners\":{},\"RemoveDSNodePubKeys\":null,\"DSBlockHashSet\":{\"ShardingHash\":\"LYaVTsbNpJlDjDOT5+gmHJ8yX+bNy0LSUrBFDYHwfhI=\",\"ReservedField\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},\"GovDSShardVotesMap\":{}},\"PrevDSHash\":\"6ecf7d3fa3fca1d35fe5852513d22a00d33909bf623870ad4ad08f1687892d5a\"}" - var dsBlock3 core.DsBlock - json.Unmarshal([]byte(ds3), &dsBlock3) - - dxBlock3 := core.TxBlockOrDsBlock{ - DsBlock: &dsBlock3, - TxBlock: nil, - } - dsBlock3Raw, _ := json.Marshal(dxBlock3) - - param := new(scom.SyncBlockHeaderParam) - param.ChainID = ZILChainID - param.Headers = append(param.Headers, txBlock2Raw) - param.Headers = append(param.Headers, dsBlock2Raw) - param.Headers = append(param.Headers, dsBlock3Raw) - - sink := common.NewZeroCopySink(nil) - param.Serialization(sink) - - native, _ := NewNative(scom.MethodSyncBlockHeader, param) - - err := zilHeader.SyncBlockHeader(native) - if err != nil { - fmt.Printf("%v", err) - } - assert.Equal(t, SUCCESS, typeOfError(err), err) - - } - -} diff --git a/contracts/native/header_sync/eth/cache.go b/contracts/native/header_sync/eth/cache.go deleted file mode 100644 index 3ca416b5..00000000 --- a/contracts/native/header_sync/eth/cache.go +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) 2020 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package eth - -import ( - "encoding/binary" - "reflect" - "sync" - "time" - "unsafe" - - "github.com/ethereum/go-ethereum/common/bitutil" - "github.com/ethereum/go-ethereum/log" - "golang.org/x/crypto/sha3" -) - -const cachesCapacity = 3 - -type Caches struct { - cap int - items map[uint64][]uint32 - mu *sync.RWMutex -} - -var caches = &Caches{ - cap: cachesCapacity, - items: make(map[uint64][]uint32), - mu: new(sync.RWMutex), -} - -func (self *Caches) serialize(values []uint32) []byte { - buf := make([]byte, len(values)*4) - for i, value := range values { - binary.LittleEndian.PutUint32(buf[i*4:], value) - } - return buf -} - -func (self *Caches) deserialize(buf []byte) []uint32 { - values := make([]uint32, len(buf)/4) - for i := 0; i < len(values); i++ { - values[i] = binary.LittleEndian.Uint32(buf[i*4:]) - } - return values -} - -func (self *Caches) tryCache(epoch uint64) []uint32 { - current := self.items[epoch] - return current -} - -func (self *Caches) addCache(epoch uint64, cache []uint32) { - self.items[epoch] = cache -} - -func (self *Caches) deleteCaches() { - self.mu.Lock() - defer self.mu.Unlock() - - if len(self.items) <= self.cap { - return - } - - minEpoch := uint64(0) - for epoch, _ := range self.items { - if minEpoch == 0 || epoch < minEpoch { - minEpoch = epoch - } - } - if minEpoch > 0 { - delete(self.items, minEpoch) - } -} - -func (self *Caches) getCache(block uint64) []uint32 { - self.mu.Lock() - defer self.mu.Unlock() - - epoch := block / epochLength - current := self.tryCache(epoch) - if current != nil { - return current - } - size := cacheSize(epoch*epochLength + 1) - seed := seedHash(epoch*epochLength + 1) - // If we don't store anything on disk, generate and return. - cache := make([]uint32, size/4) - self.generateCache(cache, seed) - self.addCache(epoch, cache) - return cache -} - -func (self *Caches) generateCache(dest []uint32, seed []byte) { - startTime := time.Now().Unix() - defer func() { - endTime := time.Now().Unix() - log.Trace("generateCache", "spent time(second)", endTime-startTime) - }() - - // Convert our destination slice to a byte buffer - header := *(*reflect.SliceHeader)(unsafe.Pointer(&dest)) - header.Len *= 4 - header.Cap *= 4 - cache := *(*[]byte)(unsafe.Pointer(&header)) - - // Calculate the number of theoretical rows (we'll store in one buffer nonetheless) - size := uint64(len(cache)) - rows := int(size) / hashBytes - - // Create a hasher to reuse between invocations - keccak512 := makeHasher(sha3.NewLegacyKeccak512()) - - // Sequentially produce the initial dataset - keccak512(cache, seed) - for offset := uint64(hashBytes); offset < size; offset += hashBytes { - keccak512(cache[offset:], cache[offset-hashBytes:offset]) - } - // Use a low-round version of randmemohash - temp := make([]byte, hashBytes) - for i := 0; i < cacheRounds; i++ { - for j := 0; j < rows; j++ { - var ( - srcOff = ((j - 1 + rows) % rows) * hashBytes - dstOff = j * hashBytes - xorOff = (binary.LittleEndian.Uint32(cache[dstOff:]) % uint32(rows)) * hashBytes - ) - bitutil.XORBytes(temp, cache[srcOff:srcOff+hashBytes], cache[xorOff:xorOff+hashBytes]) - keccak512(cache[dstOff:], temp) - } - } - // Swap the byte order on big endian systems and return - if !isLittleEndian() { - swap(cache) - } -} - -func lookup(cache []uint32, index uint32) []uint32 { - keccak512 := makeHasher(sha3.NewLegacyKeccak512()) - rawData := generateDatasetItem(cache, index, keccak512) - data := make([]uint32, len(rawData)/4) - for i := 0; i < len(data); i++ { - data[i] = binary.LittleEndian.Uint32(rawData[i*4:]) - } - return data -} - -func generateDatasetItem(cache []uint32, index uint32, keccak512 hasher) []byte { - // Calculate the number of theoretical rows (we use one buffer nonetheless) - rows := uint32(len(cache) / hashWords) - // Initialize the mix - mix := make([]byte, hashBytes) - binary.LittleEndian.PutUint32(mix, cache[(index%rows)*hashWords]^index) - for i := 1; i < hashWords; i++ { - binary.LittleEndian.PutUint32(mix[i*4:], cache[(index%rows)*hashWords+uint32(i)]) - } - keccak512(mix, mix) - // Convert the mix to uint32s to avoid constant bit shifting - intMix := make([]uint32, hashWords) - for i := 0; i < len(intMix); i++ { - intMix[i] = binary.LittleEndian.Uint32(mix[i*4:]) - } - // fnv it with a lot of random cache nodes based on index - for i := uint32(0); i < datasetParents; i++ { - parent := fnv(index^i, intMix[i%16]) % rows - fnvHash(intMix, cache[parent*hashWords:]) - } - // Flatten the uint32 mix into a binary one and return - for i, val := range intMix { - binary.LittleEndian.PutUint32(mix[i*4:], val) - } - keccak512(mix, mix) - return mix -} diff --git a/contracts/native/header_sync/eth/cache_test.go b/contracts/native/header_sync/eth/cache_test.go deleted file mode 100644 index be1bb325..00000000 --- a/contracts/native/header_sync/eth/cache_test.go +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ - -package eth - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestCache(t *testing.T) { - docache := func(epoch uint64, data []uint32) { - caches.addCache(epoch, data) - caches.deleteCaches() - } - - docache(12, []uint32{1, 2, 3}) - docache(13, []uint32{1, 2, 3}) - assert.Equal(t, 2, len(caches.items)) - - docache(14, []uint32{1, 2, 3}) - docache(15, []uint32{1, 2, 3}) - docache(16, []uint32{1, 2, 3}) - assert.Equal(t, 3, len(caches.items)) - - var ok bool - _, ok = caches.items[14] - assert.True(t, ok) - _, ok = caches.items[15] - assert.True(t, ok) - _, ok = caches.items[16] - assert.True(t, ok) -} diff --git a/contracts/native/header_sync/eth/header1559.go b/contracts/native/header_sync/eth/header1559.go deleted file mode 100644 index f1cc1196..00000000 --- a/contracts/native/header_sync/eth/header1559.go +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ - -package eth - -import ( - "encoding/json" - "errors" - "fmt" - "math/big" - "sync" - - "hash" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/common/math" - otypes "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth/types" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" -) - -type Header struct { - ParentHash common.Hash `json:"parentHash" gencodec:"required"` - UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase common.Address `json:"miner" gencodec:"required"` - Root common.Hash `json:"stateRoot" gencodec:"required"` - TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom types.Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *big.Int `json:"difficulty" gencodec:"required"` - Number *big.Int `json:"number" gencodec:"required"` - GasLimit uint64 `json:"gasLimit" gencodec:"required"` - GasUsed uint64 `json:"gasUsed" gencodec:"required"` - Time uint64 `json:"timestamp" gencodec:"required"` - Extra []byte `json:"extraData" gencodec:"required"` - MixDigest common.Hash `json:"mixHash"` - Nonce types.BlockNonce `json:"nonce"` - - // BaseFee was added by EIP-1559 and is ignored in legacy headers. - BaseFee *big.Int `json:"baseFeePerGas" rlp:"optional"` -} - -// MarshalJSON marshals as JSON. -func (h Header) MarshalJSON() ([]byte, error) { - type Header struct { - ParentHash common.Hash `json:"parentHash" gencodec:"required"` - UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase common.Address `json:"miner" gencodec:"required"` - Root common.Hash `json:"stateRoot" gencodec:"required"` - TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom types.Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` - Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Time hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra hexutil.Bytes `json:"extraData" gencodec:"required"` - MixDigest common.Hash `json:"mixHash"` - Nonce types.BlockNonce `json:"nonce"` - BaseFee *hexutil.Big `json:"baseFeePerGas,omitempty" rlp:"optional"` - Hash common.Hash `json:"hash"` - } - var enc Header - enc.ParentHash = h.ParentHash - enc.UncleHash = h.UncleHash - enc.Coinbase = h.Coinbase - enc.Root = h.Root - enc.TxHash = h.TxHash - enc.ReceiptHash = h.ReceiptHash - enc.Bloom = h.Bloom - enc.Difficulty = (*hexutil.Big)(h.Difficulty) - enc.Number = (*hexutil.Big)(h.Number) - enc.GasLimit = hexutil.Uint64(h.GasLimit) - enc.GasUsed = hexutil.Uint64(h.GasUsed) - enc.Time = hexutil.Uint64(h.Time) - enc.Extra = h.Extra - enc.MixDigest = h.MixDigest - enc.Nonce = h.Nonce - enc.BaseFee = (*hexutil.Big)(h.BaseFee) - enc.Hash = h.Hash() - return json.Marshal(&enc) -} - -func (h *Header) Hash() common.Hash { - return rlpHash(h) -} - -// hasherPool holds LegacyKeccak256 hashers for rlpHash. -var hasherPool = sync.Pool{ - New: func() interface{} { return sha3.NewLegacyKeccak256() }, -} - -// KeccakState wraps sha3.state. In addition to the usual hash methods, it also supports -// Read to get a variable amount of data from the hash state. Read is faster than Sum -// because it doesn't copy the internal state, but also modifies the internal state. -type KeccakState interface { - hash.Hash - Read([]byte) (int, error) -} - -// rlpHash encodes x and hashes the encoded bytes. -func rlpHash(x interface{}) (h common.Hash) { - sha := hasherPool.Get().(KeccakState) - defer hasherPool.Put(sha) - sha.Reset() - rlp.Encode(sha, x) - sha.Read(h[:]) - return h -} - -func To1559(h *otypes.Header) *Header { - return &Header{ - ParentHash: h.ParentHash, - UncleHash: h.UncleHash, - Coinbase: h.Coinbase, - Root: h.Root, - TxHash: h.TxHash, - ReceiptHash: h.ReceiptHash, - Bloom: h.Bloom, - Difficulty: h.Difficulty, - Number: h.Number, - GasLimit: h.GasLimit, - GasUsed: h.GasUsed, - Time: h.Time, - Extra: h.Extra, - MixDigest: h.MixDigest, - Nonce: h.Nonce, - } -} - -// UnmarshalJSON unmarshals from JSON. -func (h *Header) UnmarshalJSON(input []byte) error { - type Header struct { - ParentHash *common.Hash `json:"parentHash" gencodec:"required"` - UncleHash *common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase *common.Address `json:"miner" gencodec:"required"` - Root *common.Hash `json:"stateRoot" gencodec:"required"` - TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom *types.Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` - Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Time *hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` - MixDigest *common.Hash `json:"mixHash"` - Nonce *types.BlockNonce `json:"nonce"` - BaseFee *hexutil.Big `json:"baseFeePerGas,omitempty" rlp:"optional"` - } - var dec Header - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.ParentHash == nil { - return errors.New("missing required field 'parentHash' for Header") - } - h.ParentHash = *dec.ParentHash - if dec.UncleHash == nil { - return errors.New("missing required field 'sha3Uncles' for Header") - } - h.UncleHash = *dec.UncleHash - if dec.Coinbase == nil { - return errors.New("missing required field 'miner' for Header") - } - h.Coinbase = *dec.Coinbase - if dec.Root == nil { - return errors.New("missing required field 'stateRoot' for Header") - } - h.Root = *dec.Root - if dec.TxHash == nil { - return errors.New("missing required field 'transactionsRoot' for Header") - } - h.TxHash = *dec.TxHash - if dec.ReceiptHash == nil { - return errors.New("missing required field 'receiptsRoot' for Header") - } - h.ReceiptHash = *dec.ReceiptHash - if dec.Bloom == nil { - return errors.New("missing required field 'logsBloom' for Header") - } - h.Bloom = *dec.Bloom - if dec.Difficulty == nil { - return errors.New("missing required field 'difficulty' for Header") - } - h.Difficulty = (*big.Int)(dec.Difficulty) - if dec.Number == nil { - return errors.New("missing required field 'number' for Header") - } - h.Number = (*big.Int)(dec.Number) - if dec.GasLimit == nil { - return errors.New("missing required field 'gasLimit' for Header") - } - h.GasLimit = uint64(*dec.GasLimit) - if dec.GasUsed == nil { - return errors.New("missing required field 'gasUsed' for Header") - } - h.GasUsed = uint64(*dec.GasUsed) - if dec.Time == nil { - return errors.New("missing required field 'timestamp' for Header") - } - h.Time = uint64(*dec.Time) - if dec.Extra == nil { - return errors.New("missing required field 'extraData' for Header") - } - h.Extra = *dec.Extra - if dec.MixDigest != nil { - h.MixDigest = *dec.MixDigest - } - if dec.Nonce != nil { - h.Nonce = *dec.Nonce - } - if dec.BaseFee != nil { - h.BaseFee = (*big.Int)(dec.BaseFee) - } - return nil -} - -var ( - isTest bool - testLondonHeight uint64 -) - -func isLondon(h *Header) bool { - if isTest { - return h.Number.Uint64() >= testLondonHeight - } - return h.BaseFee != nil -} - -// VerifyGaslimit verifies the header gas limit according increase/decrease -// in relation to the parent gas limit. -func VerifyGaslimit(parentGasLimit, headerGasLimit uint64) error { - // Verify that the gas limit remains within allowed bounds - diff := int64(parentGasLimit) - int64(headerGasLimit) - if diff < 0 { - diff *= -1 - } - limit := parentGasLimit / params.GasLimitBoundDivisor - if uint64(diff) >= limit { - return fmt.Errorf("invalid gas limit: have %d, want %d +-= %d", headerGasLimit, parentGasLimit, limit-1) - } - if headerGasLimit < params.MinGasLimit { - return errors.New("invalid gas limit below 5000") - } - return nil -} - -const ( - BaseFeeChangeDenominator = 8 // Bounds the amount the base fee can change between blocks. - ElasticityMultiplier = 2 // Bounds the maximum gas limit an EIP-1559 block may have. - InitialBaseFee = 1000000000 // Initial base fee for EIP-1559 blocks. -) - -// VerifyEip1559Header verifies some header attributes which were changed in EIP-1559, -// - gas limit check -// - basefee check -func VerifyEip1559Header(parent, header *Header) error { - // Verify that the gas limit remains within allowed bounds - parentGasLimit := parent.GasLimit - if !isLondon(parent) { - parentGasLimit = parent.GasLimit * ElasticityMultiplier - } - if err := VerifyGaslimit(parentGasLimit, header.GasLimit); err != nil { - return err - } - // Verify the header is not malformed - if header.BaseFee == nil { - return fmt.Errorf("header is missing baseFee") - } - // Verify the baseFee is correct based on the parent header. - expectedBaseFee := CalcBaseFee(parent) - if header.BaseFee.Cmp(expectedBaseFee) != 0 { - return fmt.Errorf("invalid baseFee: have %s, want %s, parentBaseFee %s, parentGasUsed %d", - expectedBaseFee, header.BaseFee, parent.BaseFee, parent.GasUsed) - } - return nil -} - -// CalcBaseFee calculates the basefee of the header. -func CalcBaseFee(parent *Header) *big.Int { - // If the current block is the first EIP-1559 block, return the InitialBaseFee. - if !isLondon(parent) { - return new(big.Int).SetUint64(InitialBaseFee) - } - - var ( - parentGasTarget = parent.GasLimit / ElasticityMultiplier - parentGasTargetBig = new(big.Int).SetUint64(parentGasTarget) - baseFeeChangeDenominator = new(big.Int).SetUint64(BaseFeeChangeDenominator) - ) - // If the parent gasUsed is the same as the target, the baseFee remains unchanged. - if parent.GasUsed == parentGasTarget { - return new(big.Int).Set(parent.BaseFee) - } - if parent.GasUsed > parentGasTarget { - // If the parent block used more gas than its target, the baseFee should increase. - gasUsedDelta := new(big.Int).SetUint64(parent.GasUsed - parentGasTarget) - x := new(big.Int).Mul(parent.BaseFee, gasUsedDelta) - y := x.Div(x, parentGasTargetBig) - baseFeeDelta := math.BigMax( - x.Div(y, baseFeeChangeDenominator), - common.Big1, - ) - - return x.Add(parent.BaseFee, baseFeeDelta) - } else { - // Otherwise if the parent block used less gas than its target, the baseFee should decrease. - gasUsedDelta := new(big.Int).SetUint64(parentGasTarget - parent.GasUsed) - x := new(big.Int).Mul(parent.BaseFee, gasUsedDelta) - y := x.Div(x, parentGasTargetBig) - baseFeeDelta := x.Div(y, baseFeeChangeDenominator) - - return math.BigMax( - x.Sub(parent.BaseFee, baseFeeDelta), - common.Big0, - ) - } -} - -// Some weird constants to avoid constant memory allocs for them. -var ( - expDiffPeriod = big.NewInt(100000) - big1 = big.NewInt(1) - big2 = big.NewInt(2) - big9 = big.NewInt(9) - bigMinus99 = big.NewInt(-99) -) - -// makeDifficultyCalculator creates a difficultyCalculator with the given bomb-delay. -// the difficulty is calculated with Byzantium rules, which differs from Homestead in -// how uncles affect the calculation -func makeDifficultyCalculator(bombDelay *big.Int) func(time uint64, parent *Header) *big.Int { - // Note, the calculations below looks at the parent number, which is 1 below - // the block number. Thus we remove one from the delay given - bombDelayFromParent := new(big.Int).Sub(bombDelay, big1) - return func(time uint64, parent *Header) *big.Int { - // https://github.com/ethereum/EIPs/issues/100. - // algorithm: - // diff = (parent_diff + - // (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99)) - // ) + 2^(periodCount - 2) - - bigTime := new(big.Int).SetUint64(time) - bigParentTime := new(big.Int).SetUint64(parent.Time) - - // holds intermediate values to make the algo easier to read & audit - x := new(big.Int) - y := new(big.Int) - - // (2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9 - x.Sub(bigTime, bigParentTime) - x.Div(x, big9) - if parent.UncleHash == types.EmptyUncleHash { - x.Sub(big1, x) - } else { - x.Sub(big2, x) - } - // max((2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9, -99) - if x.Cmp(bigMinus99) < 0 { - x.Set(bigMinus99) - } - // parent_diff + (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99)) - y.Div(parent.Difficulty, params.DifficultyBoundDivisor) - x.Mul(y, x) - x.Add(parent.Difficulty, x) - - // minimum difficulty can ever be (before exponential factor) - if x.Cmp(params.MinimumDifficulty) < 0 { - x.Set(params.MinimumDifficulty) - } - // calculate a fake block number for the ice-age delay - // Specification: https://eips.ethereum.org/EIPS/eip-1234 - fakeBlockNumber := new(big.Int) - if parent.Number.Cmp(bombDelayFromParent) >= 0 { - fakeBlockNumber = fakeBlockNumber.Sub(parent.Number, bombDelayFromParent) - } - // for the exponential factor - periodCount := fakeBlockNumber - periodCount.Div(periodCount, expDiffPeriod) - - // the exponential factor, commonly referred to as "the bomb" - // diff = diff + 2^(periodCount - 2) - if periodCount.Cmp(big1) > 0 { - y.Sub(periodCount, big2) - y.Exp(big2, y, nil) - x.Add(x, y) - } - return x - } -} diff --git a/contracts/native/header_sync/eth/header_sync.go b/contracts/native/header_sync/eth/header_sync.go deleted file mode 100644 index 11065d95..00000000 --- a/contracts/native/header_sync/eth/header_sync.go +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package eth - -import ( - "bytes" - "encoding/binary" - "encoding/json" - "fmt" - "hash" - "math/big" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/consensus" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - scom "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" -) - -var ( - BIG_1 = big.NewInt(1) - BIG_2 = big.NewInt(2) - BIG_9 = big.NewInt(9) - BIG_MINUS_99 = big.NewInt(-99) - BLOCK_DIFF_FACTOR = big.NewInt(2048) - DIFF_PERIOD = big.NewInt(100000) - BOMB_DELAY = big.NewInt(8999999) -) - -type ETHHandler struct { -} - -func NewETHHandler() *ETHHandler { - return ÐHandler{} -} - -func (this *ETHHandler) SyncGenesisHeader(native *native.NativeContract) error { - ctx := native.ContractRef().CurrentContext() - params := &scom.SyncGenesisHeaderParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodSyncGenesisHeader, params, ctx.Payload); err != nil { - return fmt.Errorf("SyncGenesisHeader, contract params deserialize error: %v", err) - } - - log.Trace("SyncGenesisHeader", "sync genesis header, chainID", params.ChainID, "header", hexutil.Encode(params.GenesisHeader)) - - // Get current epoch operator - ok, err := node_manager.CheckConsensusSigns(native, scom.MethodSyncGenesisHeader, ctx.Payload, native.ContractRef().MsgSender()) - if err != nil { - return fmt.Errorf("SyncGenesisHeader, CheckConsensusSigns error: %v", err) - } - if !ok { - log.Trace("SyncGenesisHeader", "check consensus failed", "false") - return nil - } - - var header Header - err = json.Unmarshal(params.GenesisHeader, &header) - if err != nil { - return fmt.Errorf("SyncGenesisHeader, json.Unmarshal header err: %v", err) - } - - headerStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.GENESIS_HEADER), utils.GetUint64Bytes(params.ChainID))) - if err != nil { - return fmt.Errorf("ETHHandler GetHeaderByHeight, get blockHashStore error: %v", err) - } - if headerStore != nil { - return fmt.Errorf("ETHHandler GetHeaderByHeight, genesis header had been initialized") - } - - //block header storage - err = putGenesisBlockHeader(native, header, params.ChainID) - if err != nil { - return fmt.Errorf("ETHHandler SyncGenesisHeader, put blockHeader error: %v", err) - } - - return nil -} - -func (this *ETHHandler) SyncBlockHeader(native *native.NativeContract) error { - headerParams := &scom.SyncBlockHeaderParam{} - { - ctx := native.ContractRef().CurrentContext() - if err := utils.UnpackMethod(scom.ABI, scom.MethodSyncBlockHeader, headerParams, ctx.Payload); err != nil { - return err - } - } - - for _, v := range headerParams.Headers { - var header Header - err := json.Unmarshal(v, &header) - if err != nil { - return fmt.Errorf("SyncBlockHeader, deserialize header err: %v", err) - } - headerHash := header.Hash() - exist, err := IsHeaderExist(native, headerHash.Bytes(), headerParams.ChainID) - if err != nil { - return fmt.Errorf("SyncBlockHeader, check header exist err: %v", err) - } - if exist == true { - log.Warnf("SyncBlockHeader, header has exist. Header: %s", string(v)) - continue - } - // get pre header - parentHeader, parentDifficultySum, err := GetHeaderByHash(native, header.ParentHash.Bytes(), headerParams.ChainID) - if err != nil { - return fmt.Errorf("SyncBlockHeader, get the parent block failed. Error:%s, header: %s", err, string(v)) - } - parentHeaderHash := parentHeader.Hash() - /** - this code source refer to https://github.com/ethereum/go-ethereum/blob/master/consensus/ethash/consensus.go - verify header need to verify: - 1. parent hash - 2. extra size - 3. current time - */ - //verify whether parent hash validity - if !bytes.Equal(parentHeaderHash.Bytes(), header.ParentHash.Bytes()) { - return fmt.Errorf("SyncBlockHeader, parent header is not right. Header: %s", string(v)) - } - //verify whether extra size validity - if uint64(len(header.Extra)) > params.MaximumExtraDataSize { - return fmt.Errorf("SyncBlockHeader, SyncBlockHeader extra-data too long: %d > %d, header: %s", len(header.Extra), params.MaximumExtraDataSize, string(v)) - } - //verify current time validity - if header.Time > uint64(time.Now().Add(allowedFutureBlockTime).Unix()) { - return fmt.Errorf("SyncBlockHeader, verify header time error:%s, checktime: %d, header: %s", consensus.ErrFutureBlock, time.Now().Add(allowedFutureBlockTime).Unix(), string(v)) - } - //verify whether current header time and prevent header time validity - if header.Time <= parentHeader.Time { - return fmt.Errorf("SyncBlockHeader, verify header time fail. Header: %s", string(v)) - } - // Verify that the gas limit is <= 2^63-1 - cap := uint64(0x7fffffffffffffff) - if header.GasLimit > cap { - return fmt.Errorf("SyncBlockHeader, invalid gasLimit: have %v, max %v, header: %s", header.GasLimit, cap, string(v)) - } - // Verify that the gasUsed is <= gasLimit - if header.GasUsed > header.GasLimit { - return fmt.Errorf("SyncBlockHeader, invalid gasUsed: have %d, gasLimit %d, header: %s", header.GasUsed, header.GasLimit, string(v)) - } - if isLondon(&header) { - err = VerifyEip1559Header(parentHeader, &header) - } else { - err = VerifyGaslimit(parentHeader.GasLimit, header.GasLimit) - } - if err != nil { - return fmt.Errorf("SyncBlockHeader, err:%v", err) - } - - //verify difficulty - var expected *big.Int - if isLondon(&header) { - expected = makeDifficultyCalculator(big.NewInt(9700000))(header.Time, parentHeader) - } else { - return fmt.Errorf("SyncBlockHeader, header before london fork is no longer supported") - } - if expected.Cmp(header.Difficulty) != 0 { - return fmt.Errorf("SyncBlockHeader, invalid difficulty: have %v, want %v, header: %s", header.Difficulty, expected, string(v)) - } - // verfify header - err = this.verifyHeader(&header, caches) - if err != nil { - return fmt.Errorf("SyncBlockHeader, verify header error: %v, header: %s", err, string(v)) - } - //block header storage - hederDifficultySum := new(big.Int).Add(header.Difficulty, parentDifficultySum) - err = putBlockHeader(native, header, hederDifficultySum, headerParams.ChainID) - if err != nil { - return fmt.Errorf("SyncGenesisHeader, put blockHeader error: %v, header: %s", err, string(v)) - } - // get current header of main - currentHeader, currentDifficultySum, err := GetCurrentHeader(native, headerParams.ChainID) - if err != nil { - return fmt.Errorf("SyncBlockHeader, get the current block failed. error:%s", err) - } - if bytes.Equal(currentHeader.Hash().Bytes(), header.ParentHash.Bytes()) { - appendHeader2Main(native, header.Number.Uint64(), headerHash, headerParams.ChainID) - } else { - // - if hederDifficultySum.Cmp(currentDifficultySum) > 0 { - RestructChain(native, currentHeader, &header, headerParams.ChainID) - } - } - } - caches.deleteCaches() - return nil -} - -func (this *ETHHandler) SyncCrossChainMsg(native *native.NativeContract) error { - return nil -} - -func (this *ETHHandler) verifyHeader(header *Header, caches *Caches) error { - // try to verfify header - number := header.Number.Uint64() - size := datasetSize(number) - headerHash := HashHeader(header).Bytes() - nonce := header.Nonce.Uint64() - // get seed and seed head - seed := make([]byte, 40) - copy(seed, headerHash) - binary.LittleEndian.PutUint64(seed[32:], nonce) - seed = crypto.Keccak512(seed) - // get mix - mix := make([]uint32, mixBytes/4) - for i := 0; i < len(mix); i++ { - mix[i] = binary.LittleEndian.Uint32(seed[i%16*4:]) - } - // get cache - cache := caches.getCache(number) - if len(cache) <= 1 { - return fmt.Errorf("cache of proof-of-work is not generated!") - } - // get new mix with DAG data - rows := uint32(size / mixBytes) - temp := make([]uint32, len(mix)) - seedHead := binary.LittleEndian.Uint32(seed) - for i := 0; i < loopAccesses; i++ { - parent := fnv(uint32(i)^seedHead, mix[i%len(mix)]) % rows - for j := uint32(0); j < mixBytes/hashBytes; j++ { - xx := lookup(cache, 2*parent+j) - copy(temp[j*hashWords:], xx) - } - fnvHash(mix, temp) - } - // get new mix by compress - for i := 0; i < len(mix); i += 4 { - mix[i/4] = fnv(fnv(fnv(mix[i], mix[i+1]), mix[i+2]), mix[i+3]) - } - mix = mix[:len(mix)/4] - // get digest by compressed mix - digest := make([]byte, common.HashLength) - for i, val := range mix { - binary.LittleEndian.PutUint32(digest[i*4:], val) - } - // get header result hash - result := crypto.Keccak256(append(seed, digest...)) - // Verify the calculated digest against the ones provided in the header - if !bytes.Equal(header.MixDigest[:], digest) { - return fmt.Errorf("invalid mix digest!") - } - // compare result hash with target hash - target := new(big.Int).Div(two256, header.Difficulty) - if new(big.Int).SetBytes(result).Cmp(target) > 0 { - return fmt.Errorf("invalid proof-of-work!") - } - return nil -} - -func HashHeader(header *Header) (hash common.Hash) { - hasher := sha3.NewLegacyKeccak256() - enc := []interface{}{ - header.ParentHash, - header.UncleHash, - header.Coinbase, - header.Root, - header.TxHash, - header.ReceiptHash, - header.Bloom, - header.Difficulty, - header.Number, - header.GasLimit, - header.GasUsed, - header.Time, - header.Extra, - } - if header.BaseFee != nil { - enc = append(enc, header.BaseFee) - } - rlp.Encode(hasher, enc) - hasher.Sum(hash[:0]) - return hash -} - -type hasher func(dest []byte, data []byte) - -func makeHasher(h hash.Hash) hasher { - // sha3.state supports Read to get the sum, use it to avoid the overhead of Sum. - // Read alters the state but we reset the hash before every operation. - type readerHash interface { - hash.Hash - Read([]byte) (int, error) - } - rh, ok := h.(readerHash) - if !ok { - panic("can't find Read method on hash") - } - outputLen := rh.Size() - return func(dest []byte, data []byte) { - rh.Reset() - rh.Write(data) - rh.Read(dest[:outputLen]) - } -} - -func seedHash(block uint64) []byte { - seed := make([]byte, 32) - if block < epochLength { - return seed - } - keccak256 := makeHasher(sha3.NewLegacyKeccak256()) - for i := 0; i < int(block/epochLength); i++ { - keccak256(seed, seed) - } - return seed -} diff --git a/contracts/native/header_sync/eth/types/block.go b/contracts/native/header_sync/eth/types/block.go deleted file mode 100644 index 11fc0da3..00000000 --- a/contracts/native/header_sync/eth/types/block.go +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package types - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" -) - -// Header represents a block header in the Ethereum blockchain. -type Header struct { - ParentHash common.Hash `json:"parentHash" gencodec:"required"` - UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase common.Address `json:"miner" gencodec:"required"` - Root common.Hash `json:"stateRoot" gencodec:"required"` - TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom types.Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *big.Int `json:"difficulty" gencodec:"required"` - Number *big.Int `json:"number" gencodec:"required"` - GasLimit uint64 `json:"gasLimit" gencodec:"required"` - GasUsed uint64 `json:"gasUsed" gencodec:"required"` - Time uint64 `json:"timestamp" gencodec:"required"` - Extra []byte `json:"extraData" gencodec:"required"` - MixDigest common.Hash `json:"mixHash"` - Nonce types.BlockNonce `json:"nonce"` -} - -// field type overrides for gencodec -type headerMarshaling struct { - Difficulty *hexutil.Big - Number *hexutil.Big - GasLimit hexutil.Uint64 - GasUsed hexutil.Uint64 - Time hexutil.Uint64 - Extra hexutil.Bytes - Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON -} - -// Hash returns the block hash of the header, which is simply the keccak256 hash of its -// RLP encoding. -func (h *Header) Hash() common.Hash { - return rlpHash(h) -} - -func rlpHash(x interface{}) (h common.Hash) { - hw := sha3.NewLegacyKeccak256() - rlp.Encode(hw, x) - hw.Sum(h[:0]) - return h -} - -var EmptyUncleHash = rlpHash([]*Header(nil)) - -func CalcUncleHash(uncles []*Header) common.Hash { - if len(uncles) == 0 { - return EmptyUncleHash - } - return rlpHash(uncles) -} diff --git a/contracts/native/header_sync/eth/types/gen_header_json.go b/contracts/native/header_sync/eth/types/gen_header_json.go deleted file mode 100644 index 33cf20c2..00000000 --- a/contracts/native/header_sync/eth/types/gen_header_json.go +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ - -// Code generated by github.com/fjl/gencodec. DO NOT EDIT. - -package types - -import ( - "encoding/json" - "errors" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/types" -) - -var _ = (*headerMarshaling)(nil) - -// MarshalJSON marshals as JSON. -func (h Header) MarshalJSON() ([]byte, error) { - type Header struct { - ParentHash common.Hash `json:"parentHash" gencodec:"required"` - UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase common.Address `json:"miner" gencodec:"required"` - Root common.Hash `json:"stateRoot" gencodec:"required"` - TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom types.Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` - Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Time hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra hexutil.Bytes `json:"extraData" gencodec:"required"` - MixDigest common.Hash `json:"mixHash"` - Nonce types.BlockNonce `json:"nonce"` - Hash common.Hash `json:"hash"` - } - var enc Header - enc.ParentHash = h.ParentHash - enc.UncleHash = h.UncleHash - enc.Coinbase = h.Coinbase - enc.Root = h.Root - enc.TxHash = h.TxHash - enc.ReceiptHash = h.ReceiptHash - enc.Bloom = h.Bloom - enc.Difficulty = (*hexutil.Big)(h.Difficulty) - enc.Number = (*hexutil.Big)(h.Number) - enc.GasLimit = hexutil.Uint64(h.GasLimit) - enc.GasUsed = hexutil.Uint64(h.GasUsed) - enc.Time = hexutil.Uint64(h.Time) - enc.Extra = h.Extra - enc.MixDigest = h.MixDigest - enc.Nonce = h.Nonce - enc.Hash = h.Hash() - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals from JSON. -func (h *Header) UnmarshalJSON(input []byte) error { - type Header struct { - ParentHash *common.Hash `json:"parentHash" gencodec:"required"` - UncleHash *common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase *common.Address `json:"miner" gencodec:"required"` - Root *common.Hash `json:"stateRoot" gencodec:"required"` - TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom *types.Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` - Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Time *hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` - MixDigest *common.Hash `json:"mixHash"` - Nonce *types.BlockNonce `json:"nonce"` - } - var dec Header - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.ParentHash == nil { - return errors.New("missing required field 'parentHash' for Header") - } - h.ParentHash = *dec.ParentHash - if dec.UncleHash == nil { - return errors.New("missing required field 'sha3Uncles' for Header") - } - h.UncleHash = *dec.UncleHash - if dec.Coinbase == nil { - return errors.New("missing required field 'miner' for Header") - } - h.Coinbase = *dec.Coinbase - if dec.Root == nil { - return errors.New("missing required field 'stateRoot' for Header") - } - h.Root = *dec.Root - if dec.TxHash == nil { - return errors.New("missing required field 'transactionsRoot' for Header") - } - h.TxHash = *dec.TxHash - if dec.ReceiptHash == nil { - return errors.New("missing required field 'receiptsRoot' for Header") - } - h.ReceiptHash = *dec.ReceiptHash - if dec.Bloom == nil { - return errors.New("missing required field 'logsBloom' for Header") - } - h.Bloom = *dec.Bloom - if dec.Difficulty == nil { - return errors.New("missing required field 'difficulty' for Header") - } - h.Difficulty = (*big.Int)(dec.Difficulty) - if dec.Number == nil { - return errors.New("missing required field 'number' for Header") - } - h.Number = (*big.Int)(dec.Number) - if dec.GasLimit == nil { - return errors.New("missing required field 'gasLimit' for Header") - } - h.GasLimit = uint64(*dec.GasLimit) - if dec.GasUsed == nil { - return errors.New("missing required field 'gasUsed' for Header") - } - h.GasUsed = uint64(*dec.GasUsed) - if dec.Time == nil { - return errors.New("missing required field 'timestamp' for Header") - } - h.Time = uint64(*dec.Time) - if dec.Extra == nil { - return errors.New("missing required field 'extraData' for Header") - } - h.Extra = *dec.Extra - if dec.MixDigest != nil { - h.MixDigest = *dec.MixDigest - } - if dec.Nonce != nil { - h.Nonce = *dec.Nonce - } - return nil -} diff --git a/contracts/native/header_sync/eth/utils.go b/contracts/native/header_sync/eth/utils.go deleted file mode 100644 index a3d491dc..00000000 --- a/contracts/native/header_sync/eth/utils.go +++ /dev/null @@ -1,1009 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package eth - -import ( - "encoding/binary" - "encoding/json" - "fmt" - "math/big" - "time" - "unsafe" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - scom "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/utils" - cstates "github.com/polynetwork/poly/core/states" -) - -const ( - // source from https://github.com/ethereum/go-ethereum/blob/master/consensus/ethash/consensus.go#L45 - allowedFutureBlockTime = 15 * time.Second // Max time from current time allowed for blocks, before they're considered future blocks - epochLength = 30000 - maxEpoch = 2048 - datasetInitBytes = 1 << 30 - datasetGrowthBytes = 1 << 23 - mixBytes = 128 - loopAccesses = 64 - hashBytes = 64 - hashWords = 16 - datasetParents = 256 - cacheInitBytes = 1 << 24 - cacheGrowthBytes = 1 << 17 - cacheRounds = 3 -) - -type HeaderWithDifficultySum struct { - Header Header `json:"header"` - DifficultySum *big.Int `json:"difficultySum"` -} - -func putGenesisBlockHeader(native *native.NativeContract, blockHeader Header, chainID uint64) error { - contract := utils.HeaderSyncContractAddress - headerWithDifficultySum := HeaderWithDifficultySum{ - Header: blockHeader, - DifficultySum: blockHeader.Difficulty, - } - storeBytes, _ := json.Marshal(&headerWithDifficultySum) - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(scom.GENESIS_HEADER), utils.GetUint64Bytes(chainID)), - cstates.GenRawStorageItem(storeBytes)) - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), blockHeader.Hash().Bytes()), - cstates.GenRawStorageItem(storeBytes)) - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(blockHeader.Number.Uint64())), - cstates.GenRawStorageItem(blockHeader.Hash().Bytes())) - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(scom.CURRENT_HEADER_HEIGHT), - utils.GetUint64Bytes(chainID)), cstates.GenRawStorageItem(utils.GetUint64Bytes(blockHeader.Number.Uint64()))) - scom.NotifyPutHeader(native, chainID, blockHeader.Number.Uint64(), blockHeader.Hash().String()) - return nil -} - -func putBlockHeader(native *native.NativeContract, blockHeader Header, difficultySum *big.Int, chainID uint64) error { - contract := utils.HeaderSyncContractAddress - headerWithDifficultySum := HeaderWithDifficultySum{ - Header: blockHeader, - DifficultySum: difficultySum, - } - storeBytes, _ := json.Marshal(&headerWithDifficultySum) - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), blockHeader.Hash().Bytes()), - cstates.GenRawStorageItem(storeBytes)) - scom.NotifyPutHeader(native, chainID, blockHeader.Number.Uint64(), blockHeader.Hash().String()) - return nil -} -func appendHeader2Main(native *native.NativeContract, height uint64, txhash common.Hash, chainID uint64) error { - contract := utils.HeaderSyncContractAddress - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(height)), - cstates.GenRawStorageItem(txhash.Bytes())) - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(scom.CURRENT_HEADER_HEIGHT), - utils.GetUint64Bytes(chainID)), cstates.GenRawStorageItem(utils.GetUint64Bytes(height))) - scom.NotifyPutHeader(native, chainID, height, txhash.String()) - return nil -} -func GetCurrentHeader(native *native.NativeContract, chainID uint64) (*Header, *big.Int, error) { - height, err := GetCurrentHeaderHeight(native, chainID) - if err != nil { - return nil, big.NewInt(0), err - } - header, difficultySum, err := GetHeaderByHeight(native, height, chainID) - if err != nil { - return nil, big.NewInt(0), err - } - return header, difficultySum, nil -} -func GetCurrentHeaderHeight(native *native.NativeContract, chainID uint64) (uint64, error) { - heightStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.CURRENT_HEADER_HEIGHT), utils.GetUint64Bytes(chainID))) - if err != nil { - return 0, fmt.Errorf("getPrevHeaderHeight error: %v", err) - } - if heightStore == nil { - return 0, fmt.Errorf("getPrevHeaderHeight, heightStore is nil") - } - heightBytes, err := cstates.GetValueFromRawStorageItem(heightStore) - if err != nil { - return 0, fmt.Errorf("GetHeaderByHeight, deserialize headerBytes from raw storage item err:%v", err) - } - return utils.GetBytesUint64(heightBytes), err -} -func GetHeaderByHeight(native *native.NativeContract, height, chainID uint64) (*Header, *big.Int, error) { - latestHeight, err := GetCurrentHeaderHeight(native, chainID) - if err != nil { - return nil, big.NewInt(0), err - } - if height > latestHeight { - return nil, big.NewInt(0), fmt.Errorf("GetHeaderByHeight, height is too big") - } - headerStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(height))) - if err != nil { - return nil, big.NewInt(0), fmt.Errorf("GetHeaderByHeight, get blockHashStore error: %v", err) - } - if headerStore == nil { - return nil, big.NewInt(0), fmt.Errorf("GetHeaderByHeight, can not find any header records") - } - hashBytes, err := cstates.GetValueFromRawStorageItem(headerStore) - if err != nil { - return nil, big.NewInt(0), fmt.Errorf("GetHeaderByHeight, deserialize headerBytes from raw storage item err:%v", err) - } - return GetHeaderByHash(native, hashBytes, chainID) -} - -func GetHeaderByHash(native *native.NativeContract, hash []byte, chainID uint64) (*Header, *big.Int, error) { - headerStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), hash)) - if err != nil { - return nil, big.NewInt(0), fmt.Errorf("GetHeaderByHash, get blockHashStore error: %v", err) - } - if headerStore == nil { - return nil, big.NewInt(0), fmt.Errorf("GetHeaderByHash, can not find any header records") - } - storeBytes, err := cstates.GetValueFromRawStorageItem(headerStore) - if err != nil { - return nil, big.NewInt(0), fmt.Errorf("GetHeaderByHash, deserialize headerBytes from raw storage item err:%v", err) - } - var headerWithDifficultySum HeaderWithDifficultySum - if err := json.Unmarshal(storeBytes, &headerWithDifficultySum); err != nil { - return nil, big.NewInt(0), fmt.Errorf("GetHeaderByHash, deserialize header error: %v", err) - } - return &headerWithDifficultySum.Header, headerWithDifficultySum.DifficultySum, nil -} - -func IsHeaderExist(native *native.NativeContract, hash []byte, chainID uint64) (bool, error) { - headerStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), hash)) - if err != nil { - return false, fmt.Errorf("IsHeaderExist, get blockHashStore error: %v", err) - } - if headerStore == nil { - return false, nil - } else { - return true, nil - } -} -func RestructChain(native *native.NativeContract, current, new *Header, chainID uint64) error { - si, ti := current.Number.Uint64(), new.Number.Uint64() - var err error - if si > ti { - current, _, err = GetHeaderByHeight(native, ti, chainID) - if err != nil { - return fmt.Errorf("RestructChain GetHeaderByHeight height:%d error:%s", ti, err) - } - si = ti - } - newHashs := make([]common.Hash, 0) - for ti > si { - newHashs = append(newHashs, new.Hash()) - new, _, err = GetHeaderByHash(native, new.ParentHash.Bytes(), chainID) - if err != nil { - return fmt.Errorf("RestructChain GetHeaderByHash hash:%x error:%s", new.ParentHash.Bytes(), err) - } - ti-- - } - for current.ParentHash != new.ParentHash { - newHashs = append(newHashs, new.Hash()) - new, _, err = GetHeaderByHash(native, new.ParentHash.Bytes(), chainID) - if err != nil { - return fmt.Errorf("RestructChain GetHeaderByHash hash:%x error:%s", new.ParentHash.Bytes(), err) - } - ti-- - si-- - current, _, err = GetHeaderByHeight(native, si, chainID) - if err != nil { - return fmt.Errorf("RestructChain GetHeaderByHeight height:%d error:%s", ti, err) - } - } - newHashs = append(newHashs, new.Hash()) - for i := len(newHashs) - 1; i >= 0; i-- { - appendHeader2Main(native, ti, newHashs[i], chainID) - ti++ - } - return nil -} - -var two256 = new(big.Int).Exp(big.NewInt(2), big.NewInt(256), big.NewInt(0)) - -func fnv(a, b uint32) uint32 { - return a*0x01000193 ^ b -} -func fnvHash(mix []uint32, data []uint32) { - for i := 0; i < len(mix); i++ { - mix[i] = mix[i]*0x01000193 ^ data[i] - } -} - -func isLittleEndian() bool { - n := uint32(0x01020304) - return *(*byte)(unsafe.Pointer(&n)) == 0x04 -} - -func swap(buffer []byte) { - for i := 0; i < len(buffer); i += 4 { - binary.BigEndian.PutUint32(buffer[i:], binary.LittleEndian.Uint32(buffer[i:])) - } -} - -func datasetSize(value uint64) uint64 { - epoch := int(value / epochLength) - if epoch < maxEpoch { - return datasetSizes[epoch] - } - return calcDatasetSize(epoch) -} - -func calcDatasetSize(epoch int) uint64 { - size := datasetInitBytes + datasetGrowthBytes*uint64(epoch) - mixBytes - for !new(big.Int).SetUint64(size / mixBytes).ProbablyPrime(1) { // Always accurate for n < 2^64 - size -= 2 * mixBytes - } - return size -} -func cacheSize(block uint64) uint64 { - epoch := int(block / epochLength) - if epoch < maxEpoch { - return cacheSizes[epoch] - } - return calcCacheSize(epoch) -} -func calcCacheSize(epoch int) uint64 { - size := cacheInitBytes + cacheGrowthBytes*uint64(epoch) - hashBytes - for !new(big.Int).SetUint64(size / hashBytes).ProbablyPrime(1) { // Always accurate for n < 2^64 - size -= 2 * hashBytes - } - return size -} - -var datasetSizes = [maxEpoch]uint64{ - 1073739904, 1082130304, 1090514816, 1098906752, 1107293056, - 1115684224, 1124070016, 1132461952, 1140849536, 1149232768, - 1157627776, 1166013824, 1174404736, 1182786944, 1191180416, - 1199568512, 1207958912, 1216345216, 1224732032, 1233124736, - 1241513344, 1249902464, 1258290304, 1266673792, 1275067264, - 1283453312, 1291844992, 1300234112, 1308619904, 1317010048, - 1325397376, 1333787776, 1342176128, 1350561664, 1358954368, - 1367339392, 1375731584, 1384118144, 1392507008, 1400897408, - 1409284736, 1417673344, 1426062464, 1434451072, 1442839168, - 1451229056, 1459615616, 1468006016, 1476394112, 1484782976, - 1493171584, 1501559168, 1509948032, 1518337664, 1526726528, - 1535114624, 1543503488, 1551892096, 1560278656, 1568669056, - 1577056384, 1585446272, 1593831296, 1602219392, 1610610304, - 1619000192, 1627386752, 1635773824, 1644164224, 1652555648, - 1660943488, 1669332608, 1677721216, 1686109312, 1694497664, - 1702886272, 1711274624, 1719661184, 1728047744, 1736434816, - 1744829056, 1753218944, 1761606272, 1769995904, 1778382464, - 1786772864, 1795157888, 1803550592, 1811937664, 1820327552, - 1828711552, 1837102976, 1845488768, 1853879936, 1862269312, - 1870656896, 1879048064, 1887431552, 1895825024, 1904212096, - 1912601216, 1920988544, 1929379456, 1937765504, 1946156672, - 1954543232, 1962932096, 1971321728, 1979707264, 1988093056, - 1996487552, 2004874624, 2013262208, 2021653888, 2030039936, - 2038430848, 2046819968, 2055208576, 2063596672, 2071981952, - 2080373632, 2088762752, 2097149056, 2105539712, 2113928576, - 2122315136, 2130700672, 2139092608, 2147483264, 2155872128, - 2164257664, 2172642176, 2181035392, 2189426048, 2197814912, - 2206203008, 2214587264, 2222979712, 2231367808, 2239758208, - 2248145024, 2256527744, 2264922752, 2273312128, 2281701248, - 2290086272, 2298476672, 2306867072, 2315251072, 2323639168, - 2332032128, 2340420224, 2348808064, 2357196416, 2365580416, - 2373966976, 2382363008, 2390748544, 2399139968, 2407530368, - 2415918976, 2424307328, 2432695424, 2441084288, 2449472384, - 2457861248, 2466247808, 2474637184, 2483026816, 2491414144, - 2499803776, 2508191872, 2516582272, 2524970368, 2533359232, - 2541743488, 2550134144, 2558525056, 2566913408, 2575301504, - 2583686528, 2592073856, 2600467328, 2608856192, 2617240448, - 2625631616, 2634022016, 2642407552, 2650796416, 2659188352, - 2667574912, 2675965312, 2684352896, 2692738688, 2701130624, - 2709518464, 2717907328, 2726293376, 2734685056, 2743073152, - 2751462016, 2759851648, 2768232832, 2776625536, 2785017728, - 2793401984, 2801794432, 2810182016, 2818571648, 2826959488, - 2835349376, 2843734144, 2852121472, 2860514432, 2868900992, - 2877286784, 2885676928, 2894069632, 2902451584, 2910843008, - 2919234688, 2927622784, 2936011648, 2944400768, 2952789376, - 2961177728, 2969565568, 2977951616, 2986338944, 2994731392, - 3003120256, 3011508352, 3019895936, 3028287104, 3036675968, - 3045063808, 3053452928, 3061837696, 3070228352, 3078615424, - 3087003776, 3095394944, 3103782272, 3112173184, 3120562048, - 3128944768, 3137339264, 3145725056, 3154109312, 3162505088, - 3170893184, 3179280256, 3187669376, 3196056704, 3204445568, - 3212836736, 3221224064, 3229612928, 3238002304, 3246391168, - 3254778496, 3263165824, 3271556224, 3279944576, 3288332416, - 3296719232, 3305110912, 3313500032, 3321887104, 3330273152, - 3338658944, 3347053184, 3355440512, 3363827072, 3372220288, - 3380608384, 3388997504, 3397384576, 3405774208, 3414163072, - 3422551936, 3430937984, 3439328384, 3447714176, 3456104576, - 3464493952, 3472883584, 3481268864, 3489655168, 3498048896, - 3506434432, 3514826368, 3523213952, 3531603584, 3539987072, - 3548380288, 3556763264, 3565157248, 3573545344, 3581934464, - 3590324096, 3598712704, 3607098752, 3615488384, 3623877248, - 3632265856, 3640646528, 3649043584, 3657430144, 3665821568, - 3674207872, 3682597504, 3690984832, 3699367808, 3707764352, - 3716152448, 3724541056, 3732925568, 3741318016, 3749706368, - 3758091136, 3766481536, 3774872704, 3783260032, 3791650432, - 3800036224, 3808427648, 3816815488, 3825204608, 3833592704, - 3841981568, 3850370432, 3858755968, 3867147904, 3875536256, - 3883920512, 3892313728, 3900702592, 3909087872, 3917478784, - 3925868416, 3934256512, 3942645376, 3951032192, 3959422336, - 3967809152, 3976200064, 3984588416, 3992974976, 4001363584, - 4009751168, 4018141312, 4026530432, 4034911616, 4043308928, - 4051695488, 4060084352, 4068472448, 4076862848, 4085249408, - 4093640576, 4102028416, 4110413696, 4118805632, 4127194496, - 4135583104, 4143971968, 4152360832, 4160746112, 4169135744, - 4177525888, 4185912704, 4194303616, 4202691968, 4211076736, - 4219463552, 4227855488, 4236246656, 4244633728, 4253022848, - 4261412224, 4269799808, 4278184832, 4286578048, 4294962304, - 4303349632, 4311743104, 4320130432, 4328521088, 4336909184, - 4345295488, 4353687424, 4362073472, 4370458496, 4378852736, - 4387238528, 4395630208, 4404019072, 4412407424, 4420790656, - 4429182848, 4437571456, 4445962112, 4454344064, 4462738048, - 4471119232, 4479516544, 4487904128, 4496289664, 4504682368, - 4513068416, 4521459584, 4529846144, 4538232704, 4546619776, - 4555010176, 4563402112, 4571790208, 4580174464, 4588567936, - 4596957056, 4605344896, 4613734016, 4622119808, 4630511488, - 4638898816, 4647287936, 4655675264, 4664065664, 4672451968, - 4680842624, 4689231488, 4697620352, 4706007424, 4714397056, - 4722786176, 4731173248, 4739562368, 4747951744, 4756340608, - 4764727936, 4773114496, 4781504384, 4789894784, 4798283648, - 4806667648, 4815059584, 4823449472, 4831835776, 4840226176, - 4848612224, 4857003392, 4865391488, 4873780096, 4882169728, - 4890557312, 4898946944, 4907333248, 4915722368, 4924110976, - 4932499328, 4940889728, 4949276032, 4957666432, 4966054784, - 4974438016, 4982831488, 4991221376, 4999607168, 5007998848, - 5016386432, 5024763776, 5033164672, 5041544576, 5049941888, - 5058329728, 5066717056, 5075107456, 5083494272, 5091883904, - 5100273536, 5108662144, 5117048192, 5125436032, 5133827456, - 5142215296, 5150605184, 5158993024, 5167382144, 5175769472, - 5184157568, 5192543872, 5200936064, 5209324928, 5217711232, - 5226102656, 5234490496, 5242877312, 5251263872, 5259654016, - 5268040832, 5276434304, 5284819328, 5293209728, 5301598592, - 5309986688, 5318374784, 5326764416, 5335151488, 5343542144, - 5351929472, 5360319872, 5368706944, 5377096576, 5385484928, - 5393871232, 5402263424, 5410650496, 5419040384, 5427426944, - 5435816576, 5444205952, 5452594816, 5460981376, 5469367936, - 5477760896, 5486148736, 5494536832, 5502925952, 5511315328, - 5519703424, 5528089984, 5536481152, 5544869504, 5553256064, - 5561645696, 5570032768, 5578423936, 5586811264, 5595193216, - 5603585408, 5611972736, 5620366208, 5628750464, 5637143936, - 5645528192, 5653921408, 5662310272, 5670694784, 5679082624, - 5687474048, 5695864448, 5704251008, 5712641408, 5721030272, - 5729416832, 5737806208, 5746194304, 5754583936, 5762969984, - 5771358592, 5779748224, 5788137856, 5796527488, 5804911232, - 5813300608, 5821692544, 5830082176, 5838468992, 5846855552, - 5855247488, 5863636096, 5872024448, 5880411008, 5888799872, - 5897186432, 5905576832, 5913966976, 5922352768, 5930744704, - 5939132288, 5947522432, 5955911296, 5964299392, 5972688256, - 5981074304, 5989465472, 5997851008, 6006241408, 6014627968, - 6023015552, 6031408256, 6039796096, 6048185216, 6056574848, - 6064963456, 6073351808, 6081736064, 6090128768, 6098517632, - 6106906496, 6115289216, 6123680896, 6132070016, 6140459648, - 6148849024, 6157237376, 6165624704, 6174009728, 6182403712, - 6190792064, 6199176064, 6207569792, 6215952256, 6224345216, - 6232732544, 6241124224, 6249510272, 6257899136, 6266287744, - 6274676864, 6283065728, 6291454336, 6299843456, 6308232064, - 6316620928, 6325006208, 6333395584, 6341784704, 6350174848, - 6358562176, 6366951296, 6375337856, 6383729536, 6392119168, - 6400504192, 6408895616, 6417283456, 6425673344, 6434059136, - 6442444672, 6450837376, 6459223424, 6467613056, 6476004224, - 6484393088, 6492781952, 6501170048, 6509555072, 6517947008, - 6526336384, 6534725504, 6543112832, 6551500672, 6559888768, - 6568278656, 6576662912, 6585055616, 6593443456, 6601834112, - 6610219648, 6618610304, 6626999168, 6635385472, 6643777408, - 6652164224, 6660552832, 6668941952, 6677330048, 6685719424, - 6694107776, 6702493568, 6710882176, 6719274112, 6727662976, - 6736052096, 6744437632, 6752825984, 6761213824, 6769604224, - 6777993856, 6786383488, 6794770816, 6803158144, 6811549312, - 6819937664, 6828326528, 6836706176, 6845101696, 6853491328, - 6861880448, 6870269312, 6878655104, 6887046272, 6895433344, - 6903822208, 6912212864, 6920596864, 6928988288, 6937377152, - 6945764992, 6954149248, 6962544256, 6970928768, 6979317376, - 6987709312, 6996093824, 7004487296, 7012875392, 7021258624, - 7029652352, 7038038912, 7046427776, 7054818944, 7063207808, - 7071595136, 7079980928, 7088372608, 7096759424, 7105149824, - 7113536896, 7121928064, 7130315392, 7138699648, 7147092352, - 7155479168, 7163865728, 7172249984, 7180648064, 7189036672, - 7197424768, 7205810816, 7214196608, 7222589824, 7230975104, - 7239367552, 7247755904, 7256145536, 7264533376, 7272921472, - 7281308032, 7289694848, 7298088832, 7306471808, 7314864512, - 7323253888, 7331643008, 7340029568, 7348419712, 7356808832, - 7365196672, 7373585792, 7381973888, 7390362752, 7398750592, - 7407138944, 7415528576, 7423915648, 7432302208, 7440690304, - 7449080192, 7457472128, 7465860992, 7474249088, 7482635648, - 7491023744, 7499412608, 7507803008, 7516192384, 7524579968, - 7532967296, 7541358464, 7549745792, 7558134656, 7566524032, - 7574912896, 7583300992, 7591690112, 7600075136, 7608466816, - 7616854912, 7625244544, 7633629824, 7642020992, 7650410368, - 7658794112, 7667187328, 7675574912, 7683961984, 7692349568, - 7700739712, 7709130368, 7717519232, 7725905536, 7734295424, - 7742683264, 7751069056, 7759457408, 7767849088, 7776238208, - 7784626816, 7793014912, 7801405312, 7809792128, 7818179968, - 7826571136, 7834957184, 7843347328, 7851732352, 7860124544, - 7868512384, 7876902016, 7885287808, 7893679744, 7902067072, - 7910455936, 7918844288, 7927230848, 7935622784, 7944009344, - 7952400256, 7960786048, 7969176704, 7977565312, 7985953408, - 7994339968, 8002730368, 8011119488, 8019508096, 8027896192, - 8036285056, 8044674688, 8053062272, 8061448832, 8069838464, - 8078227328, 8086616704, 8095006592, 8103393664, 8111783552, - 8120171392, 8128560256, 8136949376, 8145336704, 8153726848, - 8162114944, 8170503296, 8178891904, 8187280768, 8195669632, - 8204058496, 8212444544, 8220834176, 8229222272, 8237612672, - 8246000768, 8254389376, 8262775168, 8271167104, 8279553664, - 8287944064, 8296333184, 8304715136, 8313108352, 8321497984, - 8329885568, 8338274432, 8346663296, 8355052928, 8363441536, - 8371828352, 8380217984, 8388606592, 8396996224, 8405384576, - 8413772672, 8422161536, 8430549376, 8438939008, 8447326592, - 8455715456, 8464104832, 8472492928, 8480882048, 8489270656, - 8497659776, 8506045312, 8514434944, 8522823808, 8531208832, - 8539602304, 8547990656, 8556378752, 8564768384, 8573154176, - 8581542784, 8589933952, 8598322816, 8606705024, 8615099264, - 8623487872, 8631876992, 8640264064, 8648653952, 8657040256, - 8665430656, 8673820544, 8682209152, 8690592128, 8698977152, - 8707374464, 8715763328, 8724151424, 8732540032, 8740928384, - 8749315712, 8757704576, 8766089344, 8774480768, 8782871936, - 8791260032, 8799645824, 8808034432, 8816426368, 8824812928, - 8833199488, 8841591424, 8849976448, 8858366336, 8866757248, - 8875147136, 8883532928, 8891923328, 8900306816, 8908700288, - 8917088384, 8925478784, 8933867392, 8942250368, 8950644608, - 8959032704, 8967420544, 8975809664, 8984197504, 8992584064, - 9000976256, 9009362048, 9017752448, 9026141312, 9034530688, - 9042917504, 9051307904, 9059694208, 9068084864, 9076471424, - 9084861824, 9093250688, 9101638528, 9110027648, 9118416512, - 9126803584, 9135188096, 9143581312, 9151969664, 9160356224, - 9168747136, 9177134464, 9185525632, 9193910144, 9202302848, - 9210690688, 9219079552, 9227465344, 9235854464, 9244244864, - 9252633472, 9261021824, 9269411456, 9277799296, 9286188928, - 9294574208, 9302965888, 9311351936, 9319740032, 9328131968, - 9336516736, 9344907392, 9353296768, 9361685888, 9370074752, - 9378463616, 9386849408, 9395239808, 9403629184, 9412016512, - 9420405376, 9428795008, 9437181568, 9445570688, 9453960832, - 9462346624, 9470738048, 9479121536, 9487515008, 9495903616, - 9504289664, 9512678528, 9521067904, 9529456256, 9537843584, - 9546233728, 9554621312, 9563011456, 9571398784, 9579788672, - 9588178304, 9596567168, 9604954496, 9613343104, 9621732992, - 9630121856, 9638508416, 9646898816, 9655283584, 9663675776, - 9672061312, 9680449664, 9688840064, 9697230464, 9705617536, - 9714003584, 9722393984, 9730772608, 9739172224, 9747561088, - 9755945344, 9764338816, 9772726144, 9781116544, 9789503872, - 9797892992, 9806282624, 9814670464, 9823056512, 9831439232, - 9839833984, 9848224384, 9856613504, 9865000576, 9873391232, - 9881772416, 9890162816, 9898556288, 9906940544, 9915333248, - 9923721088, 9932108672, 9940496512, 9948888448, 9957276544, - 9965666176, 9974048384, 9982441088, 9990830464, 9999219584, - 10007602816, 10015996544, 10024385152, 10032774016, 10041163648, - 10049548928, 10057940096, 10066329472, 10074717824, 10083105152, - 10091495296, 10099878784, 10108272256, 10116660608, 10125049216, - 10133437312, 10141825664, 10150213504, 10158601088, 10166991232, - 10175378816, 10183766144, 10192157312, 10200545408, 10208935552, - 10217322112, 10225712768, 10234099328, 10242489472, 10250876032, - 10259264896, 10267656064, 10276042624, 10284429184, 10292820352, - 10301209472, 10309598848, 10317987712, 10326375296, 10334763392, - 10343153536, 10351541632, 10359930752, 10368318592, 10376707456, - 10385096576, 10393484672, 10401867136, 10410262144, 10418647424, - 10427039104, 10435425664, 10443810176, 10452203648, 10460589952, - 10468982144, 10477369472, 10485759104, 10494147712, 10502533504, - 10510923392, 10519313536, 10527702656, 10536091264, 10544478592, - 10552867712, 10561255808, 10569642368, 10578032768, 10586423168, - 10594805632, 10603200128, 10611588992, 10619976064, 10628361344, - 10636754048, 10645143424, 10653531776, 10661920384, 10670307968, - 10678696832, 10687086464, 10695475072, 10703863168, 10712246144, - 10720639616, 10729026688, 10737414784, 10745806208, 10754190976, - 10762581376, 10770971264, 10779356288, 10787747456, 10796135552, - 10804525184, 10812915584, 10821301888, 10829692288, 10838078336, - 10846469248, 10854858368, 10863247232, 10871631488, 10880023424, - 10888412032, 10896799616, 10905188992, 10913574016, 10921964672, - 10930352768, 10938742912, 10947132544, 10955518592, 10963909504, - 10972298368, 10980687488, 10989074816, 10997462912, 11005851776, - 11014241152, 11022627712, 11031017344, 11039403904, 11047793024, - 11056184704, 11064570752, 11072960896, 11081343872, 11089737856, - 11098128256, 11106514816, 11114904448, 11123293568, 11131680128, - 11140065152, 11148458368, 11156845696, 11165236864, 11173624192, - 11182013824, 11190402688, 11198790784, 11207179136, 11215568768, - 11223957376, 11232345728, 11240734592, 11249122688, 11257511296, - 11265899648, 11274285952, 11282675584, 11291065472, 11299452544, - 11307842432, 11316231296, 11324616832, 11333009024, 11341395584, - 11349782656, 11358172288, 11366560384, 11374950016, 11383339648, - 11391721856, 11400117376, 11408504192, 11416893568, 11425283456, - 11433671552, 11442061184, 11450444672, 11458837888, 11467226752, - 11475611776, 11484003968, 11492392064, 11500780672, 11509169024, - 11517550976, 11525944448, 11534335616, 11542724224, 11551111808, - 11559500672, 11567890304, 11576277376, 11584667008, 11593056128, - 11601443456, 11609830016, 11618221952, 11626607488, 11634995072, - 11643387776, 11651775104, 11660161664, 11668552576, 11676940928, - 11685330304, 11693718656, 11702106496, 11710496128, 11718882688, - 11727273088, 11735660416, 11744050048, 11752437376, 11760824704, - 11769216128, 11777604736, 11785991296, 11794381952, 11802770048, - 11811157888, 11819548544, 11827932544, 11836324736, 11844713344, - 11853100928, 11861486464, 11869879936, 11878268032, 11886656896, - 11895044992, 11903433088, 11911822976, 11920210816, 11928600448, - 11936987264, 11945375872, 11953761152, 11962151296, 11970543488, - 11978928512, 11987320448, 11995708288, 12004095104, 12012486272, - 12020875136, 12029255552, 12037652096, 12046039168, 12054429568, - 12062813824, 12071206528, 12079594624, 12087983744, 12096371072, - 12104759936, 12113147264, 12121534592, 12129924992, 12138314624, - 12146703232, 12155091584, 12163481216, 12171864704, 12180255872, - 12188643968, 12197034112, 12205424512, 12213811328, 12222199424, - 12230590336, 12238977664, 12247365248, 12255755392, 12264143488, - 12272531584, 12280920448, 12289309568, 12297694592, 12306086528, - 12314475392, 12322865024, 12331253632, 12339640448, 12348029312, - 12356418944, 12364805248, 12373196672, 12381580928, 12389969024, - 12398357632, 12406750592, 12415138432, 12423527552, 12431916416, - 12440304512, 12448692352, 12457081216, 12465467776, 12473859968, - 12482245504, 12490636672, 12499025536, 12507411584, 12515801728, - 12524190592, 12532577152, 12540966272, 12549354368, 12557743232, - 12566129536, 12574523264, 12582911872, 12591299456, 12599688064, - 12608074624, 12616463488, 12624845696, 12633239936, 12641631616, - 12650019968, 12658407296, 12666795136, 12675183232, 12683574656, - 12691960192, 12700350592, 12708740224, 12717128576, 12725515904, - 12733906816, 12742295168, 12750680192, 12759071872, 12767460736, - 12775848832, 12784236928, 12792626816, 12801014656, 12809404288, - 12817789312, 12826181504, 12834568832, 12842954624, 12851345792, - 12859732352, 12868122496, 12876512128, 12884901248, 12893289088, - 12901672832, 12910067584, 12918455168, 12926842496, 12935232896, - 12943620736, 12952009856, 12960396928, 12968786816, 12977176192, - 12985563776, 12993951104, 13002341504, 13010730368, 13019115392, - 13027506304, 13035895168, 13044272512, 13052673152, 13061062528, - 13069446272, 13077838976, 13086227072, 13094613632, 13103000192, - 13111393664, 13119782528, 13128157568, 13136559232, 13144945024, - 13153329536, 13161724288, 13170111872, 13178502784, 13186884736, - 13195279744, 13203667072, 13212057472, 13220445824, 13228832128, - 13237221248, 13245610624, 13254000512, 13262388352, 13270777472, - 13279166336, 13287553408, 13295943296, 13304331904, 13312719488, - 13321108096, 13329494656, 13337885824, 13346274944, 13354663808, - 13363051136, 13371439232, 13379825024, 13388210816, 13396605056, - 13404995456, 13413380224, 13421771392, 13430159744, 13438546048, - 13446937216, 13455326848, 13463708288, 13472103808, 13480492672, - 13488875648, 13497269888, 13505657728, 13514045312, 13522435712, - 13530824576, 13539210112, 13547599232, 13555989376, 13564379008, - 13572766336, 13581154432, 13589544832, 13597932928, 13606320512, - 13614710656, 13623097472, 13631477632, 13639874944, 13648264064, - 13656652928, 13665041792, 13673430656, 13681818496, 13690207616, - 13698595712, 13706982272, 13715373184, 13723762048, 13732150144, - 13740536704, 13748926592, 13757316224, 13765700992, 13774090112, - 13782477952, 13790869376, 13799259008, 13807647872, 13816036736, - 13824425344, 13832814208, 13841202304, 13849591424, 13857978752, - 13866368896, 13874754688, 13883145344, 13891533184, 13899919232, - 13908311168, 13916692096, 13925085056, 13933473152, 13941866368, - 13950253696, 13958643584, 13967032192, 13975417216, 13983807616, - 13992197504, 14000582272, 14008973696, 14017363072, 14025752192, - 14034137984, 14042528384, 14050918016, 14059301504, 14067691648, - 14076083584, 14084470144, 14092852352, 14101249664, 14109635968, - 14118024832, 14126407552, 14134804352, 14143188608, 14151577984, - 14159968384, 14168357248, 14176741504, 14185127296, 14193521024, - 14201911424, 14210301824, 14218685056, 14227067264, 14235467392, - 14243855488, 14252243072, 14260630144, 14269021568, 14277409408, - 14285799296, 14294187904, 14302571392, 14310961792, 14319353728, - 14327738752, 14336130944, 14344518784, 14352906368, 14361296512, - 14369685376, 14378071424, 14386462592, 14394848128, 14403230848, - 14411627392, 14420013952, 14428402304, 14436793472, 14445181568, - 14453569664, 14461959808, 14470347904, 14478737024, 14487122816, - 14495511424, 14503901824, 14512291712, 14520677504, 14529064832, - 14537456768, 14545845632, 14554234496, 14562618496, 14571011456, - 14579398784, 14587789184, 14596172672, 14604564608, 14612953984, - 14621341312, 14629724288, 14638120832, 14646503296, 14654897536, - 14663284864, 14671675264, 14680061056, 14688447616, 14696835968, - 14705228416, 14713616768, 14722003328, 14730392192, 14738784128, - 14747172736, 14755561088, 14763947648, 14772336512, 14780725376, - 14789110144, 14797499776, 14805892736, 14814276992, 14822670208, - 14831056256, 14839444352, 14847836032, 14856222848, 14864612992, - 14872997504, 14881388672, 14889775744, 14898165376, 14906553472, - 14914944896, 14923329664, 14931721856, 14940109696, 14948497024, - 14956887424, 14965276544, 14973663616, 14982053248, 14990439808, - 14998830976, 15007216768, 15015605888, 15023995264, 15032385152, - 15040768384, 15049154944, 15057549184, 15065939072, 15074328448, - 15082715008, 15091104128, 15099493504, 15107879296, 15116269184, - 15124659584, 15133042304, 15141431936, 15149824384, 15158214272, - 15166602368, 15174991232, 15183378304, 15191760512, 15200154496, - 15208542592, 15216931712, 15225323392, 15233708416, 15242098048, - 15250489216, 15258875264, 15267265408, 15275654528, 15284043136, - 15292431488, 15300819584, 15309208192, 15317596544, 15325986176, - 15334374784, 15342763648, 15351151744, 15359540608, 15367929728, - 15376318336, 15384706432, 15393092992, 15401481856, 15409869952, - 15418258816, 15426649984, 15435037568, 15443425664, 15451815296, - 15460203392, 15468589184, 15476979328, 15485369216, 15493755776, - 15502146944, 15510534272, 15518924416, 15527311232, 15535699072, - 15544089472, 15552478336, 15560866688, 15569254528, 15577642624, - 15586031488, 15594419072, 15602809472, 15611199104, 15619586432, - 15627975296, 15636364928, 15644753792, 15653141888, 15661529216, - 15669918848, 15678305152, 15686696576, 15695083136, 15703474048, - 15711861632, 15720251264, 15728636288, 15737027456, 15745417088, - 15753804928, 15762194048, 15770582656, 15778971008, 15787358336, - 15795747712, 15804132224, 15812523392, 15820909696, 15829300096, - 15837691264, 15846071936, 15854466944, 15862855808, 15871244672, - 15879634816, 15888020608, 15896409728, 15904799104, 15913185152, - 15921577088, 15929966464, 15938354816, 15946743424, 15955129472, - 15963519872, 15971907968, 15980296064, 15988684928, 15997073024, - 16005460864, 16013851264, 16022241152, 16030629248, 16039012736, - 16047406976, 16055794816, 16064181376, 16072571264, 16080957824, - 16089346688, 16097737856, 16106125184, 16114514816, 16122904192, - 16131292544, 16139678848, 16148066944, 16156453504, 16164839552, - 16173236096, 16181623424, 16190012032, 16198401152, 16206790528, - 16215177344, 16223567744, 16231956352, 16240344704, 16248731008, - 16257117824, 16265504384, 16273898624, 16282281856, 16290668672, - 16299064192, 16307449216, 16315842176, 16324230016, 16332613504, - 16341006464, 16349394304, 16357783168, 16366172288, 16374561664, - 16382951296, 16391337856, 16399726208, 16408116352, 16416505472, - 16424892032, 16433282176, 16441668224, 16450058624, 16458448768, - 16466836864, 16475224448, 16483613056, 16492001408, 16500391808, - 16508779648, 16517166976, 16525555328, 16533944192, 16542330752, - 16550719616, 16559110528, 16567497088, 16575888512, 16584274816, - 16592665472, 16601051008, 16609442944, 16617832064, 16626218624, - 16634607488, 16642996096, 16651385728, 16659773824, 16668163712, - 16676552576, 16684938112, 16693328768, 16701718144, 16710095488, - 16718492288, 16726883968, 16735272832, 16743661184, 16752049792, - 16760436608, 16768827008, 16777214336, 16785599104, 16793992832, - 16802381696, 16810768768, 16819151744, 16827542656, 16835934848, - 16844323712, 16852711552, 16861101952, 16869489536, 16877876864, - 16886265728, 16894653056, 16903044736, 16911431296, 16919821696, - 16928207488, 16936592768, 16944987776, 16953375616, 16961763968, - 16970152832, 16978540928, 16986929536, 16995319168, 17003704448, - 17012096896, 17020481152, 17028870784, 17037262208, 17045649536, - 17054039936, 17062426496, 17070814336, 17079205504, 17087592064, - 17095978112, 17104369024, 17112759424, 17121147776, 17129536384, - 17137926016, 17146314368, 17154700928, 17163089792, 17171480192, - 17179864192, 17188256896, 17196644992, 17205033856, 17213423488, - 17221811072, 17230198912, 17238588032, 17246976896, 17255360384, - 17263754624, 17272143232, 17280530048, 17288918912, 17297309312, - 17305696384, 17314085504, 17322475136, 17330863744, 17339252096, - 17347640192, 17356026496, 17364413824, 17372796544, 17381190016, - 17389583488, 17397972608, 17406360704, 17414748544, 17423135872, - 17431527296, 17439915904, 17448303232, 17456691584, 17465081728, - 17473468288, 17481857408, 17490247552, 17498635904, 17507022464, - 17515409024, 17523801728, 17532189824, 17540577664, 17548966016, - 17557353344, 17565741184, 17574131584, 17582519168, 17590907008, - 17599296128, 17607687808, 17616076672, 17624455808, 17632852352, - 17641238656, 17649630848, 17658018944, 17666403968, 17674794112, - 17683178368, 17691573376, 17699962496, 17708350592, 17716739968, - 17725126528, 17733517184, 17741898112, 17750293888, 17758673024, - 17767070336, 17775458432, 17783848832, 17792236928, 17800625536, - 17809012352, 17817402752, 17825785984, 17834178944, 17842563968, - 17850955648, 17859344512, 17867732864, 17876119424, 17884511872, - 17892900224, 17901287296, 17909677696, 17918058112, 17926451072, - 17934843776, 17943230848, 17951609216, 17960008576, 17968397696, - 17976784256, 17985175424, 17993564032, 18001952128, 18010339712, - 18018728576, 18027116672, 18035503232, 18043894144, 18052283264, - 18060672128, 18069056384, 18077449856, 18085837184, 18094225792, - 18102613376, 18111004544, 18119388544, 18127781248, 18136170368, - 18144558976, 18152947328, 18161336192, 18169724288, 18178108544, - 18186498944, 18194886784, 18203275648, 18211666048, 18220048768, - 18228444544, 18236833408, 18245220736} - -var cacheSizes = [maxEpoch]uint64{ - 16776896, 16907456, 17039296, 17170112, 17301056, 17432512, 17563072, - 17693888, 17824192, 17955904, 18087488, 18218176, 18349504, 18481088, - 18611392, 18742336, 18874304, 19004224, 19135936, 19267264, 19398208, - 19529408, 19660096, 19791424, 19922752, 20053952, 20184896, 20315968, - 20446912, 20576576, 20709184, 20840384, 20971072, 21102272, 21233216, - 21364544, 21494848, 21626816, 21757376, 21887552, 22019392, 22151104, - 22281536, 22412224, 22543936, 22675264, 22806464, 22935872, 23068096, - 23198272, 23330752, 23459008, 23592512, 23723968, 23854912, 23986112, - 24116672, 24247616, 24378688, 24509504, 24640832, 24772544, 24903488, - 25034432, 25165376, 25296704, 25427392, 25558592, 25690048, 25820096, - 25951936, 26081728, 26214208, 26345024, 26476096, 26606656, 26737472, - 26869184, 26998208, 27131584, 27262528, 27393728, 27523904, 27655744, - 27786688, 27917888, 28049344, 28179904, 28311488, 28441792, 28573504, - 28700864, 28835648, 28966208, 29096768, 29228608, 29359808, 29490752, - 29621824, 29752256, 29882816, 30014912, 30144448, 30273728, 30406976, - 30538432, 30670784, 30799936, 30932672, 31063744, 31195072, 31325248, - 31456192, 31588288, 31719232, 31850432, 31981504, 32110784, 32243392, - 32372672, 32505664, 32636608, 32767808, 32897344, 33029824, 33160768, - 33289664, 33423296, 33554368, 33683648, 33816512, 33947456, 34076992, - 34208704, 34340032, 34471744, 34600256, 34734016, 34864576, 34993984, - 35127104, 35258176, 35386688, 35518528, 35650624, 35782336, 35910976, - 36044608, 36175808, 36305728, 36436672, 36568384, 36699968, 36830656, - 36961984, 37093312, 37223488, 37355072, 37486528, 37617472, 37747904, - 37879232, 38009792, 38141888, 38272448, 38403392, 38535104, 38660672, - 38795584, 38925632, 39059264, 39190336, 39320768, 39452096, 39581632, - 39713984, 39844928, 39974848, 40107968, 40238144, 40367168, 40500032, - 40631744, 40762816, 40894144, 41023552, 41155904, 41286208, 41418304, - 41547712, 41680448, 41811904, 41942848, 42073792, 42204992, 42334912, - 42467008, 42597824, 42729152, 42860096, 42991552, 43122368, 43253696, - 43382848, 43515712, 43646912, 43777088, 43907648, 44039104, 44170432, - 44302144, 44433344, 44564288, 44694976, 44825152, 44956864, 45088448, - 45219008, 45350464, 45481024, 45612608, 45744064, 45874496, 46006208, - 46136768, 46267712, 46399424, 46529344, 46660672, 46791488, 46923328, - 47053504, 47185856, 47316928, 47447872, 47579072, 47710144, 47839936, - 47971648, 48103232, 48234176, 48365248, 48496192, 48627136, 48757312, - 48889664, 49020736, 49149248, 49283008, 49413824, 49545152, 49675712, - 49807168, 49938368, 50069056, 50200256, 50331584, 50462656, 50593472, - 50724032, 50853952, 50986048, 51117632, 51248576, 51379904, 51510848, - 51641792, 51773248, 51903296, 52035136, 52164032, 52297664, 52427968, - 52557376, 52690112, 52821952, 52952896, 53081536, 53213504, 53344576, - 53475776, 53608384, 53738816, 53870528, 54000832, 54131776, 54263744, - 54394688, 54525248, 54655936, 54787904, 54918592, 55049152, 55181248, - 55312064, 55442752, 55574336, 55705024, 55836224, 55967168, 56097856, - 56228672, 56358592, 56490176, 56621888, 56753728, 56884928, 57015488, - 57146816, 57278272, 57409216, 57540416, 57671104, 57802432, 57933632, - 58064576, 58195264, 58326976, 58457408, 58588864, 58720192, 58849984, - 58981696, 59113024, 59243456, 59375552, 59506624, 59637568, 59768512, - 59897792, 60030016, 60161984, 60293056, 60423872, 60554432, 60683968, - 60817216, 60948032, 61079488, 61209664, 61341376, 61471936, 61602752, - 61733696, 61865792, 61996736, 62127808, 62259136, 62389568, 62520512, - 62651584, 62781632, 62910784, 63045056, 63176128, 63307072, 63438656, - 63569216, 63700928, 63831616, 63960896, 64093888, 64225088, 64355392, - 64486976, 64617664, 64748608, 64879424, 65009216, 65142464, 65273792, - 65402816, 65535424, 65666752, 65797696, 65927744, 66060224, 66191296, - 66321344, 66453056, 66584384, 66715328, 66846656, 66977728, 67108672, - 67239104, 67370432, 67501888, 67631296, 67763776, 67895104, 68026304, - 68157248, 68287936, 68419264, 68548288, 68681408, 68811968, 68942912, - 69074624, 69205568, 69337024, 69467584, 69599168, 69729472, 69861184, - 69989824, 70122944, 70253888, 70385344, 70515904, 70647232, 70778816, - 70907968, 71040832, 71171648, 71303104, 71432512, 71564992, 71695168, - 71826368, 71958464, 72089536, 72219712, 72350144, 72482624, 72613568, - 72744512, 72875584, 73006144, 73138112, 73268672, 73400128, 73530944, - 73662272, 73793344, 73924544, 74055104, 74185792, 74316992, 74448832, - 74579392, 74710976, 74841664, 74972864, 75102784, 75233344, 75364544, - 75497024, 75627584, 75759296, 75890624, 76021696, 76152256, 76283072, - 76414144, 76545856, 76676672, 76806976, 76937792, 77070016, 77200832, - 77331392, 77462464, 77593664, 77725376, 77856448, 77987776, 78118336, - 78249664, 78380992, 78511424, 78642496, 78773056, 78905152, 79033664, - 79166656, 79297472, 79429568, 79560512, 79690816, 79822784, 79953472, - 80084672, 80214208, 80346944, 80477632, 80608576, 80740288, 80870848, - 81002048, 81133504, 81264448, 81395648, 81525952, 81657536, 81786304, - 81919808, 82050112, 82181312, 82311616, 82443968, 82573376, 82705984, - 82835776, 82967744, 83096768, 83230528, 83359552, 83491264, 83622464, - 83753536, 83886016, 84015296, 84147776, 84277184, 84409792, 84540608, - 84672064, 84803008, 84934336, 85065152, 85193792, 85326784, 85458496, - 85589312, 85721024, 85851968, 85982656, 86112448, 86244416, 86370112, - 86506688, 86637632, 86769344, 86900672, 87031744, 87162304, 87293632, - 87424576, 87555392, 87687104, 87816896, 87947968, 88079168, 88211264, - 88341824, 88473152, 88603712, 88735424, 88862912, 88996672, 89128384, - 89259712, 89390272, 89521984, 89652544, 89783872, 89914816, 90045376, - 90177088, 90307904, 90438848, 90569152, 90700096, 90832832, 90963776, - 91093696, 91223744, 91356992, 91486784, 91618496, 91749824, 91880384, - 92012224, 92143552, 92273344, 92405696, 92536768, 92666432, 92798912, - 92926016, 93060544, 93192128, 93322816, 93453632, 93583936, 93715136, - 93845056, 93977792, 94109504, 94240448, 94371776, 94501184, 94632896, - 94764224, 94895552, 95023424, 95158208, 95287744, 95420224, 95550016, - 95681216, 95811904, 95943872, 96075328, 96203584, 96337856, 96468544, - 96599744, 96731072, 96860992, 96992576, 97124288, 97254848, 97385536, - 97517248, 97647808, 97779392, 97910464, 98041408, 98172608, 98303168, - 98434496, 98565568, 98696768, 98827328, 98958784, 99089728, 99220928, - 99352384, 99482816, 99614272, 99745472, 99876416, 100007104, - 100138048, 100267072, 100401088, 100529984, 100662592, 100791872, - 100925248, 101056064, 101187392, 101317952, 101449408, 101580608, - 101711296, 101841728, 101973824, 102104896, 102235712, 102366016, - 102498112, 102628672, 102760384, 102890432, 103021888, 103153472, - 103284032, 103415744, 103545152, 103677248, 103808576, 103939648, - 104070976, 104201792, 104332736, 104462528, 104594752, 104725952, - 104854592, 104988608, 105118912, 105247808, 105381184, 105511232, - 105643072, 105774784, 105903296, 106037056, 106167872, 106298944, - 106429504, 106561472, 106691392, 106822592, 106954304, 107085376, - 107216576, 107346368, 107478464, 107609792, 107739712, 107872192, - 108003136, 108131392, 108265408, 108396224, 108527168, 108657344, - 108789568, 108920384, 109049792, 109182272, 109312576, 109444928, - 109572928, 109706944, 109837888, 109969088, 110099648, 110230976, - 110362432, 110492992, 110624704, 110755264, 110886208, 111017408, - 111148864, 111279296, 111410752, 111541952, 111673024, 111803456, - 111933632, 112066496, 112196416, 112328512, 112457792, 112590784, - 112715968, 112852672, 112983616, 113114944, 113244224, 113376448, - 113505472, 113639104, 113770304, 113901376, 114031552, 114163264, - 114294592, 114425536, 114556864, 114687424, 114818624, 114948544, - 115080512, 115212224, 115343296, 115473472, 115605184, 115736128, - 115867072, 115997248, 116128576, 116260288, 116391488, 116522944, - 116652992, 116784704, 116915648, 117046208, 117178304, 117308608, - 117440192, 117569728, 117701824, 117833024, 117964096, 118094656, - 118225984, 118357312, 118489024, 118617536, 118749632, 118882112, - 119012416, 119144384, 119275328, 119406016, 119537344, 119668672, - 119798464, 119928896, 120061376, 120192832, 120321728, 120454336, - 120584512, 120716608, 120848192, 120979136, 121109056, 121241408, - 121372352, 121502912, 121634752, 121764416, 121895744, 122027072, - 122157632, 122289088, 122421184, 122550592, 122682944, 122813888, - 122945344, 123075776, 123207488, 123338048, 123468736, 123600704, - 123731264, 123861952, 123993664, 124124608, 124256192, 124386368, - 124518208, 124649024, 124778048, 124911296, 125041088, 125173696, - 125303744, 125432896, 125566912, 125696576, 125829056, 125958592, - 126090304, 126221248, 126352832, 126483776, 126615232, 126746432, - 126876608, 127008704, 127139392, 127270336, 127401152, 127532224, - 127663552, 127794752, 127925696, 128055232, 128188096, 128319424, - 128449856, 128581312, 128712256, 128843584, 128973632, 129103808, - 129236288, 129365696, 129498944, 129629888, 129760832, 129892288, - 130023104, 130154048, 130283968, 130416448, 130547008, 130678336, - 130807616, 130939456, 131071552, 131202112, 131331776, 131464384, - 131594048, 131727296, 131858368, 131987392, 132120256, 132250816, - 132382528, 132513728, 132644672, 132774976, 132905792, 133038016, - 133168832, 133299392, 133429312, 133562048, 133692992, 133823296, - 133954624, 134086336, 134217152, 134348608, 134479808, 134607296, - 134741056, 134872384, 135002944, 135134144, 135265472, 135396544, - 135527872, 135659072, 135787712, 135921472, 136052416, 136182848, - 136313792, 136444864, 136576448, 136707904, 136837952, 136970048, - 137099584, 137232064, 137363392, 137494208, 137625536, 137755712, - 137887424, 138018368, 138149824, 138280256, 138411584, 138539584, - 138672832, 138804928, 138936128, 139066688, 139196864, 139328704, - 139460032, 139590208, 139721024, 139852864, 139984576, 140115776, - 140245696, 140376512, 140508352, 140640064, 140769856, 140902336, - 141032768, 141162688, 141294016, 141426496, 141556544, 141687488, - 141819584, 141949888, 142080448, 142212544, 142342336, 142474432, - 142606144, 142736192, 142868288, 142997824, 143129408, 143258944, - 143392448, 143523136, 143653696, 143785024, 143916992, 144045632, - 144177856, 144309184, 144440768, 144570688, 144701888, 144832448, - 144965056, 145096384, 145227584, 145358656, 145489856, 145620928, - 145751488, 145883072, 146011456, 146144704, 146275264, 146407232, - 146538176, 146668736, 146800448, 146931392, 147062336, 147193664, - 147324224, 147455936, 147586624, 147717056, 147848768, 147979456, - 148110784, 148242368, 148373312, 148503232, 148635584, 148766144, - 148897088, 149028416, 149159488, 149290688, 149420224, 149551552, - 149683136, 149814976, 149943616, 150076352, 150208064, 150338624, - 150470464, 150600256, 150732224, 150862784, 150993088, 151125952, - 151254976, 151388096, 151519168, 151649728, 151778752, 151911104, - 152042944, 152174144, 152304704, 152435648, 152567488, 152698816, - 152828992, 152960576, 153091648, 153222976, 153353792, 153484096, - 153616192, 153747008, 153878336, 154008256, 154139968, 154270912, - 154402624, 154533824, 154663616, 154795712, 154926272, 155057984, - 155188928, 155319872, 155450816, 155580608, 155712064, 155843392, - 155971136, 156106688, 156237376, 156367424, 156499264, 156630976, - 156761536, 156892352, 157024064, 157155008, 157284416, 157415872, - 157545536, 157677248, 157810496, 157938112, 158071744, 158203328, - 158334656, 158464832, 158596288, 158727616, 158858048, 158988992, - 159121216, 159252416, 159381568, 159513152, 159645632, 159776192, - 159906496, 160038464, 160169536, 160300352, 160430656, 160563008, - 160693952, 160822208, 160956352, 161086784, 161217344, 161349184, - 161480512, 161611456, 161742272, 161873216, 162002752, 162135872, - 162266432, 162397888, 162529216, 162660032, 162790976, 162922048, - 163052096, 163184576, 163314752, 163446592, 163577408, 163707968, - 163839296, 163969984, 164100928, 164233024, 164364224, 164494912, - 164625856, 164756672, 164887616, 165019072, 165150016, 165280064, - 165412672, 165543104, 165674944, 165805888, 165936832, 166067648, - 166198336, 166330048, 166461248, 166591552, 166722496, 166854208, - 166985408, 167116736, 167246656, 167378368, 167508416, 167641024, - 167771584, 167903168, 168034112, 168164032, 168295744, 168427456, - 168557632, 168688448, 168819136, 168951616, 169082176, 169213504, - 169344832, 169475648, 169605952, 169738048, 169866304, 169999552, - 170131264, 170262464, 170393536, 170524352, 170655424, 170782016, - 170917696, 171048896, 171179072, 171310784, 171439936, 171573184, - 171702976, 171835072, 171966272, 172097216, 172228288, 172359232, - 172489664, 172621376, 172747712, 172883264, 173014208, 173144512, - 173275072, 173407424, 173539136, 173669696, 173800768, 173931712, - 174063424, 174193472, 174325696, 174455744, 174586816, 174718912, - 174849728, 174977728, 175109696, 175242688, 175374272, 175504832, - 175636288, 175765696, 175898432, 176028992, 176159936, 176291264, - 176422592, 176552512, 176684864, 176815424, 176946496, 177076544, - 177209152, 177340096, 177470528, 177600704, 177731648, 177864256, - 177994816, 178126528, 178257472, 178387648, 178518464, 178650176, - 178781888, 178912064, 179044288, 179174848, 179305024, 179436736, - 179568448, 179698496, 179830208, 179960512, 180092608, 180223808, - 180354752, 180485696, 180617152, 180748096, 180877504, 181009984, - 181139264, 181272512, 181402688, 181532608, 181663168, 181795136, - 181926592, 182057536, 182190016, 182320192, 182451904, 182582336, - 182713792, 182843072, 182976064, 183107264, 183237056, 183368384, - 183494848, 183631424, 183762752, 183893824, 184024768, 184154816, - 184286656, 184417984, 184548928, 184680128, 184810816, 184941248, - 185072704, 185203904, 185335616, 185465408, 185596352, 185727296, - 185859904, 185989696, 186121664, 186252992, 186383552, 186514112, - 186645952, 186777152, 186907328, 187037504, 187170112, 187301824, - 187429184, 187562048, 187693504, 187825472, 187957184, 188087104, - 188218304, 188349376, 188481344, 188609728, 188743616, 188874304, - 189005248, 189136448, 189265088, 189396544, 189528128, 189660992, - 189791936, 189923264, 190054208, 190182848, 190315072, 190447424, - 190577984, 190709312, 190840768, 190971328, 191102656, 191233472, - 191364032, 191495872, 191626816, 191758016, 191888192, 192020288, - 192148928, 192282176, 192413504, 192542528, 192674752, 192805952, - 192937792, 193068608, 193198912, 193330496, 193462208, 193592384, - 193723456, 193854272, 193985984, 194116672, 194247232, 194379712, - 194508352, 194641856, 194772544, 194900672, 195035072, 195166016, - 195296704, 195428032, 195558592, 195690304, 195818176, 195952576, - 196083392, 196214336, 196345792, 196476736, 196607552, 196739008, - 196869952, 197000768, 197130688, 197262784, 197394368, 197523904, - 197656384, 197787584, 197916608, 198049472, 198180544, 198310208, - 198442432, 198573632, 198705088, 198834368, 198967232, 199097792, - 199228352, 199360192, 199491392, 199621696, 199751744, 199883968, - 200014016, 200146624, 200276672, 200408128, 200540096, 200671168, - 200801984, 200933312, 201062464, 201194944, 201326144, 201457472, - 201588544, 201719744, 201850816, 201981632, 202111552, 202244032, - 202374464, 202505152, 202636352, 202767808, 202898368, 203030336, - 203159872, 203292608, 203423296, 203553472, 203685824, 203816896, - 203947712, 204078272, 204208192, 204341056, 204472256, 204603328, - 204733888, 204864448, 204996544, 205125568, 205258304, 205388864, - 205517632, 205650112, 205782208, 205913536, 206044736, 206176192, - 206307008, 206434496, 206569024, 206700224, 206831168, 206961856, - 207093056, 207223616, 207355328, 207486784, 207616832, 207749056, - 207879104, 208010048, 208141888, 208273216, 208404032, 208534336, - 208666048, 208796864, 208927424, 209059264, 209189824, 209321792, - 209451584, 209582656, 209715136, 209845568, 209976896, 210106432, - 210239296, 210370112, 210501568, 210630976, 210763712, 210894272, - 211024832, 211156672, 211287616, 211418176, 211549376, 211679296, - 211812032, 211942592, 212074432, 212204864, 212334016, 212467648, - 212597824, 212727616, 212860352, 212991424, 213120832, 213253952, - 213385024, 213515584, 213645632, 213777728, 213909184, 214040128, - 214170688, 214302656, 214433728, 214564544, 214695232, 214826048, - 214956992, 215089088, 215219776, 215350592, 215482304, 215613248, - 215743552, 215874752, 216005312, 216137024, 216267328, 216399296, - 216530752, 216661696, 216790592, 216923968, 217054528, 217183168, - 217316672, 217448128, 217579072, 217709504, 217838912, 217972672, - 218102848, 218233024, 218364736, 218496832, 218627776, 218759104, - 218888896, 219021248, 219151936, 219281728, 219413056, 219545024, - 219675968, 219807296, 219938624, 220069312, 220200128, 220331456, - 220461632, 220592704, 220725184, 220855744, 220987072, 221117888, - 221249216, 221378368, 221510336, 221642048, 221772736, 221904832, - 222031808, 222166976, 222297536, 222428992, 222559936, 222690368, - 222820672, 222953152, 223083968, 223213376, 223345984, 223476928, - 223608512, 223738688, 223869376, 224001472, 224132672, 224262848, - 224394944, 224524864, 224657344, 224788288, 224919488, 225050432, - 225181504, 225312704, 225443776, 225574592, 225704768, 225834176, - 225966784, 226097216, 226229824, 226360384, 226491712, 226623424, - 226754368, 226885312, 227015104, 227147456, 227278528, 227409472, - 227539904, 227669696, 227802944, 227932352, 228065216, 228196288, - 228326464, 228457792, 228588736, 228720064, 228850112, 228981056, - 229113152, 229243328, 229375936, 229505344, 229636928, 229769152, - 229894976, 230030272, 230162368, 230292416, 230424512, 230553152, - 230684864, 230816704, 230948416, 231079616, 231210944, 231342016, - 231472448, 231603776, 231733952, 231866176, 231996736, 232127296, - 232259392, 232388672, 232521664, 232652608, 232782272, 232914496, - 233043904, 233175616, 233306816, 233438528, 233569984, 233699776, - 233830592, 233962688, 234092224, 234221888, 234353984, 234485312, - 234618304, 234749888, 234880832, 235011776, 235142464, 235274048, - 235403456, 235535936, 235667392, 235797568, 235928768, 236057152, - 236190272, 236322752, 236453312, 236583616, 236715712, 236846528, - 236976448, 237108544, 237239104, 237371072, 237501632, 237630784, - 237764416, 237895232, 238026688, 238157632, 238286912, 238419392, - 238548032, 238681024, 238812608, 238941632, 239075008, 239206336, - 239335232, 239466944, 239599168, 239730496, 239861312, 239992384, - 240122816, 240254656, 240385856, 240516928, 240647872, 240779072, - 240909632, 241040704, 241171904, 241302848, 241433408, 241565248, - 241696192, 241825984, 241958848, 242088256, 242220224, 242352064, - 242481856, 242611648, 242744896, 242876224, 243005632, 243138496, - 243268672, 243400384, 243531712, 243662656, 243793856, 243924544, - 244054592, 244187072, 244316608, 244448704, 244580032, 244710976, - 244841536, 244972864, 245104448, 245233984, 245365312, 245497792, - 245628736, 245759936, 245889856, 246021056, 246152512, 246284224, - 246415168, 246545344, 246675904, 246808384, 246939584, 247070144, - 247199552, 247331648, 247463872, 247593536, 247726016, 247857088, - 247987648, 248116928, 248249536, 248380736, 248512064, 248643008, - 248773312, 248901056, 249036608, 249167552, 249298624, 249429184, - 249560512, 249692096, 249822784, 249954112, 250085312, 250215488, - 250345792, 250478528, 250608704, 250739264, 250870976, 251002816, - 251133632, 251263552, 251395136, 251523904, 251657792, 251789248, - 251919424, 252051392, 252182464, 252313408, 252444224, 252575552, - 252706624, 252836032, 252968512, 253099712, 253227584, 253361728, - 253493056, 253623488, 253754432, 253885504, 254017216, 254148032, - 254279488, 254410432, 254541376, 254672576, 254803264, 254933824, - 255065792, 255196736, 255326528, 255458752, 255589952, 255721408, - 255851072, 255983296, 256114624, 256244416, 256374208, 256507712, - 256636096, 256768832, 256900544, 257031616, 257162176, 257294272, - 257424448, 257555776, 257686976, 257818432, 257949632, 258079552, - 258211136, 258342464, 258473408, 258603712, 258734656, 258867008, - 258996544, 259127744, 259260224, 259391296, 259522112, 259651904, - 259784384, 259915328, 260045888, 260175424, 260308544, 260438336, - 260570944, 260700992, 260832448, 260963776, 261092672, 261226304, - 261356864, 261487936, 261619648, 261750592, 261879872, 262011968, - 262143424, 262274752, 262404416, 262537024, 262667968, 262799296, - 262928704, 263061184, 263191744, 263322944, 263454656, 263585216, - 263716672, 263847872, 263978944, 264108608, 264241088, 264371648, - 264501184, 264632768, 264764096, 264895936, 265024576, 265158464, - 265287488, 265418432, 265550528, 265681216, 265813312, 265943488, - 266075968, 266206144, 266337728, 266468032, 266600384, 266731072, - 266862272, 266993344, 267124288, 267255616, 267386432, 267516992, - 267648704, 267777728, 267910592, 268040512, 268172096, 268302784, - 268435264, 268566208, 268696256, 268828096, 268959296, 269090368, - 269221312, 269352256, 269482688, 269614784, 269745856, 269876416, - 270007616, 270139328, 270270272, 270401216, 270531904, 270663616, - 270791744, 270924736, 271056832, 271186112, 271317184, 271449536, - 271580992, 271711936, 271843136, 271973056, 272105408, 272236352, - 272367296, 272498368, 272629568, 272759488, 272891456, 273022784, - 273153856, 273284672, 273415616, 273547072, 273677632, 273808448, - 273937088, 274071488, 274200896, 274332992, 274463296, 274595392, - 274726208, 274857536, 274988992, 275118656, 275250496, 275382208, - 275513024, 275643968, 275775296, 275906368, 276037184, 276167872, - 276297664, 276429376, 276560576, 276692672, 276822976, 276955072, - 277085632, 277216832, 277347008, 277478848, 277609664, 277740992, - 277868608, 278002624, 278134336, 278265536, 278395328, 278526784, - 278657728, 278789824, 278921152, 279052096, 279182912, 279313088, - 279443776, 279576256, 279706048, 279838528, 279969728, 280099648, - 280230976, 280361408, 280493632, 280622528, 280755392, 280887104, - 281018176, 281147968, 281278912, 281411392, 281542592, 281673152, - 281803712, 281935552, 282066496, 282197312, 282329024, 282458816, - 282590272, 282720832, 282853184, 282983744, 283115072, 283246144, - 283377344, 283508416, 283639744, 283770304, 283901504, 284032576, - 284163136, 284294848, 284426176, 284556992, 284687296, 284819264, - 284950208, 285081536} diff --git a/contracts/native/header_sync/heco/header_sync.go b/contracts/native/header_sync/heco/header_sync.go deleted file mode 100644 index 34d03911..00000000 --- a/contracts/native/header_sync/heco/header_sync.go +++ /dev/null @@ -1,834 +0,0 @@ -/* - * Copyright (C) 2020 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package heco - -import ( - "encoding/json" - "errors" - "fmt" - "io" - "math/big" - "time" - - ecommon "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - scom "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - cstates "github.com/polynetwork/poly/core/states" - "golang.org/x/crypto/sha3" -) - -// only for testing purpose to check if heco chain can be normal back after fork happens -var TestFlagNoCheckHecoHeaderSig bool - -// Handler ... -type Handler struct { -} - -// NewHandler ... -func NewHecoHandler() *Handler { - return &Handler{} -} - -// GenesisHeader ... -type GenesisHeader struct { - Header eth.Header - PrevValidators []HeightAndValidators -} - -// SyncGenesisHeader ... -func (h *Handler) SyncGenesisHeader(native *native.NativeContract) (err error) { - ctx := native.ContractRef().CurrentContext() - params := &scom.SyncGenesisHeaderParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodSyncGenesisHeader, params, ctx.Payload); err != nil { - return fmt.Errorf("SyncGenesisHeader, contract params deserialize error: %v", err) - } - - // Get current epoch operator - ok, err := node_manager.CheckConsensusSigns(native, scom.MethodSyncGenesisHeader, ctx.Payload, native.ContractRef().MsgSender()) - if err != nil { - return fmt.Errorf("SyncGenesisHeader, CheckConsensusSigns error: %v", err) - } - if !ok { - return nil - } - - // can only store once - stored, err := isGenesisStored(native, params) - if err != nil { - return fmt.Errorf("heco Handler SyncGenesisHeader, isGenesisStored error: %v", err) - } - if stored { - return fmt.Errorf("heco Handler SyncGenesisHeader, genesis had been initialized") - } - - var genesis GenesisHeader - err = json.Unmarshal(params.GenesisHeader, &genesis) - if err != nil { - return fmt.Errorf("heco Handler SyncGenesisHeader, deserialize GenesisHeader err: %v", err) - } - - signersBytes := len(genesis.Header.Extra) - extraVanity - extraSeal - if signersBytes == 0 || signersBytes%ecommon.AddressLength != 0 { - return fmt.Errorf("invalid signer list, signersBytes:%d", signersBytes) - } - - if len(genesis.PrevValidators) != 1 { - return fmt.Errorf("invalid PrevValidators") - } - if genesis.Header.Number.Cmp(genesis.PrevValidators[0].Height) <= 0 { - return fmt.Errorf("invalid height orders") - } - validators, err := ParseValidators(genesis.Header.Extra[extraVanity : extraVanity+signersBytes]) - if err != nil { - return - } - genesis.PrevValidators = append([]HeightAndValidators{ - {Height: genesis.Header.Number, Validators: validators}, - }, genesis.PrevValidators...) - - err = storeGenesis(native, params, &genesis) - if err != nil { - return fmt.Errorf("heco Handler SyncGenesisHeader, storeGenesis error: %v", err) - } - - return -} - -func isGenesisStored(native *native.NativeContract, params *scom.SyncGenesisHeaderParam) (stored bool, err error) { - genesis, err := getGenesis(native, params.ChainID) - if err != nil { - return - } - - stored = genesis != nil - return -} - -func getGenesis(native *native.NativeContract, chainID uint64) (genesisHeader *GenesisHeader, err error) { - - genesisBytes, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.GENESIS_HEADER), utils.GetUint64Bytes(chainID))) - if err != nil { - err = fmt.Errorf("getGenesis, GetCacheDB err:%v", err) - return - } - - if genesisBytes == nil { - return - } - - genesisBytes, err = cstates.GetValueFromRawStorageItem(genesisBytes) - if err != nil { - err = fmt.Errorf("getGenesis, GetValueFromRawStorageItem err:%v", err) - return - } - - { - genesisHeader = &GenesisHeader{} - err = json.Unmarshal(genesisBytes, &genesisHeader) - if err != nil { - err = fmt.Errorf("getGenesis, json.Unmarshal err:%v", err) - return - } - } - - return -} - -func storeGenesis(native *native.NativeContract, params *scom.SyncGenesisHeaderParam, genesisHeader *GenesisHeader) (err error) { - - genesisBytes, err := json.Marshal(genesisHeader) - if err != nil { - return - } - - native.GetCacheDB().Put( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.GENESIS_HEADER), utils.GetUint64Bytes(params.ChainID)), - cstates.GenRawStorageItem(genesisBytes)) - - headerWithSum := &HeaderWithDifficultySum{Header: &genesisHeader.Header, DifficultySum: genesisHeader.Header.Difficulty} - - err = putHeaderWithSum(native, params.ChainID, headerWithSum) - if err != nil { - return - } - - putCanonicalHeight(native, params.ChainID, genesisHeader.Header.Number.Uint64()) - putCanonicalHash(native, params.ChainID, genesisHeader.Header.Number.Uint64(), genesisHeader.Header.Hash()) - - scom.NotifyPutHeader(native, params.ChainID, genesisHeader.Header.Number.Uint64(), genesisHeader.Header.Hash().Hex()) - return -} - -// ExtraInfo ... -type ExtraInfo struct { - ChainID *big.Int // chainId of heco chain, testnet: 256, mainnet: 128 - Period uint64 -} - -// Context ... -type Context struct { - ExtraInfo ExtraInfo - ChainID uint64 -} - -// HeaderWithChainID ... -type HeaderWithChainID struct { - Header *HeaderWithDifficultySum - ChainID uint64 -} - -// HeaderWithDifficultySum ... -type HeaderWithDifficultySum struct { - Header *eth.Header `json:"header"` - DifficultySum *big.Int `json:"difficultySum"` - EpochParentHash *ecommon.Hash `json:"epochParentHash"` -} - -// SyncBlockHeader ... -// Will verify header coming from congress consensus -// https://github.com/HuobiGroup/huobi-eco-chain/tree/master/consensus/congress -func (h *Handler) SyncBlockHeader(native *native.NativeContract) error { - headerParams := &scom.SyncBlockHeaderParam{} - { - ctx := native.ContractRef().CurrentContext() - if err := utils.UnpackMethod(scom.ABI, scom.MethodSyncBlockHeader, headerParams, ctx.Payload); err != nil { - return err - } - } - - side, err := side_chain_manager.GetSideChain(native, headerParams.ChainID) - if err != nil { - return fmt.Errorf("heco Handler SyncBlockHeader, GetSideChain error: %v", err) - } - if side == nil { - return fmt.Errorf("heco Hander SyncBlockHeader, GetSideChain info nil") - } - var extraInfo ExtraInfo - err = json.Unmarshal(side.ExtraInfo, &extraInfo) - if err != nil { - return fmt.Errorf("heco Handler SyncBlockHeader, ExtraInfo Unmarshal error: %v", err) - } - - ctx := &Context{ExtraInfo: extraInfo, ChainID: headerParams.ChainID} - - for _, v := range headerParams.Headers { - var header eth.Header - err := json.Unmarshal(v, &header) - if err != nil { - return fmt.Errorf("heco Handler SyncBlockHeader, deserialize header err: %v", err) - } - headerHash := header.Hash() - - exist, err := isHeaderExist(native, headerHash, ctx) - if err != nil { - return fmt.Errorf("heco Handler SyncBlockHeader, isHeaderExist headerHash err: %v", err) - } - if exist { - log.Warnf("heco Handler SyncBlockHeader, header has exist. Header: %s", string(v)) - continue - } - - parentExist, err := isHeaderExist(native, header.ParentHash, ctx) - if err != nil { - return fmt.Errorf("heco Handler SyncBlockHeader, isHeaderExist ParentHash err: %v", err) - } - if !parentExist { - return fmt.Errorf("heco Handler SyncBlockHeader, parent header not exist. Header: %s", string(v)) - } - - signer, err := verifySignature(native, &header, ctx) - if err != nil { - return fmt.Errorf("heco Handler SyncBlockHeader, verifySignature err: %v", err) - } - - // get prev epochs, also checking recent limit - phv, _, lastSeenHeight, err := getPrevHeightAndValidators(native, &header, ctx) - if err != nil { - return fmt.Errorf("heco Handler SyncBlockHeader, getPrevHeightAndValidators err: %v", err) - } - - inTurnHV := phv - - if lastSeenHeight > 0 { - limit := int64(len(inTurnHV.Validators) / 2) - if header.Number.Int64() <= lastSeenHeight+limit { - return fmt.Errorf("heco Handler SyncBlockHeader, RecentlySigned, lastSeenHeight:%d currentHeight:%d #V:%d", lastSeenHeight, header.Number.Int64(), len(inTurnHV.Validators)) - } - } - - indexInTurn := int(header.Number.Uint64()) % len(inTurnHV.Validators) - if indexInTurn < 0 { - return fmt.Errorf("indexInTurn is negative:%d inTurnHV.Height:%d header.Number:%d", indexInTurn, inTurnHV.Height.Int64(), header.Number.Int64()) - } - valid := false - // fmt.Println("signer", signer) - for idx, v := range inTurnHV.Validators { - if v == signer { - valid = true - if indexInTurn == idx { - if header.Difficulty.Cmp(diffInTurn) != 0 { - return fmt.Errorf("invalid difficulty, got %v expect %v index:%v", header.Difficulty.Int64(), diffInTurn.Int64(), int(indexInTurn)%len(inTurnHV.Validators)) - } - } else { - if header.Difficulty.Cmp(diffNoTurn) != 0 { - return fmt.Errorf("invalid difficulty, got %v expect %v index:%v", header.Difficulty.Int64(), diffNoTurn.Int64(), int(indexInTurn)%len(inTurnHV.Validators)) - } - } - } - } - if !valid { - return fmt.Errorf("heco Handler SyncBlockHeader, invalid signer") - } - - err = addHeader(native, &header, phv, ctx) - if err != nil { - return fmt.Errorf("heco Handler SyncBlockHeader, addHeader err: %v", err) - } - - scom.NotifyPutHeader(native, headerParams.ChainID, header.Number.Uint64(), header.Hash().Hex()) - } - return nil -} - -func isHeaderExist(native *native.NativeContract, headerHash ecommon.Hash, ctx *Context) (bool, error) { - headerStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(ctx.ChainID), headerHash.Bytes())) - if err != nil { - return false, fmt.Errorf("heco Handler isHeaderExist error: %v", err) - } - - return headerStore != nil, nil -} - -func verifySignature(native *native.NativeContract, header *eth.Header, ctx *Context) (signer ecommon.Address, err error) { - return verifyHeader(native, header, ctx) -} - -// GetCanonicalHeight ... -func GetCanonicalHeight(native *native.NativeContract, chainID uint64) (height uint64, err error) { - heightStore, err := native.GetCacheDB().Get( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.CURRENT_HEADER_HEIGHT), utils.GetUint64Bytes(chainID))) - if err != nil { - err = fmt.Errorf("heco Handler GetCanonicalHeight err:%v", err) - return - } - - storeBytes, err := cstates.GetValueFromRawStorageItem(heightStore) - if err != nil { - err = fmt.Errorf("heco Handler GetCanonicalHeight, GetValueFromRawStorageItem err:%v", err) - return - } - - height = utils.GetBytesUint64(storeBytes) - return -} - -// GetCanonicalHeader ... -func GetCanonicalHeader(native *native.NativeContract, chainID uint64, height uint64) (headerWithSum *HeaderWithDifficultySum, err error) { - hash, err := getCanonicalHash(native, chainID, height) - if err != nil { - return - } - - if hash == (ecommon.Hash{}) { - return - } - - headerWithSum, err = getHeader(native, hash, chainID) - return -} - -func deleteCanonicalHash(native *native.NativeContract, chainID uint64, height uint64) { - native.GetCacheDB().Delete(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(height))) -} - -func getCanonicalHash(native *native.NativeContract, chainID uint64, height uint64) (hash ecommon.Hash, err error) { - hashBytesStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(height))) - if err != nil { - return - } - - if hashBytesStore == nil { - return - } - - hashBytes, err := cstates.GetValueFromRawStorageItem(hashBytesStore) - if err != nil { - err = fmt.Errorf("heco Handler getCanonicalHash, GetValueFromRawStorageItem err:%v", err) - return - } - - hash = ecommon.BytesToHash(hashBytes) - return -} - -func putCanonicalHash(native *native.NativeContract, chainID uint64, height uint64, hash ecommon.Hash) { - native.GetCacheDB().Put(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(height)), - cstates.GenRawStorageItem(hash.Bytes())) -} - -func putHeaderWithSum(native *native.NativeContract, chainID uint64, headerWithSum *HeaderWithDifficultySum) (err error) { - - headerBytes, err := json.Marshal(headerWithSum) - if err != nil { - return - } - - native.GetCacheDB().Put( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), headerWithSum.Header.Hash().Bytes()), - cstates.GenRawStorageItem(headerBytes)) - return -} - -func putCanonicalHeight(native *native.NativeContract, chainID uint64, height uint64) { - native.GetCacheDB().Put( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.CURRENT_HEADER_HEIGHT), utils.GetUint64Bytes(chainID)), - cstates.GenRawStorageItem(utils.GetUint64Bytes(uint64(height)))) -} - -func addHeader(native *native.NativeContract, header *eth.Header, phv *HeightAndValidators, ctx *Context) (err error) { - - parentHeader, err := getHeader(native, header.ParentHash, ctx.ChainID) - if err != nil { - return - } - - cheight, err := GetCanonicalHeight(native, ctx.ChainID) - if err != nil { - return - } - cheader, err := GetCanonicalHeader(native, ctx.ChainID, cheight) - if err != nil { - return - } - if cheader == nil { - err = fmt.Errorf("getCanonicalHeader returns nil") - return - } - - localTd := cheader.DifficultySum - externTd := new(big.Int).Add(header.Difficulty, parentHeader.DifficultySum) - - headerWithSum := &HeaderWithDifficultySum{Header: header, DifficultySum: externTd, EpochParentHash: phv.Hash} - err = putHeaderWithSum(native, ctx.ChainID, headerWithSum) - if err != nil { - return - } - - if externTd.Cmp(localTd) > 0 { - // Delete any canonical number assignments above the new head - var headerWithSum *HeaderWithDifficultySum - for i := header.Number.Uint64() + 1; ; i++ { - headerWithSum, err = GetCanonicalHeader(native, ctx.ChainID, i) - if err != nil { - return - } - if headerWithSum == nil { - break - } - - deleteCanonicalHash(native, ctx.ChainID, i) - } - - // Overwrite any stale canonical number assignments - var ( - hash ecommon.Hash - headHeader *HeaderWithDifficultySum - ) - cheight := header.Number.Uint64() - 1 - headHash := header.ParentHash - - for { - hash, err = getCanonicalHash(native, ctx.ChainID, cheight) - if err != nil { - return - } - if hash == headHash { - break - } - - putCanonicalHash(native, ctx.ChainID, cheight, headHash) - headHeader, err = getHeader(native, headHash, ctx.ChainID) - if err != nil { - return - } - headHash = headHeader.Header.ParentHash - cheight-- - } - - // Extend the canonical chain with the new header - putCanonicalHash(native, ctx.ChainID, header.Number.Uint64(), header.Hash()) - putCanonicalHeight(native, ctx.ChainID, header.Number.Uint64()) - } - - return nil -} - -// HeightAndValidators ... -type HeightAndValidators struct { - Height *big.Int - Validators []ecommon.Address - Hash *ecommon.Hash -} - -func getPrevHeightAndValidators(native *native.NativeContract, header *eth.Header, ctx *Context) (phv, pphv *HeightAndValidators, lastSeenHeight int64, err error) { - - genesis, err := getGenesis(native, ctx.ChainID) - if err != nil { - err = fmt.Errorf("heco Handler getGenesis error: %v", err) - return - } - - if genesis == nil { - err = fmt.Errorf("heco Handler genesis not set") - return - } - - genesisHeaderHash := genesis.Header.Hash() - if header.Hash() == genesisHeaderHash { - err = fmt.Errorf("genesis header should not be synced again") - return - } - - lastSeenHeight = -1 - targetCoinbase := header.Coinbase - if header.ParentHash == genesisHeaderHash { - if genesis.Header.Coinbase == targetCoinbase { - lastSeenHeight = genesis.Header.Number.Int64() - } - - phv = &genesis.PrevValidators[0] - phv.Hash = &genesisHeaderHash - pphv = &genesis.PrevValidators[1] - return - } - - prevHeaderWithSum, err := getHeader(native, header.ParentHash, ctx.ChainID) - if err != nil { - err = fmt.Errorf("heco Handler getHeader error: %v", err) - return - } - - if prevHeaderWithSum.Header.Coinbase == targetCoinbase { - lastSeenHeight = prevHeaderWithSum.Header.Number.Int64() - } else { - nextRecentParentHash := prevHeaderWithSum.Header.ParentHash - defer func() { - if err == nil { - maxV := len(phv.Validators) - if maxV < len(pphv.Validators) { - maxV = len(pphv.Validators) - } - maxLimit := maxV / 2 - for i := 0; i < maxLimit-1; i++ { - prevHeaderWithSum, err := getHeader(native, nextRecentParentHash, ctx.ChainID) - if err != nil { - err = fmt.Errorf("heco Handler getHeader error: %v", err) - return - } - if prevHeaderWithSum.Header.Coinbase == targetCoinbase { - lastSeenHeight = prevHeaderWithSum.Header.Number.Int64() - return - } - - if nextRecentParentHash == genesisHeaderHash { - return - } - nextRecentParentHash = prevHeaderWithSum.Header.ParentHash - } - } - }() - } - - var ( - validators []ecommon.Address - nextParentHash ecommon.Hash - ) - - currentPV := &phv - - for { - - if len(prevHeaderWithSum.Header.Extra) > extraVanity+extraSeal { - validators, err = ParseValidators(prevHeaderWithSum.Header.Extra[extraVanity : len(prevHeaderWithSum.Header.Extra)-extraSeal]) - if err != nil { - err = fmt.Errorf("heco Handler ParseValidators error: %v", err) - return - } - *currentPV = &HeightAndValidators{ - Height: prevHeaderWithSum.Header.Number, - Validators: validators, - } - switch *currentPV { - case phv: - hash := prevHeaderWithSum.Header.Hash() - phv.Hash = &hash - currentPV = &pphv - case pphv: - return - default: - err = fmt.Errorf("bug in heco Handler") - return - } - } - - nextParentHash = prevHeaderWithSum.Header.ParentHash - if prevHeaderWithSum.EpochParentHash != nil { - nextParentHash = *prevHeaderWithSum.EpochParentHash - } - - if nextParentHash == genesisHeaderHash { - switch *currentPV { - case phv: - phv = &genesis.PrevValidators[0] - phv.Hash = &genesisHeaderHash - pphv = &genesis.PrevValidators[1] - case pphv: - pphv = &genesis.PrevValidators[0] - default: - err = fmt.Errorf("bug in heco Handler") - return - } - return - } - - prevHeaderWithSum, err = getHeader(native, nextParentHash, ctx.ChainID) - if err != nil { - err = fmt.Errorf("heco Handler getHeader error: %v", err) - return - } - - } -} - -func getHeader(native *native.NativeContract, hash ecommon.Hash, chainID uint64) (headerWithSum *HeaderWithDifficultySum, err error) { - - headerStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), hash.Bytes())) - if err != nil { - return nil, fmt.Errorf("heco Handler getHeader error: %v", err) - } - if headerStore == nil { - return nil, fmt.Errorf("heco Handler getHeader, can not find any header records") - } - storeBytes, err := cstates.GetValueFromRawStorageItem(headerStore) - if err != nil { - return nil, fmt.Errorf("heco Handler getHeader, deserialize headerBytes from raw storage item err:%v", err) - } - headerWithSum = &HeaderWithDifficultySum{} - if err := json.Unmarshal(storeBytes, &headerWithSum); err != nil { - return nil, fmt.Errorf("heco Handler getHeader, deserialize header error: %v", err) - } - - return -} - -var ( - inMemoryHeaders = 400 - inMemoryGenesis = 40 - extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity - extraSeal = crypto.SignatureLength // Fixed number of extra-data suffix bytes reserved for signer seal - uncleHash = types.CalcUncleHash(nil) // Always Keccak256(RLP([])) as uncles are meaningless outside of PoW. - diffInTurn = big.NewInt(2) // Block difficulty for in-turn signatures - diffNoTurn = big.NewInt(1) // Block difficulty for out-of-turn signatures - - GasLimitBoundDivisor uint64 = 256 // The bound divisor of the gas limit, used in update calculations. -) - -func verifyHeader(native *native.NativeContract, header *eth.Header, ctx *Context) (signer ecommon.Address, err error) { - - // Don't waste time checking blocks from the future - if header.Time > uint64(time.Now().Unix()) { - err = errors.New("block in the future") - return - } - - // Check that the extra-data contains both the vanity and signature - if len(header.Extra) < extraVanity { - err = errors.New("extra-data 32 byte vanity prefix missing") - return - } - if len(header.Extra) < extraVanity+extraSeal { - err = errors.New("extra-data 65 byte signature suffix missing") - return - } - - // Ensure that the extra-data contains a signer list on checkpoint, but none otherwise - signersBytes := len(header.Extra) - extraVanity - extraSeal - - if signersBytes%ecommon.AddressLength != 0 { - err = errors.New("invalid signer list") - return - } - - // Ensure that the mix digest is zero as we don't have fork protection currently - if header.MixDigest != (ecommon.Hash{}) { - err = errors.New("non-zero mix digest") - return - } - - // Ensure that the block doesn't contain any uncles which are meaningless in PoA - if header.UncleHash != uncleHash { - err = errors.New("non empty uncle hash") - return - } - - // Ensure that the block's difficulty is meaningful (may not be correct at this point) - if header.Difficulty == nil || (header.Difficulty.Cmp(diffInTurn) != 0 && header.Difficulty.Cmp(diffNoTurn) != 0) { - err = errors.New("invalid difficulty") - return - } - - // All basic checks passed, verify cascading fields - return verifyCascadingFields(native, header, ctx) -} - -func verifyCascadingFields(native *native.NativeContract, header *eth.Header, ctx *Context) (signer ecommon.Address, err error) { - - number := header.Number.Uint64() - - parent, err := getHeader(native, header.ParentHash, ctx.ChainID) - if err != nil { - return - } - - if parent.Header.Number.Uint64() != number-1 { - err = errors.New("unknown ancestor") - return - } - - if parent.Header.Time+ctx.ExtraInfo.Period > header.Time { - err = errors.New("invalid timestamp") - return - } - - // Verify that the gasUsed is <= gasLimit - if header.GasUsed > header.GasLimit { - err = fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit) - return - } - - if err = VerifyEip1559Header(parent.Header, header); err != nil { - // Verify the header's EIP-1559 attributes. - return - } - - return verifySeal(native, header, ctx) -} - -func verifySeal(native *native.NativeContract, header *eth.Header, ctx *Context) (signer ecommon.Address, err error) { - // Verifying the genesis block is not supported - number := header.Number.Uint64() - if number == 0 { - err = errors.New("unknown block") - return - } - if TestFlagNoCheckHecoHeaderSig { - signer = header.Coinbase - return - } - // Resolve the authorization key and check against validators - signer, err = ecrecover(header, ctx.ExtraInfo.ChainID) - if err != nil { - return - } - - if signer != header.Coinbase { - err = errors.New("coinbase do not match with signature") - return - } - - return -} - -// ecrecover extracts the Ethereum account address from a signed header. -func ecrecover(header *eth.Header, chainID *big.Int) (ecommon.Address, error) { - // Retrieve the signature from the header extra-data - if len(header.Extra) < extraSeal { - return ecommon.Address{}, errors.New("extra-data 65 byte signature suffix missing") - } - signature := header.Extra[len(header.Extra)-extraSeal:] - - // Recover the public key and the Ethereum address - pubkey, err := crypto.Ecrecover(SealHash(header, chainID).Bytes(), signature) - if err != nil { - return ecommon.Address{}, err - } - var signer ecommon.Address - copy(signer[:], crypto.Keccak256(pubkey[1:])[12:]) - - return signer, nil -} - -// SealHash returns the hash of a block prior to it being sealed. -func SealHash(header *eth.Header, chainID *big.Int) (hash ecommon.Hash) { - hasher := sha3.NewLegacyKeccak256() - encodeSigHeader(hasher, header, chainID) - hasher.Sum(hash[:0]) - return hash -} - -func encodeSigHeader(w io.Writer, header *eth.Header, chainID *big.Int) { - err := rlp.Encode(w, []interface{}{ - header.ParentHash, - header.UncleHash, - header.Coinbase, - header.Root, - header.TxHash, - header.ReceiptHash, - header.Bloom, - header.Difficulty, - header.Number, - header.GasLimit, - header.GasUsed, - header.Time, - header.Extra[:len(header.Extra)-65], // this will panic if extra is too short, should check before calling encodeSigHeader - header.MixDigest, - header.Nonce, - }) - if err != nil { - panic("can't encode: " + err.Error()) - } -} - -// ParseValidators ... -func ParseValidators(validatorsBytes []byte) ([]ecommon.Address, error) { - if len(validatorsBytes)%ecommon.AddressLength != 0 { - return nil, errors.New("invalid validators bytes") - } - n := len(validatorsBytes) / ecommon.AddressLength - result := make([]ecommon.Address, n) - for i := 0; i < n; i++ { - address := make([]byte, ecommon.AddressLength) - copy(address, validatorsBytes[i*ecommon.AddressLength:(i+1)*ecommon.AddressLength]) - result[i] = ecommon.BytesToAddress(address) - } - return result, nil -} - -// SyncCrossChainMsg ... -func (h *Handler) SyncCrossChainMsg(native *native.NativeContract) error { - return nil -} diff --git a/contracts/native/header_sync/heco/utils.go b/contracts/native/header_sync/heco/utils.go deleted file mode 100644 index 678ccb5a..00000000 --- a/contracts/native/header_sync/heco/utils.go +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package heco - -import ( - "errors" - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth" - "github.com/ethereum/go-ethereum/params" -) - -// VerifyGaslimit verifies the header gas limit according increase/decrease -// in relation to the parent gas limit. -func VerifyGaslimit(parentGasLimit, headerGasLimit uint64) error { - // Verify that the gas limit remains within allowed bounds - diff := int64(parentGasLimit) - int64(headerGasLimit) - if diff < 0 { - diff *= -1 - } - limit := parentGasLimit / params.GasLimitBoundDivisor - if uint64(diff) >= limit { - return fmt.Errorf("invalid gas limit: have %d, want %d +-= %d", headerGasLimit, parentGasLimit, limit-1) - } - if headerGasLimit < params.MinGasLimit { - return errors.New("invalid gas limit below 5000") - } - return nil -} - -// VerifyEip1559Header verifies some header attributes which were changed in EIP-1559, -// - gas limit check -// - basefee check -func VerifyEip1559Header(parent, header *eth.Header) error { - // Verify that the gas limit remains within allowed bounds - parentGasLimit := parent.GasLimit - - if err := VerifyGaslimit(parentGasLimit, header.GasLimit); err != nil { - return err - } - // Verify the header is not malformed - if header.BaseFee == nil { - return fmt.Errorf("header is missing baseFee") - } - // Verify the baseFee is correct based on the parent header. - expectedBaseFee := CalcBaseFee(parent) - if header.BaseFee.Cmp(expectedBaseFee) != 0 { - return fmt.Errorf("invalid baseFee: have %s, want %s, parentBaseFee %s, parentGasUsed %d", - expectedBaseFee, header.BaseFee, parent.BaseFee, parent.GasUsed) - } - return nil -} - -// CalcBaseFee calculates the basefee of the header. -func CalcBaseFee(parent *eth.Header) *big.Int { - return common.Big0 -} diff --git a/contracts/native/header_sync/msc/header_sync.go b/contracts/native/header_sync/msc/header_sync.go deleted file mode 100644 index 5a80b2fa..00000000 --- a/contracts/native/header_sync/msc/header_sync.go +++ /dev/null @@ -1,845 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package msc - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "io" - "math/big" - "time" - - "github.com/ethereum/go-ethereum/common" - ecommon "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - scom "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth/types" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - cstates "github.com/polynetwork/poly/core/states" - "golang.org/x/crypto/sha3" -) - -// Handler ... -type Handler struct { -} - -// NewHandler ... -func NewHandler() *Handler { - return &Handler{} -} - -// SyncGenesisHeader ... -func (h *Handler) SyncGenesisHeader(native *native.NativeContract) (err error) { - ctx := native.ContractRef().CurrentContext() - params := &scom.SyncGenesisHeaderParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodSyncGenesisHeader, params, ctx.Payload); err != nil { - return fmt.Errorf("SyncGenesisHeader, contract params deserialize error: %v", err) - } - - side, err := side_chain_manager.GetSideChain(native, params.ChainID) - if err != nil { - return fmt.Errorf("msc Handler SyncGenesisHeader, GetSideChain error: %v", err) - } - var extraInfo ExtraInfo - err = json.Unmarshal(side.ExtraInfo, &extraInfo) - if err != nil { - return fmt.Errorf("msc Handler SyncGenesisHeader, ExtraInfo Unmarshal error: %v", err) - } - if extraInfo.Epoch == 0 { - return fmt.Errorf("msc Handler SyncGenesisHeader, invalid epoch") - } - if extraInfo.Period == 0 { - return fmt.Errorf("msc Handler SyncGenesisHeader, invalid period") - } - // Get current epoch operator - ok, err := node_manager.CheckConsensusSigns(native, scom.MethodSyncGenesisHeader, ctx.Payload, native.ContractRef().MsgSender()) - if err != nil { - return fmt.Errorf("SyncGenesisHeader, CheckConsensusSigns error: %v", err) - } - if !ok { - return nil - } - - // can only store once - stored, err := isGenesisStored(native, params) - if err != nil { - return fmt.Errorf("msc Handler SyncGenesisHeader, isGenesisStored error: %v", err) - } - if stored { - return fmt.Errorf("msc Handler SyncGenesisHeader, genesis had been initialized") - } - - var genesis types.Header - err = json.Unmarshal(params.GenesisHeader, &genesis) - if err != nil { - return fmt.Errorf("msc Handler SyncGenesisHeader, deserialize GenesisHeader err: %v", err) - } - - if genesis.Number.Uint64()%extraInfo.Epoch != 0 { - return fmt.Errorf("invalid genesis height:%d", genesis.Number.Uint64()) - } - signersBytes := len(genesis.Extra) - extraVanity - extraSeal - if signersBytes == 0 || signersBytes%ecommon.AddressLength != 0 { - return fmt.Errorf("invalid signer list, signersBytes:%d", signersBytes) - } - - err = storeGenesis(native, params, &genesis) - if err != nil { - return fmt.Errorf("msc Handler SyncGenesisHeader, storeGenesis error: %v", err) - } - - return -} - -func isGenesisStored(native *native.NativeContract, params *scom.SyncGenesisHeaderParam) (stored bool, err error) { - genesis, err := getGenesis(native, params.ChainID) - if err != nil { - return - } - - stored = genesis != nil - return -} - -func getGenesis(native *native.NativeContract, chainID uint64) (genesisHeader *types.Header, err error) { - - genesisBytes, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.GENESIS_HEADER), utils.GetUint64Bytes(chainID))) - if err != nil { - err = fmt.Errorf("getGenesis, GetCacheDB err:%v", err) - return - } - - if genesisBytes == nil { - return - } - - genesisBytes, err = cstates.GetValueFromRawStorageItem(genesisBytes) - if err != nil { - err = fmt.Errorf("getGenesis, GetValueFromRawStorageItem err:%v", err) - return - } - - { - genesisHeader = &types.Header{} - err = json.Unmarshal(genesisBytes, &genesisHeader) - if err != nil { - err = fmt.Errorf("getGenesis, json.Unmarshal err:%v", err) - return - } - } - - return -} - -func storeGenesis(native *native.NativeContract, params *scom.SyncGenesisHeaderParam, genesisHeader *types.Header) (err error) { - - genesisBytes, err := json.Marshal(genesisHeader) - if err != nil { - return - } - - native.GetCacheDB().Put( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.GENESIS_HEADER), utils.GetUint64Bytes(params.ChainID)), - cstates.GenRawStorageItem(genesisBytes)) - - headerWithSum := &HeaderWithDifficultySum{Header: genesisHeader, DifficultySum: genesisHeader.Difficulty} - - err = putHeaderWithSum(native, params.ChainID, headerWithSum) - if err != nil { - return - } - - putCanonicalHeight(native, params.ChainID, genesisHeader.Number.Uint64()) - putCanonicalHash(native, params.ChainID, genesisHeader.Number.Uint64(), genesisHeader.Hash()) - - scom.NotifyPutHeader(native, params.ChainID, genesisHeader.Number.Uint64(), genesisHeader.Hash().Hex()) - return -} - -// ExtraInfo ... -type ExtraInfo struct { - ChainID *big.Int // for msc - Period uint64 - Epoch uint64 -} - -// Context ... -type Context struct { - ExtraInfo ExtraInfo - ChainID uint64 -} - -// HeaderWithDifficultySum ... -type HeaderWithDifficultySum struct { - Header *types.Header `json:"header"` - DifficultySum *big.Int `json:"difficultySum"` - // 1. empty for epoch header - // 2. for non-epoch headers, either points to epoch header or a vote header - LastVoteParentOrEpoch *ecommon.Hash `json:"lastVoteParentOrEpoch"` -} - -// SyncBlockHeader ... -func (h *Handler) SyncBlockHeader(native *native.NativeContract) error { - headerParams := &scom.SyncBlockHeaderParam{} - { - ctx := native.ContractRef().CurrentContext() - if err := utils.UnpackMethod(scom.ABI, scom.MethodSyncBlockHeader, headerParams, ctx.Payload); err != nil { - return err - } - } - - side, err := side_chain_manager.GetSideChain(native, headerParams.ChainID) - if err != nil { - return fmt.Errorf("msc Handler SyncBlockHeader, GetSideChain error: %v", err) - } - var extraInfo ExtraInfo - err = json.Unmarshal(side.ExtraInfo, &extraInfo) - if err != nil { - return fmt.Errorf("msc Handler SyncBlockHeader, ExtraInfo Unmarshal error: %v", err) - } - - ctx := &Context{ExtraInfo: extraInfo, ChainID: headerParams.ChainID} - - for _, v := range headerParams.Headers { - var header types.Header - err := json.Unmarshal(v, &header) - if err != nil { - return fmt.Errorf("msc Handler SyncBlockHeader, deserialize header err: %v", err) - } - headerHash := header.Hash() - - exist, err := isHeaderExist(native, headerHash, ctx) - if err != nil { - return fmt.Errorf("msc Handler SyncBlockHeader, isHeaderExist headerHash err: %v", err) - } - if exist { - log.Warnf("msc Handler SyncBlockHeader, header has exist. Header: %s", string(v)) - continue - } - - parentExist, err := isHeaderExist(native, header.ParentHash, ctx) - if err != nil { - return fmt.Errorf("msc Handler SyncBlockHeader, isHeaderExist ParentHash err: %v", err) - } - if !parentExist { - return fmt.Errorf("msc Handler SyncBlockHeader, parent header not exist. Header: %s", string(v)) - } - - err = verifyHeader(native, &header, ctx) - if err != nil { - return fmt.Errorf("msc Handler SyncBlockHeader, verifyHeader err: %v", err) - } - - err = addHeader(native, &header, ctx) - if err != nil { - return fmt.Errorf("msc Handler SyncBlockHeader, addHeader err: %v", err) - } - - scom.NotifyPutHeader(native, headerParams.ChainID, header.Number.Uint64(), header.Hash().Hex()) - } - return nil -} - -func isHeaderExist(native *native.NativeContract, headerHash ecommon.Hash, ctx *Context) (bool, error) { - headerStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(ctx.ChainID), headerHash.Bytes())) - if err != nil { - return false, fmt.Errorf("msc Handler isHeaderExist error: %v", err) - } - - return headerStore != nil, nil -} - -// GetCanonicalHeight ... -func GetCanonicalHeight(native *native.NativeContract, chainID uint64) (height uint64, err error) { - heightStore, err := native.GetCacheDB().Get( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.CURRENT_HEADER_HEIGHT), utils.GetUint64Bytes(chainID))) - if err != nil { - err = fmt.Errorf("msc Handler GetCanonicalHeight err:%v", err) - return - } - - storeBytes, err := cstates.GetValueFromRawStorageItem(heightStore) - if err != nil { - err = fmt.Errorf("msc Handler GetCanonicalHeight, GetValueFromRawStorageItem err:%v", err) - return - } - - height = utils.GetBytesUint64(storeBytes) - return -} - -// GetCanonicalHeader ... -func GetCanonicalHeader(native *native.NativeContract, chainID uint64, height uint64) (headerWithSum *HeaderWithDifficultySum, err error) { - hash, err := getCanonicalHash(native, chainID, height) - if err != nil { - return - } - - if hash == (ecommon.Hash{}) { - return - } - - headerWithSum, err = GetHeader(native, hash, chainID) - return -} - -func deleteCanonicalHash(native *native.NativeContract, chainID uint64, height uint64) { - native.GetCacheDB().Delete(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(height))) -} - -func getCanonicalHash(native *native.NativeContract, chainID uint64, height uint64) (hash ecommon.Hash, err error) { - hashBytesStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(height))) - if err != nil { - return - } - - if hashBytesStore == nil { - return - } - - hashBytes, err := cstates.GetValueFromRawStorageItem(hashBytesStore) - if err != nil { - err = fmt.Errorf("msc Handler getCanonicalHash, GetValueFromRawStorageItem err:%v", err) - return - } - - hash = ecommon.BytesToHash(hashBytes) - return -} - -func putCanonicalHash(native *native.NativeContract, chainID uint64, height uint64, hash ecommon.Hash) { - native.GetCacheDB().Put(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(height)), - cstates.GenRawStorageItem(hash.Bytes())) -} - -func putHeaderWithSum(native *native.NativeContract, chainID uint64, headerWithSum *HeaderWithDifficultySum) (err error) { - - headerBytes, err := json.Marshal(headerWithSum) - if err != nil { - return - } - - native.GetCacheDB().Put( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), headerWithSum.Header.Hash().Bytes()), - cstates.GenRawStorageItem(headerBytes)) - return -} - -func putCanonicalHeight(native *native.NativeContract, chainID uint64, height uint64) { - native.GetCacheDB().Put( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.CURRENT_HEADER_HEIGHT), utils.GetUint64Bytes(chainID)), - cstates.GenRawStorageItem(utils.GetUint64Bytes(uint64(height)))) -} - -func addHeader(native *native.NativeContract, header *types.Header, ctx *Context) (err error) { - - parentHeader, err := GetHeader(native, header.ParentHash, ctx.ChainID) - if err != nil { - return - } - - cheight, err := GetCanonicalHeight(native, ctx.ChainID) - if err != nil { - return - } - cheader, err := GetCanonicalHeader(native, ctx.ChainID, cheight) - if err != nil { - return - } - if cheader == nil { - err = fmt.Errorf("getCanonicalHeader returns nil") - return - } - - localTd := cheader.DifficultySum - externTd := new(big.Int).Add(header.Difficulty, parentHeader.DifficultySum) - - headerWithSum := &HeaderWithDifficultySum{Header: header, DifficultySum: externTd} - if header.Number.Uint64()%ctx.ExtraInfo.Epoch != 0 { - if parentHeader.Header.Number.Uint64()%ctx.ExtraInfo.Epoch == 0 { - lastVoteParentOrEpoch := parentHeader.Header.Hash() - headerWithSum.LastVoteParentOrEpoch = &lastVoteParentOrEpoch - } else { - if parentHeader.Header.Coinbase != (ecommon.Address{}) { - lastVoteParentOrEpoch := parentHeader.Header.Hash() - headerWithSum.LastVoteParentOrEpoch = &lastVoteParentOrEpoch - } else { - headerWithSum.LastVoteParentOrEpoch = parentHeader.LastVoteParentOrEpoch - } - } - } - err = putHeaderWithSum(native, ctx.ChainID, headerWithSum) - if err != nil { - return - } - - if externTd.Cmp(localTd) > 0 { - // Delete any canonical number assignments above the new head - var headerWithSum *HeaderWithDifficultySum - for i := header.Number.Uint64() + 1; ; i++ { - headerWithSum, err = GetCanonicalHeader(native, ctx.ChainID, i) - if err != nil { - return - } - if headerWithSum == nil { - break - } - - deleteCanonicalHash(native, ctx.ChainID, i) - } - - // Overwrite any stale canonical number assignments - var ( - hash ecommon.Hash - headHeader *HeaderWithDifficultySum - ) - cheight := header.Number.Uint64() - 1 - headHash := header.ParentHash - - for { - hash, err = getCanonicalHash(native, ctx.ChainID, cheight) - if err != nil { - return - } - if hash == headHash { - break - } - - putCanonicalHash(native, ctx.ChainID, cheight, headHash) - headHeader, err = GetHeader(native, headHash, ctx.ChainID) - if err != nil { - return - } - headHash = headHeader.Header.ParentHash - cheight-- - } - - // Extend the canonical chain with the new header - putCanonicalHash(native, ctx.ChainID, header.Number.Uint64(), header.Hash()) - putCanonicalHeight(native, ctx.ChainID, header.Number.Uint64()) - } - - return nil -} - -func snapshot(native *native.NativeContract, number uint64, hash ecommon.Hash, targetSigner ecommon.Address, ctx *Context) (snap *Snapshot, lastSeenHeight uint64, err error) { - var ( - headerWSs []*HeaderWithDifficultySum - headerWS *HeaderWithDifficultySum - ) - - startHash := hash - genesis, err := getGenesis(native, ctx.ChainID) - if err != nil { - err = fmt.Errorf("msc Handler snapshot getGenesis error: %v", err) - return - } - - if genesis == nil { - err = fmt.Errorf("msc Handler snapshot genesis not set") - return - } - - if number < genesis.Number.Uint64() { - err = fmt.Errorf("msc Handler snapshot header before genesis is not allowed") - return - } - - var signer ecommon.Address - - for snap == nil { - - headerWS, err = GetHeader(native, hash, ctx.ChainID) - if err != nil { - err = fmt.Errorf("msc Handler snapshot getHeader error: %v", err) - return - } - - if headerWS.LastVoteParentOrEpoch == nil { - signers := make([]ecommon.Address, (len(headerWS.Header.Extra)-extraVanity-extraSeal)/ecommon.AddressLength) - for i := 0; i < len(signers); i++ { - copy(signers[i][:], headerWS.Header.Extra[extraVanity+i*ecommon.AddressLength:]) - } - - signer, err = ecrecover(headerWS.Header) - if err != nil { - err = fmt.Errorf("msc Handler snapshot ecrecover error: %v", err) - return - } - if targetSigner == signer { - lastSeenHeight = headerWS.Header.Number.Uint64() - } - snap = newSnapshot(headerWS.Header.Number.Uint64(), hash, signers, ctx) - break - } - - if headerWS.Header.Coinbase != (ecommon.Address{}) { - headerWSs = append(headerWSs, headerWS) - } - - // LastVoteParentOrEpoch must be non nil for non-epoch headers - hash = *headerWS.LastVoteParentOrEpoch - } - - // Previous snapshot found, apply any pending headers on top of it - for i := 0; i < len(headerWSs)/2; i++ { - headerWSs[i], headerWSs[len(headerWSs)-1-i] = headerWSs[len(headerWSs)-1-i], headerWSs[i] - } - - err = snap.apply(headerWSs, targetSigner, &lastSeenHeight) - if err != nil { - err = fmt.Errorf("msc Handler snapshot apply error: %v", err) - return - } - - if lastSeenHeight > 0 { - return - } - - // try to search enough recent - toSearch := len(snap.Signers) / 2 - for i := 0; i < toSearch; i++ { - headerWS, err = GetHeader(native, startHash, ctx.ChainID) - if err != nil { - err = fmt.Errorf("msc Handler snapshot getHeader error: %v", err) - return - } - - if number != headerWS.Header.Number.Uint64() { - err = fmt.Errorf("bug happened in msc") - return - } - signer, err = ecrecover(headerWS.Header) - if err != nil { - err = fmt.Errorf("msc Handler snapshot ecrecover error: %v", err) - return - } - if targetSigner == signer { - lastSeenHeight = headerWS.Header.Number.Uint64() - break - } - number, startHash = number-1, headerWS.Header.ParentHash - if number < genesis.Number.Uint64() { - break - } - } - return -} - -func GetHeader(native *native.NativeContract, hash ecommon.Hash, chainID uint64) (headerWithSum *HeaderWithDifficultySum, err error) { - - headerStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), hash.Bytes())) - if err != nil { - return nil, fmt.Errorf("msc Handler getHeader error: %v", err) - } - if headerStore == nil { - return nil, fmt.Errorf("msc Handler getHeader, can not find any header records") - } - storeBytes, err := cstates.GetValueFromRawStorageItem(headerStore) - if err != nil { - return nil, fmt.Errorf("msc Handler getHeader, deserialize headerBytes from raw storage item err:%v", err) - } - headerWithSum = &HeaderWithDifficultySum{} - if err := json.Unmarshal(storeBytes, &headerWithSum); err != nil { - return nil, fmt.Errorf("msc Handler getHeader, deserialize header error: %v", err) - } - - return -} - -var ( - extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity - extraSeal = crypto.SignatureLength // Fixed number of extra-data suffix bytes reserved for signer seal - uncleHash = types.CalcUncleHash(nil) // Always Keccak256(RLP([])) as uncles are meaningless outside of PoW. - diffInTurn = big.NewInt(2) // Block difficulty for in-turn signatures - diffNoTurn = big.NewInt(1) // Block difficulty for out-of-turn signatures - nonceAuthVote = hexutil.MustDecode("0xffffffffffffffff") // Magic nonce number to vote on adding a new signer - nonceDropVote = hexutil.MustDecode("0x0000000000000000") // Magic nonce number to vote on removing a signer. - -) - -var ( - // errUnknownBlock is returned when the list of signers is requested for a block - // that is not part of the local blockchain. - errUnknownBlock = errors.New("unknown block") - - // errInvalidVote is returned if a nonce value is something else that the two - // allowed constants of 0x00..0 or 0xff..f. - errInvalidVote = errors.New("vote nonce not 0x00..0 or 0xff..f") - - // errInvalidCheckpointVote is returned if a checkpoint/epoch transition block - // has a vote nonce set to non-zeroes. - errInvalidCheckpointVote = errors.New("vote nonce in checkpoint block non-zero") - - // errMissingVanity is returned if a block's extra-data section is shorter than - // 32 bytes, which is required to store the signer vanity. - errMissingVanity = errors.New("extra-data 32 byte vanity prefix missing") - - // errMissingSignature is returned if a block's extra-data section doesn't seem - // to contain a 65 byte secp256k1 signature. - errMissingSignature = errors.New("extra-data 65 byte signature suffix missing") - - // errExtraSigners is returned if non-checkpoint block contain signer data in - // their extra-data fields. - errExtraSigners = errors.New("non-checkpoint block contains extra signer list") - - // errInvalidCheckpointSigners is returned if a checkpoint block contains an - // invalid list of signers (i.e. non divisible by 20 bytes). - errInvalidCheckpointSigners = errors.New("invalid signer list on checkpoint block") - - // errMismatchingCheckpointSigners is returned if a checkpoint block contains a - // list of signers different than the one the local node calculated. - errMismatchingCheckpointSigners = errors.New("mismatching signer list on checkpoint block") - - // errInvalidMixDigest is returned if a block's mix digest is non-zero. - errInvalidMixDigest = errors.New("non-zero mix digest") - - // errInvalidUncleHash is returned if a block contains an non-empty uncle list. - errInvalidUncleHash = errors.New("non empty uncle hash") - - // errInvalidDifficulty is returned if the difficulty of a block neither 1 or 2. - errInvalidDifficulty = errors.New("invalid difficulty") - - // errInvalidCheckpointBeneficiary is returned if a checkpoint/epoch transition - // block has a beneficiary set to non-zeroes. - errInvalidCheckpointBeneficiary = errors.New("beneficiary in checkpoint block non-zero") - - // errFutureBlock is returned when a block's timestamp is in the future according - // to the current node. - errFutureBlock = errors.New("block in the future") - - // errUnknownAncestor is returned when validating a block requires an ancestor - // that is unknown. - errUnknownAncestor = errors.New("unknown ancestor") - - // errInvalidTimestamp is returned if the timestamp of a block is lower than - // the previous block's timestamp + the minimum block period. - errInvalidTimestamp = errors.New("invalid timestamp") -) - -func verifyHeader(native *native.NativeContract, header *types.Header, ctx *Context) (err error) { - if header.Number == nil { - return errUnknownBlock - } - number := header.Number.Uint64() - - // Don't waste time checking blocks from the future - if header.Time > uint64(time.Now().Unix()) { - err = errFutureBlock - return - } - - // Checkpoint blocks need to enforce zero beneficiary - checkpoint := (number % ctx.ExtraInfo.Epoch) == 0 - if checkpoint && header.Coinbase != (ecommon.Address{}) { - return errInvalidCheckpointBeneficiary - } - - // Nonces must be 0x00..0 or 0xff..f, zeroes enforced on checkpoints - if !bytes.Equal(header.Nonce[:], nonceAuthVote) && !bytes.Equal(header.Nonce[:], nonceDropVote) { - return errInvalidVote - } - - if checkpoint && !bytes.Equal(header.Nonce[:], nonceDropVote) { - return errInvalidCheckpointVote - } - - // Check that the extra-data contains both the vanity and signature - if len(header.Extra) < extraVanity { - err = errMissingVanity - return - } - if len(header.Extra) < extraVanity+extraSeal { - err = errMissingSignature - return - } - - // Ensure that the extra-data contains a signer list on checkpoint, but none otherwise - signersBytes := len(header.Extra) - extraVanity - extraSeal - if !checkpoint && signersBytes != 0 { - return errExtraSigners - } - - if checkpoint && (signersBytes == 0 || signersBytes%ecommon.AddressLength != 0) { - return errInvalidCheckpointSigners - } - - // Ensure that the mix digest is zero as we don't have fork protection currently - if header.MixDigest != (ecommon.Hash{}) { - err = errInvalidMixDigest - return - } - - // Ensure that the block doesn't contain any uncles which are meaningless in PoA - if header.UncleHash != uncleHash { - err = errInvalidUncleHash - return - } - - // Ensure that the block's difficulty is meaningful (may not be correct at this point) - if header.Difficulty == nil || (header.Difficulty.Cmp(diffInTurn) != 0 && header.Difficulty.Cmp(diffNoTurn) != 0) { - err = errInvalidDifficulty - return - } - - // All basic checks passed, verify cascading fields - return verifyCascadingFields(native, header, ctx) -} - -func verifyCascadingFields(native *native.NativeContract, header *types.Header, ctx *Context) (err error) { - - number := header.Number.Uint64() - - parent, err := GetHeader(native, header.ParentHash, ctx.ChainID) - if err != nil { - return - } - - if parent.Header.Number.Uint64() != number-1 { - err = errUnknownAncestor - return - } - - if parent.Header.Time+ctx.ExtraInfo.Period > header.Time { - return errInvalidTimestamp - } - - return verifySeal(native, header, ctx) -} - -// for test -var mockSigner ecommon.Address - -func verifySeal(native *native.NativeContract, header *types.Header, ctx *Context) (err error) { - // Verifying the genesis block is not supported - number := header.Number.Uint64() - if number == 0 { - err = errUnknownBlock - return - } - - signer := mockSigner - if signer == (ecommon.Address{}) { - // Resolve the authorization key and check against validators - signer, err = ecrecover(header) - if err != nil { - return - } - } - - snap, lastSeenHeight, err := snapshot(native, header.Number.Uint64()-1, header.ParentHash, signer, ctx) - if err != nil { - return fmt.Errorf("msc Handler SyncBlockHeader, snapshot err: %v", err) - } - - if number%ctx.ExtraInfo.Epoch == 0 { - signers := make([]byte, len(snap.Signers)*ecommon.AddressLength) - for i, signer := range snap.signers() { - copy(signers[i*ecommon.AddressLength:], signer[:]) - } - extraSuffix := len(header.Extra) - extraSeal - if !bytes.Equal(header.Extra[extraVanity:extraSuffix], signers) { - return errMismatchingCheckpointSigners - } - } - - if lastSeenHeight > 0 { - limit := uint64(len(snap.Signers)/2) + 1 - if header.Number.Uint64() < lastSeenHeight+limit { - return fmt.Errorf("msc Handler SyncBlockHeader, RecentlySigned, lastSeenHeight:%d currentHeight:%d #V:%d", lastSeenHeight, header.Number.Int64(), len(snap.Signers)) - } - } - - var offset int - inturn := snap.inturn(header.Number.Uint64(), signer, &offset) - if inturn { - if header.Difficulty.Cmp(diffInTurn) != 0 { - return fmt.Errorf("invalid difficulty, got %d expect %d offset:%d signers:%d", header.Difficulty.Int64(), diffInTurn.Int64(), offset, len(snap.Signers)) - } - } else { - if header.Difficulty.Cmp(diffNoTurn) != 0 { - return fmt.Errorf("invalid difficulty, got %d expect %d offset:%d signers:%d", header.Difficulty.Int64(), diffNoTurn.Int64(), offset, len(snap.Signers)) - } - } - - return -} - -// ecrecover extracts the Ethereum account address from a signed header. -func ecrecover(header *types.Header) (ecommon.Address, error) { - // Retrieve the signature from the header extra-data - if len(header.Extra) < extraSeal { - return ecommon.Address{}, errMissingSignature - } - signature := header.Extra[len(header.Extra)-extraSeal:] - - // Recover the public key and the Ethereum address - pubkey, err := crypto.Ecrecover(SealHash(header).Bytes(), signature) - if err != nil { - return ecommon.Address{}, err - } - var signer ecommon.Address - copy(signer[:], crypto.Keccak256(pubkey[1:])[12:]) - - return signer, nil -} - -// SealHash returns the hash of a block prior to it being sealed. -func SealHash(header *types.Header) (hash common.Hash) { - hasher := sha3.NewLegacyKeccak256() - encodeSigHeader(hasher, header) - hasher.Sum(hash[:0]) - return hash -} - -func encodeSigHeader(w io.Writer, header *types.Header) { - err := rlp.Encode(w, []interface{}{ - header.ParentHash, - header.UncleHash, - header.Coinbase, - header.Root, - header.TxHash, - header.ReceiptHash, - header.Bloom, - header.Difficulty, - header.Number, - header.GasLimit, - header.GasUsed, - header.Time, - header.Extra[:len(header.Extra)-65], // this will panic if extra is too short, should check before calling encodeSigHeader - header.MixDigest, - header.Nonce, - }) - if err != nil { - panic("can't encode: " + err.Error()) - } -} - -// SyncCrossChainMsg ... -func (h *Handler) SyncCrossChainMsg(native *native.NativeContract) error { - return nil -} diff --git a/contracts/native/header_sync/msc/snapshot.go b/contracts/native/header_sync/msc/snapshot.go deleted file mode 100644 index c9554974..00000000 --- a/contracts/native/header_sync/msc/snapshot.go +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package msc - -import ( - "bytes" - "fmt" - "sort" - - "github.com/ethereum/go-ethereum/common" -) - -// Tally is a simple vote tally to keep the current score of votes. Votes that -// go against the proposal aren't counted since it's equivalent to not voting. -type Tally struct { - Authorize bool `json:"authorize"` // Whether the vote is about authorizing or kicking someone - Votes int `json:"votes"` // Number of votes until now wanting to pass the proposal -} - -// Vote represents a single vote that an authorized signer made to modify the -// list of authorizations. -type Vote struct { - Signer common.Address `json:"signer"` // Authorized signer that cast this vote - Block uint64 `json:"block"` // Block number the vote was cast in (expire old votes) - Address common.Address `json:"address"` // Account being voted on to change its authorization - Authorize bool `json:"authorize"` // Whether to authorize or deauthorize the voted account -} - -// Snapshot ... -type Snapshot struct { - Number uint64 `json:"number"` // Block number where the snapshot was created - Hash common.Hash `json:"hash"` // Block hash where the snapshot was created - Signers map[common.Address]struct{} `json:"signers"` // Set of authorized signers at this moment - Votes []*Vote `json:"votes"` // List of votes cast in chronological order - Tally map[common.Address]Tally `json:"tally"` // Current vote tally to avoid recalculating - Ctx *Context -} - -func newSnapshot(number uint64, hash common.Hash, signers []common.Address, ctx *Context) *Snapshot { - snap := &Snapshot{ - Number: number, - Hash: hash, - Signers: make(map[common.Address]struct{}), - Tally: make(map[common.Address]Tally), - Ctx: ctx, - } - for _, signer := range signers { - snap.Signers[signer] = struct{}{} - } - return snap -} - -// validVote returns whether it makes sense to cast the specified vote in the -// given snapshot context (e.g. don't try to add an already authorized signer). -func (s *Snapshot) validVote(address common.Address, authorize bool) bool { - _, signer := s.Signers[address] - return (signer && !authorize) || (!signer && authorize) -} - -// cast adds a new vote into the tally. -func (s *Snapshot) cast(address common.Address, authorize bool) bool { - // Ensure the vote is meaningful - if !s.validVote(address, authorize) { - return false - } - // Cast the vote into an existing or new tally - if old, ok := s.Tally[address]; ok { - old.Votes++ - s.Tally[address] = old - } else { - s.Tally[address] = Tally{Authorize: authorize, Votes: 1} - } - return true -} - -// uncast removes a previously cast vote from the tally. -func (s *Snapshot) uncast(address common.Address, authorize bool) bool { - // If there's no tally, it's a dangling vote, just drop - tally, ok := s.Tally[address] - if !ok { - return false - } - // Ensure we only revert counted votes - if tally.Authorize != authorize { - return false - } - // Otherwise revert the vote - if tally.Votes > 1 { - tally.Votes-- - s.Tally[address] = tally - } else { - delete(s.Tally, address) - } - return true -} - -// apply creates a new authorization snapshot by applying the given headers to -// the original one. -func (s *Snapshot) apply(headers []*HeaderWithDifficultySum, targetSigner common.Address, lastSeenAddress *uint64) (err error) { - // Allow passing in no headers for cleaner code - if len(headers) == 0 { - return - } - - var signer common.Address - for _, headerWS := range headers { - header := headerWS.Header - // Remove any votes on checkpoint blocks - number := header.Number.Uint64() - // Resolve the authorization key and check against signers - signer, err = ecrecover(header) - if err != nil { - err = fmt.Errorf("ecrecover err %v", err) - return - } - if targetSigner == signer { - *lastSeenAddress = number - } - if _, ok := s.Signers[signer]; !ok { - err = fmt.Errorf("unauthorized signer for block %d", number) - return - } - - // Header authorized, discard any previous votes from the signer - for i, vote := range s.Votes { - if vote.Signer == signer && vote.Address == header.Coinbase { - // Uncast the vote from the cached tally - s.uncast(vote.Address, vote.Authorize) - - // Uncast the vote from the chronological list - s.Votes = append(s.Votes[:i], s.Votes[i+1:]...) - break // only one vote allowed - } - } - // Tally up the new vote from the signer - var authorize bool - switch { - case bytes.Equal(header.Nonce[:], nonceAuthVote): - authorize = true - case bytes.Equal(header.Nonce[:], nonceDropVote): - authorize = false - default: - err = errInvalidVote - return - } - if s.cast(header.Coinbase, authorize) { - s.Votes = append(s.Votes, &Vote{ - Signer: signer, - Block: number, - Address: header.Coinbase, - Authorize: authorize, - }) - } - // If the vote passed, update the list of signers - if tally := s.Tally[header.Coinbase]; tally.Votes > len(s.Signers)/2 { - if tally.Authorize { - s.Signers[header.Coinbase] = struct{}{} - } else { - delete(s.Signers, header.Coinbase) - - // Discard any previous votes the deauthorized signer cast - for i := 0; i < len(s.Votes); i++ { - if s.Votes[i].Signer == header.Coinbase { - // Uncast the vote from the cached tally - s.uncast(s.Votes[i].Address, s.Votes[i].Authorize) - - // Uncast the vote from the chronological list - s.Votes = append(s.Votes[:i], s.Votes[i+1:]...) - - i-- - } - } - } - // Discard any previous votes around the just changed account - for i := 0; i < len(s.Votes); i++ { - if s.Votes[i].Address == header.Coinbase { - s.Votes = append(s.Votes[:i], s.Votes[i+1:]...) - i-- - } - } - delete(s.Tally, header.Coinbase) - } - - } - - s.Number += uint64(len(headers)) - s.Hash = headers[len(headers)-1].Header.Hash() - - return -} - -// signersAscending implements the sort interface to allow sorting a list of addresses -type signersAscending []common.Address - -func (s signersAscending) Len() int { return len(s) } -func (s signersAscending) Less(i, j int) bool { return bytes.Compare(s[i][:], s[j][:]) < 0 } -func (s signersAscending) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// signers retrieves the list of authorized signers in ascending order. -func (s *Snapshot) signers() []common.Address { - sigs := make([]common.Address, 0, len(s.Signers)) - for sig := range s.Signers { - sigs = append(sigs, sig) - } - sort.Sort(signersAscending(sigs)) - return sigs -} - -// inturn returns if a signer at a given block height is in-turn or not. -func (s *Snapshot) inturn(number uint64, signer common.Address, offsetPointer *int) bool { - signers, offset := s.signers(), 0 - for offset < len(signers) && signers[offset] != signer { - offset++ - } - if offsetPointer != nil { - *offsetPointer = offset - } - return (number % uint64(len(signers))) == uint64(offset) -} diff --git a/contracts/native/header_sync/okex/ethsecp256k1/codec.go b/contracts/native/header_sync/okex/ethsecp256k1/codec.go deleted file mode 100644 index 3584e92a..00000000 --- a/contracts/native/header_sync/okex/ethsecp256k1/codec.go +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package ethsecp256k1 - -import ( - "github.com/cosmos/cosmos-sdk/codec" - cryptoamino "github.com/tendermint/tendermint/crypto/encoding/amino" -) - -// CryptoCodec is the default amino codec used by ethermint -var CryptoCodec = codec.New() - -func init() { - RegisterCodec(CryptoCodec) -} - -// RegisterCodec registers all the necessary types with amino for the given -// codec. -func RegisterCodec(cdc *codec.Codec) { - cryptoamino.RegisterAmino(cdc) - cdc.RegisterConcrete(PubKey{}, PubKeyName, nil) - cdc.RegisterConcrete(PrivKey{}, PrivKeyName, nil) -} diff --git a/contracts/native/header_sync/okex/ethsecp256k1/ethsecp256k1.go b/contracts/native/header_sync/okex/ethsecp256k1/ethsecp256k1.go deleted file mode 100644 index 4c2f512d..00000000 --- a/contracts/native/header_sync/okex/ethsecp256k1/ethsecp256k1.go +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package ethsecp256k1 - -import ( - "bytes" - "crypto/ecdsa" - - ethcrypto "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/crypto/secp256k1" - - tmcrypto "github.com/tendermint/tendermint/crypto" -) - -const ( - // PrivKeySize defines the size of the PrivKey bytes - PrivKeySize = 32 - // KeyType is the string constant for the EthSecp256k1 algorithm - KeyType = "eth_secp256k1" -) - -// Amino encoding names -const ( - // PrivKeyName defines the amino encoding name for the EthSecp256k1 private key - PrivKeyName = "ethermint/PrivKeyEthSecp256k1" - // PubKeyName defines the amino encoding name for the EthSecp256k1 public key - PubKeyName = "ethermint/PubKeyEthSecp256k1" -) - -// ---------------------------------------------------------------------------- -// secp256k1 Private Key - -var _ tmcrypto.PrivKey = PrivKey{} - -// PrivKey defines a type alias for an ecdsa.PrivateKey that implements -// Tendermint's PrivateKey interface. -type PrivKey []byte - -// GenerateKey generates a new random private key. It returns an error upon -// failure. -func GenerateKey() (PrivKey, error) { - priv, err := ethcrypto.GenerateKey() - if err != nil { - return PrivKey{}, err - } - - return PrivKey(ethcrypto.FromECDSA(priv)), nil -} - -// PubKey returns the ECDSA private key's public key. -func (privkey PrivKey) PubKey() tmcrypto.PubKey { - ecdsaPKey := privkey.ToECDSA() - return PubKey(ethcrypto.CompressPubkey(&ecdsaPKey.PublicKey)) -} - -// Bytes returns the raw ECDSA private key bytes. -func (privkey PrivKey) Bytes() []byte { - return CryptoCodec.MustMarshalBinaryBare(privkey) -} - -// Sign creates a recoverable ECDSA signature on the secp256k1 curve over the -// Keccak256 hash of the provided message. The produced signature is 65 bytes -// where the last byte contains the recovery ID. -func (privkey PrivKey) Sign(msg []byte) ([]byte, error) { - return ethcrypto.Sign(ethcrypto.Keccak256Hash(msg).Bytes(), privkey.ToECDSA()) -} - -// Equals returns true if two ECDSA private keys are equal and false otherwise. -func (privkey PrivKey) Equals(other tmcrypto.PrivKey) bool { - if other, ok := other.(PrivKey); ok { - return bytes.Equal(privkey.Bytes(), other.Bytes()) - } - - return false -} - -// ToECDSA returns the ECDSA private key as a reference to ecdsa.PrivateKey type. -// The function will panic if the private key is invalid. -func (privkey PrivKey) ToECDSA() *ecdsa.PrivateKey { - key, err := ethcrypto.ToECDSA(privkey) - if err != nil { - panic(err) - } - return key -} - -// ---------------------------------------------------------------------------- -// secp256k1 Public Key - -var _ tmcrypto.PubKey = (*PubKey)(nil) - -// PubKey defines a type alias for an ecdsa.PublicKey that implements Tendermint's PubKey -// interface. It represents the 33-byte compressed public key format. -type PubKey []byte - -// Address returns the address of the ECDSA public key. -// The function will panic if the public key is invalid. -func (key PubKey) Address() tmcrypto.Address { - pubk, err := ethcrypto.DecompressPubkey(key) - if err != nil { - panic(err) - } - - return tmcrypto.Address(ethcrypto.PubkeyToAddress(*pubk).Bytes()) -} - -// Bytes returns the raw bytes of the ECDSA public key. -// The function panics if the key cannot be marshaled to bytes. -func (key PubKey) Bytes() []byte { - bz, err := CryptoCodec.MarshalBinaryBare(key) - if err != nil { - panic(err) - } - return bz -} - -// VerifyBytes verifies that the ECDSA public key created a given signature over -// the provided message. It will calculate the Keccak256 hash of the message -// prior to verification. -func (key PubKey) VerifyBytes(msg []byte, sig []byte) bool { - if len(sig) == 65 { - // remove recovery ID if contained in the signature - sig = sig[:len(sig)-1] - } - - // the signature needs to be in [R || S] format when provided to VerifySignature - return secp256k1.VerifySignature(key, ethcrypto.Keccak256Hash(msg).Bytes(), sig) -} - -// Equals returns true if two ECDSA public keys are equal and false otherwise. -func (key PubKey) Equals(other tmcrypto.PubKey) bool { - if other, ok := other.(PubKey); ok { - return bytes.Equal(key.Bytes(), other.Bytes()) - } - - return false -} diff --git a/contracts/native/header_sync/okex/header_sync.go b/contracts/native/header_sync/okex/header_sync.go deleted file mode 100644 index 48ae4533..00000000 --- a/contracts/native/header_sync/okex/header_sync.go +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package okex - -import ( - "encoding/hex" - "fmt" - - "bytes" - - tbytes "github.com/tendermint/tendermint/libs/bytes" - - "github.com/cosmos/cosmos-sdk/codec" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - hscommon "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/okex/ethsecp256k1" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/log" - "github.com/polynetwork/poly/common" - cstates "github.com/polynetwork/poly/core/states" - "github.com/tendermint/tendermint/types" -) - -// Handler ... -type Handler struct { -} - -// NewHandler ... -func NewHandler() *Handler { - return &Handler{} -} - -// NewCDC ... -func NewCDC() *codec.Codec { - cdc := codec.New() - - ethsecp256k1.RegisterCodec(cdc) - return cdc -} - -type CosmosHeader struct { - Header types.Header - Commit *types.Commit - Valsets []*types.Validator -} - -// SyncGenesisHeader ... -func (h *Handler) SyncGenesisHeader(native *native.NativeContract) (err error) { - ctx := native.ContractRef().CurrentContext() - param := &hscommon.SyncGenesisHeaderParam{} - if err := utils.UnpackMethod(hscommon.ABI, hscommon.MethodSyncGenesisHeader, param, ctx.Payload); err != nil { - return fmt.Errorf("SyncGenesisHeader, contract params deserialize error: %v", err) - } - - // Get current epoch operator - ok, err := node_manager.CheckConsensusSigns(native, hscommon.MethodSyncGenesisHeader, ctx.Payload, native.ContractRef().MsgSender()) - if err != nil { - return fmt.Errorf("SyncGenesisHeader, CheckConsensusSigns error: %v", err) - } - if !ok { - return nil - } - - // get genesis header from input parameters - cdc := NewCDC() - var header CosmosHeader - err = cdc.UnmarshalBinaryBare(param.GenesisHeader, &header) - if err != nil { - return fmt.Errorf("CosmosHandler SyncGenesisHeader: %s", err) - } - // check if has genesis header - info, err := GetEpochSwitchInfo(native, param.ChainID) - if err == nil && info != nil { - return fmt.Errorf("CosmosHandler SyncGenesisHeader, genesis header had been initialized") - } - PutEpochSwitchInfo(native, param.ChainID, &CosmosEpochSwitchInfo{ - Height: header.Header.Height, - NextValidatorsHash: header.Header.NextValidatorsHash, - ChainID: header.Header.ChainID, - BlockHash: header.Header.Hash(), - }) - return nil -} - -func (h *Handler) SyncBlockHeader(native *native.NativeContract) error { - params := &hscommon.SyncBlockHeaderParam{} - { - ctx := native.ContractRef().CurrentContext() - if err := utils.UnpackMethod(hscommon.ABI, hscommon.MethodSyncBlockHeader, params, ctx.Payload); err != nil { - return err - } - } - - cdc := NewCDC() - cnt := 0 - info, err := GetEpochSwitchInfo(native, params.ChainID) - if err != nil { - return fmt.Errorf("SyncBlockHeader, get epoch switching height failed: %v", err) - } - for _, v := range params.Headers { - var myHeader CosmosHeader - err := cdc.UnmarshalBinaryBare(v, &myHeader) - if err != nil { - return fmt.Errorf("SyncBlockHeader failed to unmarshal header: %v", err) - } - if bytes.Equal(myHeader.Header.NextValidatorsHash, myHeader.Header.ValidatorsHash) { - continue - } - if info.Height >= myHeader.Header.Height { - log.Debugf("SyncBlockHeader, height %d is lower or equal than epoch switching height %d", - myHeader.Header.Height, info.Height) - continue - } - if err = VerifyCosmosHeader(&myHeader, info); err != nil { - return fmt.Errorf("SyncBlockHeader, failed to verify header: %v", err) - } - info.NextValidatorsHash = myHeader.Header.NextValidatorsHash - info.Height = myHeader.Header.Height - info.BlockHash = myHeader.Header.Hash() - cnt++ - } - if cnt == 0 { - return fmt.Errorf("no header you commited is useful") - } - PutEpochSwitchInfo(native, params.ChainID, info) - return nil -} - -// SyncCrossChainMsg ... -func (h *Handler) SyncCrossChainMsg(native *native.NativeContract) error { - return nil -} - -func GetEpochSwitchInfo(service *native.NativeContract, chainId uint64) (*CosmosEpochSwitchInfo, error) { - val, err := service.GetCacheDB().Get( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(hscommon.EPOCH_SWITCH), utils.GetUint64Bytes(chainId))) - if err != nil { - return nil, fmt.Errorf("failed to get epoch switching height: %v", err) - } - raw, err := cstates.GetValueFromRawStorageItem(val) - if err != nil { - return nil, fmt.Errorf("deserialize bytes from raw storage item err: %v", err) - } - info := &CosmosEpochSwitchInfo{} - if err = info.Deserialization(common.NewZeroCopySource(raw)); err != nil { - return nil, fmt.Errorf("failed to deserialize CosmosEpochSwitchInfo: %v", err) - } - return info, nil -} - -func PutEpochSwitchInfo(service *native.NativeContract, chainId uint64, info *CosmosEpochSwitchInfo) { - sink := common.NewZeroCopySink(nil) - info.Serialization(sink) - service.GetCacheDB().Put( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(hscommon.EPOCH_SWITCH), utils.GetUint64Bytes(chainId)), - cstates.GenRawStorageItem(sink.Bytes())) - notifyEpochSwitchInfo(service, chainId, info) -} - -func notifyEpochSwitchInfo(native *native.NativeContract, chainID uint64, info *CosmosEpochSwitchInfo) { - - native.AddNotify(hscommon.ABI, []string{"OKEpochSwitchInfoEvent"}, chainID, info.BlockHash.String(), info.Height, - info.NextValidatorsHash.String(), info.ChainID, native.ContractRef().BlockHeight()) - -} - -type CosmosEpochSwitchInfo struct { - // The height where validators set changed last time. Poly only accept - // header and proof signed by new validators. That means the header - // can not be lower than this height. - Height int64 - - // Hash of the block at `Height`. Poly don't save the whole header. - // So we can identify the content of this block by `BlockHash`. - BlockHash tbytes.HexBytes - - // The hash of new validators set which used to verify validators set - // committed with proof. - NextValidatorsHash tbytes.HexBytes - - // The cosmos chain-id of this chain basing Cosmos-sdk. - ChainID string -} - -func (info *CosmosEpochSwitchInfo) Serialization(sink *common.ZeroCopySink) { - sink.WriteInt64(info.Height) - sink.WriteVarBytes(info.BlockHash) - sink.WriteVarBytes(info.NextValidatorsHash) - sink.WriteString(info.ChainID) -} - -func (info *CosmosEpochSwitchInfo) Deserialization(source *common.ZeroCopySource) error { - var eof bool - info.Height, eof = source.NextInt64() - if eof { - return fmt.Errorf("deserialize height of CosmosEpochSwitchInfo failed") - } - info.BlockHash, eof = source.NextVarBytes() - if eof { - return fmt.Errorf("deserialize BlockHash of CosmosEpochSwitchInfo failed") - } - info.NextValidatorsHash, eof = source.NextVarBytes() - if eof { - return fmt.Errorf("deserialize NextValidatorsHash of CosmosEpochSwitchInfo failed") - } - info.ChainID, eof = source.NextString() - if eof { - return fmt.Errorf("deserialize ChainID of CosmosEpochSwitchInfo failed") - } - return nil -} - -func VerifyCosmosHeader(myHeader *CosmosHeader, info *CosmosEpochSwitchInfo) error { - // now verify this header - valset := types.NewValidatorSet(myHeader.Valsets) - if !bytes.Equal(info.NextValidatorsHash, valset.Hash()) { - return fmt.Errorf("VerifyCosmosHeader, block validator is not right, next validator hash: %s, "+ - "validator set hash: %s", info.NextValidatorsHash.String(), hex.EncodeToString(valset.Hash())) - } - if !bytes.Equal(myHeader.Header.ValidatorsHash, valset.Hash()) { - return fmt.Errorf("VerifyCosmosHeader, block validator is not right!, header validator hash: %s, "+ - "validator set hash: %s", myHeader.Header.ValidatorsHash.String(), hex.EncodeToString(valset.Hash())) - } - if myHeader.Commit.GetHeight() != myHeader.Header.Height { - return fmt.Errorf("VerifyCosmosHeader, commit height is not right! commit height: %d, "+ - "header height: %d", myHeader.Commit.GetHeight(), myHeader.Header.Height) - } - if !bytes.Equal(myHeader.Commit.BlockID.Hash, myHeader.Header.Hash()) { - return fmt.Errorf("VerifyCosmosHeader, commit hash is not right!, commit block hash: %s,"+ - " header hash: %s", myHeader.Commit.BlockID.Hash.String(), hex.EncodeToString(valset.Hash())) - } - if err := myHeader.Commit.ValidateBasic(); err != nil { - return fmt.Errorf("VerifyCosmosHeader, commit is not right! err: %s", err.Error()) - } - if valset.Size() != len(myHeader.Commit.Signatures) { - return fmt.Errorf("VerifyCosmosHeader, the size of precommits is not right!") - } - talliedVotingPower := int64(0) - for idx, commitSig := range myHeader.Commit.Signatures { - if commitSig.Absent() { - continue // OK, some precommits can be missing. - } - _, val := valset.GetByIndex(idx) - // Validate signature. - precommitSignBytes := myHeader.Commit.VoteSignBytes(info.ChainID, idx) - if !val.PubKey.VerifyBytes(precommitSignBytes, commitSig.Signature) { - return fmt.Errorf("VerifyCosmosHeader, Invalid commit -- invalid signature: %v", commitSig) - } - // Good precommit! - if myHeader.Commit.BlockID.Equals(commitSig.BlockID(myHeader.Commit.BlockID)) { - talliedVotingPower += val.VotingPower - } - } - if talliedVotingPower <= valset.TotalVotingPower()*2/3 { - return fmt.Errorf("VerifyCosmosHeader, voteing power is not enough!") - } - - return nil -} diff --git a/contracts/native/header_sync/polygon/bor_header_sync.go b/contracts/native/header_sync/polygon/bor_header_sync.go deleted file mode 100644 index bfef01f6..00000000 --- a/contracts/native/header_sync/polygon/bor_header_sync.go +++ /dev/null @@ -1,869 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package polygon - -import ( - "bytes" - "encoding/hex" - "encoding/json" - "errors" - "fmt" - "io" - "math/big" - "sort" - "time" - - "github.com/cosmos/cosmos-sdk/codec" - ecommon "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - scom "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth/types" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" - cstates "github.com/polynetwork/poly/core/states" - polygonTypes "github.com/polynetwork/poly/native/service/header_sync/polygon/types" - "github.com/tendermint/tendermint/crypto/merkle" - "golang.org/x/crypto/sha3" -) - -// BorHandler ... -type BorHandler struct { -} - -// NewHandler ... -func NewBorHandler() *BorHandler { - return &BorHandler{} -} - -// HeaderWithOptionalSnap ... -type HeaderWithOptionalSnap struct { - Header types.Header - Snapshot *Snapshot -} - -// SyncGenesisHeader ... -func (h *BorHandler) SyncGenesisHeader(native *native.NativeContract) (err error) { - ctx := native.ContractRef().CurrentContext() - params := &scom.SyncGenesisHeaderParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodSyncGenesisHeader, params, ctx.Payload); err != nil { - return fmt.Errorf("SyncGenesisHeader, contract params deserialize error: %v", err) - } - - // Get current epoch operator - ok, err := node_manager.CheckConsensusSigns(native, scom.MethodSyncGenesisHeader, ctx.Payload, native.ContractRef().MsgSender()) - if err != nil { - return fmt.Errorf("SyncGenesisHeader, CheckConsensusSigns error: %v", err) - } - if !ok { - return nil - } - - // can only store once - stored, err := isGenesisStored(native, params) - if err != nil { - return fmt.Errorf("bor Handler SyncGenesisHeader, isGenesisStored error: %v", err) - } - if stored { - return fmt.Errorf("bor Handler SyncGenesisHeader, genesis had been initialized") - } - - var genesis HeaderWithOptionalSnap - err = json.Unmarshal(params.GenesisHeader, &genesis) - if err != nil { - return fmt.Errorf("bor Handler SyncGenesisHeader, deserialize GenesisHeader err: %v", err) - } - - if genesis.Snapshot == nil { - return fmt.Errorf("bor Handler SyncGenesisHeader, genesis.Snapshot is nil") - } - side, err := side_chain_manager.GetSideChain(native, params.ChainID) - if err != nil { - return fmt.Errorf("bor Handler SyncGenesisHeader, GetSideChain error: %v", err) - } - var extraInfo ExtraInfo - err = json.Unmarshal(side.ExtraInfo, &extraInfo) - if err != nil { - return fmt.Errorf("bor Handler SyncGenesisHeader, ExtraInfo Unmarshal error: %v", err) - } - - err = storeGenesis(native, params, &genesis) - if err != nil { - return fmt.Errorf("bor Handler SyncGenesisHeader, storeGenesis error: %v", err) - } - - return -} - -func isGenesisStored(native *native.NativeContract, params *scom.SyncGenesisHeaderParam) (stored bool, err error) { - genesis, err := getGenesis(native, params.ChainID) - if err != nil { - return - } - - stored = genesis != nil - return -} - -func getGenesis(native *native.NativeContract, chainID uint64) (genesisHeader *HeaderWithOptionalSnap, err error) { - - genesisBytes, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.GENESIS_HEADER), utils.GetUint64Bytes(chainID))) - if err != nil { - err = fmt.Errorf("getGenesis, GetCacheDB err:%v", err) - return - } - - if genesisBytes == nil { - return - } - - genesisBytes, err = cstates.GetValueFromRawStorageItem(genesisBytes) - if err != nil { - err = fmt.Errorf("getGenesis, GetValueFromRawStorageItem err:%v", err) - return - } - - { - genesisHeader = &HeaderWithOptionalSnap{} - err = json.Unmarshal(genesisBytes, &genesisHeader) - if err != nil { - err = fmt.Errorf("getGenesis, json.Unmarshal err:%v", err) - return - } - } - - return -} - -func storeGenesis(native *native.NativeContract, params *scom.SyncGenesisHeaderParam, genesisHeader *HeaderWithOptionalSnap) (err error) { - - genesisBytes, err := json.Marshal(genesisHeader) - if err != nil { - return - } - - native.GetCacheDB().Put( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.GENESIS_HEADER), utils.GetUint64Bytes(params.ChainID)), - cstates.GenRawStorageItem(genesisBytes)) - - headerWithSum := &HeaderWithDifficultySum{HeaderWithOptionalSnap: genesisHeader, DifficultySum: genesisHeader.Header.Difficulty} - - err = putHeaderWithSum(native, params.ChainID, headerWithSum) - if err != nil { - return - } - - putCanonicalHeight(native, params.ChainID, genesisHeader.Header.Number.Uint64()) - putCanonicalHash(native, params.ChainID, genesisHeader.Header.Number.Uint64(), genesisHeader.Header.Hash()) - - scom.NotifyPutHeader(native, params.ChainID, genesisHeader.Header.Number.Uint64(), genesisHeader.Header.Hash().Hex()) - return -} - -type ExtraInfo struct { - Sprint uint64 - Period uint64 - ProducerDelay uint64 - BackupMultiplier uint64 - HeimdallPolyChainID uint64 -} - -type Context struct { - ExtraInfo ExtraInfo - ChainID uint64 - Cdc *codec.Codec -} - -type HeaderWithDifficultySum struct { - HeaderWithOptionalSnap *HeaderWithOptionalSnap `json:"headerWithOptionalSnap"` - DifficultySum *big.Int `json:"difficultySum"` - SnapParentHash *ecommon.Hash `json:"snapParentHash"` -} - -type HeaderWithOptionalProof struct { - Header types.Header - Proof []byte -} - -// SyncBlockHeader ... -func (h *BorHandler) SyncBlockHeader(native *native.NativeContract) error { - headerParams := &scom.SyncBlockHeaderParam{} - { - ctx := native.ContractRef().CurrentContext() - if err := utils.UnpackMethod(scom.ABI, scom.MethodSyncBlockHeader, headerParams, ctx.Payload); err != nil { - return err - } - } - - side, err := side_chain_manager.GetSideChain(native, headerParams.ChainID) - if err != nil { - return fmt.Errorf("bor Handler SyncBlockHeader, GetSideChain error: %v", err) - } - var extraInfo ExtraInfo - err = json.Unmarshal(side.ExtraInfo, &extraInfo) - if err != nil { - return fmt.Errorf("bor Handler SyncBlockHeader, ExtraInfo Unmarshal error: %v", err) - } - - ctx := &Context{ExtraInfo: extraInfo, ChainID: headerParams.ChainID, Cdc: polygonTypes.NewCDC()} - - for _, v := range headerParams.Headers { - var headerWOP HeaderWithOptionalProof - err := json.Unmarshal(v, &headerWOP) - if err != nil { - return fmt.Errorf("bor Handler SyncBlockHeader, deserialize header err: %v", err) - } - headerHash := headerWOP.Header.Hash() - - exist, err := isHeaderExist(native, headerHash, ctx) - if err != nil { - return fmt.Errorf("bor Handler SyncBlockHeader, isHeaderExist headerHash err: %v", err) - } - if exist { - log.Warnf("bor Handler SyncBlockHeader, header has exist. Header: %s", string(v)) - continue - } - - parentExist, err := isHeaderExist(native, headerWOP.Header.ParentHash, ctx) - if err != nil { - return fmt.Errorf("bor Handler SyncBlockHeader, isHeaderExist ParentHash err: %v", err) - } - if !parentExist { - return fmt.Errorf("bor Handler SyncBlockHeader, parent header not exist. Header: %s", string(v)) - } - - var snap *Snapshot - snap, err = verifyHeader(native, &headerWOP, ctx) - if err != nil { - return fmt.Errorf("bor Handler SyncBlockHeader, verifyHeader err: %v", err) - } - - err = addHeader(native, &headerWOP.Header, snap, ctx) - if err != nil { - return fmt.Errorf("bor Handler SyncBlockHeader, addHeader err: %v", err) - } - - scom.NotifyPutHeader(native, headerParams.ChainID, headerWOP.Header.Number.Uint64(), headerWOP.Header.Hash().Hex()) - } - return nil -} - -func isHeaderExist(native *native.NativeContract, headerHash ecommon.Hash, ctx *Context) (bool, error) { - headerStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(ctx.ChainID), headerHash.Bytes())) - if err != nil { - return false, fmt.Errorf("bor Handler isHeaderExist error: %v", err) - } - - return headerStore != nil, nil -} - -// GetCanonicalHeight ... -func GetCanonicalHeight(native *native.NativeContract, chainID uint64) (height uint64, err error) { - heightStore, err := native.GetCacheDB().Get( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.CURRENT_HEADER_HEIGHT), utils.GetUint64Bytes(chainID))) - if err != nil { - err = fmt.Errorf("bor Handler GetCanonicalHeight err:%v", err) - return - } - - storeBytes, err := cstates.GetValueFromRawStorageItem(heightStore) - if err != nil { - err = fmt.Errorf("bor Handler GetCanonicalHeight, GetValueFromRawStorageItem err:%v", err) - return - } - - height = utils.GetBytesUint64(storeBytes) - return -} - -// GetCanonicalHeader ... -func GetCanonicalHeader(native *native.NativeContract, chainID uint64, height uint64) (headerWithSum *HeaderWithDifficultySum, err error) { - hash, err := getCanonicalHash(native, chainID, height) - if err != nil { - return - } - - if hash == (ecommon.Hash{}) { - return - } - - headerWithSum, err = getHeader(native, hash, chainID) - return -} - -func deleteCanonicalHash(native *native.NativeContract, chainID uint64, height uint64) { - native.GetCacheDB().Delete(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(height))) -} - -func getCanonicalHash(native *native.NativeContract, chainID uint64, height uint64) (hash ecommon.Hash, err error) { - hashBytesStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(height))) - if err != nil { - return - } - - if hashBytesStore == nil { - return - } - - hashBytes, err := cstates.GetValueFromRawStorageItem(hashBytesStore) - if err != nil { - err = fmt.Errorf("bor Handler getCanonicalHash, GetValueFromRawStorageItem err:%v", err) - return - } - - hash = ecommon.BytesToHash(hashBytes) - return -} - -func putCanonicalHash(native *native.NativeContract, chainID uint64, height uint64, hash ecommon.Hash) { - native.GetCacheDB().Put(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(height)), - cstates.GenRawStorageItem(hash.Bytes())) -} - -func putHeaderWithSum(native *native.NativeContract, chainID uint64, headerWithSum *HeaderWithDifficultySum) (err error) { - - headerBytes, err := json.Marshal(headerWithSum) - if err != nil { - return - } - - native.GetCacheDB().Put( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), headerWithSum.HeaderWithOptionalSnap.Header.Hash().Bytes()), - cstates.GenRawStorageItem(headerBytes)) - return -} - -func putCanonicalHeight(native *native.NativeContract, chainID uint64, height uint64) { - native.GetCacheDB().Put( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.CURRENT_HEADER_HEIGHT), utils.GetUint64Bytes(chainID)), - cstates.GenRawStorageItem(utils.GetUint64Bytes(uint64(height)))) -} - -func addHeader(native *native.NativeContract, header *types.Header, snap *Snapshot, ctx *Context) (err error) { - - parentHeader, err := getHeader(native, header.ParentHash, ctx.ChainID) - if err != nil { - return - } - - cheight, err := GetCanonicalHeight(native, ctx.ChainID) - if err != nil { - return - } - cheader, err := GetCanonicalHeader(native, ctx.ChainID, cheight) - if err != nil { - return - } - if cheader == nil { - err = fmt.Errorf("getCanonicalHeader returns nil") - return - } - - localTd := cheader.DifficultySum - externTd := new(big.Int).Add(header.Difficulty, parentHeader.DifficultySum) - - headerWithSum := &HeaderWithDifficultySum{HeaderWithOptionalSnap: &HeaderWithOptionalSnap{Header: *header}, DifficultySum: externTd} - if snap.Hash == header.Hash() { - headerWithSum.HeaderWithOptionalSnap.Snapshot = snap - } else { - headerWithSum.SnapParentHash = &snap.Hash - } - err = putHeaderWithSum(native, ctx.ChainID, headerWithSum) - if err != nil { - return - } - - if externTd.Cmp(localTd) > 0 { - // Delete any canonical number assignments above the new head - var headerWithSum *HeaderWithDifficultySum - for i := header.Number.Uint64() + 1; ; i++ { - headerWithSum, err = GetCanonicalHeader(native, ctx.ChainID, i) - if err != nil { - return - } - if headerWithSum == nil { - break - } - - deleteCanonicalHash(native, ctx.ChainID, i) - } - - // Overwrite any stale canonical number assignments - var ( - hash ecommon.Hash - headHeader *HeaderWithDifficultySum - ) - cheight := header.Number.Uint64() - 1 - headHash := header.ParentHash - - for { - hash, err = getCanonicalHash(native, ctx.ChainID, cheight) - if err != nil { - return - } - if hash == headHash { - break - } - - putCanonicalHash(native, ctx.ChainID, cheight, headHash) - headHeader, err = getHeader(native, headHash, ctx.ChainID) - if err != nil { - return - } - headHash = headHeader.HeaderWithOptionalSnap.Header.ParentHash - cheight-- - } - - // Extend the canonical chain with the new header - putCanonicalHash(native, ctx.ChainID, header.Number.Uint64(), header.Hash()) - putCanonicalHeight(native, ctx.ChainID, header.Number.Uint64()) - } - - return nil -} - -func getHeader(native *native.NativeContract, hash ecommon.Hash, chainID uint64) (headerWithSum *HeaderWithDifficultySum, err error) { - - headerStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), hash.Bytes())) - if err != nil { - return nil, fmt.Errorf("bor Handler getHeader error: %v", err) - } - if headerStore == nil { - return nil, fmt.Errorf("bor Handler getHeader, can not find any header records") - } - storeBytes, err := cstates.GetValueFromRawStorageItem(headerStore) - if err != nil { - return nil, fmt.Errorf("bor Handler getHeader, deserialize headerBytes from raw storage item err:%v", err) - } - headerWithSum = &HeaderWithDifficultySum{} - if err := json.Unmarshal(storeBytes, &headerWithSum); err != nil { - return nil, fmt.Errorf("bor Handler getHeader, deserialize header error: %v", err) - } - - return -} - -var ( - extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity - extraSeal = crypto.SignatureLength // Fixed number of extra-data suffix bytes reserved for signer seal - uncleHash = types.CalcUncleHash(nil) // Always Keccak256(RLP([])) as uncles are meaningless outside of PoW. - - validatorHeaderBytesLength = ecommon.AddressLength + 20 // address + power - -) - -func verifyHeader(native *native.NativeContract, headerWOP *HeaderWithOptionalProof, ctx *Context) (snap *Snapshot, err error) { - header := &headerWOP.Header - if header.Number == nil { - err = fmt.Errorf("errUnknownBlock") - return - } - number := header.Number.Uint64() - // Don't waste time checking blocks from the future - if header.Time > uint64(time.Now().Unix()) { - err = errors.New("block in the future") - return - } - - // check extr adata - isSprintEnd := (number+1)%ctx.ExtraInfo.Sprint == 0 - - // Ensure that the extra-data contains a signer list on checkpoint, but none otherwise - signersBytes := len(header.Extra) - extraVanity - extraSeal - if !isSprintEnd && signersBytes != 0 { - err = errors.New("errExtraValidators") - return - } - if isSprintEnd && signersBytes%validatorHeaderBytesLength != 0 { - err = errors.New("errInvalidSpanValidators") - return - } - if isSprintEnd { - if err = validateHeaderExtraField(native, headerWOP, ctx); err != nil { - return - } - } else { - if headerWOP.Proof != nil { - err = fmt.Errorf("Proof should be nil for non sprint end") - return - } - } - // Ensure that the mix digest is zero as we don't have fork protection currently - if header.MixDigest != (ecommon.Hash{}) { - err = errors.New("non-zero mix digest") - return - } - // Ensure that the block doesn't contain any uncles which are meaningless in PoA - if header.UncleHash != uncleHash { - err = errors.New("non empty uncle hash") - return - } - // Ensure that the block's difficulty is meaningful (may not be correct at this point) - if number > 0 { - if header.Difficulty == nil { - err = errors.New("errInvalidDifficulty") - return - } - } - - // All basic checks passed, verify cascading fields - return verifyCascadingFields(native, header, ctx) -} - -type CosmosProof struct { - Value CosmosProofValue - Proof merkle.Proof - Header CosmosHeader -} - -type CosmosProofValue struct { - Kp string - Value []byte -} - -func putSpan(native *native.NativeContract, ctx *Context, span *Span) (err error) { - - spanBytes, err := ctx.Cdc.MarshalBinaryBare(span) - if err != nil { - err = fmt.Errorf("putSpan MarshalBinaryBare failed:%v", err) - return - } - native.GetCacheDB().Put( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.POLYGON_SPAN), utils.GetUint64Bytes(ctx.ChainID)), - cstates.GenRawStorageItem(spanBytes)) - return -} - -func getSpan(native *native.NativeContract, ctx *Context) (span *Span, err error) { - spanBytes, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.POLYGON_SPAN), utils.GetUint64Bytes(ctx.ChainID))) - if err != nil { - err = fmt.Errorf("getSpan failed:%v", err) - return - } - - if spanBytes == nil { - err = fmt.Errorf("getSpan:no span") - return - } - - spanBytes, err = cstates.GetValueFromRawStorageItem(spanBytes) - if err != nil { - err = fmt.Errorf("getSpan, GetValueFromRawStorageItem err:%v", err) - return - } - - span = &Span{} - err = ctx.Cdc.UnmarshalBinaryBare(spanBytes, span) - if err != nil { - err = fmt.Errorf("getSpan, UnmarshalBinaryBare err:%v", err) - return - } - return -} - -func validateHeaderExtraFieldWithSpan(native *native.NativeContract, headerWOP *HeaderWithOptionalProof, ctx *Context, span *Span) (err error) { - if span == nil { - err = fmt.Errorf("empty span") - return - } - - height := headerWOP.Header.Number.Uint64() - if !(span.StartBlock <= (height+1) && span.EndBlock >= (height+1)) { - err = fmt.Errorf("span not correct, span.StartBlock:%d, span.EndBlock:%d, height:%d", span.StartBlock, span.EndBlock, height) - return - } - var newValidators []*Validator - for i := range span.SelectedProducers { - newValidators = append(newValidators, &span.SelectedProducers[i]) - } - sort.Sort(ValidatorsByAddress(newValidators)) - var extra []byte - for _, val := range newValidators { - extra = append(extra, val.HeaderBytes()...) - } - - if !bytes.Equal(extra, headerWOP.Header.Extra[extraVanity:len(headerWOP.Header.Extra)-extraSeal]) { - return fmt.Errorf("invalid validators for sprint end, expect:%s got:%s", hex.EncodeToString(extra), hex.EncodeToString(headerWOP.Header.Extra[extraVanity:len(headerWOP.Header.Extra)-extraSeal])) - } - return nil -} - -// only used for test -var SkipVerifySpan bool - -func validateHeaderExtraField(native *native.NativeContract, headerWOP *HeaderWithOptionalProof, ctx *Context) (err error) { - if SkipVerifySpan { - return - } - if headerWOP.Proof == nil { - var span *Span - span, err = getSpan(native, ctx) - if err != nil { - return - } - - return validateHeaderExtraFieldWithSpan(native, headerWOP, ctx, span) - } - cdc := polygonTypes.NewCDC() - var proof CosmosProof - if err = cdc.UnmarshalBinaryBare(headerWOP.Proof, &proof); err != nil { - return fmt.Errorf("validateHeaderExtraField, unmarshal CosmosProof err: %v", err) - } - - span, err := VerifySpan(native, ctx.ExtraInfo.HeimdallPolyChainID, &proof) - if err != nil { - return fmt.Errorf("VerifySpan err: %v", err) - } - - err = validateHeaderExtraFieldWithSpan(native, headerWOP, ctx, span) - if err == nil { - err = putSpan(native, ctx, span) - } - return -} - -func verifyCascadingFields(native *native.NativeContract, header *types.Header, ctx *Context) (snap *Snapshot, err error) { - - number := header.Number.Uint64() - - parent, err := getHeader(native, header.ParentHash, ctx.ChainID) - if err != nil { - return - } - - if parent.HeaderWithOptionalSnap.Header.Number.Uint64() != number-1 { - err = errors.New("unknown ancestor") - return - } - - if parent.HeaderWithOptionalSnap.Header.Time+ctx.ExtraInfo.Period > header.Time { - err = errors.New("ErrInvalidTimestamp") - return - } - - snap, err = getSnapshot(native, parent, ctx) - if err != nil { - err = fmt.Errorf("getSnapshot failed:%v", err) - return - } - - if isSprintStart(number, ctx.ExtraInfo.Sprint) { - parentHeader := parent.HeaderWithOptionalSnap.Header - parentValidatorBytes := parentHeader.Extra[extraVanity : len(parentHeader.Extra)-extraSeal] - var newVals []*Validator - newVals, err = ParseValidators(parentValidatorBytes) - if err != nil { - err = fmt.Errorf("ParseValidators failed:%v", err) - return - } - v := getUpdatedValidatorSet(snap.ValidatorSet.Copy(), newVals) - v.IncrementProposerPriority(1) - snap.ValidatorSet = v - snap.Hash = header.Hash() - } - - _, err = verifySeal(native, header, ctx, parent, snap) - - return -} - -func getUpdatedValidatorSet(oldValidatorSet *ValidatorSet, newVals []*Validator) *ValidatorSet { - v := oldValidatorSet - oldVals := v.Validators - - var changes []*Validator - for _, ov := range oldVals { - if f, ok := validatorContains(newVals, ov); ok { - ov.VotingPower = f.VotingPower - } else { - ov.VotingPower = 0 - } - - changes = append(changes, ov) - } - - for _, nv := range newVals { - if _, ok := validatorContains(changes, nv); !ok { - changes = append(changes, nv) - } - } - - v.UpdateWithChangeSet(changes) - return v -} - -func validatorContains(a []*Validator, x *Validator) (*Validator, bool) { - for _, n := range a { - if bytes.Compare(n.Address.Bytes(), x.Address.Bytes()) == 0 { - return n, true - } - } - return nil, false -} - -func shouldApplyFix(currentChainID uint64) bool { - return true -} - -func getSnapshot(native *native.NativeContract, parent *HeaderWithDifficultySum, ctx *Context) (s *Snapshot, err error) { - if parent.HeaderWithOptionalSnap.Snapshot != nil { - s = parent.HeaderWithOptionalSnap.Snapshot - if shouldApplyFix(ctx.ChainID) { - err = s.ValidatorSet.updateTotalVotingPower() - } - return - } - - if parent.SnapParentHash == nil { - err = fmt.Errorf("both Snapshot and SnapParentHash nil") - return - } - snapHeader, err := getHeader(native, *parent.SnapParentHash, ctx.ChainID) - if err != nil { - return - } - - if snapHeader.HeaderWithOptionalSnap.Snapshot == nil { - err = fmt.Errorf("snapHeader has no Snapshot") - return - } - - s = snapHeader.HeaderWithOptionalSnap.Snapshot - if shouldApplyFix(ctx.ChainID) { - err = s.ValidatorSet.updateTotalVotingPower() - } - return -} - -func isSprintStart(number, sprint uint64) bool { - return number%sprint == 0 -} - -// for test -var mockSigner ecommon.Address - -func verifySeal(native *native.NativeContract, header *types.Header, ctx *Context, parent *HeaderWithDifficultySum, snap *Snapshot) (signer ecommon.Address, err error) { - // Verifying the genesis block is not supported - number := header.Number.Uint64() - if number == 0 { - err = errors.New("unknown block") - return - } - - if mockSigner != (ecommon.Address{}) { - return mockSigner, nil - } - // Resolve the authorization key and check against validators - signer, err = ecrecover(header) - if err != nil { - return - } - if !snap.ValidatorSet.HasAddress(signer.Bytes()) { - err = fmt.Errorf("UnauthorizedSignerError:%d signer:%s", number, signer.Hex()) - return - } - succession, err := snap.GetSignerSuccessionNumber(signer) - if err != nil { - return - } - if header.Time < parent.HeaderWithOptionalSnap.Header.Time+CalcProducerDelay(number, succession, ctx) { - err = fmt.Errorf("BlockTooSoonError, n:%d,succession:%d", number, succession) - return - } - - difficulty := snap.Difficulty(signer) - if header.Difficulty.Uint64() != difficulty { - err = fmt.Errorf("WrongDifficultyError, n:%d, expected:%d, actual:%d", number, difficulty, header.Difficulty.Uint64()) - return - } - - return -} - -// CalcProducerDelay is the block delay algorithm based on block time, period, producerDelay and turn-ness of a signer -func CalcProducerDelay(number uint64, succession int, ctx *Context) uint64 { - // When the block is the first block of the sprint, it is expected to be delayed by `producerDelay`. - // That is to allow time for block propagation in the last sprint - delay := ctx.ExtraInfo.Period - if number%ctx.ExtraInfo.Sprint == 0 { - delay = ctx.ExtraInfo.ProducerDelay - } - if succession > 0 { - delay += uint64(succession) * ctx.ExtraInfo.BackupMultiplier - } - return delay -} - -// ecrecover extracts the Ethereum account address from a signed header. -func ecrecover(header *types.Header) (ecommon.Address, error) { - // Retrieve the signature from the header extra-data - if len(header.Extra) < extraSeal { - return ecommon.Address{}, errors.New("extra-data 65 byte signature suffix missing") - } - signature := header.Extra[len(header.Extra)-extraSeal:] - - // Recover the public key and the Ethereum address - pubkey, err := crypto.Ecrecover(SealHash(header).Bytes(), signature) - if err != nil { - return ecommon.Address{}, err - } - var signer ecommon.Address - copy(signer[:], crypto.Keccak256(pubkey[1:])[12:]) - - return signer, nil -} - -// SealHash returns the hash of a block prior to it being sealed. -func SealHash(header *types.Header) (hash ecommon.Hash) { - hasher := sha3.NewLegacyKeccak256() - encodeSigHeader(hasher, header) - hasher.Sum(hash[:0]) - return hash -} - -func encodeSigHeader(w io.Writer, header *types.Header) { - err := rlp.Encode(w, []interface{}{ - header.ParentHash, - header.UncleHash, - header.Coinbase, - header.Root, - header.TxHash, - header.ReceiptHash, - header.Bloom, - header.Difficulty, - header.Number, - header.GasLimit, - header.GasUsed, - header.Time, - header.Extra[:len(header.Extra)-65], // this will panic if extra is too short, should check before calling encodeSigHeader - header.MixDigest, - header.Nonce, - }) - if err != nil { - panic("can't encode: " + err.Error()) - } -} - -// SyncCrossChainMsg ... -func (h *BorHandler) SyncCrossChainMsg(native *native.NativeContract) error { - return nil -} diff --git a/contracts/native/header_sync/polygon/errors.go b/contracts/native/header_sync/polygon/errors.go deleted file mode 100644 index 5b60fd95..00000000 --- a/contracts/native/header_sync/polygon/errors.go +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package polygon - -import "fmt" - -// TotalVotingPowerExceededError is returned when the maximum allowed total voting power is exceeded -type TotalVotingPowerExceededError struct { - Sum int64 - Validators []*Validator -} - -func (e *TotalVotingPowerExceededError) Error() string { - return fmt.Sprintf( - "Total voting power should be guarded to not exceed %v; got: %v; for validator set: %v", - MaxTotalVotingPower, - e.Sum, - e.Validators, - ) -} diff --git a/contracts/native/header_sync/polygon/heimdall_header_sync.go b/contracts/native/header_sync/polygon/heimdall_header_sync.go deleted file mode 100644 index e92c3011..00000000 --- a/contracts/native/header_sync/polygon/heimdall_header_sync.go +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package polygon - -import ( - "encoding/hex" - "fmt" - - "bytes" - - "github.com/cosmos/cosmos-sdk/store/rootmulti" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - hscommon "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - polygonTypes "github.com/ethereum/go-ethereum/contracts/native/header_sync/polygon/types" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/log" - "github.com/polynetwork/poly/common" - cstates "github.com/polynetwork/poly/core/states" - polygonCmn "github.com/polynetwork/poly/native/service/header_sync/polygon/types/common" -) - -type HeimdallHandler struct { -} - -// NewHeimdallHandler ... -func NewHeimdallHandler() *HeimdallHandler { - return &HeimdallHandler{} -} - -type CosmosHeader struct { - Header polygonTypes.Header - Commit *polygonTypes.Commit - Valsets []*polygonTypes.Validator -} - -// SyncGenesisHeader ... -func (h *HeimdallHandler) SyncGenesisHeader(native *native.NativeContract) (err error) { - ctx := native.ContractRef().CurrentContext() - param := &hscommon.SyncGenesisHeaderParam{} - if err := utils.UnpackMethod(hscommon.ABI, hscommon.MethodSyncGenesisHeader, param, ctx.Payload); err != nil { - return fmt.Errorf("SyncGenesisHeader, contract param deserialize error: %v", err) - } - - // Get current epoch operator - ok, err := node_manager.CheckConsensusSigns(native, hscommon.MethodSyncGenesisHeader, ctx.Payload, native.ContractRef().MsgSender()) - if err != nil { - return fmt.Errorf("SyncGenesisHeader, CheckConsensusSigns error: %v", err) - } - if !ok { - return nil - } - // get genesis header from input parameters - cdc := polygonTypes.NewCDC() - var header CosmosHeader - err = cdc.UnmarshalBinaryBare(param.GenesisHeader, &header) - if err != nil { - return fmt.Errorf("HeimdallHandler SyncGenesisHeader: %s", err) - } - // check if has genesis header - info, err := GetEpochSwitchInfo(native, param.ChainID) - if err == nil && info != nil { - return fmt.Errorf("HeimdallHandler SyncGenesisHeader, genesis header had been initialized") - } - PutEpochSwitchInfo(native, param.ChainID, &CosmosEpochSwitchInfo{ - Height: header.Header.Height, - NextValidatorsHash: header.Header.NextValidatorsHash, - ChainID: header.Header.ChainID, - BlockHash: header.Header.Hash(), - }) - return nil -} - -func (h *HeimdallHandler) SyncBlockHeader(native *native.NativeContract) error { - params := &hscommon.SyncBlockHeaderParam{} - { - ctx := native.ContractRef().CurrentContext() - if err := utils.UnpackMethod(hscommon.ABI, hscommon.MethodSyncBlockHeader, params, ctx.Payload); err != nil { - return err - } - } - - cdc := polygonTypes.NewCDC() - cnt := 0 - info, err := GetEpochSwitchInfo(native, params.ChainID) - if err != nil { - return fmt.Errorf("SyncBlockHeader, get epoch switching height failed: %v", err) - } - for _, v := range params.Headers { - var myHeader CosmosHeader - err := cdc.UnmarshalBinaryBare(v, &myHeader) - if err != nil { - return fmt.Errorf("SyncBlockHeader failed to unmarshal header: %v", err) - } - if bytes.Equal(myHeader.Header.NextValidatorsHash, myHeader.Header.ValidatorsHash) { - continue - } - if info.Height >= myHeader.Header.Height { - log.Debugf("SyncBlockHeader, height %d is lower or equal than epoch switching height %d", - myHeader.Header.Height, info.Height) - continue - } - if err = VerifyCosmosHeader(&myHeader, info); err != nil { - return fmt.Errorf("SyncBlockHeader, failed to verify header: %v", err) - } - info.NextValidatorsHash = myHeader.Header.NextValidatorsHash - info.Height = myHeader.Header.Height - info.BlockHash = myHeader.Header.Hash() - cnt++ - } - if cnt == 0 { - return fmt.Errorf("no header you commited is useful") - } - PutEpochSwitchInfo(native, params.ChainID, info) - return nil -} - -// SyncCrossChainMsg ... -func (h *HeimdallHandler) SyncCrossChainMsg(native *native.NativeContract) error { - return nil -} - -func GetEpochSwitchInfo(service *native.NativeContract, chainId uint64) (*CosmosEpochSwitchInfo, error) { - val, err := service.GetCacheDB().Get( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(hscommon.EPOCH_SWITCH), utils.GetUint64Bytes(chainId))) - if err != nil { - return nil, fmt.Errorf("failed to get epoch switching height: %v", err) - } - raw, err := cstates.GetValueFromRawStorageItem(val) - if err != nil { - return nil, fmt.Errorf("deserialize bytes from raw storage item err: %v", err) - } - info := &CosmosEpochSwitchInfo{} - if err = info.Deserialization(common.NewZeroCopySource(raw)); err != nil { - return nil, fmt.Errorf("failed to deserialize CosmosEpochSwitchInfo: %v", err) - } - return info, nil -} - -func PutEpochSwitchInfo(service *native.NativeContract, chainId uint64, info *CosmosEpochSwitchInfo) { - sink := common.NewZeroCopySink(nil) - info.Serialization(sink) - service.GetCacheDB().Put( - utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(hscommon.EPOCH_SWITCH), utils.GetUint64Bytes(chainId)), - cstates.GenRawStorageItem(sink.Bytes())) -} - -type CosmosEpochSwitchInfo struct { - // The height where validators set changed last time. Poly only accept - // header and proof signed by new validators. That means the header - // can not be lower than this height. - Height int64 - - // Hash of the block at `Height`. Poly don't save the whole header. - // So we can identify the content of this block by `BlockHash`. - BlockHash polygonCmn.HexBytes - - // The hash of new validators set which used to verify validators set - // committed with proof. - NextValidatorsHash polygonCmn.HexBytes - - // The cosmos chain-id of this chain basing Cosmos-sdk. - ChainID string -} - -func (info *CosmosEpochSwitchInfo) Serialization(sink *common.ZeroCopySink) { - sink.WriteInt64(info.Height) - sink.WriteVarBytes(info.BlockHash) - sink.WriteVarBytes(info.NextValidatorsHash) - sink.WriteString(info.ChainID) -} - -func (info *CosmosEpochSwitchInfo) Deserialization(source *common.ZeroCopySource) error { - var eof bool - info.Height, eof = source.NextInt64() - if eof { - return fmt.Errorf("deserialize height of CosmosEpochSwitchInfo failed") - } - info.BlockHash, eof = source.NextVarBytes() - if eof { - return fmt.Errorf("deserialize BlockHash of CosmosEpochSwitchInfo failed") - } - info.NextValidatorsHash, eof = source.NextVarBytes() - if eof { - return fmt.Errorf("deserialize NextValidatorsHash of CosmosEpochSwitchInfo failed") - } - info.ChainID, eof = source.NextString() - if eof { - return fmt.Errorf("deserialize ChainID of CosmosEpochSwitchInfo failed") - } - return nil -} - -func VerifySpan(native *native.NativeContract, heimdallPolyChainID uint64, proof *CosmosProof) (span *Span, err error) { - info, err := GetEpochSwitchInfo(native, heimdallPolyChainID) - if err != nil { - err = fmt.Errorf("HeimdallHandler failed to get epoch switching height: %v", err) - return - } - - if err = VerifyCosmosHeader(&proof.Header, info); err != nil { - return nil, fmt.Errorf("HeimdallHandler failed to verify cosmos header: %v", err) - } - - if len(proof.Proof.Ops) != 2 { - err = fmt.Errorf("proof size wrong") - return - } - if !bytes.Equal(proof.Proof.Ops[1].Key, []byte("bor")) { - err = fmt.Errorf("wrong module for proof") - return - } - - prt := rootmulti.DefaultProofRuntime() - - err = prt.VerifyValue(&proof.Proof, proof.Header.Header.AppHash, proof.Value.Kp, proof.Value.Value) - if err != nil { - err = fmt.Errorf("validateHeaderExtraField VerifyValue error: %s", err) - return - } - - heimdallSpan := &polygonTypes.HeimdallSpan{} - err = polygonTypes.NewCDC().UnmarshalBinaryBare(proof.Value.Value, heimdallSpan) - if err != nil { - err = fmt.Errorf("validateHeaderExtraField heimdallSpan UnmarshalBinaryBare error: %s", err) - return - } - - span, err = SpanFromHeimdall(heimdallSpan) - return -} - -func VerifyCosmosHeader(myHeader *CosmosHeader, info *CosmosEpochSwitchInfo) error { - // now verify this header - valset := polygonTypes.NewValidatorSet(myHeader.Valsets) - if !bytes.Equal(info.NextValidatorsHash, valset.Hash()) { - return fmt.Errorf("VerifyCosmosHeader, block validator is not right, next validator hash: %s, "+ - "validator set hash: %s", info.NextValidatorsHash.String(), hex.EncodeToString(valset.Hash())) - } - if !bytes.Equal(myHeader.Header.ValidatorsHash, valset.Hash()) { - return fmt.Errorf("VerifyCosmosHeader, block validator is not right!, header validator hash: %s, "+ - "validator set hash: %s", myHeader.Header.ValidatorsHash.String(), hex.EncodeToString(valset.Hash())) - } - if myHeader.Commit.Height() != myHeader.Header.Height { - return fmt.Errorf("VerifyCosmosHeader, commit height is not right! commit height: %d, "+ - "header height: %d", myHeader.Commit.Height(), myHeader.Header.Height) - } - if !bytes.Equal(myHeader.Commit.BlockID.Hash, myHeader.Header.Hash()) { - return fmt.Errorf("VerifyCosmosHeader, commit hash is not right!, commit block hash: %s,"+ - " header hash: %s", myHeader.Commit.BlockID.Hash.String(), hex.EncodeToString(valset.Hash())) - } - if err := myHeader.Commit.ValidateBasic(); err != nil { - return fmt.Errorf("VerifyCosmosHeader, commit is not right! err: %s", err.Error()) - } - if valset.Size() != myHeader.Commit.Size() { - return fmt.Errorf("VerifyCosmosHeader, the size of precommits is not right!") - } - talliedVotingPower := int64(0) - for _, commitSig := range myHeader.Commit.Precommits { - if commitSig == nil { - continue - } - idx := commitSig.ValidatorIndex - _, val := valset.GetByIndex(idx) - if val == nil { - return fmt.Errorf("VerifyCosmosHeader, validator %d doesn't exist!", idx) - } - if commitSig.Type != polygonTypes.PrecommitType { - return fmt.Errorf("VerifyCosmosHeader, commitSig.Type(%d) wrong", commitSig.Type) - } - // Validate signature. - precommitSignBytes := myHeader.Commit.VoteSignBytes(info.ChainID, idx) - if !val.PubKey.VerifyBytes(precommitSignBytes, commitSig.Signature) { - return fmt.Errorf("VerifyCosmosHeader, Invalid commit -- invalid signature: %v", commitSig) - } - // Good precommit! - if myHeader.Commit.BlockID.Equals(commitSig.BlockID) { - talliedVotingPower += val.VotingPower - } - } - if talliedVotingPower <= valset.TotalVotingPower()*2/3 { - return fmt.Errorf("VerifyCosmosHeader, voteing power is not enough!") - } - - return nil -} diff --git a/contracts/native/header_sync/polygon/snapshot.go b/contracts/native/header_sync/polygon/snapshot.go deleted file mode 100644 index e35d5c75..00000000 --- a/contracts/native/header_sync/polygon/snapshot.go +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package polygon - -import ( - "bytes" - "fmt" - - "github.com/ethereum/go-ethereum/common" -) - -// Snapshot is the state of the authorization voting at a given point in time. -type Snapshot struct { - Hash common.Hash `json:"hash"` // Block hash where the snapshot was created - ValidatorSet *ValidatorSet `json:"validatorSet"` // Validator set at this moment -} - -func (s *Snapshot) GetSignerSuccessionNumber(signer common.Address) (int, error) { - vs := s.ValidatorSet - proposer := vs.GetProposer().Address - proposerIndex, _ := vs.GetByAddress(proposer) - if proposerIndex == -1 { - return -1, fmt.Errorf("UnauthorizedProposerError:%s", proposer.Hex()) - } - signerIndex, _ := vs.GetByAddress(signer) - if signerIndex == -1 { - return -1, fmt.Errorf("UnauthorizedProposerError:%s", proposer.Hex()) - } - - tempIndex := signerIndex - if proposerIndex != tempIndex { - if tempIndex < proposerIndex { - tempIndex = tempIndex + len(vs.Validators) - } - } - return tempIndex - proposerIndex, nil -} - -func (s *Snapshot) Difficulty(signer common.Address) uint64 { - // if signer is empty - if bytes.Compare(signer.Bytes(), common.Address{}.Bytes()) == 0 { - return 1 - } - - validators := s.ValidatorSet.Validators - proposer := s.ValidatorSet.GetProposer().Address - totalValidators := len(validators) - - proposerIndex, _ := s.ValidatorSet.GetByAddress(proposer) - signerIndex, _ := s.ValidatorSet.GetByAddress(signer) - - // temp index - tempIndex := signerIndex - if tempIndex < proposerIndex { - tempIndex = tempIndex + totalValidators - } - - return uint64(totalValidators - (tempIndex - proposerIndex)) -} - -// only used in test -func (s *Snapshot) Equal(s2 *Snapshot) bool { - - return s.ValidatorSet.String() == s2.ValidatorSet.String() -} diff --git a/contracts/native/header_sync/polygon/span.go b/contracts/native/header_sync/polygon/span.go deleted file mode 100644 index 810c8f5e..00000000 --- a/contracts/native/header_sync/polygon/span.go +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package polygon - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/common" - polygonTypes "github.com/ethereum/go-ethereum/contracts/native/header_sync/polygon/types" -) - -type Span struct { - ID uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id" yaml:"id"` - StartBlock uint64 `protobuf:"varint,2,opt,name=start_block,json=startBlock,proto3" json:"start_block" yaml:"start_block"` - EndBlock uint64 `protobuf:"varint,3,opt,name=end_block,json=endBlock,proto3" json:"end_block" yaml:"end_block"` - ValidatorSet ValidatorSet `protobuf:"bytes,4,opt,name=validator_set,json=validatorSet,proto3" json:"validator_set" yaml:"validator_set"` - SelectedProducers []Validator `protobuf:"bytes,5,rep,name=selected_producers,json=selectedProducers,proto3" json:"selected_producers" yaml:"selected_producers"` - BorChainId string `protobuf:"bytes,6,opt,name=bor_chain_id,json=borChainId,proto3" json:"bor_chain_id" yaml:"bor_chain_id"` -} - -func SpanFromHeimdall(hs *polygonTypes.HeimdallSpan) (span *Span, err error) { - span = &Span{ - ID: hs.ID, - StartBlock: hs.StartBlock, - EndBlock: hs.EndBlock, - BorChainId: hs.BorChainId, - } - - var bp Validator - for _, hp := range hs.SelectedProducers { - bp, err = ValidatorFromHeimdall(&hp) - if err != nil { - return - } - span.SelectedProducers = append(span.SelectedProducers, bp) - } - - span.ValidatorSet, err = ValidatorSetFromHeimdall(&hs.ValidatorSet) - return -} - -func ValidatorSetFromHeimdall(hvs *polygonTypes.HeimdallValidatorSet) (bvs ValidatorSet, err error) { - proposer, err := ValidatorFromHeimdall(hvs.Proposer) - if err != nil { - return - } - bvs.Proposer = &proposer - - for _, hv := range hvs.Validators { - var bv Validator - bv, err = ValidatorFromHeimdall(hv) - if err != nil { - return - } - bvs.Validators = append(bvs.Validators, &bv) - } - return -} - -func ValidatorFromHeimdall(val *polygonTypes.HeimdallValidator) (v Validator, err error) { - if len(val.PubKey) != 65 { - err = fmt.Errorf("invalid pubkey from heimdall") - return - } - if len(val.Signer) != 20 { - err = fmt.Errorf("invalid signer from heimdall") - return - } - v = Validator{ - ID: uint64(val.ID), - VotingPower: val.VotingPower, - ProposerPriority: val.ProposerPriority, - Address: common.BytesToAddress([]byte(val.Signer)), - } - return -} diff --git a/contracts/native/header_sync/polygon/types/common/bit_array.go b/contracts/native/header_sync/polygon/types/common/bit_array.go deleted file mode 100644 index 2afbe928..00000000 --- a/contracts/native/header_sync/polygon/types/common/bit_array.go +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package common - -import ( - "encoding/binary" - "fmt" - "regexp" - "strings" - "sync" -) - -// BitArray is a thread-safe implementation of a bit array. -type BitArray struct { - mtx sync.Mutex - Bits int `json:"bits"` // NOTE: persisted via reflect, must be exported - Elems []uint64 `json:"elems"` // NOTE: persisted via reflect, must be exported -} - -// NewBitArray returns a new bit array. -// It returns nil if the number of bits is zero. -func NewBitArray(bits int) *BitArray { - if bits <= 0 { - return nil - } - return &BitArray{ - Bits: bits, - Elems: make([]uint64, (bits+63)/64), - } -} - -// Size returns the number of bits in the bitarray -func (bA *BitArray) Size() int { - if bA == nil { - return 0 - } - return bA.Bits -} - -// GetIndex returns the bit at index i within the bit array. -// The behavior is undefined if i >= bA.Bits -func (bA *BitArray) GetIndex(i int) bool { - if bA == nil { - return false - } - bA.mtx.Lock() - defer bA.mtx.Unlock() - return bA.getIndex(i) -} - -func (bA *BitArray) getIndex(i int) bool { - if i >= bA.Bits { - return false - } - return bA.Elems[i/64]&(uint64(1)< 0 -} - -// SetIndex sets the bit at index i within the bit array. -// The behavior is undefined if i >= bA.Bits -func (bA *BitArray) SetIndex(i int, v bool) bool { - if bA == nil { - return false - } - bA.mtx.Lock() - defer bA.mtx.Unlock() - return bA.setIndex(i, v) -} - -func (bA *BitArray) setIndex(i int, v bool) bool { - if i >= bA.Bits { - return false - } - if v { - bA.Elems[i/64] |= (uint64(1) << uint(i%64)) - } else { - bA.Elems[i/64] &= ^(uint64(1) << uint(i%64)) - } - return true -} - -// Copy returns a copy of the provided bit array. -func (bA *BitArray) Copy() *BitArray { - if bA == nil { - return nil - } - bA.mtx.Lock() - defer bA.mtx.Unlock() - return bA.copy() -} - -func (bA *BitArray) copy() *BitArray { - c := make([]uint64, len(bA.Elems)) - copy(c, bA.Elems) - return &BitArray{ - Bits: bA.Bits, - Elems: c, - } -} - -func (bA *BitArray) copyBits(bits int) *BitArray { - c := make([]uint64, (bits+63)/64) - copy(c, bA.Elems) - return &BitArray{ - Bits: bits, - Elems: c, - } -} - -// Or returns a bit array resulting from a bitwise OR of the two bit arrays. -// If the two bit-arrys have different lengths, Or right-pads the smaller of the two bit-arrays with zeroes. -// Thus the size of the return value is the maximum of the two provided bit arrays. -func (bA *BitArray) Or(o *BitArray) *BitArray { - if bA == nil && o == nil { - return nil - } - if bA == nil && o != nil { - return o.Copy() - } - if o == nil { - return bA.Copy() - } - bA.mtx.Lock() - o.mtx.Lock() - c := bA.copyBits(MaxInt(bA.Bits, o.Bits)) - smaller := MinInt(len(bA.Elems), len(o.Elems)) - for i := 0; i < smaller; i++ { - c.Elems[i] |= o.Elems[i] - } - bA.mtx.Unlock() - o.mtx.Unlock() - return c -} - -// And returns a bit array resulting from a bitwise AND of the two bit arrays. -// If the two bit-arrys have different lengths, this truncates the larger of the two bit-arrays from the right. -// Thus the size of the return value is the minimum of the two provided bit arrays. -func (bA *BitArray) And(o *BitArray) *BitArray { - if bA == nil || o == nil { - return nil - } - bA.mtx.Lock() - o.mtx.Lock() - defer func() { - bA.mtx.Unlock() - o.mtx.Unlock() - }() - return bA.and(o) -} - -func (bA *BitArray) and(o *BitArray) *BitArray { - c := bA.copyBits(MinInt(bA.Bits, o.Bits)) - for i := 0; i < len(c.Elems); i++ { - c.Elems[i] &= o.Elems[i] - } - return c -} - -// Not returns a bit array resulting from a bitwise Not of the provided bit array. -func (bA *BitArray) Not() *BitArray { - if bA == nil { - return nil // Degenerate - } - bA.mtx.Lock() - defer bA.mtx.Unlock() - return bA.not() -} - -func (bA *BitArray) not() *BitArray { - c := bA.copy() - for i := 0; i < len(c.Elems); i++ { - c.Elems[i] = ^c.Elems[i] - } - return c -} - -// Sub subtracts the two bit-arrays bitwise, without carrying the bits. -// Note that carryless subtraction of a - b is (a and not b). -// The output is the same as bA, regardless of o's size. -// If bA is longer than o, o is right padded with zeroes -func (bA *BitArray) Sub(o *BitArray) *BitArray { - if bA == nil || o == nil { - // TODO: Decide if we should do 1's complement here? - return nil - } - bA.mtx.Lock() - o.mtx.Lock() - // output is the same size as bA - c := bA.copyBits(bA.Bits) - // Only iterate to the minimum size between the two. - // If o is longer, those bits are ignored. - // If bA is longer, then skipping those iterations is equivalent - // to right padding with 0's - smaller := MinInt(len(bA.Elems), len(o.Elems)) - for i := 0; i < smaller; i++ { - // &^ is and not in golang - c.Elems[i] &^= o.Elems[i] - } - bA.mtx.Unlock() - o.mtx.Unlock() - return c -} - -// IsEmpty returns true iff all bits in the bit array are 0 -func (bA *BitArray) IsEmpty() bool { - if bA == nil { - return true // should this be opposite? - } - bA.mtx.Lock() - defer bA.mtx.Unlock() - for _, e := range bA.Elems { - if e > 0 { - return false - } - } - return true -} - -// IsFull returns true iff all bits in the bit array are 1. -func (bA *BitArray) IsFull() bool { - if bA == nil { - return true - } - bA.mtx.Lock() - defer bA.mtx.Unlock() - - // Check all elements except the last - for _, elem := range bA.Elems[:len(bA.Elems)-1] { - if (^elem) != 0 { - return false - } - } - - // Check that the last element has (lastElemBits) 1's - lastElemBits := (bA.Bits+63)%64 + 1 - lastElem := bA.Elems[len(bA.Elems)-1] - return (lastElem+1)&((uint64(1)< 0 { - trueIndices = append(trueIndices, curBit) - } - curBit++ - } - } - // handle last element - lastElem := bA.Elems[numElems-1] - numFinalBits := bA.Bits - curBit - for i := 0; i < numFinalBits; i++ { - if (lastElem & (uint64(1) << uint64(i))) > 0 { - trueIndices = append(trueIndices, curBit) - } - curBit++ - } - return trueIndices -} - -// String returns a string representation of BitArray: BA{}, -// where is a sequence of 'x' (1) and '_' (0). -// The includes spaces and newlines to help people. -// For a simple sequence of 'x' and '_' characters with no spaces or newlines, -// see the MarshalJSON() method. -// Example: "BA{_x_}" or "nil-BitArray" for nil. -func (bA *BitArray) String() string { - return bA.StringIndented("") -} - -// StringIndented returns the same thing as String(), but applies the indent -// at every 10th bit, and twice at every 50th bit. -func (bA *BitArray) StringIndented(indent string) string { - if bA == nil { - return "nil-BitArray" - } - bA.mtx.Lock() - defer bA.mtx.Unlock() - return bA.stringIndented(indent) -} - -func (bA *BitArray) stringIndented(indent string) string { - lines := []string{} - bits := "" - for i := 0; i < bA.Bits; i++ { - if bA.getIndex(i) { - bits += "x" - } else { - bits += "_" - } - if i%100 == 99 { - lines = append(lines, bits) - bits = "" - } - if i%10 == 9 { - bits += indent - } - if i%50 == 49 { - bits += indent - } - } - if len(bits) > 0 { - lines = append(lines, bits) - } - return fmt.Sprintf("BA{%v:%v}", bA.Bits, strings.Join(lines, indent)) -} - -// Bytes returns the byte representation of the bits within the bitarray. -func (bA *BitArray) Bytes() []byte { - bA.mtx.Lock() - defer bA.mtx.Unlock() - - numBytes := (bA.Bits + 7) / 8 - bytes := make([]byte, numBytes) - for i := 0; i < len(bA.Elems); i++ { - elemBytes := [8]byte{} - binary.LittleEndian.PutUint64(elemBytes[:], bA.Elems[i]) - copy(bytes[i*8:], elemBytes[:]) - } - return bytes -} - -// Update sets the bA's bits to be that of the other bit array. -// The copying begins from the begin of both bit arrays. -func (bA *BitArray) Update(o *BitArray) { - if bA == nil || o == nil { - return - } - bA.mtx.Lock() - o.mtx.Lock() - defer func() { - bA.mtx.Unlock() - o.mtx.Unlock() - }() - - copy(bA.Elems, o.Elems) -} - -// MarshalJSON implements json.Marshaler interface by marshaling bit array -// using a custom format: a string of '-' or 'x' where 'x' denotes the 1 bit. -func (bA *BitArray) MarshalJSON() ([]byte, error) { - if bA == nil { - return []byte("null"), nil - } - - bA.mtx.Lock() - defer bA.mtx.Unlock() - - bits := `"` - for i := 0; i < bA.Bits; i++ { - if bA.getIndex(i) { - bits += `x` - } else { - bits += `_` - } - } - bits += `"` - return []byte(bits), nil -} - -var bitArrayJSONRegexp = regexp.MustCompile(`\A"([_x]*)"\z`) - -// UnmarshalJSON implements json.Unmarshaler interface by unmarshaling a custom -// JSON description. -func (bA *BitArray) UnmarshalJSON(bz []byte) error { - b := string(bz) - if b == "null" { - // This is required e.g. for encoding/json when decoding - // into a pointer with pre-allocated BitArray. - bA.Bits = 0 - bA.Elems = nil - return nil - } - - // Validate 'b'. - match := bitArrayJSONRegexp.FindStringSubmatch(b) - if match == nil { - return fmt.Errorf("BitArray in JSON should be a string of format %q but got %s", bitArrayJSONRegexp.String(), b) - } - bits := match[1] - - // Construct new BitArray and copy over. - numBits := len(bits) - bA2 := NewBitArray(numBits) - for i := 0; i < numBits; i++ { - if bits[i] == 'x' { - bA2.SetIndex(i, true) - } - } - *bA = *bA2 //nolint:govet - return nil -} diff --git a/contracts/native/header_sync/polygon/types/common/bytes.go b/contracts/native/header_sync/polygon/types/common/bytes.go deleted file mode 100644 index 5c2c217b..00000000 --- a/contracts/native/header_sync/polygon/types/common/bytes.go +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package common - -import ( - "encoding/hex" - "fmt" - "strings" -) - -// The main purpose of HexBytes is to enable HEX-encoding for json/encoding. -type HexBytes []byte - -// Marshal needed for protobuf compatibility -func (bz HexBytes) Marshal() ([]byte, error) { - return bz, nil -} - -// Unmarshal needed for protobuf compatibility -func (bz *HexBytes) Unmarshal(data []byte) error { - *bz = data - return nil -} - -// This is the point of Bytes. -func (bz HexBytes) MarshalJSON() ([]byte, error) { - s := strings.ToUpper(hex.EncodeToString(bz)) - jbz := make([]byte, len(s)+2) - jbz[0] = '"' - copy(jbz[1:], []byte(s)) - jbz[len(jbz)-1] = '"' - return jbz, nil -} - -// This is the point of Bytes. -func (bz *HexBytes) UnmarshalJSON(data []byte) error { - if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' { - return fmt.Errorf("Invalid hex string: %s", data) - } - bz2, err := hex.DecodeString(string(data[1 : len(data)-1])) - if err != nil { - return err - } - *bz = bz2 - return nil -} - -// Allow it to fulfill various interfaces in light-client, etc... -func (bz HexBytes) Bytes() []byte { - return bz -} - -func (bz HexBytes) String() string { - return strings.ToUpper(hex.EncodeToString(bz)) -} - -func (bz HexBytes) Format(s fmt.State, verb rune) { - switch verb { - case 'p': - s.Write([]byte(fmt.Sprintf("%p", bz))) - default: - s.Write([]byte(fmt.Sprintf("%X", []byte(bz)))) - } -} diff --git a/contracts/native/header_sync/polygon/types/common/byteslice.go b/contracts/native/header_sync/polygon/types/common/byteslice.go deleted file mode 100644 index c7b61eff..00000000 --- a/contracts/native/header_sync/polygon/types/common/byteslice.go +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package common - -// Fingerprint returns the first 6 bytes of a byte slice. -// If the slice is less than 6 bytes, the fingerprint -// contains trailing zeroes. -func Fingerprint(slice []byte) []byte { - fingerprint := make([]byte, 6) - copy(fingerprint, slice) - return fingerprint -} diff --git a/contracts/native/header_sync/polygon/types/common/math.go b/contracts/native/header_sync/polygon/types/common/math.go deleted file mode 100644 index bae6ee07..00000000 --- a/contracts/native/header_sync/polygon/types/common/math.go +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package common - -func MaxInt64(a, b int64) int64 { - if a > b { - return a - } - return b -} - -func MaxInt(a, b int) int { - if a > b { - return a - } - return b -} - -//----------------------------------------------------------------------------- - -func MinInt64(a, b int64) int64 { - if a < b { - return a - } - return b -} - -func MinInt(a, b int) int { - if a < b { - return a - } - return b -} diff --git a/contracts/native/header_sync/polygon/types/common/nil.go b/contracts/native/header_sync/polygon/types/common/nil.go deleted file mode 100644 index 77045afa..00000000 --- a/contracts/native/header_sync/polygon/types/common/nil.go +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package common - -import "reflect" - -// Go lacks a simple and safe way to see if something is a typed nil. -// See: -// - https://dave.cheney.net/2017/08/09/typed-nils-in-go-2 -// - https://groups.google.com/forum/#!topic/golang-nuts/wnH302gBa4I/discussion -// - https://github.com/golang/go/issues/21538 -func IsTypedNil(o interface{}) bool { - rv := reflect.ValueOf(o) - switch rv.Kind() { - case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice: - return rv.IsNil() - default: - return false - } -} - -// Returns true if it has zero length. -func IsEmpty(o interface{}) bool { - rv := reflect.ValueOf(o) - switch rv.Kind() { - case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String: - return rv.Len() == 0 - default: - return false - } -} diff --git a/contracts/native/header_sync/polygon/types/common/random.go b/contracts/native/header_sync/polygon/types/common/random.go deleted file mode 100644 index 48b19f5b..00000000 --- a/contracts/native/header_sync/polygon/types/common/random.go +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package common - -import ( - crand "crypto/rand" - mrand "math/rand" - "sync" - "time" -) - -const ( - strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters -) - -// Rand is a prng, that is seeded with OS randomness. -// The OS randomness is obtained from crypto/rand, however none of the provided -// methods are suitable for cryptographic usage. -// They all utilize math/rand's prng internally. -// -// All of the methods here are suitable for concurrent use. -// This is achieved by using a mutex lock on all of the provided methods. -type Rand struct { - sync.Mutex - rand *mrand.Rand -} - -var grand *Rand - -func init() { - grand = NewRand() - grand.init() -} - -func NewRand() *Rand { - rand := &Rand{} - rand.init() - return rand -} - -func (r *Rand) init() { - bz := cRandBytes(8) - var seed uint64 - for i := 0; i < 8; i++ { - seed |= uint64(bz[i]) - seed <<= 8 - } - r.reset(int64(seed)) -} - -func (r *Rand) reset(seed int64) { - r.rand = mrand.New(mrand.NewSource(seed)) -} - -//---------------------------------------- -// Global functions - -func Seed(seed int64) { - grand.Seed(seed) -} - -func RandStr(length int) string { - return grand.Str(length) -} - -func RandUint16() uint16 { - return grand.Uint16() -} - -func RandUint32() uint32 { - return grand.Uint32() -} - -func RandUint64() uint64 { - return grand.Uint64() -} - -func RandUint() uint { - return grand.Uint() -} - -func RandInt16() int16 { - return grand.Int16() -} - -func RandInt32() int32 { - return grand.Int32() -} - -func RandInt64() int64 { - return grand.Int64() -} - -func RandInt() int { - return grand.Int() -} - -func RandInt31() int32 { - return grand.Int31() -} - -func RandInt31n(n int32) int32 { - return grand.Int31n(n) -} - -func RandInt63() int64 { - return grand.Int63() -} - -func RandInt63n(n int64) int64 { - return grand.Int63n(n) -} - -func RandBool() bool { - return grand.Bool() -} - -func RandFloat32() float32 { - return grand.Float32() -} - -func RandFloat64() float64 { - return grand.Float64() -} - -func RandTime() time.Time { - return grand.Time() -} - -func RandBytes(n int) []byte { - return grand.Bytes(n) -} - -func RandIntn(n int) int { - return grand.Intn(n) -} - -func RandPerm(n int) []int { - return grand.Perm(n) -} - -//---------------------------------------- -// Rand methods - -func (r *Rand) Seed(seed int64) { - r.Lock() - r.reset(seed) - r.Unlock() -} - -// Str constructs a random alphanumeric string of given length. -func (r *Rand) Str(length int) string { - chars := []byte{} -MAIN_LOOP: - for { - val := r.Int63() - for i := 0; i < 10; i++ { - v := int(val & 0x3f) // rightmost 6 bits - if v >= 62 { // only 62 characters in strChars - val >>= 6 - continue - } else { - chars = append(chars, strChars[v]) - if len(chars) == length { - break MAIN_LOOP - } - val >>= 6 - } - } - } - - return string(chars) -} - -func (r *Rand) Uint16() uint16 { - return uint16(r.Uint32() & (1<<16 - 1)) -} - -func (r *Rand) Uint32() uint32 { - r.Lock() - u32 := r.rand.Uint32() - r.Unlock() - return u32 -} - -func (r *Rand) Uint64() uint64 { - return uint64(r.Uint32())<<32 + uint64(r.Uint32()) -} - -func (r *Rand) Uint() uint { - r.Lock() - i := r.rand.Int() - r.Unlock() - return uint(i) -} - -func (r *Rand) Int16() int16 { - return int16(r.Uint32() & (1<<16 - 1)) -} - -func (r *Rand) Int32() int32 { - return int32(r.Uint32()) -} - -func (r *Rand) Int64() int64 { - return int64(r.Uint64()) -} - -func (r *Rand) Int() int { - r.Lock() - i := r.rand.Int() - r.Unlock() - return i -} - -func (r *Rand) Int31() int32 { - r.Lock() - i31 := r.rand.Int31() - r.Unlock() - return i31 -} - -func (r *Rand) Int31n(n int32) int32 { - r.Lock() - i31n := r.rand.Int31n(n) - r.Unlock() - return i31n -} - -func (r *Rand) Int63() int64 { - r.Lock() - i63 := r.rand.Int63() - r.Unlock() - return i63 -} - -func (r *Rand) Int63n(n int64) int64 { - r.Lock() - i63n := r.rand.Int63n(n) - r.Unlock() - return i63n -} - -func (r *Rand) Float32() float32 { - r.Lock() - f32 := r.rand.Float32() - r.Unlock() - return f32 -} - -func (r *Rand) Float64() float64 { - r.Lock() - f64 := r.rand.Float64() - r.Unlock() - return f64 -} - -func (r *Rand) Time() time.Time { - return time.Unix(int64(r.Uint64()), 0) -} - -// Bytes returns n random bytes generated from the internal -// prng. -func (r *Rand) Bytes(n int) []byte { - // cRandBytes isn't guaranteed to be fast so instead - // use random bytes generated from the internal PRNG - bs := make([]byte, n) - for i := 0; i < len(bs); i++ { - bs[i] = byte(r.Int() & 0xFF) - } - return bs -} - -// Intn returns, as an int, a uniform pseudo-random number in the range [0, n). -// It panics if n <= 0. -func (r *Rand) Intn(n int) int { - r.Lock() - i := r.rand.Intn(n) - r.Unlock() - return i -} - -// Bool returns a uniformly random boolean -func (r *Rand) Bool() bool { - // See https://github.com/golang/go/issues/23804#issuecomment-365370418 - // for reasoning behind computing like this - return r.Int63()%2 == 0 -} - -// Perm returns a pseudo-random permutation of n integers in [0, n). -func (r *Rand) Perm(n int) []int { - r.Lock() - perm := r.rand.Perm(n) - r.Unlock() - return perm -} - -// NOTE: This relies on the os's random number generator. -// For real security, we should salt that with some seed. -// See github.com/tendermint/tendermint/crypto for a more secure reader. -func cRandBytes(numBytes int) []byte { - b := make([]byte, numBytes) - _, err := crand.Read(b) - if err != nil { - panic(err) - } - return b -} diff --git a/contracts/native/header_sync/polygon/types/heimdall_block.go b/contracts/native/header_sync/polygon/types/heimdall_block.go deleted file mode 100644 index e6ea4bb3..00000000 --- a/contracts/native/header_sync/polygon/types/heimdall_block.go +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package types - -import ( - "bytes" - - "github.com/polynetwork/poly/native/service/header_sync/polygon/types/common" -) - -// BlockID defines the unique ID of a block as its Hash and its PartSetHeader -type BlockID struct { - Hash common.HexBytes `json:"hash"` - PartsHeader PartSetHeader `json:"parts"` -} - -// IsZero returns true if this is the BlockID of a nil block. -func (blockID BlockID) IsZero() bool { - return len(blockID.Hash) == 0 && - blockID.PartsHeader.IsZero() -} - -// Equals returns true if the BlockID matches the given BlockID -func (blockID BlockID) Equals(other BlockID) bool { - return bytes.Equal(blockID.Hash, other.Hash) && - blockID.PartsHeader.Equals(other.PartsHeader) -} - -// CommitSig is a vote included in a Commit. -// For now, it is identical to a vote, -// but in the future it will contain fewer fields -// to eliminate the redundancy in commits. -// See https://github.com/tendermint/tendermint/issues/1648. -type CommitSig Vote diff --git a/contracts/native/header_sync/polygon/types/heimdall_canonical.go b/contracts/native/header_sync/polygon/types/heimdall_canonical.go deleted file mode 100644 index 18245d9b..00000000 --- a/contracts/native/header_sync/polygon/types/heimdall_canonical.go +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package types - -import ( - "time" - - "github.com/polynetwork/poly/native/service/header_sync/polygon/types/common" -) - -type CanonicalVote struct { - Type SignedMsgType // type alias for byte - Height int64 `binary:"fixed64"` - Round int64 `binary:"fixed64"` - BlockID CanonicalBlockID - Timestamp time.Time - ChainID string - - Data []byte // [peppermint] tx hash - SideTxResults []SideTxResult // [peppermint] side tx results -} - -type CanonicalBlockID struct { - Hash common.HexBytes - PartsHeader CanonicalPartSetHeader -} - -type CanonicalPartSetHeader struct { - Hash common.HexBytes - Total int -} - -func CanonicalizeVote(chainID string, vote *Vote) CanonicalVote { - return CanonicalVote{ - Type: vote.Type, - Height: vote.Height, - Round: int64(vote.Round), // cast int->int64 to make amino encode it fixed64 (does not work for int) - BlockID: CanonicalizeBlockID(vote.BlockID), - Timestamp: vote.Timestamp, - ChainID: chainID, - - SideTxResults: vote.SideTxResults, - } -} - -func CanonicalizeBlockID(blockID BlockID) CanonicalBlockID { - return CanonicalBlockID{ - Hash: blockID.Hash, - PartsHeader: CanonicalizePartSetHeader(blockID.PartsHeader), - } -} - -func CanonicalizePartSetHeader(psh PartSetHeader) CanonicalPartSetHeader { - return CanonicalPartSetHeader{ - psh.Hash, - psh.Total, - } -} diff --git a/contracts/native/header_sync/polygon/types/heimdall_codec.go b/contracts/native/header_sync/polygon/types/heimdall_codec.go deleted file mode 100644 index 4ae53558..00000000 --- a/contracts/native/header_sync/polygon/types/heimdall_codec.go +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package types - -import ( - "github.com/cosmos/cosmos-sdk/codec" - "github.com/polynetwork/poly/native/service/header_sync/polygon/types/secp256k1" - "github.com/tendermint/tendermint/crypto" -) - -// NewCDC ... -func NewCDC() *codec.Codec { - cdc := codec.New() - - cdc.RegisterInterface((*crypto.PubKey)(nil), nil) - cdc.RegisterConcrete(secp256k1.PubKeySecp256k1{}, secp256k1.PubKeyAminoName, nil) - - return cdc -} - -var cdc = NewCDC() diff --git a/contracts/native/header_sync/polygon/types/heimdall_commit.go b/contracts/native/header_sync/polygon/types/heimdall_commit.go deleted file mode 100644 index a1727cea..00000000 --- a/contracts/native/header_sync/polygon/types/heimdall_commit.go +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package types - -import ( - "errors" - "fmt" - - "github.com/polynetwork/poly/native/service/header_sync/polygon/types/common" -) - -// Commit contains the evidence that a block was committed by a set of validators. -// NOTE: Commit is empty for height 1, but never nil. -type Commit struct { - // NOTE: The Precommits are in order of address to preserve the bonded ValidatorSet order. - // Any peer with a block can gossip precommits by index with a peer without recalculating the - // active ValidatorSet. - BlockID BlockID `json:"block_id"` - Precommits []*CommitSig `json:"precommits"` - - // memoized in first call to corresponding method - // NOTE: can't memoize in constructor because constructor - // isn't used for unmarshaling - height int64 - round int - hash common.HexBytes - bitArray *common.BitArray -} - -// Height returns the height of the commit -func (commit *Commit) Height() int64 { - commit.memoizeHeightRound() - return commit.height -} - -// memoizeHeightRound memoizes the height and round of the commit using -// the first non-nil vote. -// Should be called before any attempt to access `commit.height` or `commit.round`. -func (commit *Commit) memoizeHeightRound() { - if len(commit.Precommits) == 0 { - return - } - if commit.height > 0 { - return - } - for _, precommit := range commit.Precommits { - if precommit != nil { - commit.height = precommit.Height - commit.round = precommit.Round - return - } - } -} - -// Size returns the number of votes in the commit -func (commit *Commit) Size() int { - if commit == nil { - return 0 - } - return len(commit.Precommits) -} - -// Round returns the round of the commit -func (commit *Commit) Round() int { - commit.memoizeHeightRound() - return commit.round -} - -// ValidateBasic performs basic validation that doesn't involve state data. -// Does not actually check the cryptographic signatures. -func (commit *Commit) ValidateBasic() error { - if commit.BlockID.IsZero() { - return errors.New("Commit cannot be for nil block") - } - if len(commit.Precommits) == 0 { - return errors.New("No precommits in commit") - } - height, round := commit.Height(), commit.Round() - - // Validate the precommits. - for _, precommit := range commit.Precommits { - // It's OK for precommits to be missing. - if precommit == nil { - continue - } - // Ensure that all votes are precommits. - if precommit.Type != PrecommitType { - return fmt.Errorf("Invalid commit vote. Expected precommit, got %v", - precommit.Type) - } - // Ensure that all heights are the same. - if precommit.Height != height { - return fmt.Errorf("Invalid commit precommit height. Expected %v, got %v", - height, precommit.Height) - } - // Ensure that all rounds are the same. - if precommit.Round != round { - return fmt.Errorf("Invalid commit precommit round. Expected %v, got %v", - round, precommit.Round) - } - } - return nil -} - -// GetVote converts the CommitSig for the given valIdx to a Vote. -// Returns nil if the precommit at valIdx is nil. -// Panics if valIdx >= commit.Size(). -func (commit *Commit) GetVote(valIdx int) *Vote { - commitSig := commit.Precommits[valIdx] - if commitSig == nil { - return nil - } - - // NOTE: this commitSig might be for a nil blockID, - // so we can't just use commit.BlockID here. - // For #1648, CommitSig will need to indicate what BlockID it's for ! - blockID := commitSig.BlockID - commit.memoizeHeightRound() - return &Vote{ - Type: PrecommitType, - Height: commit.height, - Round: commit.round, - BlockID: blockID, - Timestamp: commitSig.Timestamp, - ValidatorAddress: commitSig.ValidatorAddress, - ValidatorIndex: valIdx, - Signature: commitSig.Signature, - - SideTxResults: commitSig.SideTxResults, - } -} - -// VoteSignBytes constructs the SignBytes for the given CommitSig. -// The only unique part of the SignBytes is the Timestamp - all other fields -// signed over are otherwise the same for all validators. -// Panics if valIdx >= commit.Size(). -func (commit *Commit) VoteSignBytes(chainID string, valIdx int) []byte { - return commit.GetVote(valIdx).SignBytes(chainID) -} diff --git a/contracts/native/header_sync/polygon/types/heimdall_encoding_helper.go b/contracts/native/header_sync/polygon/types/heimdall_encoding_helper.go deleted file mode 100644 index b2e158e7..00000000 --- a/contracts/native/header_sync/polygon/types/heimdall_encoding_helper.go +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package types - -import "github.com/polynetwork/poly/native/service/header_sync/polygon/types/common" - -// cdcEncode returns nil if the input is nil, otherwise returns -// cdc.MustMarshalBinaryBare(item) -func cdcEncode(item interface{}) []byte { - if item != nil && !common.IsTypedNil(item) && !common.IsEmpty(item) { - return cdc.MustMarshalBinaryBare(item) - } - return nil -} diff --git a/contracts/native/header_sync/polygon/types/heimdall_header.go b/contracts/native/header_sync/polygon/types/heimdall_header.go deleted file mode 100644 index 45c9bbb1..00000000 --- a/contracts/native/header_sync/polygon/types/heimdall_header.go +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package types - -import ( - "bytes" - "time" - - "github.com/polynetwork/poly/native/service/header_sync/polygon/types/common" - "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/merkle" - "github.com/tendermint/tendermint/version" -) - -// Header defines the structure of a Tendermint block header. -// NOTE: changes to the Header should be duplicated in: -// - header.Hash() -// - abci.Header -// - /docs/spec/blockchain/blockchain.md -type Header struct { - // basic block info - Version version.Consensus `json:"version"` - ChainID string `json:"chain_id"` - Height int64 `json:"height"` - Time time.Time `json:"time"` - NumTxs int64 `json:"num_txs"` - TotalTxs int64 `json:"total_txs"` - - // prev block info - LastBlockID BlockID `json:"last_block_id"` - - // hashes of block data - LastCommitHash common.HexBytes `json:"last_commit_hash"` // commit from validators from the last block - DataHash common.HexBytes `json:"data_hash"` // transactions - - // hashes from the app output from the prev block - ValidatorsHash common.HexBytes `json:"validators_hash"` // validators for the current block - NextValidatorsHash common.HexBytes `json:"next_validators_hash"` // validators for the next block - ConsensusHash common.HexBytes `json:"consensus_hash"` // consensus params for current block - AppHash common.HexBytes `json:"app_hash"` // state after txs from the previous block - LastResultsHash common.HexBytes `json:"last_results_hash"` // root hash of all results from the txs from the previous block - - // consensus info - EvidenceHash common.HexBytes `json:"evidence_hash"` // evidence included in the block - ProposerAddress Address `json:"proposer_address"` // original proposer of the block -} - -// Hash returns the hash of the header. -// It computes a Merkle tree from the header fields -// ordered as they appear in the Header. -// Returns nil if ValidatorHash is missing, -// since a Header is not valid unless there is -// a ValidatorsHash (corresponding to the validator set). -func (h *Header) Hash() common.HexBytes { - if h == nil || len(h.ValidatorsHash) == 0 { - return nil - } - return merkle.SimpleHashFromByteSlices([][]byte{ - cdcEncode(h.Version), - cdcEncode(h.ChainID), - cdcEncode(h.Height), - cdcEncode(h.Time), - cdcEncode(h.NumTxs), - cdcEncode(h.TotalTxs), - cdcEncode(h.LastBlockID), - cdcEncode(h.LastCommitHash), - cdcEncode(h.DataHash), - cdcEncode(h.ValidatorsHash), - cdcEncode(h.NextValidatorsHash), - cdcEncode(h.ConsensusHash), - cdcEncode(h.AppHash), - cdcEncode(h.LastResultsHash), - cdcEncode(h.EvidenceHash), - cdcEncode(h.ProposerAddress), - }) -} - -type PartSetHeader struct { - Total int `json:"total"` - Hash common.HexBytes `json:"hash"` -} - -func (psh PartSetHeader) Equals(other PartSetHeader) bool { - return psh.Total == other.Total && bytes.Equal(psh.Hash, other.Hash) -} - -func (psh PartSetHeader) IsZero() bool { - return psh.Total == 0 && len(psh.Hash) == 0 -} - -// Address is hex bytes. -type Address = crypto.Address diff --git a/contracts/native/header_sync/polygon/types/heimdall_side_tx.go b/contracts/native/header_sync/polygon/types/heimdall_side_tx.go deleted file mode 100644 index d342b315..00000000 --- a/contracts/native/header_sync/polygon/types/heimdall_side_tx.go +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package types - -import ( - "encoding/binary" - "fmt" - - "github.com/polynetwork/poly/native/service/header_sync/polygon/types/common" -) - -// SideTxResult side tx result for vote -type SideTxResult struct { - TxHash []byte `json:"tx_hash"` - Result int32 `json:"result"` - Sig []byte `json:"sig"` -} - -func (sp *SideTxResult) String() string { - if sp == nil { - return "" - } - - return fmt.Sprintf("SideTxResult{%X (%v) %X}", - common.Fingerprint(sp.TxHash), - sp.Result, - common.Fingerprint(sp.Sig), - ) -} - -// SideTxResultWithData side tx result with data for vote -type SideTxResultWithData struct { - SideTxResult - - Data []byte `json:"data"` -} - -// GetBytes returns data bytes for sign -func (sp *SideTxResultWithData) GetBytes() []byte { - bs := make([]byte, 4) - binary.BigEndian.PutUint32(bs, uint32(sp.Result)) - - data := make([]byte, 0) - data = append(data, bs[3]) // use last byte as result - if len(sp.Data) > 0 { - data = append(data, sp.Data...) - } - return data -} - -func (sp *SideTxResultWithData) String() string { - if sp == nil { - return "" - } - - return fmt.Sprintf("SideTxResultWithData {%s %X}", - sp.SideTxResult.String(), - common.Fingerprint(sp.Data), - ) -} diff --git a/contracts/native/header_sync/polygon/types/heimdall_signed_msg_type.go b/contracts/native/header_sync/polygon/types/heimdall_signed_msg_type.go deleted file mode 100644 index a511f157..00000000 --- a/contracts/native/header_sync/polygon/types/heimdall_signed_msg_type.go +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package types - -// SignedMsgType is a type of signed message in the consensus. -type SignedMsgType byte - -const ( - // Votes - PrevoteType SignedMsgType = 0x01 - PrecommitType SignedMsgType = 0x02 - - // Proposals - ProposalType SignedMsgType = 0x20 -) - -// IsVoteTypeValid returns true if t is a valid vote type. -func IsVoteTypeValid(t SignedMsgType) bool { - switch t { - case PrevoteType, PrecommitType: - return true - default: - return false - } -} diff --git a/contracts/native/header_sync/polygon/types/heimdall_span.go b/contracts/native/header_sync/polygon/types/heimdall_span.go deleted file mode 100644 index f8222673..00000000 --- a/contracts/native/header_sync/polygon/types/heimdall_span.go +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package types - -type HeimdallSpan struct { - ID uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id" yaml:"id"` - StartBlock uint64 `protobuf:"varint,2,opt,name=start_block,json=startBlock,proto3" json:"start_block" yaml:"start_block"` - EndBlock uint64 `protobuf:"varint,3,opt,name=end_block,json=endBlock,proto3" json:"end_block" yaml:"end_block"` - ValidatorSet HeimdallValidatorSet `protobuf:"bytes,4,opt,name=validator_set,json=validatorSet,proto3" json:"validator_set" yaml:"validator_set"` - SelectedProducers []HeimdallValidator `protobuf:"bytes,5,rep,name=selected_producers,json=selectedProducers,proto3" json:"selected_producers" yaml:"selected_producers"` - BorChainId string `protobuf:"bytes,6,opt,name=bor_chain_id,json=borChainId,proto3" json:"bor_chain_id" yaml:"bor_chain_id"` -} - -type HeimdallValidatorSet struct { - Validators []*HeimdallValidator `protobuf:"bytes,1,rep,name=validators,proto3" json:"validators,omitempty"` - Proposer *HeimdallValidator `protobuf:"bytes,2,opt,name=proposer,proto3" json:"proposer,omitempty"` - TotalVotingPower int64 `protobuf:"varint,3,opt,name=total_voting_power,json=totalVotingPower,proto3" json:"total_voting_power,omitempty" yaml:"total_voting_power"` -} - -type ValidatorID int32 - -type HeimdallValidator struct { - ID ValidatorID `protobuf:"varint,1,opt,name=ID,proto3,enum=heimdall.types.ValidatorID" json:"ID,omitempty"` - StartEpoch uint64 `protobuf:"varint,2,opt,name=start_epoch,json=startEpoch,proto3" json:"start_epoch,omitempty" yaml:"start_epoch"` - EndEpoch uint64 `protobuf:"varint,3,opt,name=end_epoch,json=endEpoch,proto3" json:"end_epoch,omitempty" yaml:"end_epoch"` - Nonce uint64 `protobuf:"varint,4,opt,name=nonce,proto3" json:"nonce,omitempty"` - VotingPower int64 `protobuf:"varint,5,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty" yaml:"voting_power"` - PubKey string `protobuf:"bytes,6,opt,name=pub_key,json=pubKey,proto3" json:"pub_key,omitempty" yaml:"pub_key"` - Signer string `protobuf:"bytes,7,opt,name=signer,proto3" json:"signer,omitempty"` - LastUpdated string `protobuf:"bytes,8,opt,name=last_updated,json=lastUpdated,proto3" json:"last_updated,omitempty" yaml:"last_updated"` - Jailed bool `protobuf:"varint,9,opt,name=jailed,proto3" json:"jailed,omitempty"` - ProposerPriority int64 `protobuf:"varint,10,opt,name=proposer_priority,json=proposerPriority,proto3" json:"proposer_priority,omitempty" yaml:"proposer_priority"` -} diff --git a/contracts/native/header_sync/polygon/types/heimdall_validator.go b/contracts/native/header_sync/polygon/types/heimdall_validator.go deleted file mode 100644 index e526dcae..00000000 --- a/contracts/native/header_sync/polygon/types/heimdall_validator.go +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package types - -import ( - "bytes" - "fmt" - "strings" - - "github.com/tendermint/tendermint/crypto" -) - -// Volatile state for each Validator -// NOTE: The ProposerPriority is not included in Validator.Hash(); -// make sure to update that method if changes are made here -type Validator struct { - Address Address `json:"address"` - PubKey crypto.PubKey `json:"pub_key"` - VotingPower int64 `json:"voting_power"` - - ProposerPriority int64 `json:"proposer_priority"` -} - -func NewValidator(pubKey crypto.PubKey, votingPower int64) *Validator { - return &Validator{ - Address: pubKey.Address(), - PubKey: pubKey, - VotingPower: votingPower, - ProposerPriority: 0, - } -} - -// Creates a new copy of the validator so we can mutate ProposerPriority. -// Panics if the validator is nil. -func (v *Validator) Copy() *Validator { - vCopy := *v - return &vCopy -} - -// Returns the one with higher ProposerPriority. -func (v *Validator) CompareProposerPriority(other *Validator) *Validator { - if v == nil { - return other - } - switch { - case v.ProposerPriority > other.ProposerPriority: - return v - case v.ProposerPriority < other.ProposerPriority: - return other - default: - result := bytes.Compare(v.Address, other.Address) - switch { - case result < 0: - return v - case result > 0: - return other - default: - panic("Cannot compare identical validators") - } - } -} - -func (v *Validator) String() string { - if v == nil { - return "nil-Validator" - } - return fmt.Sprintf("Validator{%v %v VP:%v A:%v}", - v.Address, - v.PubKey, - v.VotingPower, - v.ProposerPriority) -} - -// ValidatorListString returns a prettified validator list for logging purposes. -func ValidatorListString(vals []*Validator) string { - chunks := make([]string, len(vals)) - for i, val := range vals { - chunks[i] = fmt.Sprintf("%s:%d", val.Address, val.VotingPower) - } - - return strings.Join(chunks, ",") -} - -// Bytes computes the unique encoding of a validator with a given voting power. -// These are the bytes that gets hashed in consensus. It excludes address -// as its redundant with the pubkey. This also excludes ProposerPriority -// which changes every round. -func (v *Validator) Bytes() []byte { - return cdcEncode(struct { - PubKey crypto.PubKey - VotingPower int64 - }{ - v.PubKey, - v.VotingPower, - }) -} diff --git a/contracts/native/header_sync/polygon/types/heimdall_validator_set.go b/contracts/native/header_sync/polygon/types/heimdall_validator_set.go deleted file mode 100644 index c290f8fb..00000000 --- a/contracts/native/header_sync/polygon/types/heimdall_validator_set.go +++ /dev/null @@ -1,712 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package types - -import ( - "bytes" - "fmt" - "math" - "math/big" - "sort" - "strings" - - "github.com/pkg/errors" - - "github.com/tendermint/tendermint/crypto/merkle" -) - -// MaxTotalVotingPower - the maximum allowed total voting power. -// It needs to be sufficiently small to, in all cases: -// 1. prevent clipping in incrementProposerPriority() -// 2. let (diff+diffMax-1) not overflow in IncrementProposerPriority() -// (Proof of 1 is tricky, left to the reader). -// It could be higher, but this is sufficiently large for our purposes, -// and leaves room for defensive purposes. -// PriorityWindowSizeFactor - is a constant that when multiplied with the total voting power gives -// the maximum allowed distance between validator priorities. - -const ( - MaxTotalVotingPower = int64(math.MaxInt64) / 8 - PriorityWindowSizeFactor = 2 -) - -// ValidatorSet represent a set of *Validator at a given height. -// The validators can be fetched by address or index. -// The index is in order of .Address, so the indices are fixed -// for all rounds of a given blockchain height - ie. the validators -// are sorted by their address. -// On the other hand, the .ProposerPriority of each validator and -// the designated .GetProposer() of a set changes every round, -// upon calling .IncrementProposerPriority(). -// NOTE: Not goroutine-safe. -// NOTE: All get/set to validators should copy the value for safety. -type ValidatorSet struct { - // NOTE: persisted via reflect, must be exported. - Validators []*Validator `json:"validators"` - Proposer *Validator `json:"proposer"` - - // cached (unexported) - totalVotingPower int64 -} - -// NewValidatorSet initializes a ValidatorSet by copying over the -// values from `valz`, a list of Validators. If valz is nil or empty, -// the new ValidatorSet will have an empty list of Validators. -// The addresses of validators in `valz` must be unique otherwise the -// function panics. -func NewValidatorSet(valz []*Validator) *ValidatorSet { - vals := &ValidatorSet{} - err := vals.updateWithChangeSet(valz, false) - if err != nil { - panic(fmt.Sprintf("cannot create validator set: %s", err)) - } - if len(valz) > 0 { - vals.IncrementProposerPriority(1) - } - return vals -} - -// Nil or empty validator sets are invalid. -func (vals *ValidatorSet) IsNilOrEmpty() bool { - return vals == nil || len(vals.Validators) == 0 -} - -// Increment ProposerPriority and update the proposer on a copy, and return it. -func (vals *ValidatorSet) CopyIncrementProposerPriority(times int) *ValidatorSet { - copy := vals.Copy() - copy.IncrementProposerPriority(times) - return copy -} - -// IncrementProposerPriority increments ProposerPriority of each validator and updates the -// proposer. Panics if validator set is empty. -// `times` must be positive. -func (vals *ValidatorSet) IncrementProposerPriority(times int) { - if vals.IsNilOrEmpty() { - panic("empty validator set") - } - if times <= 0 { - panic("Cannot call IncrementProposerPriority with non-positive times") - } - - // Cap the difference between priorities to be proportional to 2*totalPower by - // re-normalizing priorities, i.e., rescale all priorities by multiplying with: - // 2*totalVotingPower/(maxPriority - minPriority) - diffMax := PriorityWindowSizeFactor * vals.TotalVotingPower() - vals.RescalePriorities(diffMax) - vals.shiftByAvgProposerPriority() - - var proposer *Validator - // Call IncrementProposerPriority(1) times times. - for i := 0; i < times; i++ { - proposer = vals.incrementProposerPriority() - } - - vals.Proposer = proposer -} - -func (vals *ValidatorSet) RescalePriorities(diffMax int64) { - if vals.IsNilOrEmpty() { - panic("empty validator set") - } - // NOTE: This check is merely a sanity check which could be - // removed if all tests would init. voting power appropriately; - // i.e. diffMax should always be > 0 - if diffMax <= 0 { - return - } - - // Calculating ceil(diff/diffMax): - // Re-normalization is performed by dividing by an integer for simplicity. - // NOTE: This may make debugging priority issues easier as well. - diff := computeMaxMinPriorityDiff(vals) - ratio := (diff + diffMax - 1) / diffMax - if diff > diffMax { - for _, val := range vals.Validators { - val.ProposerPriority /= ratio - } - } -} - -func (vals *ValidatorSet) incrementProposerPriority() *Validator { - for _, val := range vals.Validators { - // Check for overflow for sum. - newPrio := safeAddClip(val.ProposerPriority, val.VotingPower) - val.ProposerPriority = newPrio - } - // Decrement the validator with most ProposerPriority. - mostest := vals.getValWithMostPriority() - // Mind the underflow. - mostest.ProposerPriority = safeSubClip(mostest.ProposerPriority, vals.TotalVotingPower()) - - return mostest -} - -// Should not be called on an empty validator set. -func (vals *ValidatorSet) computeAvgProposerPriority() int64 { - n := int64(len(vals.Validators)) - sum := big.NewInt(0) - for _, val := range vals.Validators { - sum.Add(sum, big.NewInt(val.ProposerPriority)) - } - avg := sum.Div(sum, big.NewInt(n)) - if avg.IsInt64() { - return avg.Int64() - } - - // This should never happen: each val.ProposerPriority is in bounds of int64. - panic(fmt.Sprintf("Cannot represent avg ProposerPriority as an int64 %v", avg)) -} - -// Compute the difference between the max and min ProposerPriority of that set. -func computeMaxMinPriorityDiff(vals *ValidatorSet) int64 { - if vals.IsNilOrEmpty() { - panic("empty validator set") - } - max := int64(math.MinInt64) - min := int64(math.MaxInt64) - for _, v := range vals.Validators { - if v.ProposerPriority < min { - min = v.ProposerPriority - } - if v.ProposerPriority > max { - max = v.ProposerPriority - } - } - diff := max - min - if diff < 0 { - return -1 * diff - } else { - return diff - } -} - -func (vals *ValidatorSet) getValWithMostPriority() *Validator { - var res *Validator - for _, val := range vals.Validators { - res = res.CompareProposerPriority(val) - } - return res -} - -func (vals *ValidatorSet) shiftByAvgProposerPriority() { - if vals.IsNilOrEmpty() { - panic("empty validator set") - } - avgProposerPriority := vals.computeAvgProposerPriority() - for _, val := range vals.Validators { - val.ProposerPriority = safeSubClip(val.ProposerPriority, avgProposerPriority) - } -} - -// Makes a copy of the validator list. -func validatorListCopy(valsList []*Validator) []*Validator { - if valsList == nil { - return nil - } - valsCopy := make([]*Validator, len(valsList)) - for i, val := range valsList { - valsCopy[i] = val.Copy() - } - return valsCopy -} - -// Copy each validator into a new ValidatorSet. -func (vals *ValidatorSet) Copy() *ValidatorSet { - return &ValidatorSet{ - Validators: validatorListCopy(vals.Validators), - Proposer: vals.Proposer, - totalVotingPower: vals.totalVotingPower, - } -} - -// HasAddress returns true if address given is in the validator set, false - -// otherwise. -func (vals *ValidatorSet) HasAddress(address []byte) bool { - idx := sort.Search(len(vals.Validators), func(i int) bool { - return bytes.Compare(address, vals.Validators[i].Address) <= 0 - }) - return idx < len(vals.Validators) && bytes.Equal(vals.Validators[idx].Address, address) -} - -// GetByAddress returns an index of the validator with address and validator -// itself if found. Otherwise, -1 and nil are returned. -func (vals *ValidatorSet) GetByAddress(address []byte) (index int, val *Validator) { - idx := sort.Search(len(vals.Validators), func(i int) bool { - return bytes.Compare(address, vals.Validators[i].Address) <= 0 - }) - if idx < len(vals.Validators) && bytes.Equal(vals.Validators[idx].Address, address) { - return idx, vals.Validators[idx].Copy() - } - return -1, nil -} - -// GetByIndex returns the validator's address and validator itself by index. -// It returns nil values if index is less than 0 or greater or equal to -// len(ValidatorSet.Validators). -func (vals *ValidatorSet) GetByIndex(index int) (address []byte, val *Validator) { - if index < 0 || index >= len(vals.Validators) { - return nil, nil - } - val = vals.Validators[index] - return val.Address, val.Copy() -} - -// Size returns the length of the validator set. -func (vals *ValidatorSet) Size() int { - return len(vals.Validators) -} - -// Force recalculation of the set's total voting power. -func (vals *ValidatorSet) updateTotalVotingPower() { - - sum := int64(0) - for _, val := range vals.Validators { - // mind overflow - sum = safeAddClip(sum, val.VotingPower) - if sum > MaxTotalVotingPower { - panic(fmt.Sprintf( - "Total voting power should be guarded to not exceed %v; got: %v", - MaxTotalVotingPower, - sum)) - } - } - - vals.totalVotingPower = sum -} - -// TotalVotingPower returns the sum of the voting powers of all validators. -// It recomputes the total voting power if required. -func (vals *ValidatorSet) TotalVotingPower() int64 { - if vals.totalVotingPower == 0 { - vals.updateTotalVotingPower() - } - return vals.totalVotingPower -} - -// GetProposer returns the current proposer. If the validator set is empty, nil -// is returned. -func (vals *ValidatorSet) GetProposer() (proposer *Validator) { - if len(vals.Validators) == 0 { - return nil - } - if vals.Proposer == nil { - vals.Proposer = vals.findProposer() - } - return vals.Proposer.Copy() -} - -func (vals *ValidatorSet) findProposer() *Validator { - var proposer *Validator - for _, val := range vals.Validators { - if proposer == nil || !bytes.Equal(val.Address, proposer.Address) { - proposer = proposer.CompareProposerPriority(val) - } - } - return proposer -} - -// Hash returns the Merkle root hash build using validators (as leaves) in the -// set. -func (vals *ValidatorSet) Hash() []byte { - if len(vals.Validators) == 0 { - return nil - } - bzs := make([][]byte, len(vals.Validators)) - for i, val := range vals.Validators { - bzs[i] = val.Bytes() - } - return merkle.SimpleHashFromByteSlices(bzs) -} - -// Iterate will run the given function over the set. -func (vals *ValidatorSet) Iterate(fn func(index int, val *Validator) bool) { - for i, val := range vals.Validators { - stop := fn(i, val.Copy()) - if stop { - break - } - } -} - -// Checks changes against duplicates, splits the changes in updates and removals, sorts them by address. -// -// Returns: -// updates, removals - the sorted lists of updates and removals -// err - non-nil if duplicate entries or entries with negative voting power are seen -// -// No changes are made to 'origChanges'. -func processChanges(origChanges []*Validator) (updates, removals []*Validator, err error) { - // Make a deep copy of the changes and sort by address. - changes := validatorListCopy(origChanges) - sort.Sort(ValidatorsByAddress(changes)) - - removals = make([]*Validator, 0, len(changes)) - updates = make([]*Validator, 0, len(changes)) - var prevAddr Address - - // Scan changes by address and append valid validators to updates or removals lists. - for _, valUpdate := range changes { - if bytes.Equal(valUpdate.Address, prevAddr) { - err = fmt.Errorf("duplicate entry %v in %v", valUpdate, changes) - return nil, nil, err - } - if valUpdate.VotingPower < 0 { - err = fmt.Errorf("voting power can't be negative: %v", valUpdate) - return nil, nil, err - } - if valUpdate.VotingPower > MaxTotalVotingPower { - err = fmt.Errorf("to prevent clipping/ overflow, voting power can't be higher than %v: %v ", - MaxTotalVotingPower, valUpdate) - return nil, nil, err - } - if valUpdate.VotingPower == 0 { - removals = append(removals, valUpdate) - } else { - updates = append(updates, valUpdate) - } - prevAddr = valUpdate.Address - } - return updates, removals, err -} - -// Verifies a list of updates against a validator set, making sure the allowed -// total voting power would not be exceeded if these updates would be applied to the set. -// -// Returns: -// updatedTotalVotingPower - the new total voting power if these updates would be applied -// numNewValidators - number of new validators -// err - non-nil if the maximum allowed total voting power would be exceeded -// -// 'updates' should be a list of proper validator changes, i.e. they have been verified -// by processChanges for duplicates and invalid values. -// No changes are made to the validator set 'vals'. -func verifyUpdates(updates []*Validator, vals *ValidatorSet) (updatedTotalVotingPower int64, numNewValidators int, err error) { - - updatedTotalVotingPower = vals.TotalVotingPower() - - for _, valUpdate := range updates { - address := valUpdate.Address - _, val := vals.GetByAddress(address) - if val == nil { - // New validator, add its voting power the the total. - updatedTotalVotingPower += valUpdate.VotingPower - numNewValidators++ - } else { - // Updated validator, add the difference in power to the total. - updatedTotalVotingPower += valUpdate.VotingPower - val.VotingPower - } - overflow := updatedTotalVotingPower > MaxTotalVotingPower - if overflow { - err = fmt.Errorf( - "failed to add/update validator %v, total voting power would exceed the max allowed %v", - valUpdate, MaxTotalVotingPower) - return 0, 0, err - } - } - - return updatedTotalVotingPower, numNewValidators, nil -} - -// Computes the proposer priority for the validators not present in the set based on 'updatedTotalVotingPower'. -// Leaves unchanged the priorities of validators that are changed. -// -// 'updates' parameter must be a list of unique validators to be added or updated. -// No changes are made to the validator set 'vals'. -func computeNewPriorities(updates []*Validator, vals *ValidatorSet, updatedTotalVotingPower int64) { - - for _, valUpdate := range updates { - address := valUpdate.Address - _, val := vals.GetByAddress(address) - if val == nil { - // add val - // Set ProposerPriority to -C*totalVotingPower (with C ~= 1.125) to make sure validators can't - // un-bond and then re-bond to reset their (potentially previously negative) ProposerPriority to zero. - // - // Contract: updatedVotingPower < MaxTotalVotingPower to ensure ProposerPriority does - // not exceed the bounds of int64. - // - // Compute ProposerPriority = -1.125*totalVotingPower == -(updatedVotingPower + (updatedVotingPower >> 3)). - valUpdate.ProposerPriority = -(updatedTotalVotingPower + (updatedTotalVotingPower >> 3)) - } else { - valUpdate.ProposerPriority = val.ProposerPriority - } - } - -} - -// Merges the vals' validator list with the updates list. -// When two elements with same address are seen, the one from updates is selected. -// Expects updates to be a list of updates sorted by address with no duplicates or errors, -// must have been validated with verifyUpdates() and priorities computed with computeNewPriorities(). -func (vals *ValidatorSet) applyUpdates(updates []*Validator) { - - existing := vals.Validators - merged := make([]*Validator, len(existing)+len(updates)) - i := 0 - - for len(existing) > 0 && len(updates) > 0 { - if bytes.Compare(existing[0].Address, updates[0].Address) < 0 { // unchanged validator - merged[i] = existing[0] - existing = existing[1:] - } else { - // Apply add or update. - merged[i] = updates[0] - if bytes.Equal(existing[0].Address, updates[0].Address) { - // Validator is present in both, advance existing. - existing = existing[1:] - } - updates = updates[1:] - } - i++ - } - - // Add the elements which are left. - for j := 0; j < len(existing); j++ { - merged[i] = existing[j] - i++ - } - // OR add updates which are left. - for j := 0; j < len(updates); j++ { - merged[i] = updates[j] - i++ - } - - vals.Validators = merged[:i] -} - -// Checks that the validators to be removed are part of the validator set. -// No changes are made to the validator set 'vals'. -func verifyRemovals(deletes []*Validator, vals *ValidatorSet) error { - - for _, valUpdate := range deletes { - address := valUpdate.Address - _, val := vals.GetByAddress(address) - if val == nil { - return fmt.Errorf("failed to find validator %X to remove", address) - } - } - if len(deletes) > len(vals.Validators) { - panic("more deletes than validators") - } - return nil -} - -// Removes the validators specified in 'deletes' from validator set 'vals'. -// Should not fail as verification has been done before. -func (vals *ValidatorSet) applyRemovals(deletes []*Validator) { - - existing := vals.Validators - - merged := make([]*Validator, len(existing)-len(deletes)) - i := 0 - - // Loop over deletes until we removed all of them. - for len(deletes) > 0 { - if bytes.Equal(existing[0].Address, deletes[0].Address) { - deletes = deletes[1:] - } else { // Leave it in the resulting slice. - merged[i] = existing[0] - i++ - } - existing = existing[1:] - } - - // Add the elements which are left. - for j := 0; j < len(existing); j++ { - merged[i] = existing[j] - i++ - } - - vals.Validators = merged[:i] -} - -// Main function used by UpdateWithChangeSet() and NewValidatorSet(). -// If 'allowDeletes' is false then delete operations (identified by validators with voting power 0) -// are not allowed and will trigger an error if present in 'changes'. -// The 'allowDeletes' flag is set to false by NewValidatorSet() and to true by UpdateWithChangeSet(). -func (vals *ValidatorSet) updateWithChangeSet(changes []*Validator, allowDeletes bool) error { - - if len(changes) == 0 { - return nil - } - - // Check for duplicates within changes, split in 'updates' and 'deletes' lists (sorted). - updates, deletes, err := processChanges(changes) - if err != nil { - return err - } - - if !allowDeletes && len(deletes) != 0 { - return fmt.Errorf("cannot process validators with voting power 0: %v", deletes) - } - - // Verify that applying the 'deletes' against 'vals' will not result in error. - if err := verifyRemovals(deletes, vals); err != nil { - return err - } - - // Verify that applying the 'updates' against 'vals' will not result in error. - updatedTotalVotingPower, numNewValidators, err := verifyUpdates(updates, vals) - if err != nil { - return err - } - - // Check that the resulting set will not be empty. - if numNewValidators == 0 && len(vals.Validators) == len(deletes) { - return errors.New("applying the validator changes would result in empty set") - } - - // Compute the priorities for updates. - computeNewPriorities(updates, vals, updatedTotalVotingPower) - - // Apply updates and removals. - vals.applyUpdates(updates) - vals.applyRemovals(deletes) - - vals.updateTotalVotingPower() - - // Scale and center. - vals.RescalePriorities(PriorityWindowSizeFactor * vals.TotalVotingPower()) - vals.shiftByAvgProposerPriority() - - return nil -} - -// UpdateWithChangeSet attempts to update the validator set with 'changes'. -// It performs the following steps: -// - validates the changes making sure there are no duplicates and splits them in updates and deletes -// - verifies that applying the changes will not result in errors -// - computes the total voting power BEFORE removals to ensure that in the next steps the priorities -// across old and newly added validators are fair -// - computes the priorities of new validators against the final set -// - applies the updates against the validator set -// - applies the removals against the validator set -// - performs scaling and centering of priority values -// If an error is detected during verification steps, it is returned and the validator set -// is not changed. -func (vals *ValidatorSet) UpdateWithChangeSet(changes []*Validator) error { - return vals.updateWithChangeSet(changes, true) -} - -//----------------- -// ErrTooMuchChange - -func IsErrTooMuchChange(err error) bool { - _, ok := errors.Cause(err).(errTooMuchChange) - return ok -} - -type errTooMuchChange struct { - got int64 - needed int64 -} - -func (e errTooMuchChange) Error() string { - return fmt.Sprintf("Invalid commit -- insufficient old voting power: got %v, needed %v", e.got, e.needed) -} - -//---------------- - -func (vals *ValidatorSet) String() string { - return vals.StringIndented("") -} - -// String -func (vals *ValidatorSet) StringIndented(indent string) string { - if vals == nil { - return "nil-ValidatorSet" - } - var valStrings []string - vals.Iterate(func(index int, val *Validator) bool { - valStrings = append(valStrings, val.String()) - return false - }) - return fmt.Sprintf(`ValidatorSet{ -%s Proposer: %v -%s Validators: -%s %v -%s}`, - indent, vals.GetProposer().String(), - indent, - indent, strings.Join(valStrings, "\n"+indent+" "), - indent) - -} - -//------------------------------------- -// Implements sort for sorting validators by address. - -// Sort validators by address. -type ValidatorsByAddress []*Validator - -func (valz ValidatorsByAddress) Len() int { - return len(valz) -} - -func (valz ValidatorsByAddress) Less(i, j int) bool { - return bytes.Compare(valz[i].Address, valz[j].Address) == -1 -} - -func (valz ValidatorsByAddress) Swap(i, j int) { - it := valz[i] - valz[i] = valz[j] - valz[j] = it -} - -/////////////////////////////////////////////////////////////////////////////// -// safe addition/subtraction - -func safeAdd(a, b int64) (int64, bool) { - if b > 0 && a > math.MaxInt64-b { - return -1, true - } else if b < 0 && a < math.MinInt64-b { - return -1, true - } - return a + b, false -} - -func safeSub(a, b int64) (int64, bool) { - if b > 0 && a < math.MinInt64+b { - return -1, true - } else if b < 0 && a > math.MaxInt64+b { - return -1, true - } - return a - b, false -} - -func safeAddClip(a, b int64) int64 { - c, overflow := safeAdd(a, b) - if overflow { - if b < 0 { - return math.MinInt64 - } - return math.MaxInt64 - } - return c -} - -func safeSubClip(a, b int64) int64 { - c, overflow := safeSub(a, b) - if overflow { - if b > 0 { - return math.MinInt64 - } - return math.MaxInt64 - } - return c -} diff --git a/contracts/native/header_sync/polygon/types/heimdall_vote.go b/contracts/native/header_sync/polygon/types/heimdall_vote.go deleted file mode 100644 index 87f0bd2a..00000000 --- a/contracts/native/header_sync/polygon/types/heimdall_vote.go +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package types - -import "time" - -// Vote represents a prevote, precommit, or commit vote from validators for -// consensus. -type Vote struct { - Type SignedMsgType `json:"type"` - Height int64 `json:"height"` - Round int `json:"round"` - BlockID BlockID `json:"block_id"` // zero if vote is nil. - Timestamp time.Time `json:"timestamp"` - ValidatorAddress Address `json:"validator_address"` - ValidatorIndex int `json:"validator_index"` - Signature []byte `json:"signature"` - - SideTxResults []SideTxResult `json:"side_tx_results"` // side-tx result [peppermint] -} - -func (vote *Vote) SignBytes(chainID string) []byte { - // [peppermint] converted from amino to rlp - bz, err := cdc.MarshalBinaryLengthPrefixed(CanonicalizeVote(chainID, vote)) - if err != nil { - panic(err) - } - return bz -} diff --git a/contracts/native/header_sync/polygon/types/secp256k1/secp256k1.go b/contracts/native/header_sync/polygon/types/secp256k1/secp256k1.go deleted file mode 100644 index 8ad5f6b8..00000000 --- a/contracts/native/header_sync/polygon/types/secp256k1/secp256k1.go +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package secp256k1 - -import ( - "bytes" - "crypto/sha256" - "crypto/subtle" - "fmt" - "io" - "math/big" - - secp256k1 "github.com/btcsuite/btcd/btcec" - ethCrypto "github.com/ethereum/go-ethereum/crypto" - - amino "github.com/tendermint/go-amino" - - "github.com/tendermint/tendermint/crypto" -) - -//------------------------------------- -const ( - PrivKeyAminoName = "tendermint/PrivKeySecp256k1" - PubKeyAminoName = "tendermint/PubKeySecp256k1" -) - -var cdc = amino.NewCodec() - -func init() { - cdc.RegisterInterface((*crypto.PubKey)(nil), nil) - cdc.RegisterConcrete(PubKeySecp256k1{}, - PubKeyAminoName, nil) - - cdc.RegisterInterface((*crypto.PrivKey)(nil), nil) - cdc.RegisterConcrete(PrivKeySecp256k1{}, - PrivKeyAminoName, nil) -} - -//------------------------------------- - -var _ crypto.PrivKey = PrivKeySecp256k1{} - -// PrivKeySecp256k1 implements PrivKey. -type PrivKeySecp256k1 [32]byte - -// Bytes marshalls the private key using amino encoding. -func (privKey PrivKeySecp256k1) Bytes() []byte { - return cdc.MustMarshalBinaryBare(privKey) -} - -// PubKey performs the point-scalar multiplication from the privKey on the -// generator point to get the pubkey. -func (privKey PrivKeySecp256k1) PubKey() crypto.PubKey { - privateObject, err := ethCrypto.ToECDSA(privKey[:]) - if err != nil { - panic(err) - } - - var pubkeyBytes PubKeySecp256k1 - copy(pubkeyBytes[:], ethCrypto.FromECDSAPub(&privateObject.PublicKey)) - return pubkeyBytes - - // _, pubkeyObject := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) - // var pubkeyBytes PubKeySecp256k1 - // copy(pubkeyBytes[:], pubkeyObject.SerializeCompressed()) - // return pubkeyBytes -} - -// Equals - you probably don't need to use this. -// Runs in constant time based on length of the keys. -func (privKey PrivKeySecp256k1) Equals(other crypto.PrivKey) bool { - if otherSecp, ok := other.(PrivKeySecp256k1); ok { - return subtle.ConstantTimeCompare(privKey[:], otherSecp[:]) == 1 - } - return false -} - -// GenPrivKey generates a new ECDSA private key on curve secp256k1 private key. -// It uses OS randomness to generate the private key. -func GenPrivKey() PrivKeySecp256k1 { - return genPrivKey(crypto.CReader()) -} - -// genPrivKey generates a new secp256k1 private key using the provided reader. -func genPrivKey(rand io.Reader) PrivKeySecp256k1 { - // var privKeyBytes [32]byte - // d := new(big.Int) - // for { - // privKeyBytes = [32]byte{} - // _, err := io.ReadFull(rand, privKeyBytes[:]) - // if err != nil { - // panic(err) - // } - - // d.SetBytes(privKeyBytes[:]) - // // break if we found a valid point (i.e. > 0 and < N == curverOrder) - // isValidFieldElement := 0 < d.Sign() && d.Cmp(secp256k1.S256().N) < 0 - // if isValidFieldElement { - // break - // } - // } - - // return PrivKeySecp256k1(privKeyBytes) - - privKeyBytes := [32]byte{} - _, err := io.ReadFull(rand, privKeyBytes[:]) - if err != nil { - panic(err) - } - // crypto.CRandBytes is guaranteed to be 32 bytes long, so it can be - // casted to PrivKeySecp256k1. - return PrivKeySecp256k1(privKeyBytes) -} - -var one = new(big.Int).SetInt64(1) - -// GenPrivKeySecp256k1 hashes the secret with SHA2, and uses -// that 32 byte output to create the private key. -// -// It makes sure the private key is a valid field element by setting: -// -// c = sha256(secret) -// k = (c mod (n − 1)) + 1, where n = curve order. -// -// NOTE: secret should be the output of a KDF like bcrypt, -// if it's derived from user input. -func GenPrivKeySecp256k1(secret []byte) PrivKeySecp256k1 { - secHash := sha256.Sum256(secret) - // to guarantee that we have a valid field element, we use the approach of: - // "Suite B Implementer’s Guide to FIPS 186-3", A.2.1 - // https://apps.nsa.gov/iaarchive/library/ia-guidance/ia-solutions-for-classified/algorithm-guidance/suite-b-implementers-guide-to-fips-186-3-ecdsa.cfm - // see also https://github.com/golang/go/blob/0380c9ad38843d523d9c9804fe300cb7edd7cd3c/src/crypto/ecdsa/ecdsa.go#L89-L101 - fe := new(big.Int).SetBytes(secHash[:]) - n := new(big.Int).Sub(secp256k1.S256().N, one) - fe.Mod(fe, n) - fe.Add(fe, one) - - feB := fe.Bytes() - var privKey32 [32]byte - // copy feB over to fixed 32 byte privKey32 and pad (if necessary) - copy(privKey32[32-len(feB):32], feB) - - return PrivKeySecp256k1(privKey32) -} - -//------------------------------------- - -var _ crypto.PubKey = PubKeySecp256k1{} - -// PubKeySecp256k1Size is comprised of 32 bytes for one field element -// (the x-coordinate), plus one byte for the parity of the y-coordinate. -// const PubKeySecp256k1Size = 33 -const PubKeySecp256k1Size = 65 - -// PubKeySecp256k1 implements crypto.PubKey. -// It is the compressed form of the pubkey. The first byte depends is a 0x02 byte -// if the y-coordinate is the lexicographically largest of the two associated with -// the x-coordinate. Otherwise the first byte is a 0x03. -// This prefix is followed with the x-coordinate. -type PubKeySecp256k1 [PubKeySecp256k1Size]byte - -// Address returns a Bitcoin style addresses: RIPEMD160(SHA256(pubkey)) -func (pubKey PubKeySecp256k1) Address() crypto.Address { - // hasherSHA256 := sha256.New() - // hasherSHA256.Write(pubKey[:]) // does not error - // sha := hasherSHA256.Sum(nil) - - // hasherRIPEMD160 := ripemd160.New() - // hasherRIPEMD160.Write(sha) // does not error - // return crypto.Address(hasherRIPEMD160.Sum(nil)) - return crypto.Address(ethCrypto.Keccak256(pubKey[1:])[12:]) - -} - -// Bytes returns the pubkey marshalled with amino encoding. -func (pubKey PubKeySecp256k1) Bytes() []byte { - bz, err := cdc.MarshalBinaryBare(pubKey) - if err != nil { - panic(err) - } - return bz -} - -func (pubKey PubKeySecp256k1) String() string { - return fmt.Sprintf("PubKeySecp256k1{%X}", pubKey[:]) -} - -func (pubKey PubKeySecp256k1) Equals(other crypto.PubKey) bool { - if otherSecp, ok := other.(PubKeySecp256k1); ok { - return bytes.Equal(pubKey[:], otherSecp[:]) - } - return false -} diff --git a/contracts/native/header_sync/polygon/types/secp256k1/secp256k1_nocgo.go b/contracts/native/header_sync/polygon/types/secp256k1/secp256k1_nocgo.go deleted file mode 100644 index e7dc2556..00000000 --- a/contracts/native/header_sync/polygon/types/secp256k1/secp256k1_nocgo.go +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -// +build !libsecp256k1 - -package secp256k1 - -import ( - "math/big" - - secp256k1 "github.com/btcsuite/btcd/btcec" - ethCrypto "github.com/ethereum/go-ethereum/crypto" -) - -// used to reject malleable signatures -// see: -// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93 -// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/crypto.go#L39 -var secp256k1halfN = new(big.Int).Rsh(secp256k1.S256().N, 1) - -// Sign creates an ECDSA signature on curve Secp256k1, using SHA256 on the msg. -// The returned signature will be of the form R || S (in lower-S form). -func (privKey PrivKeySecp256k1) Sign(msg []byte) ([]byte, error) { - // [peppermint] sign with ethcrypto - // priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) - // sig, err := priv.Sign(crypto.Sha256(msg)) - privateObject, err := ethCrypto.ToECDSA(privKey[:]) - if err != nil { - return nil, err - } - // sigBytes := serializeSig(sig) - // return sigBytes, nil - return ethCrypto.Sign(ethCrypto.Keccak256(msg), privateObject) -} - -// VerifyBytes verifies a signature of the form R || S. -// It rejects signatures which are not in lower-S form. -func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sigStr []byte) bool { - // if len(sigStr) != 64 { - // return false - // } - // pub, err := secp256k1.ParsePubKey(pubKey[:], secp256k1.S256()) - // if err != nil { - // return false - // } - // // parse the signature: - // signature := signatureFromBytes(sigStr) - // // Reject malleable signatures. libsecp256k1 does this check but btcec doesn't. - // // see: https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93 - // if signature.S.Cmp(secp256k1halfN) > 0 { - // return false - // } - hash := ethCrypto.Keccak256(msg) - return ethCrypto.VerifySignature(pubKey[:], hash, sigStr[:64]) - // return signature.Verify(crypto.Sha256(msg), pub) -} - -// Read Signature struct from R || S. Caller needs to ensure -// that len(sigStr) == 64. -func signatureFromBytes(sigStr []byte) *secp256k1.Signature { - return &secp256k1.Signature{ - R: new(big.Int).SetBytes(sigStr[:32]), - S: new(big.Int).SetBytes(sigStr[32:64]), - } -} - -// Serialize signature to R || S. -// R, S are padded to 32 bytes respectively. -func serializeSig(sig *secp256k1.Signature) []byte { - rBytes := sig.R.Bytes() - sBytes := sig.S.Bytes() - sigBytes := make([]byte, 64) - // 0 pad the byte arrays from the left if they aren't big enough. - copy(sigBytes[32-len(rBytes):32], rBytes) - copy(sigBytes[64-len(sBytes):64], sBytes) - return sigBytes -} diff --git a/contracts/native/header_sync/polygon/validator.go b/contracts/native/header_sync/polygon/validator.go deleted file mode 100644 index a21eaf4c..00000000 --- a/contracts/native/header_sync/polygon/validator.go +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package polygon - -import ( - "bytes" - // "encoding/json" - "errors" - "fmt" - "math/big" - "sort" - "strings" - - "github.com/ethereum/go-ethereum/common" -) - -// Validator represets Volatile state for each Validator -type Validator struct { - ID uint64 `json:"ID"` - Address common.Address `json:"signer"` - VotingPower int64 `json:"power"` - ProposerPriority int64 `json:"accum"` -} - -// NewValidator creates new validator -func NewValidator(address common.Address, votingPower int64) *Validator { - return &Validator{ - Address: address, - VotingPower: votingPower, - ProposerPriority: 0, - } -} - -// Copy creates a new copy of the validator so we can mutate ProposerPriority. -// Panics if the validator is nil. -func (v *Validator) Copy() *Validator { - vCopy := *v - return &vCopy -} - -// Cmp returns the one validator with a higher ProposerPriority. -// If ProposerPriority is same, it returns the validator with lexicographically smaller address -func (v *Validator) Cmp(other *Validator) *Validator { - // if both of v and other are nil, nil will be returned and that could possibly lead to nil pointer dereference bubbling up the stack - if v == nil { - return other - } - if other == nil { - return v - } - if v.ProposerPriority > other.ProposerPriority { - return v - } else if v.ProposerPriority < other.ProposerPriority { - return other - } else { - result := bytes.Compare(v.Address.Bytes(), other.Address.Bytes()) - if result < 0 { - return v - } else if result > 0 { - return other - } else { - panic("Cannot compare identical validators") - } - } -} - -func (v *Validator) String() string { - if v == nil { - return "nil-Validator" - } - return fmt.Sprintf("Validator{%v Power:%v Priority:%v}", - v.Address.Hex(), - v.VotingPower, - v.ProposerPriority) -} - -// ValidatorListString returns a prettified validator list for logging purposes. -func ValidatorListString(vals []*Validator) string { - chunks := make([]string, len(vals)) - for i, val := range vals { - chunks[i] = fmt.Sprintf("%s:%d", val.Address, val.VotingPower) - } - - return strings.Join(chunks, ",") -} - -// HeaderBytes return header bytes -func (v *Validator) HeaderBytes() []byte { - result := make([]byte, 40) - copy(result[:20], v.Address.Bytes()) - copy(result[20:], v.PowerBytes()) - return result -} - -// PowerBytes return power bytes -func (v *Validator) PowerBytes() []byte { - powerBytes := big.NewInt(0).SetInt64(v.VotingPower).Bytes() - result := make([]byte, 20) - copy(result[20-len(powerBytes):], powerBytes) - return result -} - -// MinimalVal returns block number of last validator update -func (v *Validator) MinimalVal() MinimalVal { - return MinimalVal{ - ID: v.ID, - VotingPower: uint64(v.VotingPower), - Signer: v.Address, - } -} - -// ParseValidators returns validator set bytes -func ParseValidators(validatorsBytes []byte) ([]*Validator, error) { - if len(validatorsBytes)%40 != 0 { - return nil, errors.New("Invalid validators bytes") - } - - result := make([]*Validator, len(validatorsBytes)/40) - for i := 0; i < len(validatorsBytes); i += 40 { - address := make([]byte, 20) - power := make([]byte, 20) - - copy(address, validatorsBytes[i:i+20]) - copy(power, validatorsBytes[i+20:i+40]) - - result[i/40] = NewValidator(common.BytesToAddress(address), big.NewInt(0).SetBytes(power).Int64()) - } - - return result, nil -} - -// --- - -// MinimalVal is the minimal validator representation -// Used to send validator information to bor validator contract -type MinimalVal struct { - ID uint64 `json:"ID"` - VotingPower uint64 `json:"power"` // TODO add 10^-18 here so that we dont overflow easily - Signer common.Address `json:"signer"` -} - -// SortMinimalValByAddress sorts validators -func SortMinimalValByAddress(a []MinimalVal) []MinimalVal { - sort.Slice(a, func(i, j int) bool { - return bytes.Compare(a[i].Signer.Bytes(), a[j].Signer.Bytes()) < 0 - }) - return a -} - -// ValidatorsToMinimalValidators converts array of validators to minimal validators -func ValidatorsToMinimalValidators(vals []Validator) (minVals []MinimalVal) { - for _, val := range vals { - minVals = append(minVals, val.MinimalVal()) - } - return -} diff --git a/contracts/native/header_sync/polygon/validator_set.go b/contracts/native/header_sync/polygon/validator_set.go deleted file mode 100644 index 8dd01c97..00000000 --- a/contracts/native/header_sync/polygon/validator_set.go +++ /dev/null @@ -1,719 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package polygon - -// Tendermint leader selection algorithm - -import ( - "bytes" - "fmt" - "math" - "math/big" - "sort" - "strings" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" -) - -// MaxTotalVotingPower - the maximum allowed total voting power. -// It needs to be sufficiently small to, in all cases: -// 1. prevent clipping in incrementProposerPriority() -// 2. let (diff+diffMax-1) not overflow in IncrementProposerPriority() -// (Proof of 1 is tricky, left to the reader). -// It could be higher, but this is sufficiently large for our purposes, -// and leaves room for defensive purposes. -// PriorityWindowSizeFactor - is a constant that when multiplied with the total voting power gives -// the maximum allowed distance between validator priorities. - -const ( - MaxTotalVotingPower = int64(math.MaxInt64) / 8 - PriorityWindowSizeFactor = 2 -) - -// ValidatorSet represent a set of *Validator at a given height. -// The validators can be fetched by address or index. -// The index is in order of .Address, so the indices are fixed -// for all rounds of a given blockchain height - ie. the validators -// are sorted by their address. -// On the other hand, the .ProposerPriority of each validator and -// the designated .GetProposer() of a set changes every round, -// upon calling .IncrementProposerPriority(). -// NOTE: Not goroutine-safe. -// NOTE: All get/set to validators should copy the value for safety. -type ValidatorSet struct { - // NOTE: persisted via reflect, must be exported. - Validators []*Validator `json:"validators"` - Proposer *Validator `json:"proposer"` - - // cached (unexported) - totalVotingPower int64 -} - -// NewValidatorSet initializes a ValidatorSet by copying over the -// values from `valz`, a list of Validators. If valz is nil or empty, -// the new ValidatorSet will have an empty list of Validators. -// The addresses of validators in `valz` must be unique otherwise the -// function panics. -func NewValidatorSet(valz []*Validator) *ValidatorSet { - vals := &ValidatorSet{} - err := vals.updateWithChangeSet(valz, false) - if err != nil { - panic(fmt.Sprintf("cannot create validator set: %s", err)) - } - if len(valz) > 0 { - vals.IncrementProposerPriority(1) - } - return vals -} - -// Nil or empty validator sets are invalid. -func (vals *ValidatorSet) IsNilOrEmpty() bool { - return vals == nil || len(vals.Validators) == 0 -} - -// Increment ProposerPriority and update the proposer on a copy, and return it. -func (vals *ValidatorSet) CopyIncrementProposerPriority(times int) *ValidatorSet { - copy := vals.Copy() - copy.IncrementProposerPriority(times) - return copy -} - -// IncrementProposerPriority increments ProposerPriority of each validator and updates the -// proposer. Panics if validator set is empty. -// `times` must be positive. -func (vals *ValidatorSet) IncrementProposerPriority(times int) { - if vals.IsNilOrEmpty() { - panic("empty validator set") - } - if times <= 0 { - panic("Cannot call IncrementProposerPriority with non-positive times") - } - - // Cap the difference between priorities to be proportional to 2*totalPower by - // re-normalizing priorities, i.e., rescale all priorities by multiplying with: - // 2*totalVotingPower/(maxPriority - minPriority) - diffMax := PriorityWindowSizeFactor * vals.TotalVotingPower() - vals.RescalePriorities(diffMax) - vals.shiftByAvgProposerPriority() - - var proposer *Validator - // Call IncrementProposerPriority(1) times times. - for i := 0; i < times; i++ { - proposer = vals.incrementProposerPriority() - } - - vals.Proposer = proposer -} - -func (vals *ValidatorSet) RescalePriorities(diffMax int64) { - if vals.IsNilOrEmpty() { - panic("empty validator set") - } - // NOTE: This check is merely a sanity check which could be - // removed if all tests would init. voting power appropriately; - // i.e. diffMax should always be > 0 - if diffMax <= 0 { - return - } - - // Calculating ceil(diff/diffMax): - // Re-normalization is performed by dividing by an integer for simplicity. - // NOTE: This may make debugging priority issues easier as well. - diff := computeMaxMinPriorityDiff(vals) - ratio := (diff + diffMax - 1) / diffMax - if diff > diffMax { - for _, val := range vals.Validators { - val.ProposerPriority = val.ProposerPriority / ratio - } - } -} - -func (vals *ValidatorSet) incrementProposerPriority() *Validator { - for _, val := range vals.Validators { - // Check for overflow for sum. - newPrio := safeAddClip(val.ProposerPriority, val.VotingPower) - val.ProposerPriority = newPrio - } - // Decrement the validator with most ProposerPriority. - mostest := vals.getValWithMostPriority() - // Mind the underflow. - mostest.ProposerPriority = safeSubClip(mostest.ProposerPriority, vals.TotalVotingPower()) - - return mostest -} - -// Should not be called on an empty validator set. -func (vals *ValidatorSet) computeAvgProposerPriority() int64 { - n := int64(len(vals.Validators)) - sum := big.NewInt(0) - for _, val := range vals.Validators { - sum.Add(sum, big.NewInt(val.ProposerPriority)) - } - avg := sum.Div(sum, big.NewInt(n)) - if avg.IsInt64() { - return avg.Int64() - } - - // This should never happen: each val.ProposerPriority is in bounds of int64. - panic(fmt.Sprintf("Cannot represent avg ProposerPriority as an int64 %v", avg)) -} - -// Compute the difference between the max and min ProposerPriority of that set. -func computeMaxMinPriorityDiff(vals *ValidatorSet) int64 { - if vals.IsNilOrEmpty() { - panic("empty validator set") - } - max := int64(math.MinInt64) - min := int64(math.MaxInt64) - for _, v := range vals.Validators { - if v.ProposerPriority < min { - min = v.ProposerPriority - } - if v.ProposerPriority > max { - max = v.ProposerPriority - } - } - diff := max - min - if diff < 0 { - return -1 * diff - } else { - return diff - } -} - -func (vals *ValidatorSet) getValWithMostPriority() *Validator { - var res *Validator - for _, val := range vals.Validators { - res = res.Cmp(val) - } - return res -} - -func (vals *ValidatorSet) shiftByAvgProposerPriority() { - if vals.IsNilOrEmpty() { - panic("empty validator set") - } - avgProposerPriority := vals.computeAvgProposerPriority() - for _, val := range vals.Validators { - val.ProposerPriority = safeSubClip(val.ProposerPriority, avgProposerPriority) - } -} - -// Makes a copy of the validator list. -func validatorListCopy(valsList []*Validator) []*Validator { - if valsList == nil { - return nil - } - valsCopy := make([]*Validator, len(valsList)) - for i, val := range valsList { - valsCopy[i] = val.Copy() - } - return valsCopy -} - -// Copy each validator into a new ValidatorSet. -func (vals *ValidatorSet) Copy() *ValidatorSet { - return &ValidatorSet{ - Validators: validatorListCopy(vals.Validators), - Proposer: vals.Proposer, - totalVotingPower: vals.totalVotingPower, - } -} - -// HasAddress returns true if address given is in the validator set, false - -// otherwise. -func (vals *ValidatorSet) HasAddress(address []byte) bool { - idx := sort.Search(len(vals.Validators), func(i int) bool { - return bytes.Compare(address, vals.Validators[i].Address.Bytes()) <= 0 - }) - return idx < len(vals.Validators) && bytes.Equal(vals.Validators[idx].Address.Bytes(), address) -} - -// GetByAddress returns an index of the validator with address and validator -// itself if found. Otherwise, -1 and nil are returned. -func (vals *ValidatorSet) GetByAddress(address common.Address) (index int, val *Validator) { - idx := sort.Search(len(vals.Validators), func(i int) bool { - return bytes.Compare(address.Bytes(), vals.Validators[i].Address.Bytes()) <= 0 - }) - if idx < len(vals.Validators) && bytes.Equal(vals.Validators[idx].Address.Bytes(), address.Bytes()) { - return idx, vals.Validators[idx].Copy() - } - return -1, nil -} - -// GetByIndex returns the validator's address and validator itself by index. -// It returns nil values if index is less than 0 or greater or equal to -// len(ValidatorSet.Validators). -func (vals *ValidatorSet) GetByIndex(index int) (address []byte, val *Validator) { - if index < 0 || index >= len(vals.Validators) { - return nil, nil - } - val = vals.Validators[index] - return val.Address.Bytes(), val.Copy() -} - -// Size returns the length of the validator set. -func (vals *ValidatorSet) Size() int { - return len(vals.Validators) -} - -// Force recalculation of the set's total voting power. -func (vals *ValidatorSet) updateTotalVotingPower() error { - - sum := int64(0) - for _, val := range vals.Validators { - // mind overflow - sum = safeAddClip(sum, val.VotingPower) - if sum > MaxTotalVotingPower { - return &TotalVotingPowerExceededError{sum, vals.Validators} - } - } - vals.totalVotingPower = sum - return nil -} - -// TotalVotingPower returns the sum of the voting powers of all validators. -// It recomputes the total voting power if required. -func (vals *ValidatorSet) TotalVotingPower() int64 { - if vals.totalVotingPower == 0 { - log.Info("invoking updateTotalVotingPower before returning it") - if err := vals.updateTotalVotingPower(); err != nil { - // Can/should we do better? - panic(err) - } - } - return vals.totalVotingPower -} - -// GetProposer returns the current proposer. If the validator set is empty, nil -// is returned. -func (vals *ValidatorSet) GetProposer() (proposer *Validator) { - if len(vals.Validators) == 0 { - return nil - } - if vals.Proposer == nil { - vals.Proposer = vals.findProposer() - } - return vals.Proposer.Copy() -} - -func (vals *ValidatorSet) findProposer() *Validator { - var proposer *Validator - for _, val := range vals.Validators { - if proposer == nil || !bytes.Equal(val.Address.Bytes(), proposer.Address.Bytes()) { - proposer = proposer.Cmp(val) - } - } - return proposer -} - -// Hash returns the Merkle root hash build using validators (as leaves) in the -// set. -// func (vals *ValidatorSet) Hash() []byte { -// if len(vals.Validators) == 0 { -// return nil -// } -// bzs := make([][]byte, len(vals.Validators)) -// for i, val := range vals.Validators { -// bzs[i] = val.Bytes() -// } -// return merkle.SimpleHashFromByteSlices(bzs) -// } - -// Iterate will run the given function over the set. -func (vals *ValidatorSet) Iterate(fn func(index int, val *Validator) bool) { - for i, val := range vals.Validators { - stop := fn(i, val.Copy()) - if stop { - break - } - } -} - -// Checks changes against duplicates, splits the changes in updates and removals, sorts them by address. -// -// Returns: -// updates, removals - the sorted lists of updates and removals -// err - non-nil if duplicate entries or entries with negative voting power are seen -// -// No changes are made to 'origChanges'. -func processChanges(origChanges []*Validator) (updates, removals []*Validator, err error) { - // Make a deep copy of the changes and sort by address. - changes := validatorListCopy(origChanges) - sort.Sort(ValidatorsByAddress(changes)) - - removals = make([]*Validator, 0, len(changes)) - updates = make([]*Validator, 0, len(changes)) - var prevAddr common.Address - - // Scan changes by address and append valid validators to updates or removals lists. - for _, valUpdate := range changes { - if bytes.Equal(valUpdate.Address.Bytes(), prevAddr.Bytes()) { - err = fmt.Errorf("duplicate entry %v in %v", valUpdate, changes) - return nil, nil, err - } - if valUpdate.VotingPower < 0 { - err = fmt.Errorf("voting power can't be negative: %v", valUpdate) - return nil, nil, err - } - if valUpdate.VotingPower > MaxTotalVotingPower { - err = fmt.Errorf("to prevent clipping/ overflow, voting power can't be higher than %v: %v ", - MaxTotalVotingPower, valUpdate) - return nil, nil, err - } - if valUpdate.VotingPower == 0 { - removals = append(removals, valUpdate) - } else { - updates = append(updates, valUpdate) - } - prevAddr = valUpdate.Address - } - return updates, removals, err -} - -// Verifies a list of updates against a validator set, making sure the allowed -// total voting power would not be exceeded if these updates would be applied to the set. -// -// Returns: -// updatedTotalVotingPower - the new total voting power if these updates would be applied -// numNewValidators - number of new validators -// err - non-nil if the maximum allowed total voting power would be exceeded -// -// 'updates' should be a list of proper validator changes, i.e. they have been verified -// by processChanges for duplicates and invalid values. -// No changes are made to the validator set 'vals'. -func verifyUpdates(updates []*Validator, vals *ValidatorSet) (updatedTotalVotingPower int64, numNewValidators int, err error) { - - updatedTotalVotingPower = vals.TotalVotingPower() - - for _, valUpdate := range updates { - address := valUpdate.Address - _, val := vals.GetByAddress(address) - if val == nil { - // New validator, add its voting power the the total. - updatedTotalVotingPower += valUpdate.VotingPower - numNewValidators++ - } else { - // Updated validator, add the difference in power to the total. - updatedTotalVotingPower += valUpdate.VotingPower - val.VotingPower - } - overflow := updatedTotalVotingPower > MaxTotalVotingPower - if overflow { - err = fmt.Errorf( - "failed to add/update validator %v, total voting power would exceed the max allowed %v", - valUpdate, MaxTotalVotingPower) - return 0, 0, err - } - } - - return updatedTotalVotingPower, numNewValidators, nil -} - -// Computes the proposer priority for the validators not present in the set based on 'updatedTotalVotingPower'. -// Leaves unchanged the priorities of validators that are changed. -// -// 'updates' parameter must be a list of unique validators to be added or updated. -// No changes are made to the validator set 'vals'. -func computeNewPriorities(updates []*Validator, vals *ValidatorSet, updatedTotalVotingPower int64) { - - for _, valUpdate := range updates { - address := valUpdate.Address - _, val := vals.GetByAddress(address) - if val == nil { - // add val - // Set ProposerPriority to -C*totalVotingPower (with C ~= 1.125) to make sure validators can't - // un-bond and then re-bond to reset their (potentially previously negative) ProposerPriority to zero. - // - // Contract: updatedVotingPower < MaxTotalVotingPower to ensure ProposerPriority does - // not exceed the bounds of int64. - // - // Compute ProposerPriority = -1.125*totalVotingPower == -(updatedVotingPower + (updatedVotingPower >> 3)). - valUpdate.ProposerPriority = -(updatedTotalVotingPower + (updatedTotalVotingPower >> 3)) - } else { - valUpdate.ProposerPriority = val.ProposerPriority - } - } - -} - -// Merges the vals' validator list with the updates list. -// When two elements with same address are seen, the one from updates is selected. -// Expects updates to be a list of updates sorted by address with no duplicates or errors, -// must have been validated with verifyUpdates() and priorities computed with computeNewPriorities(). -func (vals *ValidatorSet) applyUpdates(updates []*Validator) { - - existing := vals.Validators - merged := make([]*Validator, len(existing)+len(updates)) - i := 0 - - for len(existing) > 0 && len(updates) > 0 { - if bytes.Compare(existing[0].Address.Bytes(), updates[0].Address.Bytes()) < 0 { // unchanged validator - merged[i] = existing[0] - existing = existing[1:] - } else { - // Apply add or update. - merged[i] = updates[0] - if bytes.Equal(existing[0].Address.Bytes(), updates[0].Address.Bytes()) { - // Validator is present in both, advance existing. - existing = existing[1:] - } - updates = updates[1:] - } - i++ - } - - // Add the elements which are left. - for j := 0; j < len(existing); j++ { - merged[i] = existing[j] - i++ - } - // OR add updates which are left. - for j := 0; j < len(updates); j++ { - merged[i] = updates[j] - i++ - } - - vals.Validators = merged[:i] -} - -// Checks that the validators to be removed are part of the validator set. -// No changes are made to the validator set 'vals'. -func verifyRemovals(deletes []*Validator, vals *ValidatorSet) error { - - for _, valUpdate := range deletes { - address := valUpdate.Address - _, val := vals.GetByAddress(address) - if val == nil { - return fmt.Errorf("failed to find validator %X to remove", address) - } - } - if len(deletes) > len(vals.Validators) { - panic("more deletes than validators") - } - return nil -} - -// Removes the validators specified in 'deletes' from validator set 'vals'. -// Should not fail as verification has been done before. -func (vals *ValidatorSet) applyRemovals(deletes []*Validator) { - - existing := vals.Validators - - merged := make([]*Validator, len(existing)-len(deletes)) - i := 0 - - // Loop over deletes until we removed all of them. - for len(deletes) > 0 { - if bytes.Equal(existing[0].Address.Bytes(), deletes[0].Address.Bytes()) { - deletes = deletes[1:] - } else { // Leave it in the resulting slice. - merged[i] = existing[0] - i++ - } - existing = existing[1:] - } - - // Add the elements which are left. - for j := 0; j < len(existing); j++ { - merged[i] = existing[j] - i++ - } - - vals.Validators = merged[:i] -} - -// Main function used by UpdateWithChangeSet() and NewValidatorSet(). -// If 'allowDeletes' is false then delete operations (identified by validators with voting power 0) -// are not allowed and will trigger an error if present in 'changes'. -// The 'allowDeletes' flag is set to false by NewValidatorSet() and to true by UpdateWithChangeSet(). -func (vals *ValidatorSet) updateWithChangeSet(changes []*Validator, allowDeletes bool) error { - - if len(changes) <= 0 { - return nil - } - - // Check for duplicates within changes, split in 'updates' and 'deletes' lists (sorted). - updates, deletes, err := processChanges(changes) - if err != nil { - return err - } - - if !allowDeletes && len(deletes) != 0 { - return fmt.Errorf("cannot process validators with voting power 0: %v", deletes) - } - - // Verify that applying the 'deletes' against 'vals' will not result in error. - if err := verifyRemovals(deletes, vals); err != nil { - return err - } - - // Verify that applying the 'updates' against 'vals' will not result in error. - updatedTotalVotingPower, numNewValidators, err := verifyUpdates(updates, vals) - if err != nil { - return err - } - - // Check that the resulting set will not be empty. - if numNewValidators == 0 && len(vals.Validators) == len(deletes) { - return fmt.Errorf("applying the validator changes would result in empty set") - } - - // Compute the priorities for updates. - computeNewPriorities(updates, vals, updatedTotalVotingPower) - - // Apply updates and removals. - vals.applyUpdates(updates) - vals.applyRemovals(deletes) - - if err := vals.updateTotalVotingPower(); err != nil { - return err - } - - // Scale and center. - vals.RescalePriorities(PriorityWindowSizeFactor * vals.TotalVotingPower()) - vals.shiftByAvgProposerPriority() - - return nil -} - -// UpdateWithChangeSet attempts to update the validator set with 'changes'. -// It performs the following steps: -// - validates the changes making sure there are no duplicates and splits them in updates and deletes -// - verifies that applying the changes will not result in errors -// - computes the total voting power BEFORE removals to ensure that in the next steps the priorities -// across old and newly added validators are fair -// - computes the priorities of new validators against the final set -// - applies the updates against the validator set -// - applies the removals against the validator set -// - performs scaling and centering of priority values -// If an error is detected during verification steps, it is returned and the validator set -// is not changed. -func (vals *ValidatorSet) UpdateWithChangeSet(changes []*Validator) error { - return vals.updateWithChangeSet(changes, true) -} - -//----------------- -// ErrTooMuchChange - -func IsErrTooMuchChange(err error) bool { - switch err.(type) { - case errTooMuchChange: - return true - default: - return false - } -} - -type errTooMuchChange struct { - got int64 - needed int64 -} - -func (e errTooMuchChange) Error() string { - return fmt.Sprintf("Invalid commit -- insufficient old voting power: got %v, needed %v", e.got, e.needed) -} - -//---------------- - -func (vals *ValidatorSet) String() string { - return vals.StringIndented("") -} - -func (vals *ValidatorSet) StringIndented(indent string) string { - if vals == nil { - return "nil-ValidatorSet" - } - var valStrings []string - vals.Iterate(func(index int, val *Validator) bool { - valStrings = append(valStrings, val.String()) - return false - }) - return fmt.Sprintf(`ValidatorSet{ -%s Proposer: %v -%s Validators: -%s %v -%s}`, - indent, vals.GetProposer().String(), - indent, - indent, strings.Join(valStrings, "\n"+indent+" "), - indent) - -} - -//------------------------------------- -// Implements sort for sorting validators by address. - -// Sort validators by address. -type ValidatorsByAddress []*Validator - -func (valz ValidatorsByAddress) Len() int { - return len(valz) -} - -func (valz ValidatorsByAddress) Less(i, j int) bool { - return bytes.Compare(valz[i].Address.Bytes(), valz[j].Address.Bytes()) == -1 -} - -func (valz ValidatorsByAddress) Swap(i, j int) { - it := valz[i] - valz[i] = valz[j] - valz[j] = it -} - -/////////////////////////////////////////////////////////////////////////////// -// safe addition/subtraction - -func safeAdd(a, b int64) (int64, bool) { - if b > 0 && a > math.MaxInt64-b { - return -1, true - } else if b < 0 && a < math.MinInt64-b { - return -1, true - } - return a + b, false -} - -func safeSub(a, b int64) (int64, bool) { - if b > 0 && a < math.MinInt64+b { - return -1, true - } else if b < 0 && a > math.MaxInt64+b { - return -1, true - } - return a - b, false -} - -func safeAddClip(a, b int64) int64 { - c, overflow := safeAdd(a, b) - if overflow { - if b < 0 { - return math.MinInt64 - } - return math.MaxInt64 - } - return c -} - -func safeSubClip(a, b int64) int64 { - c, overflow := safeSub(a, b) - if overflow { - if b > 0 { - return math.MinInt64 - } - return math.MaxInt64 - } - return c -} diff --git a/contracts/native/header_sync/quorum/header_sync.go b/contracts/native/header_sync/quorum/header_sync.go deleted file mode 100644 index 185f59fa..00000000 --- a/contracts/native/header_sync/quorum/header_sync.go +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package quorum - -import ( - "encoding/json" - "fmt" - - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth/types" - "github.com/ethereum/go-ethereum/contracts/native/utils" -) - -type QuorumHandler struct{} - -func NewQuorumHandler() *QuorumHandler { - return &QuorumHandler{} -} - -func (h *QuorumHandler) SyncGenesisHeader(ns *native.NativeContract) error { - ctx := ns.ContractRef().CurrentContext() - params := &common.SyncGenesisHeaderParam{} - if err := utils.UnpackMethod(common.ABI, common.MethodSyncGenesisHeader, params, ctx.Payload); err != nil { - return fmt.Errorf("SyncGenesisHeader, contract params deserialize error: %v", err) - } - - // Get current epoch operator - ok, err := node_manager.CheckConsensusSigns(ns, common.MethodSyncGenesisHeader, ctx.Payload, ns.ContractRef().MsgSender()) - if err != nil { - return fmt.Errorf("SyncGenesisHeader, CheckConsensusSigns error: %v", err) - } - if !ok { - return nil - } - - header := &types.Header{} - if err = json.Unmarshal(params.GenesisHeader, header); err != nil { - return fmt.Errorf("QuorumHandler SyncGenesisHeader, deserialize header err: %v", err) - } - extra, err := ExtractIstanbulExtra(header) - if err != nil { - return fmt.Errorf("QuorumHandler SyncGenesisHeader, failed to ExtractIstanbulExtra: %v", err) - } - - putValSet(ns, params.ChainID, header.Number.Uint64(), extra.Validators) - return nil -} - -func (h *QuorumHandler) SyncBlockHeader(ns *native.NativeContract) error { - params := &common.SyncBlockHeaderParam{} - { - ctx := ns.ContractRef().CurrentContext() - if err := utils.UnpackMethod(common.ABI, common.MethodSyncBlockHeader, params, ctx.Payload); err != nil { - return err - } - } - - currh, err := GetCurrentValHeight(ns, params.ChainID) - if err != nil { - return fmt.Errorf("QuorumHandler SyncBlockHeader, failed to get current validator height: %v", err) - } - vs, err := GetValSet(ns, params.ChainID) - if err != nil { - return fmt.Errorf("QuorumHandler SyncBlockHeader, failed to get validators: %v", err) - } - header := &types.Header{} - for i, v := range params.Headers { - if err := json.Unmarshal(v, header); err != nil { - return fmt.Errorf("QuorumHandler SyncBlockHeader, deserialize No.%d header err: %v", i, err) - } - h := header.Number.Uint64() - if currh >= h { - return fmt.Errorf("QuorumHandler SyncBlockHeader, wrong height of No.%d header: (curr: %d, commit: %d)", i, currh, h) - } - - extra, err := VerifyQuorumHeader(vs, header, true) - if err != nil { - return fmt.Errorf("QuorumHandler SyncBlockHeader, failed to verify No.%d quorum header %s: %v", i, GetQuorumHeaderHash(header).String(), err) - } - - currh, vs = h, extra.Validators - } - - putValSet(ns, params.ChainID, currh, vs) - return nil -} - -func (h *QuorumHandler) SyncCrossChainMsg(ns *native.NativeContract) error { - return nil -} diff --git a/contracts/native/header_sync/quorum/quorum_tools.go b/contracts/native/header_sync/quorum/quorum_tools.go deleted file mode 100644 index df796647..00000000 --- a/contracts/native/header_sync/quorum/quorum_tools.go +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . -package quorum - -import ( - "bytes" - "errors" - "io" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" -) - -type IstanbulExtra struct { - Validators []common.Address - Seal []byte - CommittedSeal [][]byte -} - -// EncodeRLP serializes ist into the Ethereum RLP format. -func (ist *IstanbulExtra) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, []interface{}{ - ist.Validators, - ist.Seal, - ist.CommittedSeal, - }) -} - -// DecodeRLP implements rlp.Decoder, and load the istanbul fields from a RLP stream. -func (ist *IstanbulExtra) DecodeRLP(s *rlp.Stream) error { - var istanbulExtra struct { - Validators []common.Address - Seal []byte - CommittedSeal [][]byte - } - if err := s.Decode(&istanbulExtra); err != nil { - return err - } - ist.Validators, ist.Seal, ist.CommittedSeal = istanbulExtra.Validators, istanbulExtra.Seal, istanbulExtra.CommittedSeal - return nil -} - -// copy from quorum -func sigHash(header *types.Header) (hash common.Hash) { - hasher := sha3.NewLegacyKeccak256() - - // Clean seal is required for calculating proposer seal. - rlp.Encode(hasher, IstanbulFilteredHeader(header, false)) - hasher.Sum(hash[:0]) - return hash -} - -// copy from quorum -func IstanbulFilteredHeader(h *types.Header, keepSeal bool) *types.Header { - newHeader := CopyHeader(h) - istanbulExtra, err := ExtractIstanbulExtra(newHeader) - if err != nil { - return nil - } - - if !keepSeal { - istanbulExtra.Seal = []byte{} - } - istanbulExtra.CommittedSeal = [][]byte{} - - payload, err := rlp.EncodeToBytes(&istanbulExtra) - if err != nil { - return nil - } - - newHeader.Extra = append(newHeader.Extra[:IstanbulExtraVanity], payload...) - - return newHeader -} - -// copy from quorum -func CopyHeader(h *types.Header) *types.Header { - cpy := *h - if cpy.Difficulty = new(big.Int); h.Difficulty != nil { - cpy.Difficulty.Set(h.Difficulty) - } - if cpy.Number = new(big.Int); h.Number != nil { - cpy.Number.Set(h.Number) - } - if len(h.Extra) > 0 { - cpy.Extra = make([]byte, len(h.Extra)) - copy(cpy.Extra, h.Extra) - } - return &cpy -} - -// copy from quorum -func PrepareCommittedSeal(hash common.Hash) []byte { - var buf bytes.Buffer - buf.Write(hash.Bytes()) - buf.Write([]byte{byte(2)}) - return buf.Bytes() -} - -// copy from quorum -func GetSignatureAddress(data []byte, sig []byte) (common.Address, error) { - // 1. Keccak data - hashData := crypto.Keccak256(data) - // 2. Recover public key - pubkey, err := crypto.SigToPub(hashData, sig) - if err != nil { - return common.Address{}, err - } - return crypto.PubkeyToAddress(*pubkey), nil -} - -// copy from quorum -func ExtractIstanbulExtra(h *types.Header) (*IstanbulExtra, error) { - if len(h.Extra) < IstanbulExtraVanity { - return nil, errors.New("invalid istanbul header extra-data") - } - - var istanbulExtra *IstanbulExtra - err := rlp.DecodeBytes(h.Extra[IstanbulExtraVanity:], &istanbulExtra) - if err != nil { - return nil, err - } - return istanbulExtra, nil -} - -// copy from quorum -func GetQuorumHeaderHash(h *types.Header) common.Hash { - // If the mix digest is equivalent to the predefined Istanbul digest, use Istanbul - // specific hash calculation. - if h.MixDigest == IstanbulDigest { - // Seal is reserved in extra-data. To prove block is signed by the proposer. - if istanbulHeader := IstanbulFilteredHeader(h, true); istanbulHeader != nil { - return istanbulHeader.Hash() - } - } - return h.Hash() -} diff --git a/contracts/native/header_sync/quorum/states.go b/contracts/native/header_sync/quorum/states.go deleted file mode 100644 index c83f9cc7..00000000 --- a/contracts/native/header_sync/quorum/states.go +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package quorum - -import ( - "bytes" - "errors" - "fmt" - "math" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth/types" - pcom "github.com/polynetwork/poly/common" -) - -type QuorumValSet []common.Address - -func (vs QuorumValSet) Serialize(sink *pcom.ZeroCopySink) { - for _, v := range vs { - sink.WriteBytes(v.Bytes()) - } -} - -func (vs *QuorumValSet) Deserialize(source *pcom.ZeroCopySource) error { - if source.Size()%common.AddressLength != 0 { - return fmt.Errorf("wrong size of raw addresses: %d", source.Size()) - } - l := source.Size() / common.AddressLength - nvs := QuorumValSet(make([]common.Address, l)) - - for i := uint64(0); i < l; i++ { - raw, eof := source.NextBytes(common.AddressLength) - if eof { - return fmt.Errorf("failed to get next %d bytes for the No.%d address", common.AddressLength, i) - } - nvs[i] = common.BytesToAddress(raw) - } - *vs = nvs - - return nil -} - -func (vs QuorumValSet) String() (res string) { - res = "{\n" - for i, v := range vs { - res += fmt.Sprintf("[ %d, %s ],\n", i, v.String()) - } - res += "}" - return -} - -func VerifyQuorumHeader(vs QuorumValSet, hdr *types.Header, isEpoch bool) (*IstanbulExtra, error) { - extra, err := ExtractIstanbulExtra(hdr) - if err != nil { - return nil, fmt.Errorf("extract istanbul extra from header %s error: %v", GetQuorumHeaderHash(hdr).String(), err) - } - - checker := vs - if isEpoch { - if !vs.IfChanged(extra.Validators) { - return nil, fmt.Errorf("header %s is not epoch header supposed to contains new validators", GetQuorumHeaderHash(hdr).String()) - } - if err := vs.JustOneChanged(extra.Validators); err != nil { - return nil, err - } - checker = extra.Validators - } - - if err := checker.VerifySigner(hdr, extra.Seal); err != nil { - return nil, fmt.Errorf("failed to verify signer: %v", err) - } - if err := checker.VerifyCommittedSeals(extra, GetQuorumHeaderHash(hdr)); err != nil { - return nil, fmt.Errorf("verify committed seals failed for header %s: %v", GetQuorumHeaderHash(hdr).String(), err) - } - return extra, nil -} - -func (vs QuorumValSet) VerifySigner(hdr *types.Header, seal []byte) error { - addr, err := GetSignatureAddress(sigHash(hdr).Bytes(), seal) - if err != nil { - return err - } - idx, _ := vs.GetByAddress(addr) - if idx == -1 { - return fmt.Errorf("signer %s is not in validators", addr.Hex()) - } - - return nil -} - -func (vs QuorumValSet) VerifyCommittedSeals(extra *IstanbulExtra, hash common.Hash) error { - addrs, err := GetSigners(hash, extra.CommittedSeal) - if err != nil { - return fmt.Errorf("failed to VerifyCommittedSeals: %v", err) - } - validSeal := 1 - for _, v := range addrs { - if vs.Exist(v) { - validSeal++ - continue - } - return fmt.Errorf("addess %s is not in validators", v.String()) - } - if validSeal <= vs.F() { - return fmt.Errorf("valid seal not enough: (%d found, %d required)", validSeal, vs.F()+1) - } - return nil -} - -func (vs QuorumValSet) Exist(address common.Address) bool { - for _, v := range vs { - if bytes.Equal(address.Bytes(), v.Bytes()) { - return true - } - } - return false -} - -func (vs QuorumValSet) GetByAddress(addr common.Address) (int, common.Address) { - for i, val := range vs { - if bytes.Equal(addr.Bytes(), val.Bytes()) { - return i, val - } - } - return -1, common.Address{} -} - -func (vs QuorumValSet) IfChanged(another QuorumValSet) bool { - if len(vs) != len(another) { - return true - } - for i := 0; i < len(vs); i++ { - if bytes.Equal(vs[i].Bytes(), another[i].Bytes()) { - continue - } - return true - } - return false -} - -func (vs QuorumValSet) JustOneChanged(another QuorumValSet) error { - var more, less QuorumValSet - - switch len(vs) - len(another) { - case 1: - more, less = vs, another - case -1: - more, less = another, vs - default: - return fmt.Errorf("length of new validitors is %d but original one is %d", len(another), len(vs)) - } - - for i, j := 0, 0; i < len(less); i, j = i+1, j+1 { - if !bytes.Equal(less[i].Bytes(), more[j].Bytes()) { - if j++; j-i > 1 { - return errors.New("more than one validator changed") - } - } - } - - return nil -} - -func (vs QuorumValSet) F() int { return int(math.Ceil(float64(len(vs))/3)) - 1 } diff --git a/contracts/native/header_sync/quorum/utils.go b/contracts/native/header_sync/quorum/utils.go deleted file mode 100644 index 50e9adf0..00000000 --- a/contracts/native/header_sync/quorum/utils.go +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ -package quorum - -import ( - "fmt" - - ecom "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/utils" - pcom "github.com/polynetwork/poly/common" - "github.com/polynetwork/poly/core/states" -) - -var ( - IstanbulExtraVanity = 32 // Fixed number of extra-data bytes reserved for validator vanity - IstanbulDigest = ecom.HexToHash("0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365") -) - -func putValSet(ns *native.NativeContract, chainID, height uint64, vals []ecom.Address) { - vs := QuorumValSet(vals) - sink := pcom.NewZeroCopySink(nil) - vs.Serialize(sink) - - rawChainID := utils.GetUint64Bytes(chainID) - rawHeight := utils.GetUint64Bytes(height) - ns.GetCacheDB().Put(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(common.CONSENSUS_PEER), rawChainID), states.GenRawStorageItem(sink.Bytes())) - ns.GetCacheDB().Put(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(common.CONSENSUS_PEER_BLOCK_HEIGHT), rawChainID), - states.GenRawStorageItem(rawHeight)) -} - -func GetValSet(ns *native.NativeContract, chainID uint64) (QuorumValSet, error) { - rawChainID := utils.GetUint64Bytes(chainID) - store, err := ns.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(common.CONSENSUS_PEER), rawChainID)) - if err != nil { - return nil, err - } - if store == nil { - return nil, fmt.Errorf("GetValSet, can not find any records") - } - raw, err := states.GetValueFromRawStorageItem(store) - if err != nil { - return nil, fmt.Errorf("GetValSet, deserialize from raw storage item err: %v", err) - } - vs := QuorumValSet(make([]ecom.Address, 0)) - if err = vs.Deserialize(pcom.NewZeroCopySource(raw)); err != nil { - return nil, err - } - return vs, nil -} - -func GetCurrentValHeight(ns *native.NativeContract, chainID uint64) (uint64, error) { - rawChainID := utils.GetUint64Bytes(chainID) - store, err := ns.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(common.CONSENSUS_PEER_BLOCK_HEIGHT), rawChainID)) - if err != nil { - return 0, err - } - if store == nil { - return 0, fmt.Errorf("getCurrentValHeight, can not find any records") - } - raw, err := states.GetValueFromRawStorageItem(store) - if err != nil { - return 0, fmt.Errorf("getCurrentValHeight, deserialize from raw storage item err: %v", err) - } - - return utils.GetBytesUint64(raw), nil -} - -func GetSigners(hash ecom.Hash, sealArr [][]byte) ([]ecom.Address, error) { - proposalSeal := PrepareCommittedSeal(hash) - addrs := make([]ecom.Address, 0, len(sealArr)) - for _, seal := range sealArr { - addr, err := GetSignatureAddress(proposalSeal, seal) - if err != nil { - return nil, err - } - addrs = append(addrs, addr) - } - return addrs, nil -} diff --git a/contracts/native/header_sync/test/eth_test.go b/contracts/native/header_sync/test/eth_test.go deleted file mode 100644 index 6ff1c0de..00000000 --- a/contracts/native/header_sync/test/eth_test.go +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package test - -import ( - "bytes" - "encoding/binary" - "encoding/hex" - "encoding/json" - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" - ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - scom "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/crypto" - cstates "github.com/polynetwork/poly/core/states" - "github.com/stretchr/testify/assert" -) - -func TestSyncGenesisHeader(t *testing.T) { - header7152785, _ := hex.DecodeString("7b22706172656e7448617368223a22307837633137326261396464383763363163616531643162613031626239356366353830366465313835653966613030313065343137656666353135356335366537222c2273686133556e636c6573223a22307831646363346465386465633735643761616238356235363762366363643431616433313234353162393438613734313366306131343266643430643439333437222c226d696e6572223a22307836333562343736346431393339646661636433613830313437323631353961626332373762656363222c227374617465526f6f74223a22307838366233376564663162343537663566393664333162303963343865306133653863333738616138666531386331623431343331363331623037643430343931222c227472616e73616374696f6e73526f6f74223a22307835626663393365366461343263383138343134393766366538303762373731366161613064313432396132313130653661323737373566336631373538343536222c227265636569707473526f6f74223a22307839303533306462303165613761636466306430613334323536343934343463333633303365383231363464616334303532303464653839633837356532636464222c226c6f6773426c6f6f6d223a2230786230303031383430303030303030343230303030303134343030303030303038303030303030303038303030303030303030383030393030303030343030303030303030303030313030303030303030363031303832303030303031303030303030303030303030303830303031303830303830303830343031323030303130303038303038303030303031303030303030303030303038343030303230303038303031303030303030303030303030303030303430303030303030303031303430303230303030303230383230303030303030303030343030303030383030303030303030303030303030303030323030303038303130303130383030343130303030303830303030303030303038303432303030303030323030303030333030303031303032303030303030303030323030303031303031303030303030303230303032303030303030303030303030303130303030313030303030303030303030303030323030303030303030303038306130303030313033303030303030303030303832303030303030313430303830323030303030303031303030303030303034303030303030303430303031303030303030303630303230313030303130303030343230303034303230303030303032303138303830303030303030303034303030303035383030303030323030303030303032323030303830222c22646966666963756c7479223a2230783130326535363063222c226e756d626572223a223078366432343931222c226761734c696d6974223a223078376131323164222c2267617355736564223a223078363330633536222c2274696d657374616d70223a2230783565323431626434222c22657874726144617461223a2230786465383330323035306438663530363137323639373437393264343537343638363537323635373536643836333132653333333832653330383236633639222c226d697848617368223a22307837386637386462346565353132336139386530363361663339646663663965633464333863373739383434376462323235386665383232363437613133643465222c226e6f6e6365223a22307832376132383132336631393365663439222c2268617368223a22307839306131626339633566326532396365316636303562323366336661366262303634666462653535336138313632626664666133623962623864303630306537227d") - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = ethChainID - param.GenesisHeader = header7152785 - - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncGenesisHeader, param) - assert.Nil(t, err) - - caller := crypto.PubkeyToAddress(*acct) - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncGenesisHeader]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(scom.ABI, scom.MethodSyncGenesisHeader, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - - contract := native.NewNativeContract(sdb, contractRef) - height := getEthLatestHeight(contract) - assert.Equal(t, uint64(7152785), height) - header7152785Hash := getEthHeaderHashByHeight(contract, 7152785) - assert.Equal(t, true, bytes.Equal(ethcommon.HexToHash("90a1bc9c5f2e29ce1f605b23f3fa6bb064fdbe553a8162bfdfa3b9bb8d0600e7").Bytes(), header7152785Hash.Bytes())) - header7152785_formstore := getEthHeaderByHash(contract, header7152785Hash) - assert.Equal(t, true, bytes.Equal(header7152785_formstore, header7152785)) -} - -func getEthHeaderByHash(native *native.NativeContract, hash ethcommon.Hash) []byte { - headerStore, _ := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(ethChainID), hash.Bytes())) - headerBytes, err := cstates.GetValueFromRawStorageItem(headerStore) - if err != nil { - return nil - } - var headerWithDifficultySum eth.HeaderWithDifficultySum - if err := json.Unmarshal(headerBytes, &headerWithDifficultySum); err != nil { - return nil - } - headerOnly, err := json.Marshal(headerWithDifficultySum.Header) - if err != nil { - return nil - } - return headerOnly -} - -func getEthHeaderHashByHeight(native *native.NativeContract, height uint64) ethcommon.Hash { - headerStore, _ := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(ethChainID), utils.GetUint64Bytes(height))) - hashBytes, _ := cstates.GetValueFromRawStorageItem(headerStore) - return ethcommon.BytesToHash(hashBytes) -} - -func getEthLatestHeight(native *native.NativeContract) uint64 { - contractAddress := utils.HeaderSyncContractAddress - key := append([]byte(scom.CURRENT_HEADER_HEIGHT), utils.GetUint64Bytes(ethChainID)...) - // try to get storage - result, err := native.GetCacheDB().Get(utils.ConcatKey(contractAddress, key)) - if err != nil { - return 0 - } - if result == nil || len(result) == 0 { - return 0 - } else { - heightBytes, _ := cstates.GetValueFromRawStorageItem(result) - return binary.LittleEndian.Uint64(heightBytes) - } -} diff --git a/contracts/native/header_sync/test/init.go b/contracts/native/header_sync/test/init.go deleted file mode 100644 index 860bf5b1..00000000 --- a/contracts/native/header_sync/test/init.go +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package test - -import ( - "crypto/ecdsa" - "encoding/hex" - "encoding/json" - "log" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - "github.com/ethereum/go-ethereum/contracts/native/header_sync" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/msc" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/polygon" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/crypto" - polycomm "github.com/polynetwork/poly/common" - cstates "github.com/polynetwork/poly/core/states" -) - -func init() { - node_manager.InitNodeManager() - side_chain_manager.InitSideChainManager() - header_sync.InitHeaderSync() - db := rawdb.NewMemoryDatabase() - sdb, _ = state.New(common.Hash{}, state.NewDatabase(db), nil) - - cacheDB := (*state.CacheDB)(sdb) - putPeerMapPoolAndView(cacheDB) - putSideChain() -} - -func putPeerMapPoolAndView(db *state.CacheDB) { - key, _ := crypto.GenerateKey() - acct = &key.PublicKey - - peerPoolMap := new(node_manager.PeerPoolMap) - peerPoolMap.PeerPoolMap = make(map[string]*node_manager.PeerPoolItem) - pkStr := hex.EncodeToString(crypto.FromECDSAPub(acct)) - peerPoolMap.PeerPoolMap[pkStr] = &node_manager.PeerPoolItem{ - Index: uint32(0), - PeerPubkey: pkStr, - Address: crypto.PubkeyToAddress(*acct), - Status: node_manager.ConsensusStatus, - } - view := uint32(0) - viewBytes := utils.GetUint32Bytes(view) - sink := polycomm.NewZeroCopySink(nil) - peerPoolMap.Serialization(sink) - db.Put(utils.ConcatKey(utils.NodeManagerContractAddress, []byte(node_manager.PEER_POOL), viewBytes), cstates.GenRawStorageItem(sink.Bytes())) - - sink.Reset() - - govView := node_manager.GovernanceView{ - View: view, - } - govView.Serialization(sink) - db.Put(utils.ConcatKey(utils.NodeManagerContractAddress, []byte(node_manager.GOVERNANCE_VIEW)), cstates.GenRawStorageItem(sink.Bytes())) -} - -func putSideChain() { - caller := crypto.PubkeyToAddress(*acct) - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, extra, nil) - contract := native.NewNativeContract(sdb, contractRef) - - err := side_chain_manager.PutSideChain(contract, &side_chain_manager.SideChain{ - Router: utils.POLYGON_HEIMDALL_ROUTER, - ChainId: heimdalChainID, - }) - if err != nil { - log.Fatalf("PutSideChain fail:%v", err) - return - } - sideChain, err := side_chain_manager.GetSideChain(contract, heimdalChainID) - if err != nil { - log.Fatalf("PutSideChain fail:%v", err) - return - } - - if sideChain.ChainId != heimdalChainID { - log.Fatalf("GetSideChain mismatch") - } - extraInfo := polygon.ExtraInfo{ - Sprint: 64, - Period: 2, - ProducerDelay: 6, - BackupMultiplier: 2, - HeimdallPolyChainID: heimdalChainID, - } - extraInfoBytes, _ := json.Marshal(extraInfo) - err = side_chain_manager.PutSideChain(contract, &side_chain_manager.SideChain{ - Router: utils.POLYGON_BOR_ROUTER, - ChainId: borChainID, - ExtraInfo: extraInfoBytes, - }) - if err != nil { - log.Fatalf("PutSideChain fail:%v", err) - return - } - - sideChain, err = side_chain_manager.GetSideChain(contract, borChainID) - if err != nil { - log.Fatalf("PutSideChain fail:%v", err) - return - } - - if sideChain.ChainId != borChainID { - log.Fatalf("GetSideChain mismatch") - } - - { - err = side_chain_manager.PutSideChain(contract, &side_chain_manager.SideChain{ - Router: utils.QUORUM_ROUTER, - ChainId: quorumChainID, - BlocksToWait: 1, - Address: caller, - CCMCAddress: common.Hex2Bytes("0x0000000000000000000000000000000000000105"), - }) - if err != nil { - log.Fatalf("PutSideChain fail:%v", err) - return - } - } - - { - // add sidechain info - extra := msc.ExtraInfo{ - // test id 97 - ChainID: big.NewInt(97), - Period: 1, - Epoch: 200, - } - extraBytes, _ := json.Marshal(extra) - side_chain_manager.PutSideChain(contract, &side_chain_manager.SideChain{ - ExtraInfo: extraBytes, - Router: utils.MSC_ROUTER, - ChainId: mscChainID, - }) - } - - { - side_chain_manager.PutSideChain(contract, &side_chain_manager.SideChain{ - Router: utils.ETH_ROUTER, - ChainId: ethChainID, - }) - } -} - -var ( - sdb *state.StateDB - acct *ecdsa.PublicKey - heimdalChainID = uint64(2) - borChainID = uint64(3) - quorumChainID = uint64(4) - mscChainID = uint64(5) - ethChainID = uint64(6) -) diff --git a/contracts/native/header_sync/test/msc_test.go b/contracts/native/header_sync/test/msc_test.go deleted file mode 100644 index e0a532a5..00000000 --- a/contracts/native/header_sync/test/msc_test.go +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package test - -import ( - "bytes" - "encoding/hex" - "encoding/json" - "log" - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" - ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - scom "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - etypes "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth/types" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/msc" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/crypto" - "github.com/stretchr/testify/assert" -) - -func TestMscSyncGenesisHeader(t *testing.T) { - - genesisHeader := hex2Header("7b22706172656e7448617368223a22307833343364323161623132303964343137393466313763373466323563646637316630623762336465376239306631323836336464336561313434393838326534222c2273686133556e636c6573223a22307831646363346465386465633735643761616238356235363762366363643431616433313234353162393438613734313366306131343266643430643439333437222c226d696e6572223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c227374617465526f6f74223a22307862613732666532396233376437663336396639623561313836636533656664356330623866313562353531363130313139373065316165666162333331366563222c227472616e73616374696f6e73526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c227265636569707473526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c226c6f6773426c6f6f6d223a2230783030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c22646966666963756c7479223a22307832222c226e756d626572223a223078336139383030222c226761734c696d6974223a223078376131323030222c2267617355736564223a22307830222c2274696d657374616d70223a2230783631326562626565222c22657874726144617461223a223078643838333031306130323834363736353734363838383637366633313265333133343265333638353663363936653735373830303030303030303030303030303135316634333761346430623264393931646638303532303135623064633864646464623639376133623963333134653762656361363539356663343437306566393263356366613537363363313261383437303534303531656334393166346239333635306332373064346562633065353763323633636364333733386231373636383437626533653236616531333135643437653161343066323663363564663661343735373361396661363432643631353038393234623861663539643139653362363638653335333062616564336633393832656266616662613532373566336361653537663831323135386638626533346133333334323164326239366531313733666638383461656631646632646231363661663938663332613030222c226d697848617368223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c226e6f6e6365223a22307830303030303030303030303030303030222c2262617365466565506572476173223a6e756c6c2c2268617368223a22307839366164643161633839376232303432343662393835633436343139646338633734653063373431366138636336303831333365343437336331383130383466227d") - genesisHeaderBytes, _ := json.Marshal(genesisHeader) - - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = mscChainID - param.GenesisHeader = genesisHeaderBytes - - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncGenesisHeader, param) - assert.Nil(t, err) - - caller := crypto.PubkeyToAddress(*acct) - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncGenesisHeader]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(scom.ABI, scom.MethodSyncGenesisHeader, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - - contract := native.NewNativeContract(sdb, contractRef) - height := getMscLatestHeight(contract) - assert.Equal(t, genesisHeader.Number.Uint64(), height) - headerHash := getMscHeaderHashByHeight(contract, height) - assert.Equal(t, true, (*etypes.Header)(genesisHeader).Hash() == headerHash) - headerFromStore := getMscHeaderByHash(contract, headerHash) - assert.Equal(t, true, bytes.Equal(headerFromStore, genesisHeaderBytes)) - -} - -func TestMscSyncGenesisHeaderNoOperator(t *testing.T) { - - genesisHeader := hex2Header("7b22706172656e7448617368223a22307833343364323161623132303964343137393466313763373466323563646637316630623762336465376239306631323836336464336561313434393838326534222c2273686133556e636c6573223a22307831646363346465386465633735643761616238356235363762366363643431616433313234353162393438613734313366306131343266643430643439333437222c226d696e6572223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c227374617465526f6f74223a22307862613732666532396233376437663336396639623561313836636533656664356330623866313562353531363130313139373065316165666162333331366563222c227472616e73616374696f6e73526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c227265636569707473526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c226c6f6773426c6f6f6d223a2230783030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c22646966666963756c7479223a22307832222c226e756d626572223a223078336139383030222c226761734c696d6974223a223078376131323030222c2267617355736564223a22307830222c2274696d657374616d70223a2230783631326562626565222c22657874726144617461223a223078643838333031306130323834363736353734363838383637366633313265333133343265333638353663363936653735373830303030303030303030303030303135316634333761346430623264393931646638303532303135623064633864646464623639376133623963333134653762656361363539356663343437306566393263356366613537363363313261383437303534303531656334393166346239333635306332373064346562633065353763323633636364333733386231373636383437626533653236616531333135643437653161343066323663363564663661343735373361396661363432643631353038393234623861663539643139653362363638653335333062616564336633393832656266616662613532373566336361653537663831323135386638626533346133333334323164326239366531313733666638383461656631646632646231363661663938663332613030222c226d697848617368223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c226e6f6e6365223a22307830303030303030303030303030303030222c2262617365466565506572476173223a6e756c6c2c2268617368223a22307839366164643161633839376232303432343662393835633436343139646338633734653063373431366138636336303831333365343437336331383130383466227d") - genesisHeaderBytes, _ := json.Marshal(genesisHeader) - - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = mscChainID - param.GenesisHeader = genesisHeaderBytes - - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncGenesisHeader, param) - assert.Nil(t, err) - - caller := common.HexToAddress("0x11") - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncGenesisHeader]+extra, nil) - _, _, err = contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - - assert.Nil(t, err) - contract := native.NewNativeContract(sdb, contractRef) - height := getMscLatestHeight(contract) - assert.Equal(t, uint64(0), height) -} - -func hex2Header(hStr string) *etypes.Header { - hbytes, _ := hex.DecodeString(hStr) - var header etypes.Header - err := json.Unmarshal(hbytes, &header) - if err != nil { - log.Fatal("json invalid", err) - } - return &header -} - -func TestMscSyncBlockHeader(t *testing.T) { - - var height uint64 - { - genesisHeader := hex2Header("7b22706172656e7448617368223a22307833343364323161623132303964343137393466313763373466323563646637316630623762336465376239306631323836336464336561313434393838326534222c2273686133556e636c6573223a22307831646363346465386465633735643761616238356235363762366363643431616433313234353162393438613734313366306131343266643430643439333437222c226d696e6572223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c227374617465526f6f74223a22307862613732666532396233376437663336396639623561313836636533656664356330623866313562353531363130313139373065316165666162333331366563222c227472616e73616374696f6e73526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c227265636569707473526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c226c6f6773426c6f6f6d223a2230783030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c22646966666963756c7479223a22307832222c226e756d626572223a223078336139383030222c226761734c696d6974223a223078376131323030222c2267617355736564223a22307830222c2274696d657374616d70223a2230783631326562626565222c22657874726144617461223a223078643838333031306130323834363736353734363838383637366633313265333133343265333638353663363936653735373830303030303030303030303030303135316634333761346430623264393931646638303532303135623064633864646464623639376133623963333134653762656361363539356663343437306566393263356366613537363363313261383437303534303531656334393166346239333635306332373064346562633065353763323633636364333733386231373636383437626533653236616531333135643437653161343066323663363564663661343735373361396661363432643631353038393234623861663539643139653362363638653335333062616564336633393832656266616662613532373566336361653537663831323135386638626533346133333334323164326239366531313733666638383461656631646632646231363661663938663332613030222c226d697848617368223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c226e6f6e6365223a22307830303030303030303030303030303030222c2262617365466565506572476173223a6e756c6c2c2268617368223a22307839366164643161633839376232303432343662393835633436343139646338633734653063373431366138636336303831333365343437336331383130383466227d") - genesisHeaderBytes, _ := json.Marshal(genesisHeader) - height = genesisHeader.Number.Uint64() - - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = mscChainID - param.GenesisHeader = genesisHeaderBytes - - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncGenesisHeader, param) - assert.Nil(t, err) - - caller := crypto.PubkeyToAddress(*acct) - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncGenesisHeader]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(scom.ABI, scom.MethodSyncGenesisHeader, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - } - - caller := crypto.PubkeyToAddress(*acct) - { - - n1 := hex2Header("7b22706172656e7448617368223a22307839366164643161633839376232303432343662393835633436343139646338633734653063373431366138636336303831333365343437336331383130383466222c2273686133556e636c6573223a22307831646363346465386465633735643761616238356235363762366363643431616433313234353162393438613734313366306131343266643430643439333437222c226d696e6572223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c227374617465526f6f74223a22307862613732666532396233376437663336396639623561313836636533656664356330623866313562353531363130313139373065316165666162333331366563222c227472616e73616374696f6e73526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c227265636569707473526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c226c6f6773426c6f6f6d223a2230783030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c22646966666963756c7479223a22307832222c226e756d626572223a223078336139383031222c226761734c696d6974223a223078376131323030222c2267617355736564223a22307830222c2274696d657374616d70223a2230783631326562626631222c22657874726144617461223a2230786438383330313061303238343637363537343638383836373666333132653331333432653336383536633639366537353738303030303030303030303030303033613136646662613365393738313534336261303033323262663532653536663466643131636333383037623736303231336365636432346164626231326332366336303436353836356162376335363336353364626233663565366333363537643566353232623735383864363463363833313632376163353863323430393030222c226d697848617368223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c226e6f6e6365223a22307830303030303030303030303030303030222c2262617365466565506572476173223a6e756c6c2c2268617368223a22307861626336306634636333346536373163643563353937643064656530383734646535376166616136333431316233316139353539323837623533613165646264227d") - n1Bytes, _ := json.Marshal(n1) - n2 := hex2Header("7b22706172656e7448617368223a22307861626336306634636333346536373163643563353937643064656530383734646535376166616136333431316233316139353539323837623533613165646264222c2273686133556e636c6573223a22307831646363346465386465633735643761616238356235363762366363643431616433313234353162393438613734313366306131343266643430643439333437222c226d696e6572223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c227374617465526f6f74223a22307862613732666532396233376437663336396639623561313836636533656664356330623866313562353531363130313139373065316165666162333331366563222c227472616e73616374696f6e73526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c227265636569707473526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c226c6f6773426c6f6f6d223a2230783030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c22646966666963756c7479223a22307832222c226e756d626572223a223078336139383032222c226761734c696d6974223a223078376131323030222c2267617355736564223a22307830222c2274696d657374616d70223a2230783631326562626634222c22657874726144617461223a2230786438383330313061303238343637363537343638383836373666333132653331333532653336383536633639366537353738303030303030303030303030303066303137616131616132363465623563616434323766386137373065303930623433623134653162653035633265666233626130663534376435643631633837346235616163626438303532326637323235306538396638633730313931363037636131383236653831623935366235303439646336326462373133313137663031222c226d697848617368223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c226e6f6e6365223a22307830303030303030303030303030303030222c2262617365466565506572476173223a6e756c6c2c2268617368223a22307861613837636637613764343639633731623139646136636564353332363331373964633335363666396162333939626336336661363133623763333666323634227d") - n2Bytes, _ := json.Marshal(n2) - n3 := hex2Header("7b22706172656e7448617368223a22307861613837636637613764343639633731623139646136636564353332363331373964633335363666396162333939626336336661363133623763333666323634222c2273686133556e636c6573223a22307831646363346465386465633735643761616238356235363762366363643431616433313234353162393438613734313366306131343266643430643439333437222c226d696e6572223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c227374617465526f6f74223a22307862613732666532396233376437663336396639623561313836636533656664356330623866313562353531363130313139373065316165666162333331366563222c227472616e73616374696f6e73526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c227265636569707473526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c226c6f6773426c6f6f6d223a2230783030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c22646966666963756c7479223a22307831222c226e756d626572223a223078336139383033222c226761734c696d6974223a223078376131323030222c2267617355736564223a22307830222c2274696d657374616d70223a2230783631326562626637222c22657874726144617461223a2230786438383330313061303238343637363537343638383836373666333132653331333432653336383536633639366537353738303030303030303030303030303035343039303565343138363764623730393263663138373061353133613661373362343330623832613565396434373935326630643734633962343365313737373239343632646164666533346631656339303235623539363265376265343734373236343563663035396265663535646166653737313936383137653933643031222c226d697848617368223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c226e6f6e6365223a22307830303030303030303030303030303030222c2262617365466565506572476173223a6e756c6c2c2268617368223a22307862656233356364376132346534363036306165376361313363626339366237366530383663653836623162653262643331306163323733613339373731376136227d") - n3Bytes, _ := json.Marshal(n3) - n4 := hex2Header("7b22706172656e7448617368223a22307862656233356364376132346534363036306165376361313363626339366237366530383663653836623162653262643331306163323733613339373731376136222c2273686133556e636c6573223a22307831646363346465386465633735643761616238356235363762366363643431616433313234353162393438613734313366306131343266643430643439333437222c226d696e6572223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c227374617465526f6f74223a22307862613732666532396233376437663336396639623561313836636533656664356330623866313562353531363130313139373065316165666162333331366563222c227472616e73616374696f6e73526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c227265636569707473526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c226c6f6773426c6f6f6d223a2230783030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c22646966666963756c7479223a22307831222c226e756d626572223a223078336139383034222c226761734c696d6974223a223078376131323030222c2267617355736564223a22307830222c2274696d657374616d70223a2230783631326562626661222c22657874726144617461223a2230786438383330313061303238343637363537343638383836373666333132653331333432653336383536633639366537353738303030303030303030303030303062346238363230636365353438646461613332336463383464386633383862343534626562666135316637633635383938633564653666646563643265343139303564366537303364653239636664666461343633356363643636343033323533336162393436646437333230373531643438653463323166363339616233373031222c226d697848617368223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c226e6f6e6365223a22307830303030303030303030303030303030222c2262617365466565506572476173223a6e756c6c2c2268617368223a22307833646234396166306164663364373237313061656435613437643164326664356634643931646564346632663161373464666134306439633232303562383639227d") - n4Bytes, _ := json.Marshal(n4) - h2h := map[uint64]*etypes.Header{ - height + 1: n1, - height + 2: n2, - height + 3: n3, - height + 4: n4, - } - - param := new(scom.SyncBlockHeaderParam) - param.ChainID = mscChainID - param.Address = caller - param.Headers = append(param.Headers, n1Bytes) - param.Headers = append(param.Headers, n2Bytes) - param.Headers = append(param.Headers, n3Bytes) - param.Headers = append(param.Headers, n4Bytes) - - // fmt.Println("gHeight", height) - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncBlockHeader, param) - assert.Nil(t, err) - - caller := crypto.PubkeyToAddress(*acct) - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncBlockHeader]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(scom.ABI, scom.MethodSyncBlockHeader, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - contract := native.NewNativeContract(sdb, contractRef) - latestHeight := getMscLatestHeight(contract) - assert.Equal(t, latestHeight, height+4) - - for h := height + 1; h <= height+4; h++ { - headerHash := getMscHeaderHashByHeight(contract, h) - assert.Equal(t, true, headerHash == h2h[h].Hash()) - headerBytesFromStore := getMscHeaderByHash(contract, headerHash) - headerBytes, _ := json.Marshal(h2h[h]) - assert.Equal(t, true, bytes.Equal(headerBytesFromStore, headerBytes)) - } - } -} - -func getMscHeaderByHash(native *native.NativeContract, hash ethcommon.Hash) []byte { - hws, err := msc.GetHeader(native, hash, mscChainID) - if err != nil { - return nil - } - - headerOnly, _ := json.Marshal(hws.Header) - return headerOnly -} - -func getMscHeaderHashByHeight(native *native.NativeContract, height uint64) ethcommon.Hash { - hws, err := msc.GetCanonicalHeader(native, mscChainID, height) - if err != nil { - return ethcommon.Hash{} - } - - return hws.Header.Hash() -} - -func getMscLatestHeight(native *native.NativeContract) uint64 { - height, err := msc.GetCanonicalHeight(native, mscChainID) - if err != nil { - return 0 - } - - return height -} diff --git a/contracts/native/header_sync/test/polygon_test.go b/contracts/native/header_sync/test/polygon_test.go deleted file mode 100644 index 5af68b84..00000000 --- a/contracts/native/header_sync/test/polygon_test.go +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package test - -import ( - "encoding/hex" - "encoding/json" - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - scom "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - ethTypes "github.com/ethereum/go-ethereum/contracts/native/header_sync/eth/types" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/polygon" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/crypto" - polygonTypes "github.com/polynetwork/poly/native/service/header_sync/polygon/types" - "github.com/stretchr/testify/assert" -) - -func TestHeimdall(t *testing.T) { - - caller := crypto.PubkeyToAddress(*acct) - { - // block 1000 - heimdallGenesisHeaderBytes, _ := hex.DecodeString("0ab0020a02080a120c6865696d64616c6c2d31333718e807220c08f3becaf60510fbcd8ff20230383a480a208d86909b261ec95f2d4f7b2ee5b20fe5be8ec6f345c914c4d7b6e56b14cf2c19122408011220f994277244f6cdddc461ce887147a4a7318edd0ea0e86bd2e9ad524c33edf7c942203d29da6d4d1c286f23ed15867a59ea81753cbb6a1ff1ba751b7d32db1e606d8d52204dd3b4692add1dc3843947486ab99442fe79a4c3bfbfe3d24aa9e249b9a78c115a204dd3b4692add1dc3843947486ab99442fe79a4c3bfbfe3d24aa9e249b9a78c11622081ba6261d0077795e489737675de120cc9170adccaad805e12ef2708a2e214536a20e7ce47169e2337d3646f60cad3e1d33dc8da03eb360393ad94244958df0657d0820114b702f1c9154ac9c08da247a8e30ee6f2f3373f4112e00a0a480a20a37b6814ca79b6cf9783f37592a9eaf039cc8c840b3009898353e1eecd738d95122408011220086285cf29972d1f6ed0e50ffff2b186882f228e0c13d9e023f3fdb9b1876f3a12b601080210e80722480a20a37b6814ca79b6cf9783f37592a9eaf039cc8c840b3009898353e1eecd738d95122408011220086285cf29972d1f6ed0e50ffff2b186882f228e0c13d9e023f3fdb9b1876f3a2a0c08f9becaf6051098b09d990132140375b2fc7140977c9c76d45421564e354ed4227742419a3e2853f2c0deb69fc5697b60623ad5f5af8f37a0703413cb530d1de1a6a55b208edc64847872dc627576bebb8b7ebbd42164cc7b4f5f31e488f6e13996b9180112b801080210e80722480a20a37b6814ca79b6cf9783f37592a9eaf039cc8c840b3009898353e1eecd738d95122408011220086285cf29972d1f6ed0e50ffff2b186882f228e0c13d9e023f3fdb9b1876f3a2a0c08f9becaf60510dddbbc9801321442eefcda06ead475cde3731b8eb138e88cd0bac338014241a8d780c3bddaaf745f6005230a0067f973d0870a73d923c31fea73fb53569fe05332c23bd8cb855df312a7f459d344d6945d9c07498832280d89199646c3f93d0112b701080210e80722480a20a37b6814ca79b6cf9783f37592a9eaf039cc8c840b3009898353e1eecd738d95122408011220086285cf29972d1f6ed0e50ffff2b186882f228e0c13d9e023f3fdb9b1876f3a2a0b08f9becaf60510e6f0ed2832145973918275c01f50555d44e92c9d9b353cadad5438024241fd1e3ec74a6e8a968f1a8b64d56de941e61f3d1e2d3e293904ab561f572c83402aa5995fc5501b6eae3c405959df40951be657d74e1a147ba0b737a77809c39e0112b701080210e80722480a20a37b6814ca79b6cf9783f37592a9eaf039cc8c840b3009898353e1eecd738d95122408011220086285cf29972d1f6ed0e50ffff2b186882f228e0c13d9e023f3fdb9b1876f3a2a0b08f9becaf60510cba6cc2b32147fcd58c2d53d980b247f1612fdba93e9a76193e638034241527e63d6661c7241480810925b4648a848c3b6f1cdec23e35620ded49f2e4b343057d151c864a0606fc198be28fd94ee11f40bc6b9bf9c451701cbcf8e74e55c0012b701080210e80722480a20a37b6814ca79b6cf9783f37592a9eaf039cc8c840b3009898353e1eecd738d95122408011220086285cf29972d1f6ed0e50ffff2b186882f228e0c13d9e023f3fdb9b1876f3a2a0b08f9becaf60510cb87df2b3214b702f1c9154ac9c08da247a8e30ee6f2f3373f4138044241c5782bbc1850ebfb34df0674234b4850ca027dc84ffc2c53c190bfd69c745b3b4e1a896050d6b0bc7ea26c14f69b326f26053bf691cc25c1c67f3f67f65983070112b701080210e80722480a20a37b6814ca79b6cf9783f37592a9eaf039cc8c840b3009898353e1eecd738d95122408011220086285cf29972d1f6ed0e50ffff2b186882f228e0c13d9e023f3fdb9b1876f3a2a0b08f9becaf60510c5dadc2b3214b8bb158b93c94ed35c1970d610d1e2b34e26652c38054241fda7db105b2512c0a493f3676b9c5b45ce9923c0a03ce8028ce6214b60c37c6d62a720d286778a925ddca2750020256f28b468715e889213d547fdc9ac731cf10112b701080210e80722480a20a37b6814ca79b6cf9783f37592a9eaf039cc8c840b3009898353e1eecd738d95122408011220086285cf29972d1f6ed0e50ffff2b186882f228e0c13d9e023f3fdb9b1876f3a2a0b08f9becaf60510cf99f82b3214f84c74dea96df0ec22e11e7c33996c73fcc2d8223806424184d70e08200423bd225a05cae405a4fadf9c57d0601f1243680ebc1127e45c602893bc476bb21936399371e46c0bae5ba19189f831ab1bfa507d69e703e6dc44011a6c0a140375b2fc7140977c9c76d45421564e354ed422771246eb5ae987410447ed13442b485dd6990efc01d4297d798e90d3fa8467dd9c2f50ffe3238c8bf722f6c774f584b5fe91364b7b430c5a24fe57aca48665cf778030266f2c452bd918904e20f0b1ffffffffffffff011a6c0a1442eefcda06ead475cde3731b8eb138e88cd0bac31246eb5ae98741043522a004012c9740703f676b95b5121edd7237fb0f182c3c45e7c7a77eaa67a20e6d0ac025d5bd96295bf95e2e875ab2a9da5c0e547b7d00ca7ede33c1b0389318904e20f0b1ffffffffffffff011a6c0a145973918275c01f50555d44e92c9d9b353cadad541246eb5ae98741043c53ea6e1964e0670dc9ac72b3224207885d4c5f08cabe1e1080c662fdec278e7e833798757cb5cf121447dcd02a15f010eb4aa87cceecb23daa4bf904112e7718904e20f0b1ffffffffffffff011a6c0a147fcd58c2d53d980b247f1612fdba93e9a76193e61246eb5ae987410479efe8c50b1f9923f48a467ecac0a64c2d6bcaa9ae67e135df84cac5aed5321f9cbb29c115f26dc84f2ef0e5fea29615848c79d690cb205cc10d688324ae8bce18904e20f0b1ffffffffffffff011a6c0a14b702f1c9154ac9c08da247a8e30ee6f2f3373f411246eb5ae9874104b4e1d56b3429f7756452426be611e595debcb858d59f47d29ec9dd6e4b547dce1539f9b7144420bc309de496b70d6dc5f13345eee85e6b7fb332cd9f364ef12f18904e20f0b1ffffffffffffff011a6c0a14b8bb158b93c94ed35c1970d610d1e2b34e26652c1246eb5ae9874104d6b06c725f5410e4ccbd65906ece180364ebea4902b21232c1fb5892a76be7eec22480397d6bf653e9abe7ac50435ee472b59364fe78b17acb2be2116f92a76f18904e20f0b1ffffffffffffff011a650a14f84c74dea96df0ec22e11e7c33996c73fcc2d8221246eb5ae98741040600efda73e1404b0c596e08c78c5ed51631fc173e5f39d21deeddd5712fcd7d6d440c53d211eb48b03063a05b2c0c0eb084053dfcf1c6540def705c8e02845618904e20e0d403") - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = heimdalChainID - param.GenesisHeader = heimdallGenesisHeaderBytes - - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncGenesisHeader, param) - assert.Nil(t, err) - - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncGenesisHeader]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(scom.ABI, scom.MethodSyncGenesisHeader, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - } - { - // block 1589 - moreHeaderBytes, _ := hex.DecodeString("0af6020a02080a120c6865696d64616c6c2d31333718b50c220c0892d8caf60510b9d0b2f301280130523a480a20975eaaa5b8d23a88b107b846fbd68348e78efaa57c2d2e291fbb758503c34fef122408011220e7ef4ed3a3c0daa13a638946c58c2700251e2289fe6f3d6f7dfb90165c486eb74220f4cee00ec3156ccbd5a54d75769dbdf88970526dbceed7f559d3af19f44d4fd34a200522d72338efcee07dfaa2eef01ce077f73a4d19e5fbad3a10e3d945ec0e8a8a52204dd3b4692add1dc3843947486ab99442fe79a4c3bfbfe3d24aa9e249b9a78c115a20589e0a44c5a2ec502a77e9284c818cbb59459cd66bd55f7589e8ff8a3fc6b89f622081ba6261d0077795e489737675de120cc9170adccaad805e12ef2708a2e214536a206caa66ab079e39c83bbdb7867d15cf0fd85ce7314047fff1da64ddcb4910618a7220ce2068ccef2788f875108e0c2f21b65f72648c46f1d2db6e8655b4c2492482e2820114b8bb158b93c94ed35c1970d610d1e2b34e26652c12e80c0a480a20aeb4c6383c6de9468d4d50e1b0a2f9e8080bf97bc4d7412bb154f05c34e645b21224080112205a1ba9cd51a01d6cf3286c96ceb4db0e3242077e64be63cee18d4e271390c85b12db01080210b50c22480a20aeb4c6383c6de9468d4d50e1b0a2f9e8080bf97bc4d7412bb154f05c34e645b21224080112205a1ba9cd51a01d6cf3286c96ceb4db0e3242077e64be63cee18d4e271390c85b2a0b0898d8caf60510efa1a54a32140375b2fc7140977c9c76d45421564e354ed422774241a36e96833f40719c91e0ba3f5b61ea4d0060541bcfd1202b2bafad5a60aaa10c5587cede9ed8d3097c0b0d0684071195e5f729c63a3ca4ad1be00bbe28c1894e004a240a20822ae0281a2ef8c6950970c94f9020d3df853bc800d30c509ef6dd4d94faf1bd100112dd01080210b50c22480a20aeb4c6383c6de9468d4d50e1b0a2f9e8080bf97bc4d7412bb154f05c34e645b21224080112205a1ba9cd51a01d6cf3286c96ceb4db0e3242077e64be63cee18d4e271390c85b2a0b0898d8caf60510cdfbf049321442eefcda06ead475cde3731b8eb138e88cd0bac33801424155cbf0f735631cfcdd6e8b6e82a3c995adb5470c2f1d03a44d3bc720f8e6f82c46578115c79def2ed60db8a2518692cc6e37be9adbafe83f02c6ace3ecfe3a2d014a240a20822ae0281a2ef8c6950970c94f9020d3df853bc800d30c509ef6dd4d94faf1bd100112dd01080210b50c22480a20aeb4c6383c6de9468d4d50e1b0a2f9e8080bf97bc4d7412bb154f05c34e645b21224080112205a1ba9cd51a01d6cf3286c96ceb4db0e3242077e64be63cee18d4e271390c85b2a0b0898d8caf60510c3a2a70a32145973918275c01f50555d44e92c9d9b353cadad5438024241181fa7324c2325219c92f81c021fa65680e45aa93f03fd7f857aca75213c48e97b45f02ee54da091e8a55f800c09dc178e53a30d13d7534ee0286341902b4b42004a240a20822ae0281a2ef8c6950970c94f9020d3df853bc800d30c509ef6dd4d94faf1bd100112dd01080210b50c22480a20aeb4c6383c6de9468d4d50e1b0a2f9e8080bf97bc4d7412bb154f05c34e645b21224080112205a1ba9cd51a01d6cf3286c96ceb4db0e3242077e64be63cee18d4e271390c85b2a0b0898d8caf60510dacc9a0b32147fcd58c2d53d980b247f1612fdba93e9a76193e638034241426e3912627e1c212ca5c865f1ea7f34bda32f5c5d2b4804568276a61819e6e95d781c3abecc25a991cf95abb8cb7b812aa5e1a3ac252ed9a7874e6eca23d90b004a240a20822ae0281a2ef8c6950970c94f9020d3df853bc800d30c509ef6dd4d94faf1bd100112dd01080210b50c22480a20aeb4c6383c6de9468d4d50e1b0a2f9e8080bf97bc4d7412bb154f05c34e645b21224080112205a1ba9cd51a01d6cf3286c96ceb4db0e3242077e64be63cee18d4e271390c85b2a0b0898d8caf6051081b2f10a3214b702f1c9154ac9c08da247a8e30ee6f2f3373f4138044241de5faed7e16a9c093eb9c8784c36314ae667699c8c6ec0705c3fabdd0f21f37a68bcc33906bc9fca8e051f10088be58de7e54668d75f9bc2c0432a503ff13d1a014a240a20822ae0281a2ef8c6950970c94f9020d3df853bc800d30c509ef6dd4d94faf1bd100112dd01080210b50c22480a20aeb4c6383c6de9468d4d50e1b0a2f9e8080bf97bc4d7412bb154f05c34e645b21224080112205a1ba9cd51a01d6cf3286c96ceb4db0e3242077e64be63cee18d4e271390c85b2a0b0898d8caf605108797c60c3214b8bb158b93c94ed35c1970d610d1e2b34e26652c38054241ec23eaecbc57d6c5adec084655cc72a6a7d25a4b631c627546c548feca75883f5233b07dd3dca2725967f3b828b4ff06f58838f1f2f554e7657137789a636940014a240a20822ae0281a2ef8c6950970c94f9020d3df853bc800d30c509ef6dd4d94faf1bd100112dd01080210b50c22480a20aeb4c6383c6de9468d4d50e1b0a2f9e8080bf97bc4d7412bb154f05c34e645b21224080112205a1ba9cd51a01d6cf3286c96ceb4db0e3242077e64be63cee18d4e271390c85b2a0b0898d8caf60510e4bfd30a3214f84c74dea96df0ec22e11e7c33996c73fcc2d82238064241b99521391959e2875032d2590802ccb673a59c6647fa0552d2903ec322c5a43068b7b8f70f4be943ed9b760b590aed1e817209135b6086b448054a736140a88b014a240a20822ae0281a2ef8c6950970c94f9020d3df853bc800d30c509ef6dd4d94faf1bd10011a610a140375b2fc7140977c9c76d45421564e354ed422771246eb5ae987410447ed13442b485dd6990efc01d4297d798e90d3fa8467dd9c2f50ffe3238c8bf722f6c774f584b5fe91364b7b430c5a24fe57aca48665cf778030266f2c452bd918904e1a610a1442eefcda06ead475cde3731b8eb138e88cd0bac31246eb5ae98741043522a004012c9740703f676b95b5121edd7237fb0f182c3c45e7c7a77eaa67a20e6d0ac025d5bd96295bf95e2e875ab2a9da5c0e547b7d00ca7ede33c1b0389318904e1a610a145973918275c01f50555d44e92c9d9b353cadad541246eb5ae98741043c53ea6e1964e0670dc9ac72b3224207885d4c5f08cabe1e1080c662fdec278e7e833798757cb5cf121447dcd02a15f010eb4aa87cceecb23daa4bf904112e7718904e1a610a147fcd58c2d53d980b247f1612fdba93e9a76193e61246eb5ae987410479efe8c50b1f9923f48a467ecac0a64c2d6bcaa9ae67e135df84cac5aed5321f9cbb29c115f26dc84f2ef0e5fea29615848c79d690cb205cc10d688324ae8bce18904e1a610a14b702f1c9154ac9c08da247a8e30ee6f2f3373f411246eb5ae9874104b4e1d56b3429f7756452426be611e595debcb858d59f47d29ec9dd6e4b547dce1539f9b7144420bc309de496b70d6dc5f13345eee85e6b7fb332cd9f364ef12f18904e1a610a14b8bb158b93c94ed35c1970d610d1e2b34e26652c1246eb5ae9874104d6b06c725f5410e4ccbd65906ece180364ebea4902b21232c1fb5892a76be7eec22480397d6bf653e9abe7ac50435ee472b59364fe78b17acb2be2116f92a76f18904e1a610a14f84c74dea96df0ec22e11e7c33996c73fcc2d8221246eb5ae98741040600efda73e1404b0c596e08c78c5ed51631fc173e5f39d21deeddd5712fcd7d6d440c53d211eb48b03063a05b2c0c0eb084053dfcf1c6540def705c8e02845618904e") - param := new(scom.SyncBlockHeaderParam) - param.ChainID = heimdalChainID - param.Address = caller - param.Headers = append(param.Headers, moreHeaderBytes) - - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncBlockHeader, param) - assert.Nil(t, err) - - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncBlockHeader]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(scom.ABI, scom.MethodSyncBlockHeader, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - } -} - -func TestBor(t *testing.T) { - - caller := crypto.PubkeyToAddress(*acct) - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncBlockHeader]+extra, nil) - contract := native.NewNativeContract(sdb, contractRef) - - { - // heimdall block 6404702 - heimdallGenesisHeaderBytes, _ := hex.DecodeString("0ab6020a02080a120e6865696d64616c6c2d383030303118def48603220c08dfc4be870610d39de2950130a1fb0b3a480a203e50cc32a8d3c510ea1e7cc082448361aeaa961fc561d8a0195af115844f246c1224080112209471e0efe793456b55ad612204a62d2b192ce4bc8dd759f9038a05565c7d5abc42203b8aaa34f7370d795821279107e025fce60d3ec14eec96ed5d86f69e9db7018b5220733dc62d4b4ce18f49ec9f1f460f3012f449901b24ee2f474150c8329f0cd49a5a20733dc62d4b4ce18f49ec9f1f460f3012f449901b24ee2f474150c8329f0cd49a622081ba6261d0077795e489737675de120cc9170adccaad805e12ef2708a2e214536a206ce46f48dfec60113a218079a3ff4fac17529a497e99661e0580a29e628875d2820114c26880a0af2ea0c7e8130e6ec47af756465452e812f60a0a480a20f0e1e7b2f03a62c4609b3a5749e5b614e825b8a78a068ceead78549ca67fbdcd122408011220ff574f49a5d5a3e884ebc39b6ff192514ec0f0bb17339886bb80f589465df4de12b801080210def4860322480a20f0e1e7b2f03a62c4609b3a5749e5b614e825b8a78a068ceead78549ca67fbdcd122408011220ff574f49a5d5a3e884ebc39b6ff192514ec0f0bb17339886bb80f589465df4de2a0c08e4c4be870610f2ffb38a03321492da9f8f3ee16a276896fc7b2550b2151aae033242415b9bd77492b90b67794e1e53918283b6e552f1e4b7ab08466ebe6cd25565caa344dda798e887e6b0be998afc3e451992ea333b7684e608799747c7421d0acacb0112ba01080210def4860322480a20f0e1e7b2f03a62c4609b3a5749e5b614e825b8a78a068ceead78549ca67fbdcd122408011220ff574f49a5d5a3e884ebc39b6ff192514ec0f0bb17339886bb80f589465df4de2a0c08e4c4be870610c690d8b8023214b26c22237816d898cb9992d767444105bfdc03b638014241512f780597ac11e04642e2f02aa05a0e14036774258f4901403a15cab9c30f8868a9b771d48962b33f7434a3a36a08dc194e0be008c41b22023d14b783630c020012ba01080210def4860322480a20f0e1e7b2f03a62c4609b3a5749e5b614e825b8a78a068ceead78549ca67fbdcd122408011220ff574f49a5d5a3e884ebc39b6ff192514ec0f0bb17339886bb80f589465df4de2a0c08e4c4be870610c9b5bcb8023214be188d6641e8b680743a4815dfa0f6208038960f3802424179543ac1fe902782d2b328f8f68b39eb3e5eba1ea6f963fbbfdc0cb1d6d68e38345491b3cc5ca3d325f282bc62a85f1b4b6d0c3c18532da8c96913be8a647a650012ba01080210def4860322480a20f0e1e7b2f03a62c4609b3a5749e5b614e825b8a78a068ceead78549ca67fbdcd122408011220ff574f49a5d5a3e884ebc39b6ff192514ec0f0bb17339886bb80f589465df4de2a0c08e4c4be870610b9d6abba023214c26880a0af2ea0c7e8130e6ec47af756465452e838034241502789087c81f3ed4c97f750af480017f8738e32ef9c50abb9c258ed33efa35f1e4364628756ee73766e7084b54ef71c9e29cc524e001f36e8142e51fc52cc370012ba01080210def4860322480a20f0e1e7b2f03a62c4609b3a5749e5b614e825b8a78a068ceead78549ca67fbdcd122408011220ff574f49a5d5a3e884ebc39b6ff192514ec0f0bb17339886bb80f589465df4de2a0c08e4c4be8706109ff7a29c023214c275dc8be39f50d12f66b6a63629c39da5bae5bd3804424158b98274515db2d776cb326301ce9495c0a3f92a062509ffdcd0b0cad40bff50225816f4689f9f1cb61c1e8a2947af82e49d02d9448b4d076cbceb63c3a389d5001200120012b901080210def4860322480a20f0e1e7b2f03a62c4609b3a5749e5b614e825b8a78a068ceead78549ca67fbdcd122408011220ff574f49a5d5a3e884ebc39b6ff192514ec0f0bb17339886bb80f589465df4de2a0b08e5c4be8706108ca6a0083214e4b8e9222704401ad16d4d826732953daf07c7e238074241ebf38f7e3a21d8b7fa4d0e6900801a57f4d856fcb57b569f020f04a032fda38c5dc4affc0ea866c8e97137ce04ed0c75d5149d7f3c49fb45d8ebbc11056025980012ba01080210def4860322480a20f0e1e7b2f03a62c4609b3a5749e5b614e825b8a78a068ceead78549ca67fbdcd122408011220ff574f49a5d5a3e884ebc39b6ff192514ec0f0bb17339886bb80f589465df4de2a0c08e4c4be8706108cc5e6b8023214f903ba9e006193c1527bfbe65fe2123704ea3f9938084241a55cc4686dccc455031498a90b8b0e5385562a93eee8b86c0bbaf33a30cc097d3601dd6ba75d8201a8db939d2b0e12f07e4e024cdfb67149a24949dc0467b102001a6d0a1492da9f8f3ee16a276896fc7b2550b2151aae03321246eb5ae98741041f2c0ff8f11c0584bad20b3d275a025f567deda7b8ec97600509398cceba1f3649fc8b424b4754032980770a4c495706d5191d051e6423d5b8e63cd7792aa3d51887a80220a7b6e7ffffffffffff011a6c0a14b26c22237816d898cb9992d767444105bfdc03b61246eb5ae98741047ae11341f861697b349afdae3c7328ced67fcfc82da84f8db22c78e229edcdcfd83a5bb7d69a56b352f95eadcb51b98be15d140f06c85c9cb414dfe317df4b7418812220c9fce9ffffffffffff011a660a14be188d6641e8b680743a4815dfa0f6208038960f1246eb5ae9874104888a737a003f4e522ccf23bd9980fdbe7ef2b54365249deba0f9acd45279d66355b1864173b2cf9e75a1cbfb45e65a1a72b9ea76e47aa4bd50d79772ef30176918d7c9122084a5341a6d0a14c26880a0af2ea0c7e8130e6ec47af756465452e81246eb5ae98741040bec8102c221c7cfff3e250bb6cc01c3b9a3964fb1bf4d53e91905320eef09595acb09ee0950e7374ec19488ff2523f186f6b1a9164c78dba8602e4e3c4eb01318b0ca3f20f7f4a7ffffffffffff011a660a14c275dc8be39f50d12f66b6a63629c39da5bae5bd1246eb5ae9874104f3f18a027c929380417d2bd7d2a489cb662d4977e9daff335bc51f23c1c5f5f468aa19c6c8e937a745462ef2550bce42e4f38608dffb5a06e7b9d27d964cffee18f9c43e20d092511a650a14c443279a66280fa9bb2916999c5c2d2facab05791246eb5ae98741046e58afa78fade1229ce3bebe3ed5435d895cfdc399323d4f20752935ff04dc514e8f3320a8d5434a13acc9209b9657ebbdf154ae715830135997f6c2ae02825818d83620c7f0331a6c0a14c4acf8fbe2829cb0c209dff15a98b3dc13f12b1f1246eb5ae9874104161cf579b40ea1a68f166da216c50e88f1323213cd22a8ffa6acabc45893a80250b5aafa6dea6e4a0289ebabe8b2996ae806098b7d88d2eee8634ec73fe2edfd18a00120acaed2ffffffffffff011a6d0a14e4b8e9222704401ad16d4d826732953daf07c7e21246eb5ae987410469bd14dadd683cb4a4d1e27b79d3594c2025716abaf3a8a8282b126ea5c3a686071033ef6aa4c9b7d12efb957a7a55faaa5684653895d25e88199e4c5281dffc188a9116208edbedffffffffffff011a650a14f903ba9e006193c1527bfbe65fe2123704ea3f991246eb5ae9874104dcd2883416e7b8663caafbfc885e757b0ea809657df8d6f322f01a0c5a11fd033bf13d3e0d5e88feff92ba415d32d626e3f7d9dd7b5ec7c2fef8ded83d660ac218e25f20c9a60d") - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = heimdalChainID - param.GenesisHeader = heimdallGenesisHeaderBytes - - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncGenesisHeader, param) - assert.Nil(t, err) - - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncGenesisHeader]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(scom.ABI, scom.MethodSyncGenesisHeader, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - } - - var ( - snap254, snap255 polygon.Snapshot - ) - { - // block 254 - snapBytes, _ := hex.DecodeString("7b226e756d626572223a3235342c2268617368223a22307839373233393663333564303633333839353866643663616330303437343763623164396337313166393138393930343966363665643638383035626338353039222c2276616c696461746f72536574223a7b2276616c696461746f7273223a5b7b224944223a302c227369676e6572223a22307839323865643661336539343433376262643331366363616437383437396631643136336136613863222c22706f776572223a31303030302c22616363756d223a2d31303030307d2c7b224944223a302c227369676e6572223a22307862653138386436363431653862363830373433613438313564666130663632303830333839363066222c22706f776572223a31303030302c22616363756d223a2d31303030307d2c7b224944223a302c227369676e6572223a22307863323638383061306166326561306337653831333065366563343761663735363436353435326538222c22706f776572223a31303030302c22616363756d223a2d31303030307d2c7b224944223a302c227369676e6572223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22706f776572223a31303030302c22616363756d223a2d31303030307d2c7b224944223a302c227369676e6572223a22307866393033626139653030363139336331353237626662653635666532313233373034656133663939222c22706f776572223a31303030302c22616363756d223a34303030307d5d2c2270726f706f736572223a7b224944223a302c227369676e6572223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22706f776572223a31303030302c22616363756d223a2d31303030307d7d2c22726563656e7473223a7b22313931223a22307863323638383061306166326561306337653831333065366563343761663735363436353435326538222c22313932223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22313933223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22313934223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22313935223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22313936223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22313937223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22313938223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22313939223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323030223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323031223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323032223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323033223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323034223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323035223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323036223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323037223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323038223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323039223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323130223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323131223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323132223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323133223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323134223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323135223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323136223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323137223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323138223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323139223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323230223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323231223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323232223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323233223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323234223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323235223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323236223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323237223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323238223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323239223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323330223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323331223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323332223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323333223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323334223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323335223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323336223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323337223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323338223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323339223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323430223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323431223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323432223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323433223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323434223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323435223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323436223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323437223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323438223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323439223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323530223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323531223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323532223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323533223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323534223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264227d7d") - err := json.Unmarshal(snapBytes, &snap254) - if err != nil { - t.Fatal("snap254 json.Unmarshal fail", err) - } - headBytes, _ := hex.DecodeString("7b22706172656e7448617368223a22307866316362393835623333653136643432633435356466653264393635373337623865643839343431333161333165383635313739353333376564396332613063222c2273686133556e636c6573223a22307831646363346465386465633735643761616238356235363762366363643431616433313234353162393438613734313366306131343266643430643439333437222c226d696e6572223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c227374617465526f6f74223a22307866666362383334643632373036393935653965376266313063633961396534326138326665613939386435396233613563666164383937356462666533663837222c227472616e73616374696f6e73526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c227265636569707473526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c226c6f6773426c6f6f6d223a2230783030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c22646966666963756c7479223a22307835222c226e756d626572223a2230786665222c226761734c696d6974223a223078633338336162222c2267617355736564223a22307830222c2274696d657374616d70223a2230783565643961326337222c22657874726144617461223a2230786435383330313039303038333632366637323836363736663331326533313333383536633639366537353738303030303030303030303030303030303030303035636134646166333464613336623363386337396139666637316466393236353566626132653437303638636564646531623937353434353036376134663633323730386432623939303132383965303235383636636639643730303363393330613337626233373637613366653237616334326164376333666431633532633031222c226d697848617368223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c226e6f6e6365223a22307830303030303030303030303030303030222c2262617365466565506572476173223a6e756c6c2c2268617368223a22307839373233393663333564303633333839353866643663616330303437343763623164396337313166393138393930343966363665643638383035626338353039227d") - var header ethTypes.Header - err = json.Unmarshal(headBytes, &header) - if err != nil { - t.Fatal("header json.Unmarshal fail", err) - } - genesis := polygon.HeaderWithOptionalSnap{ - Header: header, - Snapshot: &snap254, - } - - borGenesisHeaderBytes, _ := json.Marshal(genesis) - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = borChainID - param.GenesisHeader = borGenesisHeaderBytes - - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncGenesisHeader, param) - assert.Nil(t, err) - - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncGenesisHeader]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(scom.ABI, scom.MethodSyncGenesisHeader, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - } - - { - // block 255 - headBytes, _ := hex.DecodeString("7b22706172656e7448617368223a22307839373233393663333564303633333839353866643663616330303437343763623164396337313166393138393930343966363665643638383035626338353039222c2273686133556e636c6573223a22307831646363346465386465633735643761616238356235363762366363643431616433313234353162393438613734313366306131343266643430643439333437222c226d696e6572223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c227374617465526f6f74223a22307866666362383334643632373036393935653965376266313063633961396534326138326665613939386435396233613563666164383937356462666533663837222c227472616e73616374696f6e73526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c227265636569707473526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c226c6f6773426c6f6f6d223a2230783030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c22646966666963756c7479223a22307835222c226e756d626572223a2230786666222c226761734c696d6974223a223078633362343861222c2267617355736564223a22307830222c2274696d657374616d70223a2230783565643961326339222c22657874726144617461223a223078643538333031303930303833363236663732383636373666333132653331333338353663363936653735373830303030303030303030303030303030303030303932386564366133653934343337626264333136636361643738343739663164313633613661386330303030303030303030303030303030303030303030303030303030303030303030303032373130626531383864363634316538623638303734336134383135646661306636323038303338393630663030303030303030303030303030303030303030303030303030303030303030303030303237313063323638383061306166326561306337653831333065366563343761663735363436353435326538303030303030303030303030303030303030303030303030303030303030303030303030323731306332373564633862653339663530643132663636623661363336323963333964613562616535626430303030303030303030303030303030303030303030303030303030303030303030303032373130663930336261396530303631393363313532376266626536356665323132333730346561336639393030303030303030303030303030303030303030303030303030303030303030303030303237313062346435323265306231373638393237343234336339663135363161383639363534346461613930383934383637646636323239636236346636633862636639326530646535316136643037326535333966313635363833643735623934643735396233663531633766393361343630313763633531326530326438313638313031222c226d697848617368223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c226e6f6e6365223a22307830303030303030303030303030303030222c2262617365466565506572476173223a6e756c6c2c2268617368223a22307864323664333338326265326564393261386232333564376533356233313266643838613036383135393563653636666131623931323761336330396465373933227d") - var header ethTypes.Header - err := json.Unmarshal(headBytes, &header) - if err != nil { - t.Fatal("header json.Unmarshal fail", err) - } - // heimdall block 6404703 - proofHeaderBytes, _ := hex.DecodeString("0ab6020a02080a120e6865696d64616c6c2d383030303118dff48603220c08e4c4be870610b9d6abba0230a1fb0b3a480a20f0e1e7b2f03a62c4609b3a5749e5b614e825b8a78a068ceead78549ca67fbdcd122408011220ff574f49a5d5a3e884ebc39b6ff192514ec0f0bb17339886bb80f589465df4de4220df3b887c750c01e938a3c08d6e9f241cd701f544304a2bdd78965c6665545c415220733dc62d4b4ce18f49ec9f1f460f3012f449901b24ee2f474150c8329f0cd49a5a20733dc62d4b4ce18f49ec9f1f460f3012f449901b24ee2f474150c8329f0cd49a622081ba6261d0077795e489737675de120cc9170adccaad805e12ef2708a2e214536a206ce46f48dfec60113a218079a3ff4fac17529a497e99661e0580a29e628875d2820114c275dc8be39f50d12f66b6a63629c39da5bae5bd12f20a0a480a20dbc841abcdc3bf033263446b9f6911c1915f67099efbc119ddf8624e8a90050e122408011220c30d0451a851deb09ab267717ac09413068f3973e3641adb9129f019100610cd12b801080210dff4860322480a20dbc841abcdc3bf033263446b9f6911c1915f67099efbc119ddf8624e8a90050e122408011220c30d0451a851deb09ab267717ac09413068f3973e3641adb9129f019100610cd2a0c08eac4be870610e591a2de01321492da9f8f3ee16a276896fc7b2550b2151aae033242419375aab1f6951e371ec106cbe37df571a7f9d34e9c99873984198b3493e38c31688d60da23b0c01a558a6acac13e59bb781d487a66652b122ed364f41928a8340112b901080210dff4860322480a20dbc841abcdc3bf033263446b9f6911c1915f67099efbc119ddf8624e8a90050e122408011220c30d0451a851deb09ab267717ac09413068f3973e3641adb9129f019100610cd2a0b08eac4be870610b8f7e9713214b26c22237816d898cb9992d767444105bfdc03b6380142418dc93be8a80f68f3b4ac7e72eba7803b7f872e91d676decff294368e18ebb1552fbe1b92fa5e84405fe534d79534c7f12bafc7f87b8c570a08c67c47141254600112b901080210dff4860322480a20dbc841abcdc3bf033263446b9f6911c1915f67099efbc119ddf8624e8a90050e122408011220c30d0451a851deb09ab267717ac09413068f3973e3641adb9129f019100610cd2a0b08eac4be870610daa196723214be188d6641e8b680743a4815dfa0f6208038960f380242410add4e51e049be5540dd5f47c6d5396353341a7d18e4ba6722b43c458fd2f109696f133aa1037190ad8740a4f4bf3f976ec1b1e17493aa0a6318ad64f1c7ea2d0112b901080210dff4860322480a20dbc841abcdc3bf033263446b9f6911c1915f67099efbc119ddf8624e8a90050e122408011220c30d0451a851deb09ab267717ac09413068f3973e3641adb9129f019100610cd2a0b08eac4be87061088b7a34d3214c26880a0af2ea0c7e8130e6ec47af756465452e8380342419479250c91ca229f7fb02441511922163251460b00eeef5a6805bc2854fb3958400395865f8476e54da227abe4442d16a071b8a1f122bffecc69a0ff1a7a71b20112b901080210dff4860322480a20dbc841abcdc3bf033263446b9f6911c1915f67099efbc119ddf8624e8a90050e122408011220c30d0451a851deb09ab267717ac09413068f3973e3641adb9129f019100610cd2a0b08eac4be870610ffd4fd713214c275dc8be39f50d12f66b6a63629c39da5bae5bd38044241151a235689f14312b1a15f73f97a5dd40ef1ca8271288fcfe3518926c84b438d759516113a92daab2a39ecc48569069453e82ba5e609513313d19d441a113c08011200120012ba01080210dff4860322480a20dbc841abcdc3bf033263446b9f6911c1915f67099efbc119ddf8624e8a90050e122408011220c30d0451a851deb09ab267717ac09413068f3973e3641adb9129f019100610cd2a0c08eac4be870610c992af98023214e4b8e9222704401ad16d4d826732953daf07c7e238074241cbaca7edd430f904a7d95c01c3d3116569c696d0b1d9f476b92055960dec0e00568cb9fff470a6890151dc96dd386c19c42428a68d630fe20759f4a122045d7c0012b901080210dff4860322480a20dbc841abcdc3bf033263446b9f6911c1915f67099efbc119ddf8624e8a90050e122408011220c30d0451a851deb09ab267717ac09413068f3973e3641adb9129f019100610cd2a0b08eac4be870610a885b9723214f903ba9e006193c1527bfbe65fe2123704ea3f993808424185552463bb7f8170ba9e25e196132c34dd665ed5e75c0a21cdcdc7287247767a34c6934ef07fd535f6ee76da9d99ae366d9c8cdf4ec4d4cd98755750ada71d8e001a6d0a1492da9f8f3ee16a276896fc7b2550b2151aae03321246eb5ae98741041f2c0ff8f11c0584bad20b3d275a025f567deda7b8ec97600509398cceba1f3649fc8b424b4754032980770a4c495706d5191d051e6423d5b8e63cd7792aa3d51887a80220aedee9ffffffffffff011a6c0a14b26c22237816d898cb9992d767444105bfdc03b61246eb5ae98741047ae11341f861697b349afdae3c7328ced67fcfc82da84f8db22c78e229edcdcfd83a5bb7d69a56b352f95eadcb51b98be15d140f06c85c9cb414dfe317df4b7418812220ca9eeaffffffffffff011a660a14be188d6641e8b680743a4815dfa0f6208038960f1246eb5ae9874104888a737a003f4e522ccf23bd9980fdbe7ef2b54365249deba0f9acd45279d66355b1864173b2cf9e75a1cbfb45e65a1a72b9ea76e47aa4bd50d79772ef30176918d7c91220dbee461a6d0a14c26880a0af2ea0c7e8130e6ec47af756465452e81246eb5ae98741040bec8102c221c7cfff3e250bb6cc01c3b9a3964fb1bf4d53e91905320eef09595acb09ee0950e7374ec19488ff2523f186f6b1a9164c78dba8602e4e3c4eb01318b0ca3f20a7bfe7ffffffffffff011a6d0a14c275dc8be39f50d12f66b6a63629c39da5bae5bd1246eb5ae9874104f3f18a027c929380417d2bd7d2a489cb662d4977e9daff335bc51f23c1c5f5f468aa19c6c8e937a745462ef2550bce42e4f38608dffb5a06e7b9d27d964cffee18f9c43e20dd8be5ffffffffffff011a650a14c443279a66280fa9bb2916999c5c2d2facab05791246eb5ae98741046e58afa78fade1229ce3bebe3ed5435d895cfdc399323d4f20752935ff04dc514e8f3320a8d5434a13acc9209b9657ebbdf154ae715830135997f6c2ae02825818d836209fa7341a6c0a14c4acf8fbe2829cb0c209dff15a98b3dc13f12b1f1246eb5ae9874104161cf579b40ea1a68f166da216c50e88f1323213cd22a8ffa6acabc45893a80250b5aafa6dea6e4a0289ebabe8b2996ae806098b7d88d2eee8634ec73fe2edfd18a00120ccafd2ffffffffffff011a660a14e4b8e9222704401ad16d4d826732953daf07c7e21246eb5ae987410469bd14dadd683cb4a4d1e27b79d3594c2025716abaf3a8a8282b126ea5c3a686071033ef6aa4c9b7d12efb957a7a55faaa5684653895d25e88199e4c5281dffc188a91162098ec031a650a14f903ba9e006193c1527bfbe65fe2123704ea3f991246eb5ae9874104dcd2883416e7b8663caafbfc885e757b0ea809657df8d6f322f01a0c5a11fd033bf13d3e0d5e88feff92ba415d32d626e3f7d9dd7b5ec7c2fef8ded83d660ac218e25f20ab860e") - cdc := polygonTypes.NewCDC() - var proofHeader polygon.CosmosHeader - err = cdc.UnmarshalBinaryBare(proofHeaderBytes, &proofHeader) - if err != nil { - t.Fatal("CosmosHeader UnmarshalBinaryBare fail", err) - } - merkleProofBytes, _ := hex.DecodeString("7b226f7073223a5b7b2274797065223a226961766c3a76222c226b6579223a224e6a453d222c2264617461223a226e77514b6e41514b4c41676145494555474f507568674d71494350633037436e5678556458455a506b5a4856504863454a4b47476b5873562f2b715a744d4b514f566151436977494742435a44686a6a376f59444b6943462b3243327a7342774254474c686c31615069335059773871426a4f346e78434e6f374c6a76704b4c2f416f734342595138415959342b364741796f677272667657615444616b3958633962536450477379686753594257752f566c736b4562387145365746506f4b4c416755454d4144474f507568674d7149443531536e6f3968384e794d356e50327a69316c716239575631586175586b5a644e6f473545422b6d536a4369734945424279474f507568674d714942646352714573464759304743704a3168493166695659467345715a423755345335554d4e4b2f6d3035334369734944684138474f507568674d714950563377593270724b717444694b6a6f5262373837746346595a50794c37614e547870365a4a54544c5063436973494442416b474f507568674d7149464a6f74624f70714d564843363965435241666f4e4c65777262614c6263726c547334796b6d6c367568634369734943684150474f507568674d71494e52587770777675664c52736752514268444f724652374f794f347679393050706a6e6459584d326344314369734942684147474f507568674d7149447731483941536a554b435a354b4333355043774b4d70616d4d5a7850514646435a4c395343696d4a4a4f4369734942424145474f507568674d69494f6173576c502b5335666b69774f344242626558417a6652616364764432614933796430735833634b725543696f494168414347502f7644696f6735424e73696f7a4e4a79427155346842594d4442485955414875594b6837476862324c68786b446b533873614b416f434e6a4553494c632f4179646e626e57423871787a32747854376a4f74776f4b73762f4d6f6742366e336176666a736d414741343d227d2c7b2274797065223a226d756c746973746f7265222c226b6579223a22596d3979222c2264617461223a226877554b6841554b46776f4d5932686861573574595735685a3256794567634b42516a6639495944436a494b425852766348567745696b4b4a776a66394959444569415948334c6c583946676d39384933596b4a70514f4b45734a744d624b74756f3055446156565463766969516f7743674e69623349534b516f6e434e2f3068674d53494239516a68656c336e7571756d445659617a32394b687a65366d4e616f63622b527762424a77357433414b436a4d4b426e4e31634842736552497043696349332f534741784967612b435a736234644a6945712f615537676338644b4a55654c66596c3957342f412f5779616e7a714a41774b4d516f45595856306142497043696349332f534741784967614d31334452776d39444f316338743779735778576e4b2f6f73784e4a5041435a713772644634644871304b4e516f496332786863326870626d63534b516f6e434e2f3068674d53494d6f4259325646514376634765325850545a37525331544a506872454d3638373875655a4b2f5578533132436a494b42574e735a584a7245696b4b4a776a66394959444569415930394a363238785a677247494d464f6e72635342627a4e5672624148396a4e464c7a464d616a7a6146516f7a43675a7759584a6862584d534b516f6e434e2f3068674d5349426f52556c6f7a544f6b5253424c5956614361304c6772466c377266786a644e3249707735783631616565436a414b413264766468497043696349332f5347417849673052717755515139584867762b79735351596247505772703075376774346354726a6378513266687165414b4e416f486333526861326c755a78497043696349332f53474178496773694e3158516f32694852586b4d6a452b39364a5635447a794d7249496c7236514c646678585366744a4d4b46676f4c63326c6b5a574e6f595735755a57775342776f46434e2f3068674d4b4d516f45625746706268497043696349332f53474178496778766b6147592b6974354c514630396d614b744734644437327758744d684175504f715552736a6a3847734b44776f45596d46756178494843675549332f534741776f334367706a6147566a613342766157353045696b4b4a776a663949594445694336367951446443686d774c43724b312b495a496a472b6d7957736f6d2b597a347a685069516f59583779513d3d227d5d7d") - cpvBytes, _ := hex.DecodeString("7b224b70223a222f783a3632366637322f783a33363331222c2256616c7565223a2243414551674149592f7a4d693767514b617767464941456f6b453479515153695a366e426e53764957386a58515a364754743758345a4e5948396d4a46644238726f623969674f75746d3759657749414f6e69585a55566930705a334968674931336b4c4d41357046697259624274374a4d30484f6853536a74616a3655513375394d577a4b313452353864466a70716a464441782f332f2f2f2f2f2f2f3842436d4d49416941424b4a424f4d6b45456949707a6567412f546c49737a794f396d594439766e377974554e6c4a4a33726f506d7331464a35316d4e5673595a4263374c506e6e5768792f7446356c6f6163726e7164755236704c315131356479377a415861546f557668694e5a6b486f746f42304f6b675633364432494941346c6739516b45344b597767424941456f6b4534795151514c37494543776948487a2f382b4a5175327a41484475614f575437472f54565070475155794475384a5756724c4365344a554f6333547347556950386c492f474739724770466b7834323668674c6b3438547241544f6854436149436772793667782b6754446d374565766457526c5253364643515467706a43414d6741536951546a4a424250507869674a386b704f415158307231394b6b6963746d4c556c333664722f4d3176464879504278665830614b6f5a78736a704e366446526937795651764f5175547a68676a662b316f4735376e53665a5a4d2f2b3436464d4a313349766a6e3144524c326132706a59707735326c75755739554a424f436d4d49424341424b4a424f4d6b4545334e4b494e42626e7547593871767638694635316577366f435756392b4e627a4976416144466f522f514d373854302b445636492f762b53756b46644d74596d342f665a3358746578384c2b2b4e37595057594b776a6f552b514f366e6742686b384653652f766d582b49534e77547150356c516b453453617767464941456f6b453479515153695a366e426e53764957386a58515a364754743758345a4e5948396d4a46644238726f623969674f75746d3759657749414f6e69585a55566930705a334968674931336b4c4d41357046697259624274374a4d30484f6853536a74616a3655513375394d577a4b313452353864466a70716a464441782f332f2f2f2f2f2f2f38424b6d7349425341424b4a424f4d6b45456f6d6570775a30727946764931304765686b3765312b475457422f5a69525851664b36472f596f4472725a7532487343414470346c32564659744b5764794959434e6435437a414f61525971324777626579544e427a6f556b6f37576f2b6c454e377654467379746545656648525936616f7851774d66392f2f2f2f2f2f2f2f4153706a4341496741536951546a4a424249694b63336f41503035534c4d386a765a6d412f62352b387256445a53536436364435724e525365645a6a5662474751584f797a3535316f63763752655a61476e4b35366e626b65715339554e65586375387746326b36464c34596a575a42364c61416444704946642b67396943414f4a5950554a424f4b6d4d49415341424b4a424f4d6b4545432b79424173496878382f2f5069554c7473774277376d6a6c6b2b787630315436526b464d67377643566c6179776e754356446e4e3037426c496a2f4a5350786876617871525a4d654e756f5943354f50453677457a6f55776d69416f4b38756f4d666f4577357578487233566b5a55557568516b453471597767444941456f6b4534795151547a38596f43664a4b54674546394b39665370496e4c5a69314a642b6e612f7a4e627852386a7763583139476971476362493654656e52555975386c554c7a6b4c6b38345949332f746142756535306e325754502f754f6854436464794c343539513053396d747159324b634f647062726c765643515469706a4341516741536951546a4a42424e7a53694451573537686d504b72372f4968656458734f71416c6c66666a5738794c7747677861456630444f2f4539506731656950372f6b72704258544c574a75503332643137587366432f766a653244316d4373493646506b4475703441595a5042556e7637356c2f69456a6345366a2b5a554a424f4d6755344d4441774d513d3d227d") - - proof := polygon.CosmosProof{ - Header: proofHeader, - } - err = json.Unmarshal(merkleProofBytes, &proof.Proof) - if err != nil { - t.Fatal("merkleProofBytes json.Unmarshal fail", err) - } - err = json.Unmarshal(cpvBytes, &proof.Value) - if err != nil { - t.Fatal("cpvBytes json.Unmarshal fail", err) - } - - proofBytes, err := cdc.MarshalBinaryBare(proof) - if err != nil { - t.Fatal("CosmosProof MarshalBinaryBare fail", err) - } - - headerWOP := polygon.HeaderWithOptionalProof{Header: header, Proof: proofBytes} - n1Bytes, _ := json.Marshal(headerWOP) - param := new(scom.SyncBlockHeaderParam) - param.ChainID = borChainID - param.Address = caller - param.Headers = append(param.Headers, n1Bytes) - - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncBlockHeader, param) - assert.Nil(t, err) - - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncBlockHeader]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(scom.ABI, scom.MethodSyncBlockHeader, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - - } - - { - // block 256 - headBytes, _ := hex.DecodeString("7b22706172656e7448617368223a22307864323664333338326265326564393261386232333564376533356233313266643838613036383135393563653636666131623931323761336330396465373933222c2273686133556e636c6573223a22307831646363346465386465633735643761616238356235363762366363643431616433313234353162393438613734313366306131343266643430643439333437222c226d696e6572223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c227374617465526f6f74223a22307866666362383334643632373036393935653965376266313063633961396534326138326665613939386435396233613563666164383937356462666533663837222c227472616e73616374696f6e73526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c227265636569707473526f6f74223a22307835366538316631373162636335356136666638333435653639326330663836653562343865303162393936636164633030313632326662356533363362343231222c226c6f6773426c6f6f6d223a2230783030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c22646966666963756c7479223a22307835222c226e756d626572223a223078313030222c226761734c696d6974223a223078633365353736222c2267617355736564223a22307830222c2274696d657374616d70223a2230783565643961326366222c22657874726144617461223a2230786435383330313039303038333632366637323836363736663331326533313333383536633639366537353738303030303030303030303030303030303030303062343739353662666137636533393061386362306337373237333537623762363261333137626637333234613563663565653939396331353332623335303764356662313466346333613633376232653365656565633164623264616334373666316335383530363730636266613764306335663738663465353030316562373031222c226d697848617368223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c226e6f6e6365223a22307830303030303030303030303030303030222c2262617365466565506572476173223a6e756c6c2c2268617368223a22307830626536636335363230323537626232303563353132303234313537636136366138326136393266663565643936663134323934653264633533363232646437227d") - var header ethTypes.Header - err := json.Unmarshal(headBytes, &header) - if err != nil { - t.Fatal("header json.Unmarshal fail", err) - } - - headerWOP := polygon.HeaderWithOptionalProof{Header: header, Proof: nil} - n1Bytes, _ := json.Marshal(headerWOP) - param := new(scom.SyncBlockHeaderParam) - param.ChainID = borChainID - param.Address = caller - param.Headers = append(param.Headers, n1Bytes) - - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncBlockHeader, param) - assert.Nil(t, err) - - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncBlockHeader]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(scom.ABI, scom.MethodSyncBlockHeader, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - - contract := native.NewNativeContract(sdb, contractRef) - headerFromStore, err := polygon.GetCanonicalHeader(contract, borChainID, 256) - if err != nil { - t.Fatal("GetCanonicalHeader fail", err) - } - if headerFromStore.HeaderWithOptionalSnap.Header.Hash() != header.Hash() { - t.Fatal("header mismatch after store") - } - } - - { - // check snapshot for block 256 - cheight, err := polygon.GetCanonicalHeight(contract, borChainID) - if err != nil { - t.Fatal("SyncBlockHeader fail", err) - } - cheader, err := polygon.GetCanonicalHeader(contract, borChainID, cheight) - if err != nil { - t.Fatal("SyncBlockHeader fail", err) - } - if cheader == nil { - t.Fatal("SyncBlockHeader fail:empty header") - } - headerSnap := cheader.HeaderWithOptionalSnap.Snapshot - if headerSnap == nil { - t.Fatal("SyncBlockHeader fail:empty snap") - } - - snapBytes, _ := hex.DecodeString("7b226e756d626572223a3235352c2268617368223a22307864323664333338326265326564393261386232333564376533356233313266643838613036383135393563653636666131623931323761336330396465373933222c2276616c696461746f72536574223a7b2276616c696461746f7273223a5b7b224944223a302c227369676e6572223a22307839323865643661336539343433376262643331366363616437383437396631643136336136613863222c22706f776572223a31303030302c22616363756d223a307d2c7b224944223a302c227369676e6572223a22307862653138386436363431653862363830373433613438313564666130663632303830333839363066222c22706f776572223a31303030302c22616363756d223a307d2c7b224944223a302c227369676e6572223a22307863323638383061306166326561306337653831333065366563343761663735363436353435326538222c22706f776572223a31303030302c22616363756d223a307d2c7b224944223a302c227369676e6572223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22706f776572223a31303030302c22616363756d223a307d2c7b224944223a302c227369676e6572223a22307866393033626139653030363139336331353237626662653635666532313233373034656133663939222c22706f776572223a31303030302c22616363756d223a307d5d2c2270726f706f736572223a7b224944223a302c227369676e6572223a22307866393033626139653030363139336331353237626662653635666532313233373034656133663939222c22706f776572223a31303030302c22616363756d223a307d7d2c22726563656e7473223a7b22313932223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22313933223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22313934223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22313935223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22313936223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22313937223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22313938223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22313939223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323030223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323031223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323032223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323033223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323034223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323035223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323036223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323037223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323038223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323039223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323130223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323131223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323132223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323133223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323134223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323135223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323136223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323137223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323138223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323139223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323230223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323231223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323232223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323233223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323234223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323235223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323236223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323237223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323238223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323239223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323330223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323331223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323332223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323333223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323334223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323335223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323336223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323337223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323338223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323339223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323430223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323431223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323432223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323433223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323434223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323435223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323436223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323437223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323438223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323439223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323530223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323531223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323532223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323533223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323534223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264222c22323535223a22307863323735646338626533396635306431326636366236613633363239633339646135626165356264227d7d") - - err = json.Unmarshal(snapBytes, &snap255) - if err != nil { - t.Fatal("snap json.Unmarshal fail", err) - } - if snap254.Equal(&snap255) { - t.Fatal("SyncBlockHeader fail:snap the same") - } - if !headerSnap.Equal(&snap255) { - t.Fatal("SyncBlockHeader fail:snap not expected") - } - } - -} - -func TestBorSnap(t *testing.T) { - var err error - - caller := crypto.PubkeyToAddress(*acct) - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncBlockHeader]+extra, nil) - contract := native.NewNativeContract(sdb, contractRef) - - { - // heimdall block 5908043 - heimdallGenesisHeaderBytes, _ := hex.DecodeString("0ab3020a02080a120c6865696d64616c6c2d31333718cfcbe802220b0880b5fb870610bdd3c160308df23e3a480a207f7a2e62342d2b6ba33b80115a22ac3b008fd4a8bbe684db4b25c20d75d14ac512240801122026ff2bdac6f16b977c98ab4b1b322a54905465bc7f299a7eb9baf3aa21c4e3f142208ccbf8b69d0ea00fa1f6f89a07d4bf6d99fe5ad1cd51fc01b01d6a944ef65c4252202195a2715637db9e8662eb71b71a346d2960816bdc1ededc93ed96c6e9dad96d5a202195a2715637db9e8662eb71b71a346d2960816bdc1ededc93ed96c6e9dad96d622081ba6261d0077795e489737675de120cc9170adccaad805e12ef2708a2e214536a208aadf70f37c4ba2775a9dc39300e819d86c864ecca2e53c3082bbc8d535fbf10820114c0ffdb5e938d6de2c5e5ed35ede0e881cdbbbc9a12af8f010a480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea12b801080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb8706109084fbcb0332140208652a93baf5f1962849efcf5795eac7439a5e42412413daaa7a33ca0e7f337624f014dd0b57083e2f779b4b52e5843049309c91d840e203d6edda3e930502b311cf735a4859bdc1c5ea44c346f91f0f67d4ab68780112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610efeea519321402f70172f7f490653665c9bfac0666147c8af1f538014241a5d29b6b5fe19995f7155a2b73b072a9cc964a728b932e1cff3162b34eaa9ef47cbd90f7be7e9101e92c3a616eca9870f0140fed70a81dde53961a57bcebe9460012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb87061090d1a22032140306b7d3095ab008927166cd648a8ca7dbe53f0538024241355f8e1e9bed5a760cb783c38e1c475e3f127d78decaeb03bad879545b4c831a12ff4fa0abfe99ccb05cede5374195b5c09538d9f936f453ca5192b737bf4be70012ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610eaf789ce03321404cb8d907fda121fd3dd70bd2ef9c7841f70ed3f38034241eacf0439055743ca107b6e457f6b70ae1f40d47069e69df7fadf0896a253a0fd5fa329943d6ef3531b3f11279ee1173ce70df19fef544f668ae5b032262797fd0012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610bccd951f3214055bd801ca712b4ddf67db8bc23fb6c8510d52b9380442413e54e0d6347adc7f538983aea0c28a74d0ad1c5ba959e1713b5ea71efa8cb3cd3b46fd4a3c45698f7b5ab5cd10d4cc2b2c03caba3a3dbfa8c9aef55819cb6e7c0112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610dabcd428321410ad27a96cdbffc90ab3b83bf695911426a69f5e38054241884352b407d33091b146cfcb5fffb7e4ebbe83094378a9d33cecccf6a58150ce6b35b3eb76081455adc8be27011bc6677da32a564aaf4bc4d02af5b987243f8d0112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610c59fed3b3214127685d6dd6683085da4b6a041efcef1681e5c9c38064241ee4f8bb4a980f2028370fc245c227e4ed681c64662cc625619d6ef9f5e652136385f24c4f518aaf83a5287d116f35d1c563d190a5065dc5e70c1c529b0cf9d930112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610a59af015321413a9d78f4712a65678d7735682819b4f4f74253c380742414037c78275fcbcc9520b65f8b987fa1da2f98890a4a08e5e1766e405ece0219300606406651d0288c276529ddde6ca893de23c0605fd44610651be4bf068ad950012ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0888b5fb870610b4e0f7d201321413dc53fa54e7d662ff305b6c3ef95090c31dc576380842415a3ff27bf469d1b585d5f93961fa709b0d7cb6d27785dc5530ea4ba4042a2a7e08308d01308abdeba8aa0da831a8414c814606b3439fe185ec66624d63a48a680112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb87061083a3ddce033214160cdef60e786295728a6ea334c091238e474e01380942415f228f3bbf37e654d83b7b95cdc86d62a114bed637728818f74be77871771cd248b59f100becafe7acada718f77f6f421e9c2fbc80c24001c68fb474a5dcb4670112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0888b5fb870610b0c7d381013214168b2779146ba862b04ca146385645eddb9d592e380a4241f843a071eb3980e940dd60981587cb7dcc1d1017110d78fc6de8c41dad9f377f182cf146f064a57a5e677474eae306ea5907b9b0fad4299d0b09907f116c83f20112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610cfd6a69803321418f371aeee4e2636df789931c9cd43e5d7b72d66380b4241f3f15c4765220bcd81fee403dad9b847972a9c6dbecdd6b9813767dc00b7ffc25649c64a89ecc39846a8200e4a2d20fb06d3563f5b43527e1544e28a161c14900012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610fcd1fd6c32141a578699956c2174b4762de95316b3ad09ba34e9380c42416d8d524cc2536a4fc977fddfeb116dc5b23e278691b08c5f8b98aa2450a3d8aa341ed9bc0da6fc39697adfd74ffc6a934d3a45fd4f987cd51fb1f5b4739b1d9a0012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610d8ed9e2032141ca971963bdb4ba2bf337c90660674acff5beb3f380d424170f526b97e1f5335fc3ee9a827a4c353d6bc404f555838d20558581563e74bac46eef9c7bc1033dd0828a219ba4a2cdccdef8b32fa6aabf91578094fe483ed9b0112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb8706108593a32332141d25c827abd466387bda00b429fe728627d6eee6380e4241719b1686636c946a3dd1e2cb8ef74a26c9706ee170f162c2d137be4e35fc5d306775765aea04f2e62fb8bc4095da75b8f8e48a54cc0df3ec05e84426b819243a0012ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb8706108dfccfc50332141fbc8746975598d58b0757eb2a273324dd28f6a0380f4241547b6965eb6d10ea36ff94f00f6fa3f910b6ca412263f82fe70cc07e879a0d3d025af51359b96380b08f18650e0f3d22b84ec22a951fed846f1ad3bcc33254020012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb87061099e5e461321425c32fd6ed7b84435a222084ef3fdbb36252b8de38104241a4b125effe1c26e3c11b1737232077cbebd412e703ed97f3b13fbde36e31462911041e18c745ec91de18f07184c12389293b4575d62a9ea1e1250866d2f10c1f0112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610a8929c2c321426c80cc193b27d73d2c40943acec77f4da2c5bd838114241452944f12b9ef466bb0e5b76469091df1039e3181c37adb1cd31635cb29fdf50559813a1a35de521bc3989f419540a189cf01db36c3ea3ebc78f7a83955b1aee0112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610fa9fc55a321428247de2d9829f3080899749b92e34959c06b59c381242419684d1d9ae81f49f8c5d4f5fc3afb916e7d3ceec8819e4d27ebfe3470bea9cd4794928e6612f3afecc285140a6bd3e6d20f6fecfeb2a26f5d6d1ffd70214701b0112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610da9ef6bb03321428c0d4328520ed7e8657de141eee74a954b07c1f3813424173964033e559a71f3925209fa69a5d72d58971a5424391ab6780af9a15aa6aa0514ee3b4e4a19fcaf1b3114707d8d363a7b4410e11174a9e5c6d86246ca475480012ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610f18d87d80332142a998cc0bb43dc510e523fe33c8f1c04bf607a1e381442413f7edf93fccdba6880fcb90ed373e7dd37e382825c79177135310525a021ccaa0f089e61ff297198b5e25b53e81a6c21697c0ef4e19456fe79f4cc7c3fa1710d0012ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610b3a7a3ae0332142c74ca71679cf1299936d6104d825c965448907b381542411d0ba59ba2a74223ac1ae1c9d690e8cec43ac4bc26711e8b233304117f86e25146d84bad421a36a62891f55bc150681a89c7b8a07506cd69f837c79f83ec074d0112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610ef81fbc303321430523527aced0ed2f5ce1721086d1d282d3af38f38164241d72c6256d680ab9b9306d2e7d4681df488e574a756e99e7c0561ee8c418349bc1601ca9891ab20d40399a23c0e0fdcfde80712e3dcb8720f9399a1e6ba0ae5f50112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610c7afa2cd03321430dd252c7c150f26a3a06e4eada9e706db3fa58c381742418e7785b4edd7d16f80953446ef683eda43c299ca76538fbd2433584628670a974c91989e1932f13f2c607412a8e2a76e00556b4764c89bb55732bf02e49cc2620012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610809c8c153214374c87b673409e13053dbd35ebe868be42beabc53818424127da95e4a5baf2427b657b55d0ce724caf7c32f90ed2e842d8027bf9549ffa7e719b1039e19224829abc6251342ce9c599c13872c685ccf8aa6c0828beba60da0112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610dbdec3cb03321439f5455840874f4251cf92b14d6dfe10d3cf223438194241b34d028c89aa371d21ca111373a64c1f1826ba6972930cf83c471e2697586e6261ad4f2f75d92016b24ad56834c12ed59833ca7c77d8171b942bce41876beb2a0012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb87061097a1ad4b32143a9df5dfcb4cc102ce20d40434a2b1baca9eafd3381a42418988fb50ce17106efea33529d731d05ccc283f3369bc2bbc88329e57584e3a79378a1e483b4f5b4b9c850d76e0d73f809473218ee8b7bc25038d3d99d03d3c370112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610c2a1dbd2033214406c3fef5969b36231bd573adfc34e16f54d23e0381b424159e80c7148513ed706f71af29409b059e6a3e355893ffb410e7e1e309790cfd41325d1715594b7dc1295fa1bbe214a7fcfc188a264e092b074bec733fd9b1b2c0012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb8706109bb9bc493214414b4b5a2a0e303b89360eda83598ab7702eae04381c4241dd3120f8ceb2c67ea00b3fa6b0cef1872b11fc514279a73f804ff39e3edb4cc667477243a1fc5cb7604ae9213a72f3bb3c8f57c8ae1263597db4bc0a66ea3c7a0012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610eb8cc901321441d5b3e2ec53583bc0601dfb4f2a11a392049489381d4241e10eb79f5e284c85479924124be176937073ef6943445739aac77480a9ce4512705839bc97e57a9595f45966ac4207c6ae93a44aec3523a2adfe4abc09ef88460012ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb87061084fdd7bd03321442eefcda06ead475cde3731b8eb138e88cd0bac3381e4241a287be924e122c76b56c23ce64202257ffca53dd2e2cdc747959af23c4d4c732416cc8a6845ce04091b63d97d874127a9365bc58783129afde9b61e36674ed020112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610c2c49607321443c7c14d94197a30a44dab27bfb3eee9e05496d4381f42417a2a43f95912cb291b1de685df609c91310d842f91ff9f756ea354e9d5589add348c581b53adf59c2d04e048bd7b8e6b78b5f139a15f85f7dea733f5f1197a470012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610f690c44c3214448aa1665fe1fae6d1a00a9209ea62d7dcd81a4b38204241990b2a2eea1e4b29c0995a15a2a5300f2fe0e9d0cdb1c090a1db3b05e764c3dd113eac3ef27c6de9d6359d72aac34e8cbf49bbf98ea99dc421d519b4ed07f2fd0112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb8706108ff5ee2c321446a3a41bd932244dd08186e4c19f1a7e48cbcdf4382142411136e3deeb71afc5c120edb3b0c34c3cfd4b850b738e02ed4ab782f647c5546d3d63162c9bacf73d347ac07768bce49ea6492764fdafb2147378f8adef7ee77a0012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610a394ee06321448aff66a7a9ce3b8fc4f62c80604bc310edf94cd3822424144a4283ba96f8ea539343fe3e2ed747b4bd006bdcd78fb52e73906cf9abcdaba48324f5e1953b91893b55c118663ea05cbdcea39880d3dfd4014e549ac456f900012ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb8706108d9fbdc30332144923de87853e95751a87eafe957a88a564387dac38234241da88064a9cdd3f2d3f801f2b40ea7dd7d325a87f1b556b3f65722a35338b37417ab77c71015a91b7db007250e2e2c0aed686571a5fc855bc1cd8b060b776ec6f0112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610faa2c85232144df34fac8313dcd3442064b90e22129ad82b510338244241615b57638064f65ef63a7c2da499c05806233e6bfef785f1c883e36de3dd9f587122a745a68e57652cf11251fe2c338c93903e9623735b627096c29a6cd6cc610012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb87061089d6936e32144f856f79f54592a48c8a1a1fafa1b0a3ac053f99382542412999356ee4e1f8fdfd38a3b4af8d604d892f098603bfdec849c8f18b0f51b6e642457a828368c8975c9a198680a3c9d08ce123d4dbf49b01fa00e5dbb4a67a110112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb8706109ccb9938321454fab55f18248690264769ef9c0b3c30b8344b8e382642416454a6ef51e6e1ad8f60f10f8875218aff238a02ec1ff7169d96569b768ea7c0527eea70beb8e0f8d0ac5a598a8b66b5d0d1420c19b776e15ee72edba4f963080112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610a285b1d00332145973918275c01f50555d44e92c9d9b353cadad54382742416dde182cdd6fbf885489ce736b7639b59ec636a4e76634fd9dfb16e547e993a401dc7273ac63d0b37acdd97bd997e0c1ab187d1b0317a17a8f961222bc95aff40012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610b895d42332145b106f49f30620a07b4fbdcebb1e08b70499c85138284241be62a031c343804a82843cdaae252389c7d788e8e75e9a0bfc2e7a69a505298c37c441d142bea9552135430158332db9c1b69c266d2ed1c0eafb64161d88c1460012ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610c2f6adcb0332145e1f84c7f7d19a8d6d918ad2b5f714a6e5d1c552382942410bfec75c25c7af734ea711e4030174725e30b56f7f65280d47d45676f5482e087993a6d61437dc6da6c35de85f584da12001f7fe0ffe7b520d8c590c30c2e6db0012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610c3a1fa0b32145fe93ddf4490a02257bef079f2498650c97c44de382a4241c4abc8f07e337ac1a00086d97b6c45f922b80158fbdc917f025d7fea613083f57a1fd7ac34a3a1db905e07fa20c40bc2f8de15dd1de655a202861076545bdf120112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610b0c2e00c32146237b2af1238d12248630ce21aa84f0952122232382b424165c41eed28c55cf8936c9ca8b0dd11d9e79c46e45a8ef4d24179428e86f3926418c815375295266c0a23e4cc1cd52c2de1ee1cdd98f6fb25c74175f595cfff3e0112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610928fb30b321462bc6a92f4a4d0f5b4e16967b88db2d9e196c9f9382c4241cc902cacf5327c3cecc97a0703c0c7972cd38b62e0e758d3e0245d90ae5e2f5410cf5d7dc2dc48fc21e503405c8b2e703ec62a745eda6f043fad870f4de673600112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0888b5fb870610baa5bea701321462fb676db64f87fd1602048106476c6036d44c92382d424160867f0a8467698ec0735168b1506e8edaeffd5a18e6a101e135dd7c28bf94fa098d4e0ac3c657b8dce0ba234abb8100e8437398063ba2b052793bb5ec53583f0012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610dfb1fd2d32146a654ca3bfb5cfb23bf30bafbf96b3b6ec26bb0e382e42417b3fff9c66e3004e6c8c761843969987ceb8a30e82d5cc3deb89009ab8fd56695d69d0f67f4ef9853cd91c35853a408d5e932cedbb3aabd9c0f60926297de9180012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb8706109ffe813e32146b2ed7e4b12a544ca7d215fed85dc16240d64aea382f4241c53a94d066faf89fffe650c608cae6d7096d69d8df3ed3d32e781f77097e75632d6f27429a81a3bacb326f30c02c5b26580924fa457b122ececc3295ac296dd00112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610ac879b15321472f93a2740e00112d5f2cef404c0aa16fae21fa43830424171e1a0850f869ff2537e39296c64bc86ff2c1329c5902a88a15eef39f58c32eb1caa06c8d92c73d184549bfdff693b93a385a0f38f41178ab66d92eea704558301120012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb87061082aea406321477ee14d1a9ba7130b686b736a316b5bf1d3ccb363832424118b14f6e8371b41bb2b9dfa7225733efd86f160acb8d541c7938faa20667c2e9707d6f92cfcf253bc00bf4f4a98f460fbfb496329c4fe48b3af47b7132def3e90012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610acefd93332147b5000af8ab69fd59eb0d4f5762bff57c9c043853833424158d1e08050304298ebc3e2eb64c45ec6529fb6fb5012cd1f8c4209f64b803f664ff792dc7f6ab6d4176e7cd9d34e8361a987410a90a82f2c6c451a5f61274d110012ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb87061087e8f0c10332147c7379531b2aee82e4ca06d4175d13b9cbeafd4938344241b7bce9a3ea3355bb8456aa235006117fabd210c4e48acd00bb003bfaa49a1950607c72f94b7a34de5852c3035b3ce9442caae81dc26ab2b887e705cbbeec84f80012ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb8706108ec2e5cf0332147e01c7c1a29584e6e54c2ce44313461fa84092fd38354241c7df2f72b4b2c98e8f907c76b492f46f848530438e62b98ae795a138734df2b90dd29f403c8e8099215a7ed32c99f7255f0ff91e295bb12671670d2871fea3010112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610e2fbdc3932147e8024132d07e3e69c9bc2012dffe300b9c5807d38364241e0e4ed509c965be983eafef595b82d46991e52cdcad07b28813d1d636236b3207dfdeac8b3306d037500f8441416872245d05c443ac37f96c1625cdf40dd1cc10012ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610fad1bcb60332147fcd58c2d53d980b247f1612fdba93e9a76193e638374241a5a1d9c265648d897385d76cf4cca38ee9e29d81d3d6fcf4363f9e900462e8305d91f438c03c856f3a31e84c8d65dae00b2f18516eacb769e2cb1ffee1fc1aac0012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610f8f4a00f321485517022e380408b698ea0ea379d2b69f907c19938384241865f2c6de8ae155b79ffe1751529188fb44e45e92e7da041e19956743bbd132a787fcf7bdbda61f0cb1231b1df2a308cb5454c7be3ceb5a6467607237f7a62150112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610f4a7d3cb0332148bbf92f4da9be0478464a077f582abd7b6df193c38394241881c569acb59364fc080471cd1bee45a5e559f3baa66764230dbe9d5cef070e12a7402c2b0d3e8cffaf435014fce06eb8834dbfaf6623980831742ea1e7cb8ba0112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610b3ceddd00332148cb120478e9503760656c1fcac9c1539158bdb55383a4241070329b9fa65994f37a29c34a58afb07c2e3f013efa7d114fe57e6fcfa7108073255a86554572ba1591d8158638cb1b7c197e5c5f765929e8cab6c40c7c4bf780012ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb8706109baacac90332148e9700392f9246a6c5b32ee3ecef586f156ed683383b42414b409b1ba1f0dc0723165b8cfdaff5a67402b757e01c88d3535de1276de584e31201a66528837f0e0fc715e82951274a60c45c994322ad12709fb11de5ce305a0112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610eab1b6be03321490b11143a0cb64e067402307bc7f2276dcec8250383c4241c6898c560635fc05aebec546a35e17bdf7d3cad8538aac3d38a320a78189b19567c7813d6f49f7666bf3b7e6c67b5f6f69de5b2fa5cb8fa3f5da92821d360e4c0012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610f5ffed08321491935751ba30494c4fd276adcf134ecd66f8eca6383d424141889cba5318781c0a2e02681512a5118cfa275914c136ae44a48e8f74438dfc17d78e4c886b48a06c106ec441b06bdd2e300cba18b6c761c22472c81b0ad5070112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb8706108bfb91623214951c881cab59ed669915a2b04ea5721600794ec3383e424131bfceb06109fc4f61b5dd5b80019e73389ba2508a6c776c1733023cb46661de62d0242e4a2e69cb2789f4dc477d5fe39a23699b795c0486d7602f5d31b74c3801120012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610f0b5d65f321498c27cc3f0301b6272049dc3f972e2f542780629384042416e61c11c1cf8dd4403f25c2befbf4284271609dfb1a20e9e92ad5afd55d2f6827fd73c67495420cb5e6f4bcd7f6ab13cc9028fb83c544173016ed1b82aef53350012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610fdaba60f32149c56f33b968f83922bccf6d7689b9c883af9de49384142416d210a63f185895f645d6f1b937d2c507b6d0efa465dc82454577b8dd5450b794543077b104739478270db5c368d3b2fda21ee18c5fc8b6d18ecce28e0eecf3c0112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb8706108db0bcd4033214a3bf7e661822fcc4f2129e93096cbb70dce6d3c93842424198dd378068519a6309aefcb21bf73cc8be2658046fe9734fa8f555b09e99297148d721d070547ad3a3d73da0ac02a4da05ec8dbf22983df74313e2be542581600112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610e7b993673214a5a2c0eef6ee3e4b0bf79e0c9378d101d3cbec1338434241a4144d955b0ed473f8ec4271f9fbf22b1b0cb9a4fd4610c0a12c400ffe6d86880a2a19e76b5dbdb04b6b1ca86a917abb35521225754cdf7b62b6e7c356b40f170112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610f9b7d7d1033214a5d5a7c2ebd2a381f7e958754c0d6a2d469b131b3844424144151b901c9c217df2248b7f7747cbf2fe153f17970d81cbea611cc244be32b007f67bf2d0f6c55b791713a280300cdc78744ba5f4abd99e6446544494dff0a90012ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0888b5fb870610acd8c4aa023214b0695fe376b48a3f39040ebbb2192e919c6b8aba38454241fc6a5fbddb3f02585a015c732d201d877f1ed9a739c74170b4d4032436d07800205ca039d23d6d4ddd805a91bf12d4f145f06b30f702be63840f56cea033b0900012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610e0bad71b3214b5cb4fdb37e9fe8d7b8f473268128dfb4f862f4f384642418e00a798d0b3f19189546ae4677353ff9caa28001fe077342e130e00c5e3a4b7702c634e71ff134493fb5abc1373e5546379b1e242bf696f6d4c5cfb8fe9b3f20112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb8706109ccffc243214b702f1c9154ac9c08da247a8e30ee6f2f3373f41384742418f7c1b7846c70c2ac35d68b0211c337e50f32f18ea07abb28f5a3a559bae4dc97aeecb0c20d857be3195d40ebf325bf7e9060f1c1c56ccbfe8585b98301b63c20012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610dab8823f3214b79fad4ca981472442f53d16365fdf0305ffd8e93848424120d16125e28e31d5a51d2a0155e21ebe7b6033af93277d29fec2a46313396836399621bf00d2e127e36bf5fde2c4b1ab607059f3503f297867f5e947821252700112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610f3e6ec0f3214b8bb158b93c94ed35c1970d610d1e2b34e26652c3849424105672ca60130f2baead60fff1ad287ea06cea61e394f547ef1de74b3c39b87cc7ddebf0c75d9b3f0007040356ee604ea5919b5a34bfe787a5e0d0f43105a668f0112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610a1f794023214b95d435df3f8b2a8d8b9c2b7c8766c9ae6ed8cc9384a424106fbf7d7aceabf15fdcb3680f0489f608a2a49d48babae5925c3a6e4e0bbf13d22b21943198121f3058fb314e81d458739b3609ff56f82813721a51a58a1da320012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610d8f9fb043214bc6044f4a1688d8b8596a9f7d4659e09985eebe6384b4241fe7c51980e08e8023e169d7ef84dea3a6b460b19c75dbcd0e2352d57c1d27b1844f81dbed95a3b397584d28fdad7fe8e16a53ead0577ee02b173dca8d7f3bb320112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610f7a3912c3214bdbd4347b082d9d6bdf2da4555a37ce52a2e2120384c4241c3180eed3b5f2c220f92c08f33490a0b8f1e76bac114a34e2e1c29973fae4bb35bdad988b664f1a3124fc3a0bf4cac2cf2b88d6b415cffe6e5ae1ea6acbe7c840112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610b2eef8cc033214c0ffdb5e938d6de2c5e5ed35ede0e881cdbbbc9a384d4241dc2b2ecffe693474bfd7b2d565898ca2cbeb2589007827e7438b2565838959c66cc4096c61e385cb8d00e340ff8d23f929f07918829f72df476bb2b407f3e1ed0012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610bcb8bd583214c35649ae99be820c7b200a0add09b96d7032d232384e4241ce3e43e43f4833cce842be2e63e5d1253c48bf78e5bc13ccf9d049e93f4d66c915205d244763807913bc9bee7ac1d5c18130122cc49281fa880f5b4417d849860012ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610bacff5d8033214c6869257205e20c2a43cb31345db534aecb49f6e384f42415ccbcbe4c42427afdd9166fc1938b1ba30c86f76fccccfef7c8af3af57dbdbf46a383db9b331856fb20e6842d1bef754a155b8cf173ac2c1c9436ff73a5d2b2b0112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c088ab5fb870610eede94a1023214c74d21957b34e4b9bae50e436a2581bd81ed581d385042415d12af0c1cd72cc808fd32e8f6d9be37d977ec4c039566f601fb588bdb91620c3d5d8edd17fa36ff35a38b9b656e062c70562e3f1cdf97a870ffe73661722ec90112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb8706109fbcab6d3214cdfc898128dbc380a60895c6e8c0975dc07d07e038514241a4efe6ae5f323a5ca740af9d0f7300412879e14d16b5dddc11388539192145d66fee43476a7e5586545621e37d2f4f74f6d95676de7d88ae3e7b27be6e7cd6140012ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610dc8dc0ba033214d48611f40a37623bbcf9f047b8538177d879bad03852424153de38e491c1ea9ae3a38cfa8f946bd211a10d70072f25d00e095cb1cf3665c02f1d2ac776ff515051945d038e741d52701d30fb7f60ce8ff0bb74008608a7b70112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb87061093f2b2cc033214d56fbe3294ea4d73cca99ff8751ce7bd9b688cd5385342413cff6cd671aff9ee88fb35be3ddeefa1cabda7df52924bb6f104081f1c88a8c60e4cc5098923add64cecbec1cca21dfe9c9e2b8c48004806180c108024963f980012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610c5aaba403214d93622443da1f3e81cde6e2c0e482b4d8084251a385442411cf8cc6ccf67d6b199d4d525b65948570d3b61fee89c0377327aed9054849ad51fd5cf3ed54ea6b97a7154d05d4ab309e3c11d3ffa98ec7a2056e2ba4180182e0112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610c59df9cb033214ddb833b9e0e3f2f521480e7bcb3e676e0737047d38554241583aa1975c51b338ea7991a8fe486a8a4364c8ba6788c18641fea4cdd21c4a234258e8f2910b5ba6bc2039e76e310a4aa410751a1c86d2a3b0866c05434e1eac0112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb8706108aa984063214ddc6f0e66a442632f6c4fbf9eacf363170ee29163856424159b5d56ea65cbdc67a28fadf830225a7aa4c9dd77f6a9252951f3e9161d23a774b09be7c1cbc61743d2dfbd440523674cc36606cba82f96e85868e7a73b0462f0012b801080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0a0888b5fb87061082fd153214de8da1ee512529b6c61fe7c769affc160308dea23857424138d8cff44d970ef26a77919d14d775f04338c7233c9e80c6f02cc35340698af26d0559a4dd4a5463c464830cd5b72eeb821d9ba9a58715f9c3ec699d503d79bb0012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610c0eef1663214e05ae0e76f582817c9e31d9c1a5c02287a31d68938584241df6ff3b7fa56adb4372b29feef0b5177510879fd56f558fa46fb83ef9c7f99ad0ac32fe957dbda2a524426637b083a62e39d4764c3ed5658f3bba9108ba6461e0012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610f5bf89533214e296cf6511ab951e026c620fb0e266db4d6de4a03859424155e7d305aa6ad10b6fec4d02711ea354360878a99a8d7eebb9ace39307c57f3302574ef33d3f5bbd213c5efaf62016b701aeb173383119584bfa58300087a48d0112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610ba88af413214e4cd4c302befddf3d544301369ae3ed1481652fd385a424138c2b4332e1462b9f05b82d7c49a425be4b9606561e462ea3a495f86fbedec1870e0b836f86e10c29ace87c6e3601bdde6dfda7ea72f5150ad8f2720706a245b0012ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0888b5fb870610daa7ff90013214e63727cb2b3a8d6e3a2d1df4990f441938b67a34385b4241e06790d0dab1ca723b5129033c7b7f253dff63e0e32db5869b15159b13a03fc741534984eb0ba2a317d6131703c0b5aa4beb106edab58f4666b0b6ca7e453b8c00120012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610ddd3c92d3214e77bbfd8ed65720f187efdd109e38d75eaca7385385d4241270f33e1683b7a3d8d4a0fe4fbca5c0953a157a1a5bcbf70bad27561350061ab72a5b88c150512f09af7bdbf08aaeaadfb94bd50bcc2ce230a1a46a786e7c5c50112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610c6e88f2c3214e7e2cb8c81c10ff191a73fe266788c9ce62ec754385e42418b4752cfc06f6563c2a65e8b25fd98a4821feee0e4c6fd92f64a6a6e353e59b578d4664680a53b5ac56c9d8a52e4912e7042d00e67f3431df55e7a695eaca97c0012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb8706109ef8cd1f3214e87d858ca83ffc1e8372b57b2d4f8aaaf8156f19385f42419882b2d52074816fbb9804a109503e92279857d08d8c1bf959802ebba960df3923187bddf0633662d90d10509fda131e344fc4fac5c54d9348c712220bd461ab0012ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0887b5fb870610ebf595cb033214ea7755c8fca76e6c1ecba0c678c5694ad8a8529238604241db4d2e451e5165dc796bcb9142dad5406f6db2eeb48632822694509759a671394704c4ec77c1f993bc8bfb0ab5447b7a3f597096069fc7212f3e97e89665598c0012b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb8706109dd2c3263214ef46d5fe753c988606e6f703260d816af53b03eb386142412bcec3ca64936492732543518fbf7f64fdf7e17661ef89edff9315811a83755c3825ba81b906f4aa127b539554d5783ce508f2762c4cf247babd0aaaa9258d8d0112ba01080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0c0888b5fb870610cfa0bb94013214f10ac184c3f8e98793675d4499241aa803c760c6386242413bb9425945677f8e5e70695d866c95dbe3943059566ee94133e4543d231a46f504aabfc8851f91b699d2ecaaeccc0eb07fe19c3909fd9316883543ef6325cc2b0112b901080210cfcbe80222480a2077a11c96d03b0044c7194fc221def4a11932fcb0d8600c4cbfe22772fdf2d7621224080112202f7c014f572ae8f936aa356cb6d279724eaad6fd2520102eb571df238b22d5ea2a0b0888b5fb870610dc9aa10f3214f84c74dea96df0ec22e11e7c33996c73fcc2d822386342417629e115c4f41dffe0249041b328ab7d682c7c98d5e9c252358b7baa41164bfc04d81efe55f76b46a1db68fb92c1e7d87b520b0eb32df75d29cc5511df82b033001a6c0a140208652a93baf5f1962849efcf5795eac7439a5e1246eb5ae9874104841b0cba6c27f4e77bd8a7105f0f0a85e158cccc39487158257d84879c2a6c57c3d8f30be8bc1e3383e6d329db0d9321d6f151b4689c71edb2128c32f43730da18fb5420abf88f91ffffffffff011a690a1402f70172f7f490653665c9bfac0666147c8af1f51246eb5ae9874104d1228cce225214fc1c36c5ac76f6f9e2394de97bee956197f632ebf406469ffe218193ac7425d9b827b1bf6928ba5967043c7e88e09f7ba5f6a45599a115eec218e7c7a20220a9f69ed2021a6d0a140306b7d3095ab008927166cd648a8ca7dbe53f051246eb5ae987410407ad4b275b9e9c73c27639e4679c560d473aae0c7fc11b88ffb0d74b9dbb9d9550da8eda54b3a5de8ecdb42c1b6a4757ddfe2277adf03f2e00a7ed7ca0bf97b81884ac4120d5af91f3fcffffffff011a6d0a1404cb8d907fda121fd3dd70bd2ef9c7841f70ed3f1246eb5ae9874104c50daae284879aee85f31904f6b03662677cf299341d3aa1a420f1426766b9b6e1a3de267f82ff8300203102346909f62b6bf79279f46317173951fec7ff4d5f1897fb0420f9d8b5abfdffffffff011a6e0a14055bd801ca712b4ddf67db8bc23fb6c8510d52b91246eb5ae9874104088437a36ee99d2b71955ccf2e1c9ffb32f6edbf206f27cfee1027ae55f9961e2c4eb6c179b88c237db58cc109cc97e10d0114be2aaa232c1e922ce2e16b4ded18efa5b70120a8f2bcf1feffffffff011a6e0a1410ad27a96cdbffc90ab3b83bf695911426a69f5e1246eb5ae98741046977227921443208ff86b7b80c2491099a5c342081059b20692a8231af02b8c642f181b3487fffe972a4746f0ad56906417c8238c9363a4095f10852bcdb580c1887aa8d0520a2a5fc8afeffffffff011a680a14127685d6dd6683085da4b6a041efcef1681e5c9c1246eb5ae98741046996fd88565bd0d4e2bc5162e822bb4fd76126e641d5a240cff1074411f217c6d6503ea7616f10297ce7646c1794cd5ddbc1eaf5b4130f26c43c9c34feb5ee0f18bbbb95022098a2ef761a6d0a1413a9d78f4712a65678d7735682819b4f4f74253c1246eb5ae98741044fa9ace6016c6543ec37a6324790633db2d5757fbd02cb784bc15978dc6a1fbcb1b907a2cab94b271d1e58c96ee8432d58fcf9f2fa71f69e5c4216d830b35eb31895d8112083b69db1ffffffffff011a6d0a1413dc53fa54e7d662ff305b6c3ef95090c31dc5761246eb5ae98741041699ba58acac5b78efce3be9caded63091fcb76556d5c4672118e67d1249f9b9b6e45b33d3b1ad47abeb58ac57fadd59f81b18cdaa51e280ca7d586efe8c820a1886cc4220b6b8e8a9fdffffffff011a6d0a14160cdef60e786295728a6ea334c091238e474e011246eb5ae9874104cb7728536d97b5cd3d6442133a9f4867959941b6161db8caf732298181892d184e4e4a95e126d59e9d9838aceac5c43e73d15cdd6cbda04e819697f0e2e15adc189da60220db8188b5fdffffffff011a6d0a14168b2779146ba862b04ca146385645eddb9d592e1246eb5ae9874104f5970a9a363ea37a2c390506783d94a8e5efc3ead3f32a4224a489de96e17273e2181e2f6f170215c9859092c5deb0c8b20b60007c3b9080656af53c1696e4f01883b70120faf5ead8fdffffffff011a670a1418f371aeee4e2636df789931c9cd43e5d7b72d661246eb5ae9874104ca36a3591de0fe7ced56e611c067bb16eb4038cfc81aa77eaaa101b7753231a3d3bca30a36200a0954703c4a77871c5ca6d73b616e010a639664cbdd412b38161880192093a0d180011a670a141a578699956c2174b4762de95316b3ad09ba34e91246eb5ae987410426721078ef970a05d17c60c0b05d536aa7151dd48a0e7cb32feb731ab820acf5dce01b3cf8e465206fef32f4bbd8cc5b6c62906ea978f766ccadb1adf9c2605618b7f05020e2809e701a690a141ca971963bdb4ba2bf337c90660674acff5beb3f1246eb5ae9874104bcb9741052a1b818d1c2410b975f5edf7e3a64cabb9f73cad6e8819dad7b1039697bcbd6bf69d9dd5b9d335194b36d1f9fbad329a18bffd6c5e9ec6b7cefd58018c5a2c62b20b8bed7b6031a690a141d25c827abd466387bda00b429fe728627d6eee61246eb5ae9874104b656d36d057c0c1a6ae8128099088f4e641b9c5d055554642f96bcd690a2dd74b849363296f5b309cd8351380056cefacc7318a1f810559685eaa4699474bc0d18cae1ad0120d7cbbdf2011a680a141fbc8746975598d58b0757eb2a273324dd28f6a01246eb5ae98741041b31c051fcc4cbe9d71014bd15d54fcf752f5c08c6b045ab19e7617b684d06d4b272ed1e8dedb63474d7bc959df4d75ef2fa5f206419fac6809aa11308a2fd5d18f6921d20f0b9c2ea011a680a1425c32fd6ed7b84435a222084ef3fdbb36252b8de1246eb5ae987410406398702db4f95eb7848670a488fecdf070c83c6799650e1509ca64d11f8cf9ff5298ffc8af578137df24ec598b77be557c5a29663ffe086106c9f9c00807b1318d7e9cc0320ebd4f20a1a6d0a1426c80cc193b27d73d2c40943acec77f4da2c5bd81246eb5ae9874104877af9e5e26bca4f9063d4baf2803a491fad3219865d9d5fbda6edea5e1c1b4272d4f4704ee167b77091498d6eb8442ef8ab6c2b5a02722b15e0e5ab0ca27a0018f5fb0a20f4819b97feffffffff011a670a1428247de2d9829f3080899749b92e34959c06b59c1246eb5ae9874104e4159c4f9eb8227885d37ea988dc12cf07154af62ae7021422a128d568318ed5458c5c3ceea3dc0b7da34424515639c68a76a48614b5e07ec3508153e1a0ec5018bce60920d7b7dc021a690a1428c0d4328520ed7e8657de141eee74a954b07c1f1246eb5ae9874104b24d50f05b6e709a93ba13d67484c750e13fb2eba74cd87a373ea21908be274232c703cc30bd66263202a745cfb4f207d5466872abb89f4f75e966d10e4a8bf718f6b0b90220c6a0a4a8011a680a142a998cc0bb43dc510e523fe33c8f1c04bf607a1e1246eb5ae987410488afb121139af92659fae285e6bae620cdfe5f35e8cd6c266e0b9ef11f91a7c898a8770886fb269cbe48c41171f1578159bead0f3a8c77aa4794847f75836925188cab012099c79198021a6d0a142c74ca71679cf1299936d6104d825c965448907b1246eb5ae987410441bda7846a4bf03d50ba81e7f082cfb736534e5db7213c10cee08b6e4e12c5460fd10ffe213f599ffa372879e0803240c95dc225f7074bae3c0cf4828d3290fb18ecf44920d3fef3c5ffffffffff011a6c0a1430523527aced0ed2f5ce1721086d1d282d3af38f1246eb5ae987410439a3232e18c22876b20fc1c5fef1b2ce82d5393e7e592622aa271471c6ae0366e69879bcc1c2c19dba0c1b1b7a33bae48ddda6e5d130afb687dd2e6f258d280218fe7520d5d9e1c5fcffffffff011a6e0a1430dd252c7c150f26a3a06e4eada9e706db3fa58c1246eb5ae987410434f30e5ed1fbc44c7b41b0134c886097c2ed98d17141ac40e0796a7c4ec93c0c1eceec4160192bcb75997f57f4a2783343883450421ac750f360aba5ac826cb51888a9b70120ceabb3f6feffffffff011a660a14374c87b673409e13053dbd35ebe868be42beabc51246eb5ae9874104a4cd9f0d5b34a57270e8a661cd4b9d8a5f5f6c9bef9201db5ccde2bdcc7483e15b904d3d09637521676c69bd6bfae419f1ce33b9e6b2814ae0cc138e6bbf660618e26d2096e3b40e1a6e0a1439f5455840874f4251cf92b14d6dfe10d3cf22341246eb5ae9874104432d6868d570d161709c59f1aa37979f2552beb41ce811e8f0f5573b02cc4c688c18a7259007baf16312b6bac1d521314173b60e9165ffdc46dfb1e8adfc7f7c18dc858d0220defae5acfeffffffff011a6d0a143a9df5dfcb4cc102ce20d40434a2b1baca9eafd31246eb5ae98741047ccefa8460faea3a81b4ce41be62c29ea1cfc1a8fda2b3e4eb634a3c0a8da104a4c916fe0612ba2ae22e3ec9b8521efaaffcda7b05afa4826bd36242ece756cc18d2850220a0ba8bdffcffffffff011a670a14406c3fef5969b36231bd573adfc34e16f54d23e01246eb5ae98741047ad53f370481eb0babe5439180af6942cb6272d3fe2989696a7f630c11752f9209a5714fced679f6981b5a70048f1e7ae05cebafb4df9c63271ac2aaa933a3df18eaac1c20b58ba3421a670a14414b4b5a2a0e303b89360eda83598ab7702eae041246eb5ae987410445c2815f01217c3e7e730304196f7d72c440387addbf2fb743728e2fbfa6ad585fb2c4d996b3556597f2a845613e9a469caa65934a55c41ca9d982cb9b7075f11893ae752094c4c3481a680a1441d5b3e2ec53583bc0601dfb4f2a11a3920494891246eb5ae98741041662065d05db051bcee3a554ef5c1c6c8b2946a38bc48bd1a70ec63816444a2d9dd6413cde5ab026247519bcbb1b88dbb3bb2f62fd6a0af473df978d80ad6d7a1882f0b20720c7bea04c1a680a1442eefcda06ead475cde3731b8eb138e88cd0bac31246eb5ae98741043522a004012c9740703f676b95b5121edd7237fb0f182c3c45e7c7a77eaa67a20e6d0ac025d5bd96295bf95e2e875ab2a9da5c0e547b7d00ca7ede33c1b0389318bd8d7120a4d0b4af031a6d0a1443c7c14d94197a30a44dab27bfb3eee9e05496d41246eb5ae9874104fe0e75276f667c335d798e4c11de8a0cb938b41e91d4f184fa11f2cb09845edb5bdc914f4da87db1511ef6ff90727142a6acc3d55d963350962c322879584eaa18afe34820c188cdeafeffffffff011a6e0a14448aa1665fe1fae6d1a00a9209ea62d7dcd81a4b1246eb5ae987410420f2d4e8ca210f9976821d94fe9f57410a3800fd54010726c74336a702f7261716186e1f834e247a3ab095aa96af7c3663652ea4c42ae85eea27c2be29cb09701883a1e70420ae91d9b0fdffffffff011a690a1446a3a41bd932244dd08186e4c19f1a7e48cbcdf41246eb5ae9874104af2b42565d5c22d1353e23936bf32fd0642d2a2c567d866135d2e547fc4679524a2306141bc214c96893ef6c6d312fd5bc3654abbbf3b74ac96180f0c2efab9018f0fabe0a20f182b2cd011a680a1448aff66a7a9ce3b8fc4f62c80604bc310edf94cd1246eb5ae9874104cc7a0adaa5d58b8b9aff67696f52e59541a0d208c22f56097f92522e9e4da98b7dedf2924cbb69e922414bbc090f4e28f6b42a310e96abcef80539a95dba950318b89c4520d5c1f591031a6e0a144923de87853e95751a87eafe957a88a564387dac1246eb5ae9874104c74de15a4e622b0d47958034da5f8376f8f3c36a77fb807e2b6533b9b9445af8c1d9d7271e0e2d1d9e1f1e2976851241452517cd25658a438fad8b908412865e1883ddaf0320abd5dbf9fdffffffff011a6d0a144df34fac8313dcd3442064b90e22129ad82b51031246eb5ae987410408a8eb34eccba507e5aa16e783e3fd3bc4b70b1d10a8cb3d31674a1b00bfa7968514c584520a8575a4afb4bb25bc10baa97639f1be380dbf3eace482da57925818fce81520c6f6dd85ffffffffff011a6e0a144f856f79f54592a48c8a1a1fafa1b0a3ac053f991246eb5ae98741049c0af0f00b2336bdf3a83b4a68b59caadf84fe7f3a59882e5174ed2d0d96b1f7c6378200fc8a0083fcd7c0cf62d142ac8bfbb187db9506b01f4b95f4a9ce8ee118a8b1d22720aef898d5ffffffffff011a680a1454fab55f18248690264769ef9c0b3c30b8344b8e1246eb5ae9874104d25fb5117d46b0d3958241762a2dd04a4a02b2dd459e71576824fa5b4fe3c1d0c851e101491b0530f8215f9d4ae46da84f57c2f437bddec790d0656789063d8b18abc859209091e7b7021a6e0a145973918275c01f50555d44e92c9d9b353cadad541246eb5ae98741043c53ea6e1964e0670dc9ac72b3224207885d4c5f08cabe1e1080c662fdec278e7e833798757cb5cf121447dcd02a15f010eb4aa87cceecb23daa4bf904112e7718c0fbe70320ac9eb0eefdffffffff011a690a145b106f49f30620a07b4fbdcebb1e08b70499c8511246eb5ae98741049d73839b66cfdecd2ecce0dfaefca77e9ee3a795ad51c752974c24385f904bd51746e04b4c0bdb47469f24bf9a0ba8c89011b65833850f0e589a08ceaf185fb218b8e8ef092089a089ee011a690a145e1f84c7f7d19a8d6d918ad2b5f714a6e5d1c5521246eb5ae987410423f2a1ac55c387ed2949bcc5979c950b24c665cbdce539913b66342dfe866857e2b75e522248b78e5e43b573510058e9bd6eea573225c8d26c2b2abde0e7516b18d1c3910520eefad08a021a690a145fe93ddf4490a02257bef079f2498650c97c44de1246eb5ae9874104e048dae89bb4235dd4216a54a46312427db9cffb82959f48cba797f04605ee8c47cd9025ae7099cb6bc80deea1bea207a26d4b4ec8ef5c0cd2ed3671acd5ff7f18b281b60120b0f08790011a690a146237b2af1238d12248630ce21aa84f09521222321246eb5ae9874104b91df3078221d1f13a7fec6d07230f878e3f01c4d3d3ff486c403ae68a95be8048f9738a7772e928a54d4c1da4ccea7d4654590e781037768b87d0dea199aeb918c798bc0120dbc3d9bd031a6d0a1462bc6a92f4a4d0f5b4e16967b88db2d9e196c9f91246eb5ae9874104ff7cb0d8cd62746c5a5df7b78585ed256b0ccbc9da020790e8d1f72d45b3499ecd0bc7deb166bcd9859de0c9b7833f1af0fc90e54c553a73c3bb75e4666cf4f718bdf46c20f381f3f2fdffffffff011a6d0a1462fb676db64f87fd1602048106476c6036d44c921246eb5ae98741041e7b1045fa8d8dce5d97d021da9a715499485570bb38d9d72deb1c76fbcb8043f5ed4477cf756e68de3f98d9476db8dbee5707650c91d3d4983af2889ce96a6618c3c60b20e6e5ace2fcffffffff011a690a146a654ca3bfb5cfb23bf30bafbf96b3b6ec26bb0e1246eb5ae987410425d18e5a222901cfe92269e5a073c977995df6a6752fbcec0f4da7e82f7fcb539575198816c331847a4ef1e74f43ae161c3e087b366b242b49e345fcaeaf64091887ebc30120abbbd381031a680a146b2ed7e4b12a544ca7d215fed85dc16240d64aea1246eb5ae9874104e488ff6fd81fb21f7fc098f727786fd9a3454d0e7a0c48bfdf0cb01228260dbf9d7cfc3ca5bd6706a525973299589baa6ed1c28ab3973bc81477127438eea3bf189199452082e4d6c2021a6d0a1472f93a2740e00112d5f2cef404c0aa16fae21fa41246eb5ae98741041a98b875a62e03aa51d60812d57d03b22d51b36cff91cd4070db64c7eb4206a1a4f8b6265f6297045ea5074d997b2d5db0417115a4e5175d10390410c19aadce18befd7b20f3f0d8adffffffffff011a6e0a14742d13f0b2a19c823bdd362b16305e4704b97a381246eb5ae9874104e3d9d418d82e60dcad162478f8e7d6362c8d584b42c93e4a9e6ad877a941c2b1e58a1571b39c89316e78729ae9190bef889a58e847fe104cff01e1c62cb3ed4718dce8d8062098fdf980ffffffffff011a660a1477ee14d1a9ba7130b686b736a316b5bf1d3ccb361246eb5ae98741049d1deb5737da28cb1ceae91b6fb112a36a3d9f36d2bd2edb2792bedf81310c7d761364b520bc28d802aa17db02a60d4bb498fc69dc82a9990dd62ef4a7099e6018d7132097dbc45a1a6a0a147b5000af8ab69fd59eb0d4f5762bff57c9c043851246eb5ae9874104ff5b89b73a23af4821f0408663b56f0c622b6220ac14a323eda86f8224ba69ed474df8287db198fd0534259684a05b5328eed970649d09c62aa5f790552285b418a7dd9cf20120cfedf1cb011a6e0a147c7379531b2aee82e4ca06d4175d13b9cbeafd491246eb5ae987410449b4c834634c6893da4ab09f54f4167388ff229d4002e92665a625e30b07feca3aa907e1234e5fa032e8f1cd277caf3d392513ac8a40e288a9da45bb206ed02c18a687ab3b20d58cd3befeffffffff011a6e0a147e01c7c1a29584e6e54c2ce44313461fa84092fd1246eb5ae9874104ce1721ee587aabba6a3fecc0c5209e531399dd939b23b86142de2116ebe38d10c4e2e1abd0665e514d0d2881f966b11f466f2eb714573582adcc87e2b83395bb18b2d8980320a3e9ebc6ffffffffff011a690a147e8024132d07e3e69c9bc2012dffe300b9c5807d1246eb5ae9874104ea262816cc0e5ef341aaadd1a295ec6fc65afc46921baa86aface3bfc11df179ba5825b143913e43438952f954c3a34a9d6bc8633ebd67d25d498f3bf472f35618add5f301208a95c5d1011a690a147fcd58c2d53d980b247f1612fdba93e9a76193e61246eb5ae987410479efe8c50b1f9923f48a467ecac0a64c2d6bcaa9ae67e135df84cac5aed5321f9cbb29c115f26dc84f2ef0e5fea29615848c79d690cb205cc10d688324ae8bce18d4b6cf0120e7a8eeb6021a690a1485517022e380408b698ea0ea379d2b69f907c1991246eb5ae987410469d59b49b6424746b9df25d0ef18305220b08800160ec0db793207ec9239700388990f0fc291316d00ebf9c1db7e78522b5e83ed26407ca815a47e76d65453b118ebf6a90120c1cf8193011a6d0a148bbf92f4da9be0478464a077f582abd7b6df193c1246eb5ae9874104ee62945cef0b885c98781802dfdaab67e7104cc3010fa73bf179a5dfcea50aec410c6e07160576daf0ba5ce8885e78de575933b55b36eb23121ddf8a7831fb3818aad30320a59ce486ffffffffff011a6e0a148cb120478e9503760656c1fcac9c1539158bdb551246eb5ae987410466d071600a26ff3c046afb7f556ec840b39f5bf1a27660a5f739f48970807e80b1d4125473ffd52eb494fd07255777ce19865590837da46edaa50f77d447120418b1b68a0120a6e5cbf6ffffffffff011a690a148e9700392f9246a6c5b32ee3ecef586f156ed6831246eb5ae987410480b48e24338369cd3c10913d26fdbcf57b6133291a28c2392b36b38dbd0b37c44e077f4551efce25ef13f138b899e4c3bfedc6ea43d52b893546db45b971e9f018edb296062086d78383031a6d0a1490b11143a0cb64e067402307bc7f2276dcec82501246eb5ae9874104050e946ae40dcb277af26c22338f89b7e5912a435f45ee63293367e977ce26fe437a855204b4de9396dfc7cee6b8d92be26a37235e2afcd9baa0551f27b2ebd918bfc04c20d9878e92ffffffffff011a670a1491935751ba30494c4fd276adcf134ecd66f8eca61246eb5ae98741041dec50455dec8b1e2dde8062e90a1cc1ea69dfeea23415bced071b21f31a4d287d7e3ef7f6703f79fa7e57fc2b929e001a12342a007e6b27d86498abf3e7a03418a4bc0620df9ed6031a670a14951c881cab59ed669915a2b04ea5721600794ec31246eb5ae9874104dc5de4ecc100f12fd467e9674e2894b4061118e210d3bd19ce53feb5e6df24ce1811fc198340d06ce9f275eb5b764b7d864c8818324d161a4ecdcb81b910e5e218d4b95220e7a88c1f1a6d0a14959a4d857b7071c38878beb9dc77051b5fed1dfd1246eb5ae98741041506bd87d2844fe8bb60ca3f7f286ca9991fb17483917668114fcc7d42a701f95e6a83524bbddd7b5cf2010b8ec55b47793d6d179bf547a5504a3ebf0b9cd0ba1893e00220a98b83f5ffffffffff011a680a1498c27cc3f0301b6272049dc3f972e2f5427806291246eb5ae98741044bc95f26db29fd21204871f7011a4606ae8253f879cc1a988b0858e2d95894d4fe2bb18d46cda7859367ffea3344ebdf960b0ac073023635aadcb59f47b0a79c1886bd810120b089ec111a6e0a149c56f33b968f83922bccf6d7689b9c883af9de491246eb5ae987410427ca49d47de88f14492b240602913b155c372d0c8bb77e3e1d9da7c7466cfcd8992c0cc0deb2887abcd88fef8836170110df807508b5e3f90dba2d14b0c65a71188aefa60220b2b0f3acffffffffff011a6e0a14a3bf7e661822fcc4f2129e93096cbb70dce6d3c91246eb5ae9874104c5c59cf8d2be64aead0884283a8653a8b885ad4107f4c426954fa82b0af0a6fc9e0a6b4fee793c0248522d4c2b89fe9d4d6d05a40b71a2fec7dce873ad4ab1e91889b2b70120cec3e4bbffffffffff011a680a14a5a2c0eef6ee3e4b0bf79e0c9378d101d3cbec131246eb5ae98741048a929ea45fc8a4e13c7bb48206b0549cabb55f6c084f494a27c8735f21d1df07ebda79beb3f677bc4b98681fb59efff89ccecacf380074c5c349a55d84bc11af18f7c20c20aade8fd0011a680a14a5d5a7c2ebd2a381f7e958754c0d6a2d469b131b1246eb5ae98741040572f6bac2320d4ea912b99ce6828cd8dd3e0d3471f8102df7b05dd8ad8791a53e00f74b6f89499e5d0c0f8254a33d85947486afe02565430b9345e1c24bc2dd18b19de60120a7c2c8271a6d0a14b0695fe376b48a3f39040ebbb2192e919c6b8aba1246eb5ae98741049b13ee89d1640235fc9438e640b6eb16dd59c30f2e1a56730a6b5af4a05a804766d6d07e2c44daff505b4bb7f63573908f502f0f55bce3134e2c4b64ce4530cd18e5941c20fdc0f1c0ffffffffff011a660a14b5cb4fdb37e9fe8d7b8f473268128dfb4f862f4f1246eb5ae9874104ac3cc74871b745e99c93692c71f1704106b4d24f807a21fa13bd123a91f9ecb4cf4cd740ece9f6c4519b4087f72f4659280e4892636eddb0de58c519de8d052118fc6d20a0b9b11a1a6e0a14b702f1c9154ac9c08da247a8e30ee6f2f3373f411246eb5ae9874104b4e1d56b3429f7756452426be611e595debcb858d59f47d29ec9dd6e4b547dce1539f9b7144420bc309de496b70d6dc5f13345eee85e6b7fb332cd9f364ef12f18fff7b9032083e29eeafdffffffff011a690a14b79fad4ca981472442f53d16365fdf0305ffd8e91246eb5ae987410441e7ecd5e6ddbe76e3e9dc4479e2d7c24fc5e4d80d0ee1a42e1f1dc5021c3b83acc90ebd6dd09a5f2f03c5cfe52f2b6d1f68c56700a66496a1663f71c9b3a63518b08eb08d01209eb0e4711a6e0a14b8bb158b93c94ed35c1970d610d1e2b34e26652c1246eb5ae9874104d6b06c725f5410e4ccbd65906ece180364ebea4902b21232c1fb5892a76be7eec22480397d6bf653e9abe7ac50435ee472b59364fe78b17acb2be2116f92a76f189985a80220a7c3bb93ffffffffff011a680a14b95d435df3f8b2a8d8b9c2b7c8766c9ae6ed8cc91246eb5ae9874104181ff8d843c85b3773504bb7a693378eed4a2137a6a8c75d91c5acb3d97876cc4155d0889d389204774aae71eb2288181252aebb78b52592c4feba35224de204189ce1cc0120d7e0e7331a690a14bc6044f4a1688d8b8596a9f7d4659e09985eebe61246eb5ae987410476ecb34921018cb5359fc16a8e676cf055e5b155a45a51dcb23c29c161432b037ff1bb8b44a190d367202c0b6d64783858e4c3f232cfc75836e81e1f30e8d1b018d1b6f707208ec5cec1011a690a14bdbd4347b082d9d6bdf2da4555a37ce52a2e21201246eb5ae9874104f4efb1dc25cf3653a408e3640a13d11855bc2cd9957976d793a18491d674c99bd410312bf891f4eb87e37cea6372ddd31e60fb0eb255e197a52be71eaef62b671892de911b20cff9df9f031a6e0a14c0ffdb5e938d6de2c5e5ed35ede0e881cdbbbc9a1246eb5ae9874104a011ca716e22b3a5a61daea6ccb6f2ef6be88e17f44b141117fc35b1d728b48bc4350d8f0570f40c5e8fc52fabcedb835521cca6f685d301ae92969e9025805118ecb1fb0320bfc4a2a6fdffffffff011a680a14c35649ae99be820c7b200a0add09b96d7032d2321246eb5ae9874104071930b3d77174fae43dcfbfba3079081c8ae3788cf00e758fc74e19da7cbc651be23673b027ca85570d021789a87d3ac6e04e71140ac4d8c09dd35ddda52b471891f3e50420d1e3fd4e1a6e0a14c6869257205e20c2a43cb31345db534aecb49f6e1246eb5ae9874104e039bb399a4b185f97d3842b01b3fe86e794bbfe39d7110b75dd0727d69eb8114ac573ba9cb1fb34d7b944253dfa9832276902a283ff39605bc27639d7404f8018bc96a70b20d7ebf7f5fdffffffff011a670a14c74d21957b34e4b9bae50e436a2581bd81ed581d1246eb5ae9874104bc50fa9796f3e2dc92ad7d0e094018882fe809463a7bce1f5f0c21a1a6d76354e1c07e2103071e835bc72a69c1d58b87d8b7a3977699f4e6a4191185f5cd8a331888f33c20c6ddd4321a6d0a14cdfc898128dbc380a60895c6e8c0975dc07d07e01246eb5ae987410470b2486dc020603eb122350cd58c54a28837c8c30a6b98e8fcf03217d6881f07e3cb15eed9e3b86bc6c9590f7b242588f3276c74f1e2e2088545eb40e45d108f18f1c830209f81a6b3feffffffff011a670a14d48611f40a37623bbcf9f047b8538177d879bad01246eb5ae9874104690010a73742050da4ffaa1bae9a0b2188bce80d3f29ce43f6223c024e516110ee142d694f2fcc9b025ea48aca9191e015922fd442d8cd17c87ecab1ad3e543418c1e40320adb9ce3b1a6d0a14d56fbe3294ea4d73cca99ff8751ce7bd9b688cd51246eb5ae98741043171932c1a17af7256fe0951d1d8a69f7be98207c0fbbcda87a62d3fb341fc0430ebd33f385759c6283af5698f595ffab12424f59d5be241ffe528def858384718bd970c20fba385b2ffffffffff011a670a14d93622443da1f3e81cde6e2c0e482b4d8084251a1246eb5ae987410444e616b6cd21c31154961495dbb4260080ee5db04ffea1a4bd4e2965f34b4a9f8356ca3952096c49a46f0a5d71e2dd8e42edc193dd4e9da9d390de5665043a7c189de1362097959d3f1a690a14ddb833b9e0e3f2f521480e7bcb3e676e0737047d1246eb5ae987410475324a3391a214edeeb53ea015b54a23c770007b58004a7f0f5e94b445b4e2a2b419c665bd076ee51fe9f1e09212fa19119958f3460325a5869f47a592f176aa18e3e2c647208cbca4a2011a6d0a14ddc6f0e66a442632f6c4fbf9eacf363170ee29161246eb5ae987410459e8054a65b448e0aeb39255fff5de2e9f914bf7bbc7c6524262bb4fc04c9438e7bd9742beaa504af1ac3f09e7ebed986bad07128c3380fe9fd2e95f0ce1d1b5188a880220ecf89dc9feffffffff011a6d0a14de8da1ee512529b6c61fe7c769affc160308dea21246eb5ae98741043fef3dbac0ac22f7261d9f5b71671bdd6ac3b024d7a8a4d63b4fe9a8b3abba68063161f364fc2feedea2dfe1daea59bd2715a9991fbe5c6e7b9b34a46323d13218b3a34920c2e0d7ebfcffffffff011a6d0a14e05ae0e76f582817c9e31d9c1a5c02287a31d6891246eb5ae98741045c242a0228b3956b89132fc9ad810de460285adc17a5ed19f6e9bd2c92b2a53384f0416d336e8fc3924542a6069ed17e1fa532ed93f872a818f65a02f66b7e3218caa45220c7d490a8fdffffffff011a6d0a14e296cf6511ab951e026c620fb0e266db4d6de4a01246eb5ae98741043d33f282f64a03d8ea84908c07bdf1ec81c4c6ccdea46a5562e67e8aef14009c9b13489177964a63de768f2aeb0f885e5e40a9c0e6a816b01267419d6f495cee18d2be442095f1d0d1fdffffffff011a6e0a14e4cd4c302befddf3d544301369ae3ed1481652fd1246eb5ae9874104014f644674239c547b9486e164eefcf818fbcf2085cd12e0d9393162b97d3fc77347a890831df83b4429b06807ec714d1a67f1d5b1d422a3ca7bd493345c0f1818b4f49c0620bdecd5cafdffffffff011a6e0a14e63727cb2b3a8d6e3a2d1df4990f441938b67a341246eb5ae987410439ff7824e759b9ace75ff977d86fb6d54cd9a67ac87d9ed72850b68a1cec7bdbaa3d9ab87881b50f870d5095dece87077f98f417a05333306dc55924b703a370189cc68601209e8cf094feffffffff011a680a14e6aaa7f77dbbcbeff2c9b188381d571b900281691246eb5ae98741044e9a5cf80118a58439fe384c4eca79016f95bea3a8693706a22e992aa3dc95e870bafdbb85a9a1153c595f3f790aca34e270e862077208dda4878f529f887b211882861a20d7e6f2f5021a6e0a14e77bbfd8ed65720f187efdd109e38d75eaca73851246eb5ae9874104053015a485e04c39236b3cf0dd4f0a8d50f4cdca2e806725ba5c732d098a5e156d1bfa6f8ce2189e12dd91378c723dc63a408794410365d181971b52f511bc6818aba6f80c2094b8cf93ffffffffff011a690a14e7e2cb8c81c10ff191a73fe266788c9ce62ec7541246eb5ae98741046ff196614c2398bc7e2c0a95a8be5ee41604e3f5e678afc642cb7f982386433142b7f7320affa049cb2840b431f40b28ce0796c68f21d2198bf2a91a961b692518bce0f42e20d99c8de2031a670a14e87d858ca83ffc1e8372b57b2d4f8aaaf8156f191246eb5ae987410436632af11a092c3bdaf3bf0a7d495494e062b461c04370e3ebead6653f9721db36568f12ee960f4723895769450489b2746f3a9230913fd774d4a4494cc4000f18e7b67a20f2beeb041a670a14ea7755c8fca76e6c1ecba0c678c5694ad8a852921246eb5ae9874104f52b8bd6fbe9561ab7b3d5c3781d6250e88922bceffb6549997598377d13ec71b47a10b3e6834aad847d3b4d0840c0066ba962ce61f8fa76efd5d2596e742ec718835a209a87d9ba021a670a14ef46d5fe753c988606e6f703260d816af53b03eb1246eb5ae9874104f942d6ca3d87de9b0767262db4363758753bdb2dbed83a65b1b731c60a8ecf9be0a9cb70547bae211875f7965df789da6177692f200b403d6fdfde92283a9a9818cdd50a20f4d8a91a1a6d0a14f10ac184c3f8e98793675d4499241aa803c760c61246eb5ae9874104ed21770790bc33725f1f80ec798672426b3fec59224b835ca9e176ddba9038e321c9cad7fff6d346944b25657515f1f1ae409443d37c91de018f7187f4c3aa5618fac51420dc85df92ffffffffff011a690a14f84c74dea96df0ec22e11e7c33996c73fcc2d8221246eb5ae98741040600efda73e1404b0c596e08c78c5ed51631fc173e5f39d21deeddd5712fcd7d6d440c53d211eb48b03063a05b2c0c0eb084053dfcf1c6540def705c8e02845618bf87bf0120dad7bec602") - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = heimdalChainID - param.GenesisHeader = heimdallGenesisHeaderBytes - - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncGenesisHeader, param) - assert.Nil(t, err) - - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncGenesisHeader]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(scom.ABI, scom.MethodSyncGenesisHeader, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - } - - { - var snap17241854 polygon.Snapshot - // block 17241854 - snapBytes, _ := hex.DecodeString("7b226e756d626572223a31373234313835342c2268617368223a22307864353664356365623135343932373430613939383938663061346231656631653863636133653638373862656337623865623864376662393063626162386235222c2276616c696461746f72536574223a7b2276616c696461746f7273223a5b7b224944223a302c227369676e6572223a22307830353562643830316361373132623464646636376462386263323366623663383531306435326239222c22706f776572223a312c22616363756d223a2d33317d2c7b224944223a302c227369676e6572223a22307831636139373139363362646234626132626633333763393036363036373461636666356265623366222c22706f776572223a332c22616363756d223a2d32397d2c7b224944223a302c227369676e6572223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c22706f776572223a312c22616363756d223a2d32397d2c7b224944223a302c227369676e6572223a22307834326565666364613036656164343735636465333733316238656231333865383863643062616333222c22706f776572223a312c22616363756d223a2d33317d2c7b224944223a302c227369676e6572223a22307834336337633134643934313937613330613434646162323762666233656565396530353439366434222c22706f776572223a312c22616363756d223a31397d2c7b224944223a302c227369676e6572223a22307834393233646538373835336539353735316138376561666539353761383861353634333837646163222c22706f776572223a312c22616363756d223a31397d2c7b224944223a302c227369676e6572223a22307834663835366637396635343539326134386338613161316661666131623061336163303533663939222c22706f776572223a312c22616363756d223a31397d2c7b224944223a302c227369676e6572223a22307837623530303061663861623639666435396562306434663537363262666635376339633034333835222c22706f776572223a32302c22616363756d223a307d2c7b224944223a302c227369676e6572223a22307837633733373935333162326165653832653463613036643431373564313362396362656166643439222c22706f776572223a342c22616363756d223a32317d2c7b224944223a302c227369676e6572223a22307837653830323431333264303765336536396339626332303132646666653330306239633538303764222c22706f776572223a312c22616363756d223a31397d2c7b224944223a302c227369676e6572223a22307838353531373032326533383034303862363938656130656133373964326236396639303763313939222c22706f776572223a312c22616363756d223a31397d2c7b224944223a302c227369676e6572223a22307862373032663163393135346163396330386461323437613865333065653666326633333733663431222c22706f776572223a312c22616363756d223a2d31337d2c7b224944223a302c227369676e6572223a22307862373966616434636139383134373234343266353364313633363566646630333035666664386539222c22706f776572223a372c22616363756d223a367d2c7b224944223a302c227369676e6572223a22307862386262313538623933633934656433356331393730643631306431653262333465323636353263222c22706f776572223a312c22616363756d223a31397d2c7b224944223a302c227369676e6572223a22307862633630343466346131363838643862383539366139663764343635396530393938356565626536222c22706f776572223a312c22616363756d223a31397d2c7b224944223a302c227369676e6572223a22307864646238333362396530653366326635323134383065376263623365363736653037333730343764222c22706f776572223a342c22616363756d223a327d2c7b224944223a302c227369676e6572223a22307865376532636238633831633130666631393161373366653236363738386339636536326563373534222c22706f776572223a312c22616363756d223a2d32397d5d2c2270726f706f736572223a7b224944223a302c227369676e6572223a22307831636139373139363362646234626132626633333763393036363036373461636666356265623366222c22706f776572223a332c22616363756d223a2d32397d7d2c22726563656e7473223a7b223137323431373931223a22307837623530303061663861623639666435396562306434663537363262666635376339633034333835222c223137323431373932223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431373933223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431373934223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431373935223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431373936223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431373937223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431373938223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431373939223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383030223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383031223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383032223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383033223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383034223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383035223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383036223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383037223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383038223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383039223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383130223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383131223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383132223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383133223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383134223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383135223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383136223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383137223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383138223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383139223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383230223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383231223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383232223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383233223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383234223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383235223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383236223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383237223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383238223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383239223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383330223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383331223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383332223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383333223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383334223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383335223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383336223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383337223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383338223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383339223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383430223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383431223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383432223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383433223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383434223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383435223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383436223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383437223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383438223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383439223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383530223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383531223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383532223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383533223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383534223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839227d7d") - err := json.Unmarshal(snapBytes, &snap17241854) - if err != nil { - t.Fatal("snap17241854 json.Unmarshal fail", err) - } - headBytes, _ := hex.DecodeString("7b22706172656e7448617368223a22307830343164356134633066646364653330343338303733376265616265316666303035396138333637386539636361323034643632313531623833616138323233222c2273686133556e636c6573223a22307831646363346465386465633735643761616238356235363762366363643431616433313234353162393438613734313366306131343266643430643439333437222c226d696e6572223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c227374617465526f6f74223a22307835343430666238313038633566326530373265376362643032316666633036303936393930666236346331346234356266376535663361633132356537623137222c227472616e73616374696f6e73526f6f74223a22307839306634306435646161663238663931336632356530653835383239313731333661393032316231303739373939656464333462616336373631643934373739222c227265636569707473526f6f74223a22307836336237666335346232623366666466356631353638633562373165343062313030636332393438333961383730356561353435636334356436333735306330222c226c6f6773426c6f6f6d223a2230783765366461373265353730323164356534326139366564326236633734363837386463613333613961353739303036636261363939396434663838633264643039383931396539383237343961346333353639646231373965303531396665393265393864663063353735663930336336613362383531366462336330303333313936343732383561393333656133383931373335633962393437613363623662646261343732653866663638353333646264373766663865326331336138323534356334336261333238376535306366393837396531323032383162663563646337393163353130363165366637353835613637303730623435333234616334333364663335316462316430323533313765633265326135383836353562643462313362666366376131643933306332343039346364356539373432636432623363326635353337396537363138333436363835626163336232646137646636666534383338316638393031616465616335316133323861363466343134653964636436366533306431303265643339316231373537653930393735653564653937323437393431343737613531376661333038626162623437383739303836386439313466393365623464346339326365663833356136646331313331366266393163323735343965646435653931636334333536346334393033653065222c22646966666963756c7479223a2230783130222c226e756d626572223a22307831303731366665222c226761734c696d6974223a22307831333132643030222c2267617355736564223a22307831333036626362222c2274696d657374616d70223a2230783630666365376338222c22657874726144617461223a2230786437383330313061303338333632366637323838363736663331326533313335326533353835366336393665373537383030303030303030303030303030303064333963626338393363303932636539656132613032333136306164323033346636633336653765376466656463343061663263313835306638656635666235356461366233323734326430323138303831346464366534633333353734336566653333653935353037383836376131353935353031303837336435346162363030222c226d697848617368223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c226e6f6e6365223a22307830303030303030303030303030303030222c2262617365466565506572476173223a6e756c6c2c2268617368223a22307864353664356365623135343932373430613939383938663061346231656631653863636133653638373862656337623865623864376662393063626162386235227d") - var header ethTypes.Header - err = json.Unmarshal(headBytes, &header) - if err != nil { - t.Fatal("header json.Unmarshal fail", err) - } - genesis := polygon.HeaderWithOptionalSnap{ - Header: header, - Snapshot: &snap17241854, - } - - borGenesisHeaderBytes, _ := json.Marshal(genesis) - param := new(scom.SyncGenesisHeaderParam) - param.ChainID = borChainID - param.GenesisHeader = borGenesisHeaderBytes - - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncGenesisHeader, param) - assert.Nil(t, err) - - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncGenesisHeader]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(scom.ABI, scom.MethodSyncGenesisHeader, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - } - - { - // block 17241855 - headBytes, _ := hex.DecodeString("7b22706172656e7448617368223a22307864353664356365623135343932373430613939383938663061346231656631653863636133653638373862656337623865623864376662393063626162386235222c2273686133556e636c6573223a22307831646363346465386465633735643761616238356235363762366363643431616433313234353162393438613734313366306131343266643430643439333437222c226d696e6572223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c227374617465526f6f74223a22307832346338316261393435343565666632633031626632663162333963663935323131616339366636316230323130313933613261396436623831366239383162222c227472616e73616374696f6e73526f6f74223a22307830303131393964343636316264623266383535323134333534353465663838303162623135336236363866666534356662396564633362383232363163323032222c227265636569707473526f6f74223a22307832386530396537313737633732353630353464636433303633623835663963653639626661313237636563303639653032316236616138356631393163653961222c226c6f6773426c6f6f6d223a2230783332326465323638366435303465376636366437313637353839373034313066656538396531636138653464313161396461656235613630613963653466313238316464373333613536393031343933353733353230663961383439333138313539396464663561353831323931366336623565633935323732373530346133353563383330303638613339353861666263663965643166633432663166663164663636616336623266626461353934663834663364316539326431336263323733356335326137623263316133383235396564663831333434346638653535353566323364613939653061623635313833373864636430646664396231613035363831636637393966326531653737353538343139383964636330326361376161353362636466666436636330306335303731346535666365353861343538666264363336303733303833363930323661633065353863336432663764383735366361613438383334323735646439663938363831613839643033373535646439386332343937346535336230643630353931303137386161356239653963646537653433333864643666646564656631393939316336393031316539326630306437376366336130313566663339363830396136326565643530316265363932336165613262633963396565666636393032313465303662313137633465222c22646966666963756c7479223a2230783130222c226e756d626572223a22307831303731366666222c226761734c696d6974223a22307831333132643030222c2267617355736564223a22307831333062373766222c2274696d657374616d70223a2230783630666365376363222c22657874726144617461223a2230786437383330313061303338333632366637323838363736663331326533313335326533353835366336393665373537383030303030303030303030303030303031306164323761393663646266666339306162336238336266363935393131343236613639663565303030303030303030303030303030303030303030303030303030303030303030303030303030343163613937313936336264623462613262663333376339303636303637346163666635626562336630303030303030303030303030303030303030303030303030303030303030303030303030303034346638353666373966353435393261343863386131613166616661316230613361633035336639393030303030303030303030303030303030303030303030303030303030303030303030303030303235393733393138323735633031663530353535643434653932633964396233353363616461643534303030303030303030303030303030303030303030303030303030303030303030303030303030313562313036663439663330363230613037623466626463656262316530386237303439396338353130303030303030303030303030303030303030303030303030303030303030303030303030303031356531663834633766376431396138643664393138616432623566373134613665356431633535323030303030303030303030303030303030303030303030303030303030303030303030303030303137623530303061663861623639666435396562306434663537363262666635376339633034333835303030303030303030303030303030303030303030303030303030303030303030303030303030663763373337393533316232616565383265346361303664343137356431336239636265616664343930303030303030303030303030303030303030303030303030303030303030303030303030303032623739666164346361393831343732343432663533643136333635666466303330356666643865393030303030303030303030303030303030303030303030303030303030303030303030303030303962633630343466346131363838643862383539366139663764343635396530393938356565626536303030303030303030303030303030303030303030303030303030303030303030303030303030316264626434333437623038326439643662646632646134353535613337636535326132653231323030303030303030303030303030303030303030303030303030303030303030303030303030303031646462383333623965306533663266353231343830653762636233653637366530373337303437643030303030303030303030303030303030303030303030303030303030303030303030303030303565346364346333303262656664646633643534343330313336396165336564313438313635326664303030303030303030303030303030303030303030303030303030303030303030303030303030316537376262666438656436353732306631383765666464313039653338643735656163613733383530303030303030303030303030303030303030303030303030303030303030303030303030303031653765326362386338316331306666313931613733666532363637383863396365363265633735343030303030303030303030303030303030303030303030303030303030303030303030303030303262386662373064313036666634636230373236643662373365666535336361656438626230396163353765656665386465313664376433306664396331313535353538666364303461623139663330643961656235663161373733313132623833383531353733306432363034356439333662333637373630333832393838383030222c226d697848617368223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c226e6f6e6365223a22307830303030303030303030303030303030222c2262617365466565506572476173223a6e756c6c2c2268617368223a22307866393834303162623036636436313035306566353835393263306435643036393461383561646632656362326437623666376465633430363535326536353830227d") - var header ethTypes.Header - err = json.Unmarshal(headBytes, &header) - if err != nil { - t.Fatal("header json.Unmarshal fail", err) - } - headerWOP := polygon.HeaderWithOptionalProof{Header: header} - n1Bytes, _ := json.Marshal(headerWOP) - - // block 17241856 - headBytes, _ = hex.DecodeString("7b22706172656e7448617368223a22307866393834303162623036636436313035306566353835393263306435643036393461383561646632656362326437623666376465633430363535326536353830222c2273686133556e636c6573223a22307831646363346465386465633735643761616238356235363762366363643431616433313234353162393438613734313366306131343266643430643439333437222c226d696e6572223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c227374617465526f6f74223a22307864633162393138663933633531616334323263613264323034336161653865396364396534633461663635333834343335356634666631623738656361616332222c227472616e73616374696f6e73526f6f74223a22307831316166333038313635376166303233303763633466373164626532333439663833343436303463613931376465326463336132383464623832663963363431222c227265636569707473526f6f74223a22307838633233383461326533343365343963643937313066623634656530656135616562323435323537663061326264336631633330613665656130623736313439222c226c6f6773426c6f6f6d223a2230786137363966373133626631303130303364373238643364386535633530633832363432623033353363643163363333306534383363313137643164663362633461633061376465643030343238656264316330323136316430396630363131626566623464323234666664373636303836636231303535643232333630313965666239396135633931363866373831353061323062383339623133383232613164393833353532333731646532653134643336333237663165366339326134336463663035373831303234626330323336646131333738643331383362666435643861656435383139646338653431376131616664656430666433393864383363353937386231363138316332303032343139633139323837363130663430343539373330636239346133393061316335366538326164633334613339616239656139303964656233303261343362613462383836356435316337363532393135326530323063306630353234666435343632613931303961383431623263353334636264373032356631303839313630303039303031663766353331303662363534303431306338666336623562653738353863393636613938356537613634356431393665366433303035343035663066653064383735316431346230323832346131303433633065303730343130326430373132343438333839613862222c22646966666963756c7479223a22307866222c226e756d626572223a22307831303731373030222c226761734c696d6974223a22307831333132643030222c2267617355736564223a22307831333131616166222c2274696d657374616d70223a2230783630666365376432222c22657874726144617461223a2230786437383330313061303338333632366637323838363736663331326533313335326533353835366336393665373537383030303030303030303030303030303038653962333637376533623339323233336335643832323234393466656163656536613766643738353964393839313736396262623330386564333564343037353838333631333634303063653736366261313032326334356433323462306637303733343337363961323938353735333861313838633565383639376533613030222c226d697848617368223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c226e6f6e6365223a22307830303030303030303030303030303030222c2262617365466565506572476173223a6e756c6c2c2268617368223a22307831326266643132376665316566663330376130653630346566306332613335383863323733383535633931333130646238343165313236373362323030623634227d") - err = json.Unmarshal(headBytes, &header) - if err != nil { - t.Fatal("header json.Unmarshal fail", err) - } - headerWOP = polygon.HeaderWithOptionalProof{Header: header} - n2Bytes, _ := json.Marshal(headerWOP) - - param := new(scom.SyncBlockHeaderParam) - param.ChainID = borChainID - param.Address = caller - param.Headers = append(param.Headers, n1Bytes, n2Bytes) - - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncBlockHeader, param) - assert.Nil(t, err) - - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncBlockHeader]+extra, nil) - polygon.SkipVerifySpan = true - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - polygon.SkipVerifySpan = false - assert.Nil(t, err) - - result, err := utils.PackOutputs(scom.ABI, scom.MethodSyncBlockHeader, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - - } - - { - // check snapshot for block 17241855 - cheight, err := polygon.GetCanonicalHeight(contract, borChainID) - if err != nil { - t.Fatal("SyncBlockHeader fail", err) - } - cheader, err := polygon.GetCanonicalHeader(contract, borChainID, cheight) - if err != nil { - t.Fatal("SyncBlockHeader fail", err) - } - if cheader == nil { - t.Fatal("SyncBlockHeader fail:empty header") - } - headerSnap := cheader.HeaderWithOptionalSnap.Snapshot - if headerSnap == nil { - t.Fatal("SyncBlockHeader fail:empty snap") - } - - var snap17241855 polygon.Snapshot - snapBytes, _ := hex.DecodeString("7b226e756d626572223a31373234313835352c2268617368223a22307866393834303162623036636436313035306566353835393263306435643036393461383561646632656362326437623666376465633430363535326536353830222c2276616c696461746f72536574223a7b2276616c696461746f7273223a5b7b224944223a302c227369676e6572223a22307831306164323761393663646266666339306162336238336266363935393131343236613639663565222c22706f776572223a342c22616363756d223a2d33327d2c7b224944223a302c227369676e6572223a22307831636139373139363362646234626132626633333763393036363036373461636666356265623366222c22706f776572223a342c22616363756d223a367d2c7b224944223a302c227369676e6572223a22307834663835366637396635343539326134386338613161316661666131623061336163303533663939222c22706f776572223a322c22616363756d223a35327d2c7b224944223a302c227369676e6572223a22307835393733393138323735633031663530353535643434653932633964396233353363616461643534222c22706f776572223a312c22616363756d223a2d33357d2c7b224944223a302c227369676e6572223a22307835623130366634396633303632306130376234666264636562623165303862373034393963383531222c22706f776572223a312c22616363756d223a2d33357d2c7b224944223a302c227369676e6572223a22307835653166383463376637643139613864366439313861643262356637313461366535643163353532222c22706f776572223a312c22616363756d223a2d33357d2c7b224944223a302c227369676e6572223a22307837623530303061663861623639666435396562306434663537363262666635376339633034333835222c22706f776572223a31352c22616363756d223a34367d2c7b224944223a302c227369676e6572223a22307837633733373935333162326165653832653463613036643431373564313362396362656166643439222c22706f776572223a322c22616363756d223a347d2c7b224944223a302c227369676e6572223a22307862373966616434636139383134373234343266353364313633363566646630333035666664386539222c22706f776572223a392c22616363756d223a34367d2c7b224944223a302c227369676e6572223a22307862633630343466346131363838643862383539366139663764343635396530393938356565626536222c22706f776572223a312c22616363756d223a35317d2c7b224944223a302c227369676e6572223a22307862646264343334376230383264396436626466326461343535356133376365353261326532313230222c22706f776572223a312c22616363756d223a2d33357d2c7b224944223a302c227369676e6572223a22307864646238333362396530653366326635323134383065376263623365363736653037333730343764222c22706f776572223a352c22616363756d223a33387d2c7b224944223a302c227369676e6572223a22307865346364346333303262656664646633643534343330313336396165336564313438313635326664222c22706f776572223a312c22616363756d223a2d33357d2c7b224944223a302c227369676e6572223a22307865373762626664386564363537323066313837656664643130396533386437356561636137333835222c22706f776572223a312c22616363756d223a2d33357d2c7b224944223a302c227369676e6572223a22307865376532636238633831633130666631393161373366653236363738386339636536326563373534222c22706f776572223a322c22616363756d223a347d5d2c2270726f706f736572223a7b224944223a302c227369676e6572223a22307837633733373935333162326165653832653463613036643431373564313362396362656166643439222c22706f776572223a322c22616363756d223a347d7d2c22726563656e7473223a7b223137323431373932223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431373933223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431373934223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431373935223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431373936223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431373937223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431373938223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431373939223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383030223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383031223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383032223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383033223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383034223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383035223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383036223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383037223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383038223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383039223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383130223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383131223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383132223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383133223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383134223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383135223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383136223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383137223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383138223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383139223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383230223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383231223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383232223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383233223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383234223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383235223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383236223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383237223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383238223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383239223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383330223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383331223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383332223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383333223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383334223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383335223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383336223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383337223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383338223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383339223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383430223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383431223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383432223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383433223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383434223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383435223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383436223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383437223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383438223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383439223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383530223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383531223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383532223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383533223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383534223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839222c223137323431383535223a22307834316435623365326563353335383362633036303164666234663261313161333932303439343839227d7d") - err = json.Unmarshal(snapBytes, &snap17241855) - if err != nil { - t.Fatal("snap17241855 json.Unmarshal fail", err) - } - if !headerSnap.Equal(&snap17241855) { - t.Fatal("SyncBlockHeader fail:snap not expected") - } - } -} diff --git a/contracts/native/header_sync/test/quorum_test.go b/contracts/native/header_sync/test/quorum_test.go deleted file mode 100644 index c12bc3cd..00000000 --- a/contracts/native/header_sync/test/quorum_test.go +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2021 The Zion Authors - * This file is part of The Zion library. - * - * The Zion is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Zion is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with The Zion. If not, see . - */ -package test - -import ( - "encoding/hex" - "fmt" - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/contracts/native" - scom "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/header_sync/quorum" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/crypto" - "github.com/stretchr/testify/assert" -) - -var ( - gh = "7b22706172656e7448617368223a22307834623032653838303537336565366165383632623330303638323033366337663363626434323633323666643431643965326566393739633737333637346138222c2273686133556e636c6573223a22307831646363346465386465633735643761616238356235363762366363643431616433313234353162393438613734313366306131343266643430643439333437222c226d696e6572223a22307863313931663630653765333633336634366430313535373530386563383137633461376337323462222c227374617465526f6f74223a22307863316539373733383964613465386637356466343930393232353332343231616439336136623862303439346531376339353136343435656466303561643332222c227472616e73616374696f6e73526f6f74223a22307862363138613633643064346437356261353766303762346233326433323462666661633962303132613133323263613661653738646366363937373335306438222c227265636569707473526f6f74223a22307865376364653339376639326531333339303834646136616338383038626231663537333233623764666163356139356537306130663037316639396534376238222c226c6f6773426c6f6f6d223a2230783030303030303030303030303030303030303030303030303032303030303030303030303030313030323030303030303030303030303030303030303030303030303030303030303030303030303830303030303030303030303030303030303030303030303030303030303030303030303030303038303030303030303030303030303230303030303030313030303030303030303030303030303030303830303030303030303130303830303030303030303030303030303030303030303030303130303030303030303030313030303030383030303030303030303030303030303031303430303030323030303034303030303030303030303030303838303030303030303030303030313030303030303030303030303030303430303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030313030303030303030303030303030303030303030303030303030303030303030303030303230303030303030303030303030303030303030303030303030303030303031303030303030303032303030303030303031303830303030303030303030303030303030303034303030303030303030303030303030303034303030303030303032303030303030303030303030303030222c22646966666963756c7479223a22307831222c226e756d626572223a22307831336662222c226761734c696d6974223a2230783430336566353336222c2267617355736564223a22307830222c2274696d657374616d70223a2230783566653262626539222c22657874726144617461223a22307864393833303130393037383436373635373436383838363736663331326533313335326533333836363436313732373736393665303030303030303030303030663930323832663861383934303366663662656236356665623564613837636131623534363862336539356461373637323535653934323538616634386532386534613638343665393331646466663865316364663835373938323165353934366137303834353563383737373633306161633964316537373032643133663761383635623237633934386330396439333661316234303864366530616661613533376261346530366334353034613061653934616433626635656436343063633732663337626432316436346136356333633735366539633838633934626662353538663064636562303766626230396531633238333034386235353161343331303932313934633039353434383432346135656364356361376363646164666161643132376139643765383865633934643437613465353665393236323534336462333964393230336366316132653533373335663833346238343139613963343938633639333962623935316161646261613531393930663333303635333963346465393965323439373232626339616134383635313634333234366563363966303633636530373465623266653830356239373362646539316463306130386635393538393763376133333737646531386337393562616635353031663930313932623834316530303131623462303434343363333735366337356234336535383837613830613432303166373962306262303832643239363835316236383363623037313835653738646531396362636139616636396466373335373462653030646466643466626339366137353164333164663130396565636339316130363232313861303162383431323433346261313539333134333934303464393737336534366666303537396332323835663762313233663364643638316137646535346463353165626633363735656531633431633030633739386535626238633037366335376333343732653837393839623635303734663966316439663534386661613335643262366530316238343136326461366163663866313230333237306164613535373536343335373035623865633437386335393531383161346132323230323935663437663334636563303364346364326262613135636639353363313731303938313238633439306534326639633834323139323364323232393233306532646337323566383562653030623834313138363263343137633236326161626663373631643334643866636361646165383335386662333437643837633732336331313932623061633631306134383535623138623235653033383663656530306361396431313766323964383863313864656233393535653863313832393865666536663061393962626335663865303062383431353332306233363865376135346163643635383638343338643937636234313865626135666536313536363566653438326238383238356439656466613766323231366534386563623063313332323935353831336435613737616163363533383331656162373335386336323435376566346134666432343164383035346630306238343164326136353936383562326134343136633930353733653563306638656539303562623738316237326436316634353864613366383664663030306130343131343065386361316239356466376538383761306530616639623835643466616235363563316632623831323730303764613235386636623937393435633138613030222c226d697848617368223a22307836333734363936333631366332303632373937613631366537343639366536353230363636313735366337343230373436663663363537323631366536333635222c226e6f6e6365223a22307866666666666666666666666666666666222c2268617368223a22307838623539396139376439303336643633343063323161643730616161333838323539313034323937653666306238623534306537376234383837303835396461227d" - h1 = "7b22706172656e7448617368223a22307838623539396139376439303336643633343063323161643730616161333838323539313034323937653666306238623534306537376234383837303835396461222c2273686133556e636c6573223a22307831646363346465386465633735643761616238356235363762366363643431616433313234353162393438613734313366306131343266643430643439333437222c226d696e6572223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c227374617465526f6f74223a22307838653539346466323834363764346631663163643034643534613030346535636233313962653539363862666635643432386262383531346334313333396238222c227472616e73616374696f6e73526f6f74223a22307836613963333365653165323562363766313437373536626331613939643435666365373531363562376666323135643933336561653330393564633862363263222c227265636569707473526f6f74223a22307862363434303864613662386665333961623736346166383865636531653863636131633335666439383864623537383036653939313338633632393336356130222c226c6f6773426c6f6f6d223a2230783030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c22646966666963756c7479223a22307831222c226e756d626572223a22307831336663222c226761734c696d6974223a2230783430336166313438222c2267617355736564223a22307830222c2274696d657374616d70223a2230783566653262626565222c22657874726144617461223a22307864393833303130393037383436373635373436383838363736663331326533313335326533333836363436313732373736393665303030303030303030303030663930323937663862643934303366663662656236356665623564613837636131623534363862336539356461373637323535653934323538616634386532386534613638343665393331646466663865316364663835373938323165353934366137303834353563383737373633306161633964316537373032643133663761383635623237633934386330396439333661316234303864366530616661613533376261346530366334353034613061653934616433626635656436343063633732663337626432316436346136356333633735366539633838633934626662353538663064636562303766626230396531633238333034386235353161343331303932313934633039353434383432346135656364356361376363646164666161643132376139643765383865633934633139316636306537653336333366343664303135353735303865633831376334613763373234623934643437613465353665393236323534336462333964393230336366316132653533373335663833346238343165363131313835376130383833313038353062633063383139633632373030383436363336666664616638323034326238306530303738663266623735333234323063373166383933386130643465383164333539383736313965393265393064313634336465616365646533623464616563356536343839613161613135333031663930313932623834316266663662366161306361643738336534396336323763316365333264366336643064393937653763353430646239323766666435306233653364653163333434666132333964353434663338393239303463623764396631363565616239653561633633336432363161613238396631393639333964376361653938643161303062383431373135333539626565323232346666373764316538663433306362303566343965643631643164303364633163313464643161396166653462316132383262383539383936613561333463363934613965653562653439656535303832363334636238346334643438663963653039643763396366333662363738313932323730316238343136653430643766326463633264616433623636373338333130326635356163383032353731313563373162623533316564643334363865363034313763613332343437656661306565613437336531623236363135653237666230323037343739306264343863613838323665316661653863353764306533663235333937373031623834313862383230366631306530333638663431666264353731306531383235643137306339653465333761353861303164336335353331653435313732633135663631653435636335656562383030346262623962363966393436383631623861636265623434323065366631666334636533356530396565346136643637613139303162383431383935316266313632656630306534353465313933313665643261613537373035386536653366643632643964613965626432663861303939343235613930613464393034333566633837666562383665616662353330626434393162666462636137623332393434343037396431666235663239653561626262343936326630316238343130303836386337366262346332643138353932333838613566663763623965303262393031343961306235303739663631393562613134633730366435313531303462326161393237393834613662346163303738333833663137616639373761313965623932663562363666613762353465353636643961343030316638613031222c226d697848617368223a22307836333734363936333631366332303632373937613631366537343639366536353230363636313735366337343230373436663663363537323631366536333635222c226e6f6e6365223a22307830303030303030303030303030303030222c2268617368223a22307831626137396532353231313833616532633135633364326563336436623366656137633438613337333232326135623164386530663664386564363737343231227d" - h2 = "7b22706172656e7448617368223a22307833346333633638323238366364653563346133313565623731643337656534383536343937363763333535333164663264636234363134386636383130386365222c2273686133556e636c6573223a22307831646363346465386465633735643761616238356235363762366363643431616433313234353162393438613734313366306131343266643430643439333437222c226d696e6572223a22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c227374617465526f6f74223a22307835653436613162636162653138363633613638303533656363633733393132313339396233393931613061313335613065363531373236333933656435333135222c227472616e73616374696f6e73526f6f74223a22307863356230623838363638313063323665303665623838343435643866643733646537346637643434353139393461653237376434343631303766306166356533222c227265636569707473526f6f74223a22307862363434303864613662386665333961623736346166383865636531653863636131633335666439383864623537383036653939313338633632393336356130222c226c6f6773426c6f6f6d223a2230783030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c22646966666963756c7479223a22307831222c226e756d626572223a22307831343161222c226761734c696d6974223a2230783366633265666434222c2267617355736564223a22307830222c2274696d657374616d70223a2230783566653262633834222c22657874726144617461223a22307864393833303130393037383436373635373436383838363736663331326533313335326533333836363436313732373736393665303030303030303030303030663930323832663861383934303366663662656236356665623564613837636131623534363862336539356461373637323535653934323538616634386532386534613638343665393331646466663865316364663835373938323165353934366137303834353563383737373633306161633964316537373032643133663761383635623237633934386330396439333661316234303864366530616661613533376261346530366334353034613061653934616433626635656436343063633732663337626432316436346136356333633735366539633838633934626662353538663064636562303766626230396531633238333034386235353161343331303932313934633039353434383432346135656364356361376363646164666161643132376139643765383865633934643437613465353665393236323534336462333964393230336366316132653533373335663833346238343135376165653833313331623663366335653438396661393761396432666135353763386232613132633963613563313238636432613166313963336465373631366431646138646632616366396438663161383436363932656364623533366363653765306432626162383335656662626434643865356335653433353239353031663930313932623834316537373930643537663735633562623137356663396333333366353630646230373861626335633238316236316238323630653330666365313263383865353531653637653531393633386362613462636366623664383065323462616538353836663237353761393936353131386161376530373131306130633231373563303062383431333333393134623030383533643833656166383139313839336232333239643837643639363862363633393232303965613338626539623831316161393232363433316364636132623766663563383938646165303335333233613237353834336539356332356431366538353437653430656266326136363265323736623030316238343131613563666333353735333435646463343533643363633834366665666234363538623333343136353464616166633233313232646365346535643963656237346432636165316363386239326339393166643534353563613436663864313339373530363433663436623134353234336365386530363864323833613365383031623834316632346236626162383566383266356565326331373962366461363031326335663566333637646430313531636235646138386333353235363931343938396636373433396535613339653732656262643435363163653331396161626364353737373731616239646364643435643661666337393262383535313165313531303162383431373936656462633061636237646236323637666465383536313866306435303936346431376630363832333964383362653930613936623661623436306139613338326662326433393938613437396532653839313739373762333838346531323262313638386530646639356561383566646133356335333335393036653430316238343137613664383364383731376131626139633363626566316132333666623965323237343730336231366333366564623439343638353736366639343664363063306130313766363939646461306130616433303263376138646337326633656332333461623638636635613165663866393533653635323630353935326661663030222c226d697848617368223a22307836333734363936333631366332303632373937613631366537343639366536353230363636313735366337343230373436663663363537323631366536333635222c226e6f6e6365223a22307830303030303030303030303030303030222c2268617368223a22307832643031336334633036343766653831303838343031316664656365633830633135383761646433636166383831396263613065316537363534323762646130227d" -) - -func TestQuorumHandler_SyncGenesisHeader(t *testing.T) { - raw, err := hex.DecodeString(gh) - if err != nil { - t.Fatal(err) - } - param := &scom.SyncGenesisHeaderParam{ - ChainID: quorumChainID, - GenesisHeader: raw, - } - - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncGenesisHeader, param) - assert.Nil(t, err) - - caller := crypto.PubkeyToAddress(*acct) - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncGenesisHeader]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(scom.ABI, scom.MethodSyncGenesisHeader, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - - contract := native.NewNativeContract(sdb, contractRef) - pvs, err := quorum.GetValSet(contract, quorumChainID) - if err != nil { - t.Fatal(err) - } - - fmt.Println(pvs) -} - -func TestQuorumHandler_SyncBlockHeader(t *testing.T) { - raw, err := hex.DecodeString(gh) - if err != nil { - t.Fatal(err) - } - param := &scom.SyncGenesisHeaderParam{ - ChainID: quorumChainID, - GenesisHeader: raw, - } - - input, err := utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncGenesisHeader, param) - assert.Nil(t, err) - - caller := crypto.PubkeyToAddress(*acct) - blockNumber := big.NewInt(1) - extra := uint64(10) - contractRef := native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncGenesisHeader]+extra, nil) - ret, leftOverGas, err := contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - - assert.Nil(t, err) - - result, err := utils.PackOutputs(scom.ABI, scom.MethodSyncGenesisHeader, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - - contract := native.NewNativeContract(sdb, contractRef) - - pvs, err := quorum.GetValSet(contract, quorumChainID) - if err != nil { - t.Fatal(err) - } - fmt.Println(pvs) - - { - raw, err = hex.DecodeString(h1) - if err != nil { - t.Fatal(err) - } - p1 := &scom.SyncBlockHeaderParam{ - ChainID: quorumChainID, - Address: caller, - Headers: [][]byte{ - raw, - }, - } - input, err = utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncBlockHeader, p1) - assert.Nil(t, err) - - contractRef = native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncBlockHeader]+extra, nil) - ret, leftOverGas, err = contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - - assert.Nil(t, err) - - result, err = utils.PackOutputs(scom.ABI, scom.MethodSyncBlockHeader, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - - pvs, err = quorum.GetValSet(contract, quorumChainID) - if err != nil { - t.Fatal(err) - } - fmt.Println(pvs) - } - - { - raw, err = hex.DecodeString(h2) - if err != nil { - t.Fatal(err) - } - p2 := &scom.SyncBlockHeaderParam{ - ChainID: quorumChainID, - Address: caller, - Headers: [][]byte{ - raw, - }, - } - - input, err = utils.PackMethodWithStruct(scom.ABI, scom.MethodSyncBlockHeader, p2) - assert.Nil(t, err) - - contractRef = native.NewContractRef(sdb, caller, caller, blockNumber, common.Hash{}, scom.GasTable[scom.MethodSyncBlockHeader]+extra, nil) - ret, leftOverGas, err = contractRef.NativeCall(caller, utils.HeaderSyncContractAddress, input) - - assert.Nil(t, err) - - result, err = utils.PackOutputs(scom.ABI, scom.MethodSyncBlockHeader, true) - assert.Nil(t, err) - assert.Equal(t, ret, result) - assert.Equal(t, leftOverGas, extra) - - pvs, err = quorum.GetValSet(contract, quorumChainID) - if err != nil { - t.Fatal(err) - } - fmt.Println(pvs) - } - -} diff --git a/contracts/native/header_sync/zilliqa/header_sync.go b/contracts/native/header_sync/zilliqa/header_sync.go deleted file mode 100644 index e9f96632..00000000 --- a/contracts/native/header_sync/zilliqa/header_sync.go +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ - -package zilliqa - -import ( - "encoding/json" - "fmt" - "github.com/Zilliqa/gozilliqa-sdk/core" - "github.com/Zilliqa/gozilliqa-sdk/util" - verifier2 "github.com/Zilliqa/gozilliqa-sdk/verifier" - "github.com/ethereum/go-ethereum/contracts/native" - "github.com/ethereum/go-ethereum/contracts/native/governance/node_manager" - "github.com/ethereum/go-ethereum/contracts/native/governance/side_chain_manager" - scom "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/utils" - "github.com/ethereum/go-ethereum/log" -) - -// Handler ... -type Handler struct { -} - -// NewHandler ... -func NewHandler() *Handler { - return &Handler{} -} - -// SyncGenesisHeader ... -func (h *Handler) SyncGenesisHeader(native *native.NativeContract) (err error) { - ctx := native.ContractRef().CurrentContext() - params := &scom.SyncGenesisHeaderParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodSyncGenesisHeader, params, ctx.Payload); err != nil { - return fmt.Errorf("SyncGenesisHeader, contract params deserialize error: %v", err) - } - - // Get current epoch operator - ok, err := node_manager.CheckConsensusSigns(native, scom.MethodSyncGenesisHeader, ctx.Payload, native.ContractRef().MsgSender()) - if err != nil { - return fmt.Errorf("SyncGenesisHeader, CheckConsensusSigns error: %v", err) - } - if !ok { - return nil - } - - txBlockAndDsComm, err := getGenesisHeader(native) - if err != nil { - return fmt.Errorf("ZILHandler SyncGenesisHeader: %s", err) - } - - headerStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, []byte(scom.GENESIS_HEADER), utils.GetUint64Bytes(params.ChainID))) - if err != nil { - return fmt.Errorf("ZILHandler GetHeaderByHeight, get blockHashStore error: %v", err) - } - if headerStore != nil { - return fmt.Errorf("ZILHandler GetHeaderByHeight, genesis header had been initialized") - } - err = putGenesisBlockHeader(native, txBlockAndDsComm, params.ChainID) - if err != nil { - return fmt.Errorf("ZILHandler SyncGenesisHeader, put blockHeader error: %v", err) - } - - return -} - -// SyncBlockHeader ... -func (h *Handler) SyncBlockHeader(native *native.NativeContract) error { - headerParams := &scom.SyncBlockHeaderParam{} - { - ctx := native.ContractRef().CurrentContext() - if err := utils.UnpackMethod(scom.ABI, scom.MethodSyncBlockHeader, headerParams, ctx.Payload); err != nil { - return err - } - } - - side, err := side_chain_manager.GetSideChainApply(native, headerParams.ChainID) - if err != nil { - return fmt.Errorf("zil Handler SyncBlockHeader, GetSideChain error: %v", err) - } - - var extraInfo ExtraInfo - err = json.Unmarshal(side.ExtraInfo, &extraInfo) - if err != nil { - return fmt.Errorf("zil Handler SyncBlockHeader, ExtraInfo Unmarshal error: %v", err) - } - - verifier := &verifier2.Verifier{ - NumOfDsGuard: extraInfo.NumOfGuardList, - } - - // ...txblock1-1,txblock1-2...dsblock2,txblock2-1,txblock2-2... - for _, v := range headerParams.Headers { - var txBlockAndDsComm core.TxBlockOrDsBlock - err := json.Unmarshal(v, &txBlockAndDsComm) - if err != nil { - return fmt.Errorf("SyncBlockHeader, deserialize header err: %v", err) - } - - txBlock := txBlockAndDsComm.TxBlock - dsBlock := txBlockAndDsComm.DsBlock - - if dsBlock != nil { - // if ds block is not nil, we need to verify itself, then update DsComm list - - // 1. if ds block exist already - blockHash := dsBlock.BlockHash - exist, err := IsHeaderExist(native, blockHash[:], headerParams.ChainID) - if err != nil { - return fmt.Errorf("SyncDsBlockHeader, check header exist err: %v", err) - } - if exist == true { - log.Warnf("SyncDsBlockHeader, header has exist. Header: %s", string(v)) - continue - } - - // 2. check parent block - preHash := util.DecodeHex(dsBlock.PrevDSHash) - _, err = GetDsHeaderByHash(native, preHash[:], headerParams.ChainID) - if err != nil { - return fmt.Errorf("SyncDsBlockHeader, get the parent block failed. parent hash is: %s, Error:%s, header: %s", dsBlock.PrevDSHash, err, string(v)) - } - - // 3. get old ds comm list - dsBlockNum := dsBlock.BlockHeader.BlockNum - dscomm, err := getDsComm(native, dsBlockNum-1, headerParams.ChainID) - if err != nil { - return fmt.Errorf("SyncDsBlockHeader, get dscomm err: %v", err) - } - dsList := dsCommListFromArray(dscomm) - - // 4. verify ds block, generate new ds comm list - newDsList, err2 := verifier.VerifyDsBlock(dsBlock, dsList) - if err2 != nil { - return fmt.Errorf("SyncDsBlockHeader, verify ds block err: %v", err2) - } - - // 5. update ds comm list, put ds block - putDsComm(native, dsBlockNum, dsCommArrayFromList(newDsList), headerParams.ChainID) - err = putDsBlockHeader(native, dsBlock, headerParams.ChainID) - if err != nil { - return fmt.Errorf("SyncDsBlockHeader, put blockHeader failed. Error:%s, header: %s", err, string(v)) - } - } - - if txBlock != nil { - // 1. if tx block exist - blockHash := txBlock.BlockHash - exist, err := IsHeaderExist(native, blockHash[:], headerParams.ChainID) - if err != nil { - return fmt.Errorf("SyncTxBlockHeader, check header exist err: %v", err) - } - if exist == true { - log.Warnf("SyncTxBlockHeader, header has exist. Header: %s", string(v)) - continue - } - - // 2. check parent tx block - preHash := txBlock.BlockHeader.BlockHeaderBase.PrevHash - _, err = GetTxHeaderByHash(native, preHash[:], headerParams.ChainID) - if err != nil { - return fmt.Errorf("SyncTxBlockHeader, get the parent block failed. Error:%s, header: %s", err, string(v)) - } - - // 3. get comm list - dscomm, err := getDsComm(native, txBlock.BlockHeader.DSBlockNum, headerParams.ChainID) - if err != nil { - return fmt.Errorf("SyncTxBlockHeader, get dscomm for tx block err: %s", err.Error()) - } - - // 4. verify tx block and store it - err = verifier.VerifyTxBlock(txBlock, dsCommListFromArray(dscomm)) - if err != nil { - return fmt.Errorf("SyncTxBlockHeader, verify block failed. Error:%s, header: %s", err, string(v)) - } - - err = putTxBlockHeader(native, txBlock, headerParams.ChainID) - if err != nil { - return fmt.Errorf("SyncTxBlockHeader, put blockHeader failed. Error:%s, header: %s", err, string(v)) - } - - // 5. update header of main - AppendHeader2Main(native, txBlock.BlockHeader.BlockNum, txBlock.BlockHash[:], headerParams.ChainID) - } - } - - return nil -} - -// SyncCrossChainMsg ... -func (h *Handler) SyncCrossChainMsg(native *native.NativeContract) error { - return nil -} - -type TxBlockAndDsComm struct { - TxBlock *core.TxBlock - DsBlock *core.DsBlock - DsComm []core.PairOfNode -} - -func getGenesisHeader(native *native.NativeContract) (TxBlockAndDsComm, error) { - ctx := native.ContractRef().CurrentContext() - params := &scom.SyncGenesisHeaderParam{} - if err := utils.UnpackMethod(scom.ABI, scom.MethodSyncGenesisHeader, params, ctx.Payload); err != nil { - return TxBlockAndDsComm{}, fmt.Errorf("SyncGenesisHeader, contract params deserialize error: %v", err) - } - var txBlockAndDsComm TxBlockAndDsComm - err := json.Unmarshal(params.GenesisHeader, &txBlockAndDsComm) - if err != nil { - return TxBlockAndDsComm{}, fmt.Errorf("getGenesisHeader, deserialize header err: %v", err) - } - return txBlockAndDsComm, nil -} - -// ExtraInfo ... -type ExtraInfo struct { - NumOfGuardList int // for zilliqa -} diff --git a/contracts/native/header_sync/zilliqa/utils.go b/contracts/native/header_sync/zilliqa/utils.go deleted file mode 100644 index 304598dd..00000000 --- a/contracts/native/header_sync/zilliqa/utils.go +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2021 The poly network Authors - * This file is part of The poly network library. - * - * The poly network is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The poly network is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License - * along with The poly network . If not, see . - */ - -package zilliqa - -import ( - "container/list" - "encoding/json" - "fmt" - "github.com/Zilliqa/gozilliqa-sdk/core" - "github.com/Zilliqa/gozilliqa-sdk/util" - "github.com/ethereum/go-ethereum/contracts/native" - scom "github.com/ethereum/go-ethereum/contracts/native/header_sync/common" - "github.com/ethereum/go-ethereum/contracts/native/utils" - cstates "github.com/polynetwork/poly/core/states" -) - -const dsCommKey = "dsComm" - -func IsHeaderExist(native *native.NativeContract, hash []byte, chainID uint64) (bool, error) { - headerStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), hash)) - if err != nil { - return false, fmt.Errorf("IsHeaderExist, get blockHashStore error: %v", err) - } - if headerStore == nil { - return false, nil - } else { - return true, nil - } -} - -func GetTxHeaderByHeight(native *native.NativeContract, height, chainID uint64) (*core.TxBlock, error) { - latestHeight, err := GetCurrentTxHeaderHeight(native, chainID) - if err != nil { - return nil, err - } - - if height > latestHeight { - return nil, fmt.Errorf("GetTxHeaderByHeight, height is too big") - } - - headerStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(height))) - - if err != nil { - return nil, fmt.Errorf("GetTxHeaderByHeight, get blockHashStore error: %v", err) - } - - if headerStore == nil { - return nil, fmt.Errorf("GetTxHeaderByHeight, can not find any header records") - } - hashBytes, err := cstates.GetValueFromRawStorageItem(headerStore) - if err != nil { - return nil, fmt.Errorf("GetHeaderByHeight, deserialize headerBytes from raw storage item err:%v", err) - } - return GetTxHeaderByHash(native, hashBytes, chainID) -} - -func GetTxHeaderByHash(native *native.NativeContract, hash []byte, chainID uint64) (*core.TxBlock, error) { - headerStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), hash)) - if err != nil { - return nil, fmt.Errorf("GetTxHeaderByHash, get blockHashStore error: %v", err) - } - if headerStore == nil { - return nil, fmt.Errorf("GetTxHeaderByHash, can not find any header records") - } - storeBytes, err := cstates.GetValueFromRawStorageItem(headerStore) - if err != nil { - return nil, fmt.Errorf("GetTxHeaderByHash, deserialize headerBytes from raw storage item err:%v", err) - } - var txBlock core.TxBlock - if err := json.Unmarshal(storeBytes, &txBlock); err != nil { - return nil, fmt.Errorf("GetTxHeaderByHash, deserialize header error: %v", err) - } - return &txBlock, nil -} - -func GetCurrentTxHeader(native *native.NativeContract, chainId uint64) (*core.TxBlock, error) { - height, err := GetCurrentTxHeaderHeight(native, chainId) - if err != nil { - return nil, err - } - - txBlock, err := GetTxHeaderByHeight(native, height, chainId) - if err != nil { - return nil, err - } - - return txBlock, nil -} - -func AppendHeader2Main(native *native.NativeContract, height uint64, txHash []byte, chainID uint64) error { - contract := utils.HeaderSyncContractAddress - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(height)), - cstates.GenRawStorageItem(txHash)) - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(scom.CURRENT_HEADER_HEIGHT), - utils.GetUint64Bytes(chainID)), cstates.GenRawStorageItem(utils.GetUint64Bytes(height))) - scom.NotifyPutHeader(native, chainID, height, util.EncodeHex(txHash)) - return nil -} - -func GetCurrentTxHeaderHeight(native *native.NativeContract, chainID uint64) (uint64, error) { - heightStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.CURRENT_HEADER_HEIGHT), utils.GetUint64Bytes(chainID))) - - if err != nil { - return 0, fmt.Errorf("GetCurrentTxBlockHeight error: %v", err) - } - - if heightStore == nil { - return 0, fmt.Errorf("GetCurrentTxBlockHeight, heightStore is nil") - } - - heightBytes, err := cstates.GetValueFromRawStorageItem(heightStore) - if err != nil { - return 0, fmt.Errorf("GetCurrentTxBlockHeight, deserialize headerBytes from raw storage item err:%v", err) - } - return utils.GetBytesUint64(heightBytes), nil -} - -func putTxBlockHeader(native *native.NativeContract, txBlock *core.TxBlock, chainID uint64) error { - contract := utils.HeaderSyncContractAddress - storeBytes, _ := json.Marshal(txBlock) - hash := txBlock.BlockHash[:] - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), hash), - cstates.GenRawStorageItem(storeBytes)) - scom.NotifyPutHeader(native, chainID, txBlock.BlockHeader.BlockNum, util.EncodeHex(hash)) - return nil -} - -func GetDsHeaderByHash(native *native.NativeContract, hash []byte, chainID uint64) (*core.DsBlock, error) { - headerStore, err := native.GetCacheDB().Get(utils.ConcatKey(utils.HeaderSyncContractAddress, - []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), hash)) - if err != nil { - return nil, fmt.Errorf("GetDsHeaderByHash, get blockHashStore error: %v", err) - } - if headerStore == nil { - return nil, fmt.Errorf("GetDsHeaderByHash, can not find any header records") - } - storeBytes, err := cstates.GetValueFromRawStorageItem(headerStore) - if err != nil { - return nil, fmt.Errorf("GetDsHeaderByHash, deserialize headerBytes from raw storage item err:%v", err) - } - var dsBlock core.DsBlock - if err := json.Unmarshal(storeBytes, &dsBlock); err != nil { - return nil, fmt.Errorf("GetDsHeaderByHash, deserialize header error: %v", err) - } - return &dsBlock, nil -} - -func putDsBlockHeader(native *native.NativeContract, dsBlock *core.DsBlock, chainID uint64) error { - contract := utils.HeaderSyncContractAddress - storeBytes, _ := json.Marshal(dsBlock) - hash := dsBlock.BlockHash[:] - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), hash), - cstates.GenRawStorageItem(storeBytes)) - scom.NotifyPutHeader(native, chainID, dsBlock.BlockHeader.BlockNum, util.EncodeHex(hash)) - return nil -} - -func putGenesisBlockHeader(native *native.NativeContract, txBlockAndDsComm TxBlockAndDsComm, chainID uint64) error { - blockHash := txBlockAndDsComm.TxBlock.BlockHash[:] - blockNum := txBlockAndDsComm.TxBlock.BlockHeader.BlockNum - dsBlockNum := txBlockAndDsComm.TxBlock.BlockHeader.DSBlockNum - contract := utils.HeaderSyncContractAddress - storeBytes, _ := json.Marshal(&txBlockAndDsComm.TxBlock) - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(scom.GENESIS_HEADER), utils.GetUint64Bytes(chainID)), - cstates.GenRawStorageItem(storeBytes)) - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(scom.HEADER_INDEX), utils.GetUint64Bytes(chainID), blockHash), - cstates.GenRawStorageItem(storeBytes)) - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(scom.MAIN_CHAIN), utils.GetUint64Bytes(chainID), utils.GetUint64Bytes(blockNum)), - cstates.GenRawStorageItem(blockHash)) - native.GetCacheDB().Put(utils.ConcatKey(contract, []byte(scom.CURRENT_HEADER_HEIGHT), - utils.GetUint64Bytes(chainID)), cstates.GenRawStorageItem(utils.GetUint64Bytes(blockNum))) - putDsComm(native, dsBlockNum, txBlockAndDsComm.DsComm, chainID) - putDsBlockHeader(native, txBlockAndDsComm.DsBlock, chainID) - scom.NotifyPutHeader(native, chainID, blockNum, util.EncodeHex(blockHash)) - return nil -} - -func putDsComm(native *native.NativeContract, blockNum uint64, dsComm []core.PairOfNode, chainID uint64) { - contract := utils.HeaderSyncContractAddress - dsbytes, _ := json.Marshal(dsComm) - native.GetCacheDB().Put(utils.ConcatKey(contract, utils.GetUint64Bytes(chainID), []byte(dsCommKey), utils.GetUint64Bytes(blockNum)), cstates.GenRawStorageItem(dsbytes)) - native.GetCacheDB().Delete(utils.ConcatKey(contract, utils.GetUint64Bytes(chainID), []byte(dsCommKey), utils.GetUint64Bytes(blockNum-1))) -} - -func getDsComm(native *native.NativeContract, blockNum uint64, chainID uint64) ([]core.PairOfNode, error) { - contract := utils.HeaderSyncContractAddress - dsbytesStore, err := native.GetCacheDB().Get(utils.ConcatKey(contract, utils.GetUint64Bytes(chainID), []byte(dsCommKey), utils.GetUint64Bytes(blockNum))) - if err != nil { - return nil, err - } - dsbytes, err := cstates.GetValueFromRawStorageItem(dsbytesStore) - if err != nil { - return nil, err - } - var dsComm []core.PairOfNode - err = json.Unmarshal(dsbytes, &dsComm) - if err != nil { - return nil, err - } - - return dsComm, nil -} - -func dsCommListFromArray(dscomm []core.PairOfNode) *list.List { - dsComm := list.New() - for _, ds := range dscomm { - dsComm.PushBack(ds) - } - return dsComm -} - -func dsCommArrayFromList(dscomm *list.List) []core.PairOfNode { - var dsArray []core.PairOfNode - head := dscomm.Front() - for head != nil { - pairOfNode := head.Value.(core.PairOfNode) - dsArray = append(dsArray, pairOfNode) - head = head.Next() - } - return dsArray -} diff --git a/contracts/native/native_client/maasconfig.go b/contracts/native/native_client/maasconfig.go new file mode 100644 index 00000000..cfc92f17 --- /dev/null +++ b/contracts/native/native_client/maasconfig.go @@ -0,0 +1,129 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package native_client + +import ( + "errors" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/contracts/native" + "github.com/ethereum/go-ethereum/contracts/native/governance/maas_config" + "github.com/ethereum/go-ethereum/contracts/native/utils" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/log" +) + +var ErrAccountBlocked = errors.New("account is in blacklist") +var ErrNotGasManager = errors.New("address is not in gas manager or user list") + +func IsBlocked(state *state.StateDB, address *common.Address) bool { + if address == nil { + return false + } + caller := common.EmptyAddress + ref := native.NewContractRef(state, caller, caller, big.NewInt(-1), common.EmptyHash, 0, nil) + + payload, err := (&maas_config.MethodIsBlockedInput{Addr: *address}).Encode() + if err != nil { + log.Error("[PackMethod]", "pack `isBlocked` input failed", err) + return false + } + enc, _, err := ref.NativeCall(caller, utils.MaasConfigContractAddress, payload) + if err != nil { + return false + } + output := new(maas_config.MethodBoolOutput) + if err := output.Decode(enc, maas_config.MethodIsBlocked); err != nil { + log.Error("[native call]", "unpack `IsBlocked` output failed", err) + return false + } + + return output.Success +} + +func IsGasManageEnable(state *state.StateDB) bool { + caller := common.EmptyAddress + ref := native.NewContractRef(state, caller, caller, big.NewInt(-1), common.EmptyHash, 0, nil) + + payload, err := utils.PackMethod(maas_config.ABI, maas_config.MethodIsGasManageEnabled) + if err != nil { + log.Error("[PackMethod]", "pack `IsGasManageEnable` input failed", err) + return false + } + enc, _, err := ref.NativeCall(caller, utils.MaasConfigContractAddress, payload) + if err != nil { + return false + } + output := new(maas_config.MethodBoolOutput) + if err := output.Decode(enc, maas_config.MethodIsGasManageEnabled); err != nil { + log.Error("[native call]", "unpack `IsGasManageEnable` output failed", err) + return false + } + + return output.Success +} + +func IsGasManager(state *state.StateDB, address *common.Address) bool { + if address == nil { + return false + } + caller := common.EmptyAddress + ref := native.NewContractRef(state, caller, caller, big.NewInt(-1), common.EmptyHash, 0, nil) + + payload, err := (&maas_config.MethodIsGasManagerInput{Addr: *address}).Encode() + if err != nil { + log.Error("[PackMethod]", "pack `IsGasManager` input failed", err) + return false + } + enc, _, err := ref.NativeCall(caller, utils.MaasConfigContractAddress, payload) + if err != nil { + return false + } + output := new(maas_config.MethodBoolOutput) + if err := output.Decode(enc, maas_config.MethodIsGasManager); err != nil { + log.Error("[native call]", "unpack `IsGasManager` output failed", err) + return false + } + + return output.Success +} + +func IsGasUser(state *state.StateDB, address *common.Address) bool { + if address == nil { + return false + } + caller := common.EmptyAddress + ref := native.NewContractRef(state, caller, caller, big.NewInt(-1), common.EmptyHash, 0, nil) + + payload, err := (&maas_config.MethodIsGasUserInput{Addr: *address}).Encode() + if err != nil { + log.Error("[PackMethod]", "pack `IsGasUser` input failed", err) + return false + } + enc, _, err := ref.NativeCall(caller, utils.MaasConfigContractAddress, payload) + if err != nil { + return false + } + output := new(maas_config.MethodBoolOutput) + if err := output.Decode(enc, maas_config.MethodIsGasUser); err != nil { + log.Error("[native call]", "unpack `IsGasUser` output failed", err) + return false + } + + return output.Success +} diff --git a/contracts/native/params.go b/contracts/native/params.go index b1cc4f22..6e016c44 100644 --- a/contracts/native/params.go +++ b/contracts/native/params.go @@ -26,16 +26,14 @@ import ( const FailedTxGasUsage = uint64(100) const ( - NativeGovernance = "governance" - NativeSyncHeader = "sync_header" - NativeCrossChain = "cross_chain" - NativeNeo3StateManager = "neo3_state_manager" - NativeNodeManager = "node_manager" - NativeRelayerManager = "relayer_manager" - NativeSideChainManager = "side_chain_manager" + NativeNodeManager = "node_manager" + NativeMaasConfig = "maas_config" // native backup contracts - NativeExtra4 = "extra4" - NativeExtra5 = "extra5" + NativeExtra1 = "extra1" + NativeExtra2 = "extra2" + NativeExtra3 = "extra3" + NativeExtra4 = "extra4" + // NativeExtra5 = "extra5" NativeExtra6 = "extra6" NativeExtra7 = "extra7" NativeExtra8 = "extra8" @@ -44,38 +42,42 @@ const ( NativeExtra11 = "extra11" NativeExtra12 = "extra12" NativeExtra13 = "extra13" - NativeExtra14 = "extra14" + // NativeExtra14 = "extra14" NativeExtra15 = "extra15" NativeExtra16 = "extra16" NativeExtra17 = "extra17" NativeExtra18 = "extra18" NativeExtra19 = "extra19" + NativeExtra20 = "extra20" + NativeExtra21 = "extra21" + NativeExtra22 = "extra22" + NativeExtra23 = "extra23" ) var NativeContractAddrMap = map[string]common.Address{ - NativeGovernance: common.HexToAddress("0x4600691499997fCc224425ba5C93EebC57f3615b"), - NativeSyncHeader: utils.HeaderSyncContractAddress, - NativeCrossChain: utils.CrossChainManagerContractAddress, - NativeNeo3StateManager: utils.Neo3StateManagerContractAddress, - NativeNodeManager: utils.NodeManagerContractAddress, - NativeRelayerManager: utils.RelayerManagerContractAddress, - NativeSideChainManager: utils.SideChainManagerContractAddress, - NativeExtra4: common.HexToAddress("0x7d79D936DA7833c7fe056eB450064f34A327DcA8"), - NativeExtra5: common.HexToAddress("0xD37F626c9E007DdD244E5Cbee0C223fec6D11289"), - NativeExtra6: common.HexToAddress("0x33463b771Da32D450723C7C23a2240dE223b53bd"), - NativeExtra7: common.HexToAddress("0x0F257CD338Fa8F1Af3D31b16C1fBddae2Dc96D41"), - NativeExtra8: common.HexToAddress("0x4479AcbCeA458Badf21dbEC7Db6fC236Bf08fbb9"), - NativeExtra9: common.HexToAddress("0xc204aDF052C52F74863d76c94a311b82D98d87AE"), - NativeExtra10: common.HexToAddress("0xD62B67170A6bb645f1c59601FbC6766940ee12e5"), - NativeExtra11: common.HexToAddress("0xf7EBd79DB6240b9A85571f61b543425e2A7045Fb"), - NativeExtra12: common.HexToAddress("0x20B019ea369923eF1971A30f1974003051f1863C"), - NativeExtra13: common.HexToAddress("0x2951b823F25344797D9294634F44e867490B86c9"), - NativeExtra14: common.HexToAddress("0x370f0dDA62BDc610d8FFE8c71882D27d2a26648f"), - NativeExtra15: common.HexToAddress("0xC782D7244bdd2ebeb56ac87A65c4873B6c4D427D"), - NativeExtra16: common.HexToAddress("0x90dc8B0B8625DD3Fa33eBd5E502D6c908EFB68Fe"), - NativeExtra17: common.HexToAddress("0x40E25A4c3316F54c913542Ad293420cF3c6C2Ff3"), - NativeExtra18: common.HexToAddress("0x5e66f4D53236348334E13F1d5F83b48083a4ADd0"), - NativeExtra19: common.HexToAddress("0x0763E5717f8bD8C710E0d38a21e224D8C560e597"), + NativeExtra1: common.HexToAddress("0x4600691499997fCc224425ba5C93EebC57f3615b"), + NativeExtra2: common.HexToAddress("0xb2799bDE6831449d73C1F22CE815f773D0CafCc5"), + NativeExtra3: common.HexToAddress("0x5747C05FF236F8d18BB21Bc02ecc389deF853cae"), + NativeExtra4: common.HexToAddress("0x5E839898821dB2A2F0eC9F8aAE7D7053744DB051"), + NativeNodeManager: utils.NodeManagerContractAddress, + NativeExtra6: common.HexToAddress("0xA22f301D7Cb5b50dcA4a015b12EC0cc5f3971412"), + NativeExtra7: common.HexToAddress("0x864Ff06eC5fFc75aB6eaf64263308ef5fa7d6637"), + NativeExtra8: common.HexToAddress("0x7d79D936DA7833c7fe056eB450064f34A327DcA8"), + NativeExtra9: common.HexToAddress("0xD37F626c9E007DdD244E5Cbee0C223fec6D11289"), + NativeExtra10: common.HexToAddress("0x33463b771Da32D450723C7C23a2240dE223b53bd"), + NativeExtra11: common.HexToAddress("0x0F257CD338Fa8F1Af3D31b16C1fBddae2Dc96D41"), + NativeExtra12: common.HexToAddress("0x4479AcbCeA458Badf21dbEC7Db6fC236Bf08fbb9"), + NativeExtra13: common.HexToAddress("0xc204aDF052C52F74863d76c94a311b82D98d87AE"), + NativeMaasConfig: utils.MaasConfigContractAddress, + NativeExtra15: common.HexToAddress("0xf7EBd79DB6240b9A85571f61b543425e2A7045Fb"), + NativeExtra16: common.HexToAddress("0x20B019ea369923eF1971A30f1974003051f1863C"), + NativeExtra17: common.HexToAddress("0x2951b823F25344797D9294634F44e867490B86c9"), + NativeExtra18: common.HexToAddress("0x370f0dDA62BDc610d8FFE8c71882D27d2a26648f"), + NativeExtra19: common.HexToAddress("0xC782D7244bdd2ebeb56ac87A65c4873B6c4D427D"), + NativeExtra20: common.HexToAddress("0x90dc8B0B8625DD3Fa33eBd5E502D6c908EFB68Fe"), + NativeExtra21: common.HexToAddress("0x40E25A4c3316F54c913542Ad293420cF3c6C2Ff3"), + NativeExtra22: common.HexToAddress("0x5e66f4D53236348334E13F1d5F83b48083a4ADd0"), + NativeExtra23: common.HexToAddress("0x0763E5717f8bD8C710E0d38a21e224D8C560e597"), } func IsNativeContract(addr common.Address) bool { diff --git a/contracts/native/solidity/maas_config.sol b/contracts/native/solidity/maas_config.sol new file mode 100644 index 00000000..a471138e --- /dev/null +++ b/contracts/native/solidity/maas_config.sol @@ -0,0 +1,32 @@ +pragma solidity >=0.6.0 <0.9.0; + +interface IMaasConfig { + function name() external view returns (string memory); + function changeOwner(address addr) external returns (bool); + function getOwner() external view returns (address); + + function blockAccount(address addr, bool doBlock) external returns (bool); + function isBlocked(address addr) external view returns (bool); + function getBlacklist() external view returns (string memory); + + function enableGasManage(bool doEnable) external returns (bool); + function isGasManageEnabled() external view returns (bool); + function setGasManager(address addr, bool isManager) external returns (bool); + function isGasManager(address addr) external view returns (bool); + function getGasManagerList() external view returns (string memory); + + function setGasUsers(address[] memory addrs, bool addOrRemove) external returns (bool); + function isGasUser(address addr) external view returns (bool); + function getGasUserList() external view returns (string memory); + + function setAdmins(address[] memory addrs, bool addOrRemove) external returns (bool); + function isAdmin(address addr) external view returns (bool); + function getAdminList() external view returns (string memory); + + event ChangeOwner(address indexed oldOwner, address indexed newOwner); + event BlockAccount(address indexed addr, bool doBlock); + event EnableGasManage(bool doEnable); + event SetGasManager(address indexed addr, bool isManager); + event SetGasUsers(address[] addrs, bool addOrRemove); + event SetAdmins(address[] addrs, bool addOrRemove); +} diff --git a/contracts/native/solidity/node_manager.sol b/contracts/native/solidity/node_manager.sol index e6f5a9db..06799aa5 100644 --- a/contracts/native/solidity/node_manager.sol +++ b/contracts/native/solidity/node_manager.sol @@ -9,6 +9,10 @@ interface INodeManager { function getChangingEpoch() external view returns (bytes memory); function getEpochByID(uint64 epochID) external view returns (bytes memory); function proof(uint64 epochID) external view returns (bytes memory); + + function getEpochListJson(uint64 epochID) external view returns (string memory); + function getCurrentEpochJson() external view returns (string memory); + function getChangingEpochJson() external view returns (string memory); event Proposed(bytes epoch); event Voted(uint64 epochID, bytes epochHash, uint64 votedNumber, uint64 groupSize); diff --git a/contracts/native/utils/abi.go b/contracts/native/utils/abi.go index 531b6cb7..ea6b4b05 100644 --- a/contracts/native/utils/abi.go +++ b/contracts/native/utils/abi.go @@ -113,7 +113,17 @@ func PackEvents(ab *abi.ABI, event string, args ...interface{}) ([]byte, error) if !exist { return nil, fmt.Errorf("event '%s' not found", event) } - return evt.Inputs.Pack(args...) + // only pack not indexed args + var arguments abi.Arguments + var notIndexed []interface{} + for i, v := range evt.Inputs { + if !v.Indexed { + arguments = append(arguments, v) + notIndexed = append(notIndexed, args[i]) + } + } + + return arguments.Pack(notIndexed...) } func UnpackEvent(ab abi.ABI, event string, payload []byte) ([]interface{}, error) { diff --git a/contracts/native/utils/params.go b/contracts/native/utils/params.go index e7ef5855..f464c39a 100644 --- a/contracts/native/utils/params.go +++ b/contracts/native/utils/params.go @@ -19,42 +19,12 @@ package utils import "github.com/ethereum/go-ethereum/common" -type BtcNetType int - -const ( - TyTestnet3 BtcNetType = iota - TyRegtest - TySimnet - TyMainnet -) - var ( BYTE_FALSE = []byte{0} BYTE_TRUE = []byte{1} ) var ( - HeaderSyncContractAddress = common.HexToAddress("0xb2799bDE6831449d73C1F22CE815f773D0CafCc5") - CrossChainManagerContractAddress = common.HexToAddress("0x5747C05FF236F8d18BB21Bc02ecc389deF853cae") - SideChainManagerContractAddress = common.HexToAddress("0x864Ff06eC5fFc75aB6eaf64263308ef5fa7d6637") - NodeManagerContractAddress = common.HexToAddress("0xA4Bf827047a08510722B2d62e668a72FCCFa232C") - RelayerManagerContractAddress = common.HexToAddress("0xA22f301D7Cb5b50dcA4a015b12EC0cc5f3971412") - Neo3StateManagerContractAddress = common.HexToAddress("0x5E839898821dB2A2F0eC9F8aAE7D7053744DB051") - - VOTE_ROUTER = uint64(0) - BTC_ROUTER = uint64(1) - ETH_ROUTER = uint64(2) - ONT_ROUTER = uint64(3) - NEO_ROUTER = uint64(4) - COSMOS_ROUTER = uint64(5) - BSC_ROUTER = uint64(6) - HECO_ROUTER = uint64(7) - QUORUM_ROUTER = uint64(8) - ZILLIQA_ROUTER = uint64(9) - MSC_ROUTER = uint64(10) - NEO3_LEGACY_ROUTER = uint64(11) - OKEX_ROUTER = uint64(12) - NEO3_ROUTER = uint64(14) - POLYGON_HEIMDALL_ROUTER = uint64(15) - POLYGON_BOR_ROUTER = uint64(16) + NodeManagerContractAddress = common.HexToAddress("0xA4Bf827047a08510722B2d62e668a72FCCFa232C") + MaasConfigContractAddress = common.HexToAddress("0xD62B67170A6bb645f1c59601FbC6766940ee12e5") ) diff --git a/core/block_validator.go b/core/block_validator.go index 8dbd0f75..9a752984 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -126,15 +126,13 @@ func CalcGasLimit(parent *types.Block, gasFloor, gasCeil uint64) uint64 { } // If we're outside our allowed gas range, we try to hone towards them if limit < gasFloor { - limit = parent.GasLimit() + decay - if limit > gasFloor { - limit = gasFloor - } + limit = gasFloor } else if limit > gasCeil { - limit = parent.GasLimit() - decay - if limit < gasCeil { - limit = gasCeil - } + limit = gasCeil + // limit = parent.GasLimit() - decay + // if limit < gasCeil { + // limit = gasCeil + // } } return limit } diff --git a/core/tx_pool.go b/core/tx_pool.go index f619dbf3..4a9d59f5 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/prque" + "github.com/ethereum/go-ethereum/contracts/native/native_client" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" @@ -280,7 +281,7 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain block queueTxEventCh: make(chan *types.Transaction), reorgDoneCh: make(chan chan struct{}), reorgShutdownCh: make(chan struct{}), - gasPrice: new(big.Int).SetUint64(DefaultTxPoolConfig.PriceLimit), + gasPrice: new(big.Int).SetUint64(config.PriceLimit), } pool.locals = newAccountSet(pool.signer) for _, addr := range config.Locals { @@ -539,8 +540,24 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { if err != nil { return ErrInvalidSender } - // `pool.gasPrice` is a personalized attribute of `POW` miners, zion allows - // that txs of different nodes and prices to be spread freely, and do not to drop it. + // check if address is blocked + if native_client.IsBlocked(pool.currentState, &from) || native_client.IsBlocked(pool.currentState, tx.To()) { + return native_client.ErrAccountBlocked + } + // gas manager check + if tx.Value().Cmp(common.Big0) > 0 { + if native_client.IsGasManageEnable(pool.currentState) && !native_client.IsGasManager(pool.currentState, &from) && + !native_client.IsGasManager(pool.currentState, tx.To()) && !native_client.IsGasUser(pool.currentState, tx.To()) { + return native_client.ErrNotGasManager + } + } + + // Drop non-local transactions under our own minimal accepted gas price or tip + log.Trace("### Txpool gas limit", "local", local, "tx gasPrice", tx.GasPrice(), "pool gasPrice", pool.gasPrice) + // if !local && tx.GasTipCapIntCmp(pool.gasPrice) < 0 { + if tx.GasTipCapIntCmp(pool.gasPrice) < 0 { + return ErrUnderpriced + } // Ensure the transaction adheres to nonce ordering if pool.currentState.GetNonce(from) > tx.Nonce() { return ErrNonceTooLow diff --git a/core/types/transaction.go b/core/types/transaction.go index 795e253e..cca79417 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -301,6 +301,16 @@ func (tx *Transaction) GasPriceIntCmp(other *big.Int) int { return tx.inner.gasPrice().Cmp(other) } +// GasTipCapCmp compares the gasTipCap of two transactions. +func (tx *Transaction) GasTipCapCmp(other *Transaction) int { + return tx.GasPrice().Cmp(other.GasPrice()) +} + +// GasTipCapIntCmp compares the gasTipCap of the transaction against the given gasTipCap. +func (tx *Transaction) GasTipCapIntCmp(other *big.Int) int { + return tx.GasPrice().Cmp(other) +} + // Hash returns the transaction hash. func (tx *Transaction) Hash() common.Hash { if hash := tx.hash.Load(); hash != nil { diff --git a/docs/install_guide/install.md b/docs/install_guide/install.md new file mode 100644 index 00000000..7ad7c303 --- /dev/null +++ b/docs/install_guide/install.md @@ -0,0 +1,184 @@ +# 1. 私链环境搭建 + +## 1.1. 安装环境 + +Ubuntu 16或18 +CentOS 7 +MacOS +golang版本1.14及以上,同时需要C编译器 + +## 1.2. 获取源代码 + +```shell +$ git clone https://github.com/DNAProject/Zion +``` +## 1.3. 编译源代码 + +* 编译geth + +```shell +$ make geth +``` + +* 全部编译 + +```shell +$ make all +``` + +编译后可在build/bin目录中生成二进制可执行文件 + +## 1.4. 环境搭建 + +环境搭建以单机搭建4节点私链网络为例。 + +### 1.4.1. 生成节点初始配置信息 + +利用 genesisTool 生成节点初始化配置文件 +``` +./geth genesisTool generate --basePath --nodeCount --nodePass +``` + +以下是生成4节点配置文件示例: + +``` +./geth genesisTool generate --basePath ./genesisOutput --nodeCount 4 --nodePass 1234 +``` + +生成三份文件: +* genesis.json + +```json +{ + "config": { + "chainId": 10898, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "hotstuff": { + "protocol": "basic" + } + }, + "alloc": { + "0x49525E980345C81498fE0e30a9ACC7f4dC9E237B": { + "publicKey": "0x0213db218e3638d64ae0cb440482c5cfda460ad02759c51a0b53a42f4954e40137", + "balance": "100000000000000000000000000000" + }, + "0xA29cfe2827fFf2d38e300be374c8a89214fa5C95": { + "publicKey": "0x033b2d6b8db288cffe1b10de45e3c920942b069dc6db2a4110a63194fa147352f9", + "balance": "100000000000000000000000000000" + }, + "0xAD048c8a4Fc1002B8414F23e4a0105799e9A232D": { + "publicKey": "0x037595cdec137c1c81fffc70a9bdd77af3add53e91e28cce4675e856de79128cf6", + "balance": "100000000000000000000000000000" + }, + "0xeffc0210C58fFE4c523309F0e0918b89911C0985": { + "publicKey": "0x023bfcaab2a46272bbc5fa5a1fe8c8e19af32120e6299ad7006b6038dd892510ed", + "balance": "100000000000000000000000000000" + } + }, + "coinbase": "0x0000000000000000000000000000000000000000", + "difficulty": "0x1", + "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000f89bf8549449525e980345c81498fe0e30a9acc7f4dc9e237b94a29cfe2827fff2d38e300be374c8a89214fa5c9594ad048c8a4fc1002b8414f23e4a0105799e9a232d94effc0210c58ffe4c523309f0e0918b89911c0985b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080", + "gasLimit": "0xffffffff", + "nonce": "0x4510809143055965", + "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp": "0x00" +} +``` +* nodes.json 节点的私钥、公钥、地址、静态通讯地址 + +```json +[ + { + "address": "0x1D3a781db87D57a2091f968734186c8C72353116", + "nodeKey": "0x1ca9dcf44053a4241b2b8350b08dcade1b52ecba340237be69004caf76d6ab43", + "keystore": { + "address": "1d3a781db87d57a2091f968734186c8c72353116", + "crypto": { + "cipher": "aes-128-ctr", + "ciphertext": "2d5c5cc5ff6c7e2f2e49cb53859df5457fbada13b179f41e160bb6d80897d87f", + "cipherparams": { + "iv": "978375653c56f3255763bd509336782b" + }, + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 262144, + "p": 1, + "r": 8, + "salt": "de8296b9cdb58b1f220841c1c84bbc2452a87fbce2d4d7c9cfbaf16e5501dee2" + }, + "mac": "40cecc8a51db200f9afde4b85d7715951be0295723d148dfaa46ca7da20b0643" + }, + "id": "93415801-0d57-4d62-8329-f82ebae37939", + "version": 3 + }, + "pubKey": "0x02b68faf75dd7ec8f2e9a3a23354795069c77e7955ee6b2bdb42e8858d06968a2a", + "static": "enode://b68faf75dd7ec8f2e9a3a23354795069c77e7955ee6b2bdb42e8858d06968a2a4bfe1073f3a74e3b61b3efa86bb25d655b664a2c106c5fbc07b4455039f84742@127.0.0.1:30300?discport=0" + }, + ........ +``` +* static-nodes.json 静态节点通讯配置 + +```json +[ + "enode://f460929ebaf0ec94f872246c653a5e47c137ca9c8bddb2c872c6cd96d209311ec2380242061e0f5cc6015d137a51430877167c4442099d86a608d2af8b857004@127.0.0.1:30300?discport=0", + "enode://93a5568672fa325a1c36b0a73c974489c36d6658f71bf56da7b3aa6cc46a3397688a6ae289f7cde8c585c6368aa5a92e0eeedc62888f9cb16c274681e1f040c2@127.0.0.1:30300?discport=0", + "enode://fdacbff85c9544af0c4dd072d5c570e4854fd9ee7d1677384a1bd6e2d13b245491109e1c2a50b3625fa5ea59dd1682ad7a67f6a340fce3d896f270d92bd1778a@127.0.0.1:30300?discport=0", + "enode://999ae3f263795e025fb89f96a177287fe620e0509c0c511f2c0c144bbd77b5c52c43bd681d888f1a39a295b7d655e142eac4456c3c1bfcb72b6a602a200047e6@127.0.0.1:30300?discport=0" +] +``` + +### 1.4.2. 拷贝安装辅助文件目录到安装文件夹 + +```shell +$ cd zion/docs/install_guide/install_file +$ ls +init.sh setup start.sh stop.sh +$ cp -r setup /your/install/folder/. +$ cp *.sh /your/install/folder/. + +$ cd zion/build/bin +$ cp geth /your/install/folder/. + +$ cd /path/to/genesisOutput +$ ls genesis.json nodes.json static-nodes.json +$ cp *.json /your/instal/folder/setup/. +``` + +### 1.4.3. 将setup/node i的目录中的nodekey和pubkey改成setup/nodes.json对应的key + +```shell +cd setup +``` + +顺序修改node0-node3中的nodekey和pubkey,nodekey为keystore, pubkey为pubKey + +### 1.4.4. 修改setup/static-nodes.json的ip和端口 + +将各节点的和端口改为不同的数字 + +### 1.4.5. 修改start.sh + +顺序修改start.sh中的coinbase为setup/nodes.json中的各节点address + +### 1.4.6. 执行init.sh,初始化各个节点 + +按顺序执行4遍init.sh, 在console的交互中输入0-3的节点号 + +### 1.4.7. 启动节点 + +执行4遍start.sh, 在console的交互中顺序输入0-3的节点号 + +### 1.4.8. 停止节点 + +执行4遍stop.sh,在console的交互中顺序输入0-3的节点号 + + diff --git a/docs/install_guide/install_file/init.sh b/docs/install_guide/install_file/init.sh new file mode 100644 index 00000000..17cba733 --- /dev/null +++ b/docs/install_guide/install_file/init.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +echo "input node index" +read nodeIndex +node="node$nodeIndex" + +echo "input node pass" +read -s pass +export NODE_PASS=$pass + +if [ ! -f $node/genesis.json ] +then + mkdir -p $node/geth/ + cp setup/genesis.json $node/genesis.json +fi + +if [ ! -f $node/static-nodes.json ] +then + cp setup/static-nodes.json $node/static-nodes.json +fi + +if [ ! -f $node/geth/nodekey ] +then + cp setup/$node/nodekey $node/geth/ +fi + +./geth init $node/genesis.json --datadir $node diff --git a/docs/install_guide/install_file/setup/node0/nodekey b/docs/install_guide/install_file/setup/node0/nodekey new file mode 100755 index 00000000..2d88668b --- /dev/null +++ b/docs/install_guide/install_file/setup/node0/nodekey @@ -0,0 +1,21 @@ +{ + "address": "42f373f01fd7bed512368032eff0e0d8e5ccb665", + "crypto": { + "cipher": "aes-128-ctr", + "ciphertext": "5670ac66f4b2a5904dad9667afc318576e7423007db5fe552f8126ed04f8c262", + "cipherparams": { + "iv": "7ff9cb596c39d3c9ce0697a48718915d" + }, + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 262144, + "p": 1, + "r": 8, + "salt": "23f4e8bdc5294963a18090ea13710665292379d4fa3c5ab0b5c5915c93926a7f" + }, + "mac": "c2b66144714a3b9e09d4bf29e23df8d2b4b6f35a609eea68dfa11892f7195c2a" + }, + "id": "b9c80fb2-7d3c-4eb6-b9fd-c2a005b6b5f1", + "version": 3 +} \ No newline at end of file diff --git a/docs/install_guide/install_file/setup/node1/nodekey b/docs/install_guide/install_file/setup/node1/nodekey new file mode 100644 index 00000000..c610ff41 --- /dev/null +++ b/docs/install_guide/install_file/setup/node1/nodekey @@ -0,0 +1,21 @@ +{ + "address": "53f1f66a297cb6576f2da328874bddba460f61f8", + "crypto": { + "cipher": "aes-128-ctr", + "ciphertext": "f69192d1a46c843853fcf54d15a9582af11c9e31a2c43ce9f5cb64ae2556c15b", + "cipherparams": { + "iv": "a59e064045d06db2693304f734950f2b" + }, + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 262144, + "p": 1, + "r": 8, + "salt": "b9a661bde28fee90df284ed8051176bdccd35c4b5f6364a7ca1d322c42040409" + }, + "mac": "76e0904542eb9bdbf5c60bd0c2153d7976ab64cc921b84095d7ff275be581d66" + }, + "id": "1a17e17b-954e-40ff-a5bb-28e0d8ff7937", + "version": 3 +} \ No newline at end of file diff --git a/docs/install_guide/install_file/setup/node2/nodekey b/docs/install_guide/install_file/setup/node2/nodekey new file mode 100755 index 00000000..e28f7a81 --- /dev/null +++ b/docs/install_guide/install_file/setup/node2/nodekey @@ -0,0 +1,21 @@ +{ + "address": "646c61860a22b27126c13ff15abb4de5df481dfb", + "crypto": { + "cipher": "aes-128-ctr", + "ciphertext": "2d0682641b622e23cb50d3b7a862b054683864ba7f93ccc8931b66347f32f978", + "cipherparams": { + "iv": "addabde081931992c7b63be75c52f1fe" + }, + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 262144, + "p": 1, + "r": 8, + "salt": "21db0489091242cb43ab9fc47e0ac67c08be01482fe1d78c2e7d3cd318cc0c1b" + }, + "mac": "4b2b89e1acb7ab7273a2b25fccccaa3e42d22ff857e21c12846bf26658db8ccb" + }, + "id": "9f671f49-2155-4e61-9eff-84376d23aef7", + "version": 3 +} \ No newline at end of file diff --git a/docs/install_guide/install_file/setup/node3/nodekey b/docs/install_guide/install_file/setup/node3/nodekey new file mode 100644 index 00000000..bc9ded58 --- /dev/null +++ b/docs/install_guide/install_file/setup/node3/nodekey @@ -0,0 +1,21 @@ +{ + "address": "76dd393f02067115557dd5626fb3c701291c6519", + "crypto": { + "cipher": "aes-128-ctr", + "ciphertext": "7e9329e4d685326f06ae4d3a5393dc813c7003f45b94e1074d09f67eb5cc420f", + "cipherparams": { + "iv": "08394eda40eead64f03e357a5a8e67c5" + }, + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 262144, + "p": 1, + "r": 8, + "salt": "1a7fdf505328570765cf5b714db925ac32f1dbab15c96b3bef2374643a58feb2" + }, + "mac": "9b485cddcd6f6179e5baf86f4dcf8e7223a4b1b3da6345f4ac79beda45c6cf85" + }, + "id": "f7f270c5-b5ab-4ceb-bc83-408eaaa31fed", + "version": 3 +} \ No newline at end of file diff --git a/docs/install_guide/install_file/setup/node4/nodekey b/docs/install_guide/install_file/setup/node4/nodekey new file mode 100755 index 00000000..b77832d3 --- /dev/null +++ b/docs/install_guide/install_file/setup/node4/nodekey @@ -0,0 +1,21 @@ +{ + "address": "8a69e9d4a51e44ef1e94871848e31d73e375f861", + "crypto": { + "cipher": "aes-128-ctr", + "ciphertext": "18653ae4070ff62013b8a61a65173faf5a7d11be51ba81232414807adfb03dbd", + "cipherparams": { + "iv": "02b2f8d721d6eda59842a41efc70b9e6" + }, + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 262144, + "p": 1, + "r": 8, + "salt": "902fba21c5154d283a6799db7c683aacfa779cfeb1483b61de6071714afe8a37" + }, + "mac": "1212991e5837c034ad519532eb7088d9e13bf9269559a989424ebe27c54a3262" + }, + "id": "064f6f01-fedf-4511-9642-07b9358e1d87", + "version": 3 +} \ No newline at end of file diff --git a/docs/install_guide/install_file/setup/node5/nodekey b/docs/install_guide/install_file/setup/node5/nodekey new file mode 100755 index 00000000..c96edce6 --- /dev/null +++ b/docs/install_guide/install_file/setup/node5/nodekey @@ -0,0 +1,21 @@ +{ + "address": "95cd4f39d9705b8da63bffbdd825911383a108b1", + "crypto": { + "cipher": "aes-128-ctr", + "ciphertext": "efb3ef90fa0226aeeadc7adcab09afc530c2545c24027865138d78ef030b387f", + "cipherparams": { + "iv": "e559cd504e92b73f3a8f8015b106b833" + }, + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 262144, + "p": 1, + "r": 8, + "salt": "ac8fe5bd5a5d10c46e1fdc4db556925a636f7e34f9154670c2bc8f3c4970a8a9" + }, + "mac": "4192cdcc93270b20d973744cb654f7564b35036419a5f55d07a8afa43a8a05a4" + }, + "id": "80a32552-8374-4feb-b475-a130d7c9c5c5", + "version": 3 +} \ No newline at end of file diff --git a/docs/install_guide/install_file/setup/node6/nodekey b/docs/install_guide/install_file/setup/node6/nodekey new file mode 100644 index 00000000..0f50a9d1 --- /dev/null +++ b/docs/install_guide/install_file/setup/node6/nodekey @@ -0,0 +1,21 @@ +{ + "address": "ec4e8824c05ce57ce7c8b18d10175e48f3837f3a", + "crypto": { + "cipher": "aes-128-ctr", + "ciphertext": "29d8a67763e27e1e83f36091566fd68b000b34631c03c4a3bb2239354ddcbdc7", + "cipherparams": { + "iv": "7ecd046b92d7e270a130774aa28cd8c3" + }, + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 262144, + "p": 1, + "r": 8, + "salt": "cc23eebcf4e68550cef2298de3f4cf870ec6ac79164ea9a93134169ff37e5198" + }, + "mac": "8e99f75a6aff09308f507a12865efd448332578d964acda59cc6cb9288bd329d" + }, + "id": "5b4417e6-2a20-4ee6-83e3-72887f7ea866", + "version": 3 +} \ No newline at end of file diff --git a/docs/install_guide/install_file/start.sh b/docs/install_guide/install_file/start.sh new file mode 100644 index 00000000..27b9fe9f --- /dev/null +++ b/docs/install_guide/install_file/start.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +echo "input node index" +read nodeIndex +node="node$nodeIndex" + +echo "input node pass" +read -s pass +export NODE_PASS=$pass + +startP2PPort=30300 +startRPCPort=8545 +mod=`expr $nodeIndex` + +port=`expr $startP2PPort + $mod` +rpcport=`expr $startRPCPort + $mod` + +coinbases=(0x1B7347c655d7B09aCB3cA13dfed1585235FA187E 0x296c57c333676C5cDB68bBB5d45Eca40b2D40b90 0x38Da2a6DEa3519ecadf934B6F80Dd48145811311 0x3baBf6AC5b776dBDB07420FcB0D79Ae28669Fde7 0x7f9f4af365ae4d1EcCe9fBbC605a7e8a00482343 0xC502652b4aD530d0E1e62884d48F26eD615204FA 0xaF1A5CB144f608B9411B9D75d4BA8eD93eEE7ad9) +miner=${coinbases[$nodeIndex]} +echo "$node and miner is $miner, rpc port $rpcport, p2p port $port" + +nohup ./geth --mine --miner.threads 1 \ +--miner.etherbase=$miner \ +--identity=$node \ +--maxpeers=100 \ +--syncmode full \ +--allow-insecure-unlock \ +--datadir $node \ +--txlookuplimit 0 \ +--networkid 10898 \ +--http.corsdomain "*" \ +--http.api admin,eth,debug,miner,net,txpool,personal,web3 \ +--http --http.addr 0.0.0.0 --http.port $rpcport --http.vhosts "*" \ +--port $port \ +--verbosity 5 \ +--nodiscover >> $node/node.log 2>&1 & + +sleep 3s; +ps -ef|grep geth|grep mine|grep -v grep; diff --git a/docs/install_guide/install_file/stop.sh b/docs/install_guide/install_file/stop.sh new file mode 100644 index 00000000..89a1c76e --- /dev/null +++ b/docs/install_guide/install_file/stop.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +echo "input node index" +read nodeIndex +node="node$nodeIndex" + +kill -s SIGINT $(ps aux|grep geth|grep mine|grep $node|grep -v grep|awk '{print $2}'); + +sleep 3s; +ps -ef|grep geth|grep mine|grep -v grep; \ No newline at end of file diff --git a/docs/jsonrpc/jsonrpc.md b/docs/jsonrpc/jsonrpc.md new file mode 100644 index 00000000..67de87b7 --- /dev/null +++ b/docs/jsonrpc/jsonrpc.md @@ -0,0 +1,1366 @@ +# Zion JSON RPC API Guide + +## The default block parameter + +The following methods have an extra `defaultBlock` parameter: + +- [eth_estimateGas](#eth_estimategas) +- [eth_getBalance](#eth_getbalance) +- [eth_getCode](#eth_getcode) +- [eth_getTransactionCount](#eth_gettransactioncount) +- [eth_getStorageAt](#eth_getstorageat) +- [eth_call](#eth_call) + +When requests are made that act on the state of Zion, the last parameter determines the height of the block. + +The following options are possible for the `defaultBlock` parameter: + +- `Quantity`/`Integer` - an integer block number; +- `String "earliest"` - for the earliest/genesis block; +- `String "latest"` - for the latest mined block; +- `String "pending"` - for the pending state/transactions. + +## JSON-RPC methods + +- [eth_accounts](#eth_accounts) +- [eth_blockNumber](#eth_blocknumber) +- [eth_call](#eth_call) +- [eth_chainId](#eth_chainid) +- [eth_coinbase](#eth_coinbase) +- [eth_estimateGas](#eth_estimategas) +- [eth_gasPrice](#eth_gasprice) +- [eth_getBalance](#eth_getbalance) +- [eth_getBlockByHash](#eth_getblockbyhash) +- [eth_getBlockByNumber](#eth_getblockbynumber) +- [eth_getBlockTransactionCountByHash](#eth_getblocktransactioncountbyhash) +- [eth_getBlockTransactionCountByNumber](#eth_getblocktransactioncountbynumber) +- [eth_getCode](#eth_getcode) +- [eth_getFilterChanges](#eth_getfilterchanges) +- [eth_getFilterLogs](#eth_getfilterlogs) +- [eth_getLogs](#eth_getlogs) +- [eth_getStorageAt](#eth_getstorageat) +- [eth_getTransactionByBlockHashAndIndex](#eth_gettransactionbyblockhashandindex) +- [eth_getTransactionByBlockNumberAndIndex](#eth_gettransactionbyblocknumberandindex) +- [eth_getTransactionByHash](#eth_gettransactionbyhash) +- [eth_getTransactionCount](#eth_gettransactioncount) +- [eth_getTransactionReceipt](#eth_gettransactionreceipt) +- [eth_newBlockFilter](#eth_newblockfilter) +- [eth_newFilter](#eth_newfilter) +- [eth_newPendingTransactionFilter](#eth_newpendingtransactionfilter) +- [eth_sendRawTransaction](#eth_sendrawtransaction) +- [eth_sendTransaction](#eth_sendtransaction) +- [eth_sign](#eth_sign) +- [eth_signTransaction](#eth_signtransaction) +- [eth_syncing](#eth_syncing) +- [eth_uninstallFilter](#eth_uninstallfilter) + +## JSON-RPC API Reference + +### eth_accounts + +Returns a list of addresses owned by client. + +#### Parameters + +None + +#### Returns + +- `Array` - 20 Bytes - addresses owned by the client. + +#### Example + +Request +```bash +curl --data '{"method":"eth_accounts","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": ["0x407d73d8a49eeb85d32cf465507dd71d507100c1"] +} +``` + +*** + +### eth_blockNumber + +Returns the number of most recent block. + +#### Parameters + +None + +#### Returns + +- `Quantity` - integer of the current block number the client is on. + +#### Example + +Request +```bash +curl --data '{"method":"eth_blockNumber","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0x4b7" // 1207 +} +``` + +*** + +### eth_call + +Executes a new message call immediately without creating a transaction on the block chain. + +#### Parameters + +0. `Object` - [Transaction object](https://github.com/openethereum/openethereum.github.io/blob/master/JSONRPC.md#transactions) where `from` field is optional and `nonce` field is ommited. + +0. `Quantity` or `Tag` - Integer block number, or the string `'latest'`, `'earliest'` or `'pending'`, see the [default block parameter](#the-default-block-parameter). + +```js +params: [{ + "from": "0x407d73d8a49eeb85d32cf465507dd71d507100c1", + "to": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value": "0x186a0" // 100000 +}, +"latest"] +``` + +#### Returns + +- `Data` - the return value of executed contract. + +#### Example + +Request +```bash +curl --data '{"method":"eth_call","params":[{"from":"0x407d73d8a49eeb85d32cf465507dd71d507100c1","to":"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b","value":"0x186a0"},"latest"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0x" +} +``` + +*** + +### eth_chainId + +Returns the EIP155 chain ID used for transaction signing at the current best block. Null is returned if not available. + +#### Parameters + +None + +#### Returns + +- `Quantity` - EIP155 Chain ID, or `null` if not available. + +#### Example + +Request +```bash +curl --data '{"method":"eth_chainId","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0x1" +} +``` + +*** + +### eth_coinbase + +Returns the client coinbase address. + +#### Parameters + +None + +#### Returns + +- `Address` - The current coinbase address. + +#### Example + +Request +```bash +curl --data '{"method":"eth_coinbase","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0x407d73d8a49eeb85d32cf465507dd71d507100c1" +} +``` + +*** + +### eth_estimateGas + +Makes a call or transaction, which won't be added to the blockchain and returns the used gas, which can be used for estimating the used gas. + +#### Parameters + +0. `Object` - [Transaction object](https://github.com/openethereum/openethereum.github.io/blob/master/JSONRPC.md#transactions) where `from` field is optional and `nonce` field is ommited. +0. `Quantity` or `Tag` - Integer block number, or the string `'latest'`, `'earliest'` or `'pending'`, see the [default block parameter](#the-default-block-parameter). + +#### Returns + +- `Quantity` - The amount of gas used. + +#### Example + +Request +```bash +curl --data '{"method":"eth_estimateGas","params":[{ ... }],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0x5208" // 21000 +} +``` + +*** + +### eth_gasPrice + +Returns the current price per gas in wei. + +#### Parameters + +None + +#### Returns + +- `Quantity` - integer of the current gas price in wei. + +#### Example + +Request +```bash +curl --data '{"method":"eth_gasPrice","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0x9184e72a000" // 10000000000000 +} +``` + +*** + +### eth_getBalance + +Returns the balance of the account of given address. + +#### Parameters + +0. `Address` - 20 Bytes - address to check for balance. +0. `Quantity` or `Tag` - integer block number, or the string `'latest'`, `'earliest'` or `'pending'`, see the [default block parameter](#the-default-block-parameter). + +```js +params: ["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"] +``` + +#### Returns + +- `Quantity` - integer of the current balance in wei. + +#### Example + +Request +```bash +curl --data '{"method":"eth_getBalance","params":["0x407d73d8a49eeb85d32cf465507dd71d507100c1","latest"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0x0234c8a3397aab58" +} +``` + +*** + +### eth_getBlockByHash + +Returns information about a block by hash. + +#### Parameters + +0. `Hash` - Hash of a block. +0. `Boolean` - If `true` it returns the full transaction objects, if `false` only the hashes of the transactions. + +```js +params: [ + "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", + true +] +``` + +#### Returns + +- `Object` - A block object, or `null` when no block was found. + - `number`: `Quantity` - The block number. `null` when its pending block + - `hash`: `Hash` - 32 Bytes - hash of the block. `null` when its pending block + - `parentHash`: `Hash` - 32 Bytes - hash of the parent block + - `nonce`: `Data` - 8 Bytes - hash of the generated proof-of-work. `null` when its pending block. Missing in case of PoA. + - `sha3Uncles`: `Data` - 32 Bytes - SHA3 of the uncles data in the block + - `logsBloom`: `Data` - 256 Bytes - the bloom filter for the logs of the block. `null` when its pending block + - `transactionsRoot`: `Data` - 32 Bytes - the root of the transaction trie of the block + - `stateRoot`: `Data` - 32 Bytes - the root of the final state trie of the block + - `receiptsRoot`: `Data` - 32 Bytes - the root of the receipts trie of the block + - `author`: `Address` - 20 Bytes - the address of the author of the block (the beneficiary to whom the mining rewards were given) + - `miner`: `Address` - 20 Bytes - alias of 'author' + - `difficulty`: `Quantity` - integer of the difficulty for this block + - `totalDifficulty`: `Quantity` - integer of the total difficulty of the chain until this block + - `extraData`: `Data` - the 'extra data' field of this block + - `size`: `Quantity` - integer the size of this block in bytes + - `gasLimit`: `Quantity` - the maximum gas allowed in this block + - `gasUsed`: `Quantity` - the total used gas by all transactions in this block + - `timestamp`: `Quantity` - the unix timestamp for when the block was collated + - `transactions`: `Array` - Array of transaction objects, or 32 Bytes transaction hashes depending on the last given parameter + - `uncles`: `Array` - Array of uncle hashes + +#### Example + +Request +```bash +curl --data '{"method":"eth_getBlockByHash","params":["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331",true],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": { + "number": "0x1b4", // 436 + "hash": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", + "parentHash": "0x9646252be9520f6e71339a8df9c55e4d7619deeb018d2a3f2d21fc165dde5eb5", + "sealFields": [ + "0xe04d296d2460cfb8472af2c5fd05b5a214109c25688d3704aed5484f9a7792f2", + "0x0000000000000042" + ], + "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "logsBloom": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", + "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0xd5855eb08b3387c0af375e9cdb6acfc05eb8f519e419b874b6ff2ffda7ed1dff", + "miner": "0x4e65fda2159562a496f9f3522f89122a3088497a", + "difficulty": "0x27f07", // 163591 + "totalDifficulty": "0x27f07", // 163591 + "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000", + "size": "0x27f07", // 163591 + "gasLimit": "0x9f759", // 653145 + "minGasPrice": "0x9f759", // 653145 + "gasUsed": "0x9f759", // 653145 + "timestamp": "0x54e34e8e", // 1424182926 + "transactions": [{ ... }, { ... }, ...], + "uncles": [ + "0x1606e5...", + "0xd5145a9..." + ] + } +} +``` + +*** + +### eth_getBlockByNumber + +Returns information about a block by block number. + +#### Parameters + +0. `Quantity` or `Tag` - integer of a block number, or the string `'earliest'`, `'latest'` or `'pending'`, as in the [default block parameter](#the-default-block-parameter). +0. `Boolean` - If `true` it returns the full transaction objects, if `false` only the hashes of the transactions. + +```js +params: [ + "0x1b4", // 436 + true +] +``` + +#### Returns + +- `Object` - A block object, or `null` when no block was found. + - `number`: `Quantity` - The block number. `null` when its pending block + - `hash`: `Hash` - 32 Bytes - hash of the block. `null` when its pending block + - `parentHash`: `Hash` - 32 Bytes - hash of the parent block + - `nonce`: `Data` - 8 Bytes - hash of the generated proof-of-work. `null` when its pending block. Missing in case of PoA. + - `sha3Uncles`: `Data` - 32 Bytes - SHA3 of the uncles data in the block + - `logsBloom`: `Data` - 256 Bytes - the bloom filter for the logs of the block. `null` when its pending block + - `transactionsRoot`: `Data` - 32 Bytes - the root of the transaction trie of the block + - `stateRoot`: `Data` - 32 Bytes - the root of the final state trie of the block + - `receiptsRoot`: `Data` - 32 Bytes - the root of the receipts trie of the block + - `author`: `Address` - 20 Bytes - the address of the author of the block (the beneficiary to whom the mining rewards were given) + - `miner`: `Address` - 20 Bytes - alias of 'author' + - `difficulty`: `Quantity` - integer of the difficulty for this block + - `totalDifficulty`: `Quantity` - integer of the total difficulty of the chain until this block + - `extraData`: `Data` - the 'extra data' field of this block + - `size`: `Quantity` - integer the size of this block in bytes + - `gasLimit`: `Quantity` - the maximum gas allowed in this block + - `gasUsed`: `Quantity` - the total used gas by all transactions in this block + - `timestamp`: `Quantity` - the unix timestamp for when the block was collated + - `transactions`: `Array` - Array of transaction objects, or 32 Bytes transaction hashes depending on the last given parameter + - `uncles`: `Array` - Array of uncle hashes + +#### Example + +Request +```bash +curl --data '{"method":"eth_getBlockByNumber","params":["0x1b4",true],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": { + "number": "0x1b4", // 436 + "hash": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", + "parentHash": "0x9646252be9520f6e71339a8df9c55e4d7619deeb018d2a3f2d21fc165dde5eb5", + "sealFields": [ + "0xe04d296d2460cfb8472af2c5fd05b5a214109c25688d3704aed5484f9a7792f2", + "0x0000000000000042" + ], + "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "logsBloom": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", + "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0xd5855eb08b3387c0af375e9cdb6acfc05eb8f519e419b874b6ff2ffda7ed1dff", + "miner": "0x4e65fda2159562a496f9f3522f89122a3088497a", + "difficulty": "0x27f07", // 163591 + "totalDifficulty": "0x27f07", // 163591 + "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000", + "size": "0x27f07", // 163591 + "gasLimit": "0x9f759", // 653145 + "minGasPrice": "0x9f759", // 653145 + "gasUsed": "0x9f759", // 653145 + "timestamp": "0x54e34e8e", // 1424182926 + "transactions": [{ ... }, { ... }, ...], + "uncles": [ + "0x1606e5...", + "0xd5145a9..." + ] + } +} +``` + +*** + +### eth_getBlockTransactionCountByHash + +Returns the number of transactions in a block from a block matching the given block hash. + +#### Parameters + +0. `Hash` - 32 Bytes - hash of a block. + +```js +params: ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"] +``` + +#### Returns + +- `Quantity` - integer of the number of transactions in this block. + +#### Example + +Request +```bash +curl --data '{"method":"eth_getBlockTransactionCountByHash","params":["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0xb" // 11 +} +``` + +*** + +### eth_getBlockTransactionCountByNumber + +Returns the number of transactions in a block from a block matching the given block number. + +#### Parameters + +0. `Quantity` or `Tag` - integer of a block number, or the string `'earliest'`, `'latest'` or `'pending'`, as in the [default block parameter](#the-default-block-parameter). + +```js +params: [ + "0xe8" // 232 +] +``` + +#### Returns + +- `Quantity` - integer of the number of transactions in this block. + +#### Example + +Request +```bash +curl --data '{"method":"eth_getBlockTransactionCountByNumber","params":["0xe8"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0xa" // 10 +} +``` + +*** + +### eth_getCode + +Returns code at a given address. + +#### Parameters + +0. `Address` - 20 Bytes - address. +0. `Quantity` or `Tag` - integer block number, or the string `'latest'`, `'earliest'` or `'pending'`, see the [default block parameter](#the-default-block-parameter). + +```js +params: [ + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "0x2" // 2 +] +``` + +#### Returns + +- `Data` - the code from the given address. + +#### Example + +Request +```bash +curl --data '{"method":"eth_getCode","params":["0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b","0x2"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0x600160008035811a818181146012578301005b601b6001356025565b8060005260206000f25b600060078202905091905056" +} +``` + +*** + +### eth_getFilterChanges + +Polling method for a filter, which returns an array of logs which occurred since last poll. + +#### Parameters + +0. `Quantity` - The filter id. + +```js +params: [ + "0x16" // 22 +] +``` + +#### Returns + +- `Array` - Array of log objects, or an empty array if nothing has changed since last poll. + +#### Example + +Request +```bash +curl --data '{"method":"eth_getFilterChanges","params":["0x16"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": [ + { + "logIndex": "0x1", // 1 + "blockNumber": "0x1b4", // 436 + "blockHash": "0x8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcfdf829c5a142f1fccd7d", + "transactionHash": "0xdf829c5a142f1fccd7d8216c5785ac562ff41e2dcfdf5785ac562ff41e2dcf", + "transactionIndex": "0x0", // 0 + "address": "0x16c5785ac562ff41e2dcfdf829c5a142f1fccd7d", + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "topics": ["0x59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a5"] + }, + ... + ] +} +``` + +*** + +### eth_getFilterLogs + +Returns an array of all logs matching filter with given id. + +#### Parameters + +0. `Quantity` - The filter id. + +```js +params: [ + "0x16" // 22 +] +``` + +#### Returns + +- See [eth_getFilterChanges](#eth_getfilterchanges) + +#### Example + +Request +```bash +curl --data '{"method":"eth_getFilterLogs","params":["0x16"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +*** + +### eth_getLogs + +Returns an array of all logs matching a given filter object. + +#### Parameters + +0. `Object` - The filter object, see [eth_newFilter parameters](#eth_newfilter). + +```js +params: [{ + "topics": ["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"] +}] +``` + +#### Returns + +- See [eth_getFilterChanges](#eth_getfilterchanges) + +#### Example + +Request +```bash +curl --data '{"method":"eth_getLogs","params":[{"topics":["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b"]}],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +*** + +### eth_getStorageAt + +Returns the value from a storage position at a given address. + +#### Parameters + +0. `Address` - 20 Bytes - address of the storage. +0. `Quantity` - integer of the position in the storage. +0. `Quantity` or `Tag` - integer block number, or the string `'latest'`, `'earliest'` or `'pending'`, see the [default block parameter](#the-default-block-parameter). + +```js +params: [ + "0x407d73d8a49eeb85d32cf465507dd71d507100c1", + "0x0", // 0 + "0x2" // 2 +] +``` + +#### Returns + +- `Data` - the value at this storage position. + +#### Example + +Request +```bash +curl --data '{"method":"eth_getStorageAt","params":["0x407d73d8a49eeb85d32cf465507dd71d507100c1","0x0","0x2"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0x0000000000000000000000000000000000000000000000000000000000000003" +} +``` + +*** + +### eth_getTransactionByBlockHashAndIndex + +Returns information about a transaction by block hash and transaction index position. + +#### Parameters + +0. `Hash` - hash of a block. +0. `Quantity` - integer of the transaction index position. + +```js +params: [ + "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", + "0x0" // 0 +] +``` + +#### Returns + +- `Object` - [Transaction Response Object](https://github.com/openethereum/openethereum.github.io/blob/master/JSONRPC.md#transaction-responses), or `null` when no transaction + +#### Example + +Request +```bash +curl --data '{"method":"eth_getTransactionByBlockHashAndIndex","params":["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331","0x0"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": { + "hash": "0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b", + "nonce": "0x0", // 0 + "blockHash": "0xbeab0aa2411b7ab17f30a99d3cb9c6ef2fc5426d6ad6fd9e2a26a6aed1d1055b", + "blockNumber": "0x15df", // 5599 + "transactionIndex": "0x1", // 1 + "from": "0x407d73d8a49eeb85d32cf465507dd71d507100c1", + "to": "0x853f43d8a49eeb85d32cf465507dd71d507100c1", + "value": "0x7f110", // 520464 + "gas": "0x7f110", // 520464 + "gasPrice": "0x09184e72a000", + "input": "0x603880600c6000396000f300603880600c6000396000f3603880600c6000396000f360" + } +} +``` + +*** + +### eth_getTransactionByBlockNumberAndIndex + +Returns information about a transaction by block number and transaction index position. + +#### Parameters + +0. `Quantity` or `Tag` - a block number, or the string `'earliest'`, `'latest'` or `'pending'`, as in the [default block parameter](#the-default-block-parameter). +0. `Quantity` - The transaction index position. + +```js +params: [ + "0x29c", // 668 + "0x0" // 0 +] +``` + +#### Returns + +- `Object` - A block object, or `null` when no block was found. + - `number`: `Quantity` - The block number. `null` when its pending block + - `hash`: `Hash` - 32 Bytes - hash of the block. `null` when its pending block + - `parentHash`: `Hash` - 32 Bytes - hash of the parent block + - `nonce`: `Data` - 8 Bytes - hash of the generated proof-of-work. `null` when its pending block. Missing in case of PoA. + - `sha3Uncles`: `Data` - 32 Bytes - SHA3 of the uncles data in the block + - `logsBloom`: `Data` - 256 Bytes - the bloom filter for the logs of the block. `null` when its pending block + - `transactionsRoot`: `Data` - 32 Bytes - the root of the transaction trie of the block + - `stateRoot`: `Data` - 32 Bytes - the root of the final state trie of the block + - `receiptsRoot`: `Data` - 32 Bytes - the root of the receipts trie of the block + - `author`: `Address` - 20 Bytes - the address of the author of the block (the beneficiary to whom the mining rewards were given) + - `miner`: `Address` - 20 Bytes - alias of 'author' + - `difficulty`: `Quantity` - integer of the difficulty for this block + - `totalDifficulty`: `Quantity` - integer of the total difficulty of the chain until this block + - `extraData`: `Data` - the 'extra data' field of this block + - `size`: `Quantity` - integer the size of this block in bytes + - `gasLimit`: `Quantity` - the maximum gas allowed in this block + - `gasUsed`: `Quantity` - the total used gas by all transactions in this block + - `timestamp`: `Quantity` - the unix timestamp for when the block was collated + - `transactions`: `Array` - Array of transaction objects, or 32 Bytes transaction hashes depending on the last given parameter + - `uncles`: `Array` - Array of uncle hashes + +#### Example + +Request +```bash +curl --data '{"method":"eth_getTransactionByBlockNumberAndIndex","params":["0x29c","0x0"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": { + "number": "0x1b4", // 436 + "hash": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", + "parentHash": "0x9646252be9520f6e71339a8df9c55e4d7619deeb018d2a3f2d21fc165dde5eb5", + "sealFields": [ + "0xe04d296d2460cfb8472af2c5fd05b5a214109c25688d3704aed5484f9a7792f2", + "0x0000000000000042" + ], + "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "logsBloom": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", + "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0xd5855eb08b3387c0af375e9cdb6acfc05eb8f519e419b874b6ff2ffda7ed1dff", + "miner": "0x4e65fda2159562a496f9f3522f89122a3088497a", + "difficulty": "0x27f07", // 163591 + "totalDifficulty": "0x27f07", // 163591 + "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000", + "size": "0x27f07", // 163591 + "gasLimit": "0x9f759", // 653145 + "minGasPrice": "0x9f759", // 653145 + "gasUsed": "0x9f759", // 653145 + "timestamp": "0x54e34e8e", // 1424182926 + "transactions": [{ ... }, { ... }, ...], + "uncles": [ + "0x1606e5...", + "0xd5145a9..." + ] + } +} +``` + +*** + +### eth_getTransactionByHash + +Returns the information about a transaction requested by transaction hash. + +#### Parameters + +0. `Hash` - 32 Bytes - hash of a transaction. + +```js +params: ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"] +``` + +#### Returns + +- `Object` - [Transaction Response Object](https://github.com/openethereum/openethereum.github.io/blob/master/JSONRPC.md#transaction-responses), or `null` when no transaction was found. + +#### Example + +Request +```bash +curl --data '{"method":"eth_getTransactionByHash","params":["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": { + "hash": "0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b", + "nonce": "0x0", // 0 + "blockHash": "0xbeab0aa2411b7ab17f30a99d3cb9c6ef2fc5426d6ad6fd9e2a26a6aed1d1055b", + "blockNumber": "0x15df", // 5599 + "transactionIndex": "0x1", // 1 + "from": "0x407d73d8a49eeb85d32cf465507dd71d507100c1", + "to": "0x853f43d8a49eeb85d32cf465507dd71d507100c1", + "value": "0x7f110", // 520464 + "gas": "0x7f110", // 520464 + "gasPrice": "0x09184e72a000", + "input": "0x603880600c6000396000f300603880600c6000396000f3603880600c6000396000f360" + } +} +``` + +*** + +### eth_getTransactionCount + +Returns the number of transactions *sent* from an address. + +#### Parameters + +0. `Address` - 20 Bytes - address. +0. `Quantity` or `Tag` - integer block number, or the string `'latest'`, `'earliest'` or `'pending'`, see the [default block parameter](#the-default-block-parameter). + +```js +params: ["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x2"] +``` + +#### Returns + +- `Quantity` - integer of the number of transactions send from this address. + +#### Example + +Request +```bash +curl --data '{"method":"eth_getTransactionCount","params":["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x2"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0x1" // 1 +} +``` + +*** + +### eth_getTransactionReceipt + +Returns the receipt of a transaction by transaction hash. + +**Note** That the receipt is available even for pending transactions. + +#### Parameters + +0. `Hash` - hash of a transaction. + +```js +params: ["0x444172bef57ad978655171a8af2cfd89baa02a97fcb773067aef7794d6913374"] +``` + +#### Returns + +- `Object` - [Receipt object](./JSONRPC.md#Receipts) + +#### Example + +Request +```bash +curl --data '{"method":"eth_getTransactionReceipt","params":["0x444172bef57ad978655171a8af2cfd89baa02a97fcb773067aef7794d6913374"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": { + "blockHash": "0x67c0303244ae4beeec329e0c66198e8db8938a94d15a366c7514626528abfc8c", + "blockNumber": "0x6914b0", + "contractAddress": "0x471a8bf3fd0dfbe20658a97155388cec674190bf", // or null, if none was created + "from": "0xc931d93e97ab07fe42d923478ba2465f2", + "to": null, // value is null because this example transaction is a contract creation + "cumulativeGasUsed": "0x158e33", + "gasUsed": "0xba2e6", + "logs": [], // logs as returned by eth_getFilterLogs, etc. + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "0x1", + "transactionHash": "0x444172bef57ad978655171a8af2cfd89baa02a97fcb773067aef7794d6913374", + "transactionIndex": "0x4" + } +} +``` + +*** + +### eth_newBlockFilter + +Creates a filter in the node, to notify when a new block arrives. +To check if the state has changed, call [eth_getFilterChanges](#eth_getfilterchanges). + +#### Parameters + +None + +#### Returns + +- `Quantity` - A filter id. + +#### Example + +Request +```bash +curl --data '{"method":"eth_newBlockFilter","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0x1" // 1 +} +``` + +*** + +### eth_newFilter + +Creates a filter object, based on filter options, to notify when the state changes (logs). +To check if the state has changed, call [eth_getFilterChanges](#eth_getfilterchanges). + +##### A note on specifying topic filters: +Topics are order-dependent. A transaction with a log with topics [A, B] will be matched by the following topic filters: +* `[]` "anything" +* `[A]` "A in first position (and anything after)" +* `[null, B]` "anything in first position AND B in second position (and anything after)" +* `[A, B]` "A in first position AND B in second position (and anything after)" +* `[[A, B], [A, B]]` "(A OR B) in first position AND (A OR B) in second position (and anything after)" + +#### Parameters + +0. `Object` - The filter options: + - `fromBlock`: `Quantity` or `Tag` - (optional) (default: `latest`) Integer block number, or `'latest'` for the last mined block or `'pending'`, `'earliest'` for not yet mined transactions. + - `toBlock`: `Quantity` or `Tag` - (optional) (default: `latest`) Integer block number, or `'latest'` for the last mined block or `'pending'`, `'earliest'` for not yet mined transactions. + - `address`: `Address` - (optional) 20 Bytes - Contract address or a list of addresses from which logs should originate. + - `topics`: `Array` - (optional) Array of 32 Bytes `Data` topics. Topics are order-dependent. It's possible to pass in `null` to match any topic, or a subarray of multiple topics of which one should be matching. + - `limit`: `Quantity` - (optional) The maximum number of entries to retrieve (latest first). + +```js +params: [{ + "fromBlock": "0x1", // 1 + "toBlock": "0x2", // 2 + "address": "0x8888f1f195afa192cfee860698584c030f4c9db1", + "topics": [ + "0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", // This topic in first position + null, // Any topic in second position + [ + "0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "0x000000000000000000000000aff3454fce5edbc8cca8697c15331677e6ebccc" + ] // Either topic of the two in third position + ] // ... and anything after +}] +``` + +#### Returns + +- `Quantity` - The filter id. + +#### Example + +Request +```bash +curl --data '{"method":"eth_newFilter","params":[{"fromBlock":"0x1","toBlock":"0x2","address":"0x8888f1f195afa192cfee860698584c030f4c9db1","topics":["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b",null,["0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b","0x000000000000000000000000aff3454fce5edbc8cca8697c15331677e6ebccc"]]}],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0x1" // 1 +} +``` + +*** + +### eth_newPendingTransactionFilter + +Creates a filter in the node, to notify when new pending transactions arrive. + +To check if the state has changed, call [eth_getFilterChanges](#eth_getfilterchanges). + +#### Parameters + +None + +#### Returns + +- `Quantity` - A filter id. + +#### Example + +Request +```bash +curl --data '{"method":"eth_newPendingTransactionFilter","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0x1" // 1 +} +``` + +*** + +### eth_sendRawTransaction + +Creates new message call transaction or a contract creation for signed transactions. + +**Note:** `eth_submitTransaction` is an alias of this method. + +#### Parameters + +0. `Data` - The signed transaction data. + +```js +params: ["0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"] +``` + +#### Returns + +- `Hash` - 32 Bytes - the transaction hash, or the zero hash if the transaction is not yet available + +Use [eth_getTransactionReceipt](#eth_gettransactionreceipt) to get the contract address, after the transaction was mined, when you created a contract. + +#### Example + +Request +```bash +curl --data '{"method":"eth_sendRawTransaction","params":["0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" +} +``` + +*** + +### eth_sendTransaction + +Creates new message call transaction or a contract creation, if the data field contains code. + +#### Parameters + +0. `Object` - [Transaction object with optional `condition` field](./JSONRPC.md#transactions). + +```js +params: [{ + "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", + "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", + "gas": "0x76c0", // 30400 + "gasPrice": "0x9184e72a000", // 10000000000000 + "value": "0x9184e72a", // 2441406250 + "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" +}] +``` + +#### Returns + +- `Hash` - 32 Bytes - the transaction hash, or the zero hash if the transaction is not yet available. + +Use [eth_getTransactionReceipt](#eth_gettransactionreceipt) to get the contract address, after the transaction was mined, when you created a contract. + +#### Example + +Request +```bash +curl --data '{"method":"eth_sendTransaction","params":[{"from":"0xb60e8dd61c5d32be8058bb8eb970870f07233155","to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","gas":"0x76c0","gasPrice":"0x9184e72a000","value":"0x9184e72a","data":"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"}],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" +} +``` + +*** + +### eth_sign + +The sign method calculates an Ethereum specific signature with: `sign(keccak256("Ethereum Signed Message: +" + len(message) + message)))`. + +**Note**: the address to sign with must be unlocked. + +#### Parameters + +0. `Address` - 20 Bytes - address. +0. `Data` - Data which hash to sign. + +```js +params: [ + "0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826", + "0x5363686f6f6c627573" // Schoolbus +] +``` + +#### Returns + +- `Data` - Signed data. + +#### Example + +Request +```bash +curl --data '{"method":"eth_sign","params":["0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826","0x5363686f6f6c627573"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": "0xb1092cb5b23c2aa55e5b5787729c6be812509376de99a52bea2b41e5a5f8601c5641e74d01e4493c17bf1ef8b179c49362b2c721222128d58422a539310c6ecd1b" +} +``` + +*** + +### eth_signTransaction + +Signs transactions without dispatching it to the network. It can be later submitted using [eth_sendRawTransaction](#eth_sendrawtransaction). + +**Note**: the address to sign with must be unlocked. + +#### Parameters + +1. `Object` - [Transaction object with optional `condition` field](./JSONRPC.md#transactions). See [eth_sendTransaction](#eth_sendTransaction). + +#### Returns + +- `Object` - Signed transaction and it's details: + - `raw`: `Data` - The signed, RLP encoded transaction. + - `tx`: `Object` - [Transaction Response Object](./JSONRPC.md#transaction-responses) + +#### Example + +Request +```bash +curl --data '{"method":"eth_signTransaction","params":[{ ... }],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": { + "raw": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675", + "tx": { + "hash": "0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b", + "nonce": "0x0", // 0 + "blockHash": "0xbeab0aa2411b7ab17f30a99d3cb9c6ef2fc5426d6ad6fd9e2a26a6aed1d1055b", + "blockNumber": "0x15df", // 5599 + "transactionIndex": "0x1", // 1 + "from": "0x407d73d8a49eeb85d32cf465507dd71d507100c1", + "to": "0x853f43d8a49eeb85d32cf465507dd71d507100c1", + "value": "0x7f110", // 520464 + "gas": "0x7f110", // 520464 + "gasPrice": "0x09184e72a000", + "input": "0x603880600c6000396000f300603880600c6000396000f3603880600c6000396000f360" + } + } +} +``` + +*** + +### eth_syncing + +Returns an object with data about the sync status or `false`. + +#### Parameters + +None + +#### Returns + +- `Object` - An object with sync status data or `FALSE`, when not syncing. + - `startingBlock`: `Quantity` - The block at which the import started (will only be reset, after the sync reached this head) + - `currentBlock`: `Quantity` - The current block, same as eth_blockNumber + - `highestBlock`: `Quantity` - The estimated highest block + - `blockGap`: `Array` - Array of "first", "last", such that [first, last) are all missing from the chain + - `warpChunksAmount`: `Quantity` - Total amount of snapshot chunks + - `warpChunksProcessed`: `Quantity` - Total amount of snapshot chunks processed + +#### Example + +Request +```bash +curl --data '{"method":"eth_syncing","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": { + "startingBlock": "0x384", // 900 + "currentBlock": "0x386", // 902 + "highestBlock": "0x454" // 1108 + } // Or `false` when not syncing +} +``` + +*** + +### eth_uninstallFilter + +Uninstalls a filter with given id. Should always be called when watch is no longer needed. +Additonally Filters timeout when they aren't requested with [eth_getFilterChanges](#eth_getfilterchanges) for a period of time. + +#### Parameters + +0. `Quantity` - The filter id. + +```js +params: [ + "0xb" // 11 +] +``` + +#### Returns + +- `Boolean` - `true` if the filter was successfully uninstalled, otherwise `false`. + +#### Example + +Request +```bash +curl --data '{"method":"eth_uninstallFilter","params":["0xb"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` + +Response +```js +{ + "id": 1, + "jsonrpc": "2.0", + "result": true +} +``` + diff --git a/eth/backend.go b/eth/backend.go index 1b7b4df0..91a2ed0a 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -207,6 +207,9 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { } eth.txPool = core.NewTxPool(config.TxPool, chainConfig, eth.blockchain) + // set blockchain for p2pServer + eth.p2pServer.Chain = eth.blockchain + // Permit the downloader to use the trie cache allowance during fast sync cacheLimit := cacheConfig.TrieCleanLimit + cacheConfig.TrieDirtyLimit + cacheConfig.SnapshotLimit checkpoint := config.Checkpoint diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 4c86af98..e37eaa78 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -81,13 +81,13 @@ var Defaults = Config{ TrieTimeout: 60 * time.Minute, SnapshotCache: 102, Miner: miner.Config{ - GasFloor: 8000000, - GasCeil: 8000000, + GasFloor: 40000000, + GasCeil: 40000000, GasPrice: big.NewInt(params.GWei), Recommit: 1 * time.Second, }, TxPool: core.DefaultTxPoolConfig, - RPCGasCap: 25000000, + RPCGasCap: 40000000, GPO: FullNodeGPO, RPCTxFeeCap: 1, // 1 ether } diff --git a/go.sum b/go.sum index 9a2743f4..18deb401 100644 --- a/go.sum +++ b/go.sum @@ -61,7 +61,6 @@ github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/Workiva/go-datastructures v1.0.50/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= -github.com/Workiva/go-datastructures v1.0.52 h1:PLSK6pwn8mYdaoaCZEMsXBpBotr4HHn9abU0yMQt0NI= github.com/Workiva/go-datastructures v1.0.52/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20210329093354-1b8e0a7a2e25 h1:DFzNXEpvnU8Wdo2+51OptoHY/WJQenrhJFslbQydRR0= github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20210329093354-1b8e0a7a2e25/go.mod h1:XLd05IRvH+nQt2lLvW6I2pfWBtRYE4i8Tpx45xBrlUE= @@ -208,7 +207,6 @@ github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= -github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -228,8 +226,6 @@ github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI= -github.com/fjl/gencodec v0.0.0-20191126094850-e283372f291f h1:Y/gg/utVetS+WS6htAKCTDralkm/8hLIIUAtLFdbdQ8= -github.com/fjl/gencodec v0.0.0-20191126094850-e283372f291f/go.mod h1:q+7Z5oyy8cvKF3TakcuihvQvBHFTnXjB+7UP1e2Q+1o= github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= @@ -240,8 +236,6 @@ github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 h1:IZqZOB2fydHte3kUgxrzK5E1fW7RQGeDwE8F/ZZnUYc= -github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gcash/bchd v0.14.7/go.mod h1:Gk/O1ktRVW5Kao0RsnVXp3bWxeYQadqawZ1Im9HE78M= @@ -480,7 +474,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= @@ -557,7 +550,6 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= @@ -568,12 +560,11 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/ontio/go-bip32 v0.0.0-20190520025953-d3cea6894a2b/go.mod h1:J0eVc7BEMmVVXbGv9PHoxjRSEwOwLr0qfzPk8Rdl5iw= -github.com/ontio/ontology v1.10.0/go.mod h1:Qw74bfTBlIQka+jQX4nXuWvyOYGGt368/V7XFxaf4tY= +github.com/ontio/ontology v1.10.0/go.mod h1:iok/imHJVQXi5/Yr88dcbrKBRHGdiota1ZC6qh6l6Rc= github.com/ontio/ontology v1.11.0/go.mod h1:Qw74bfTBlIQka+jQX4nXuWvyOYGGt368/V7XFxaf4tY= github.com/ontio/ontology v1.11.1-0.20200812075204-26cf1fa5dd47/go.mod h1:aoLM6pLdjBLx2CwC/AUtxdHvLZzAVqYH/xehh6/sRP4= github.com/ontio/ontology-crypto v1.0.9 h1:6fxBsz3W4CcdJk4/9QO7j0Qq7NdlP2ixPrViu8XpzzM= github.com/ontio/ontology-crypto v1.0.9/go.mod h1:h/jeqqb9Ma/Leszxqh6zY3eTF2yks44hyRKikMni+YQ= -github.com/ontio/ontology-eventbus v0.9.1 h1:nt3AXWx3gOyqtLiU4EwI92Yc4ik/pWHu9xRK15uHSOs= github.com/ontio/ontology-eventbus v0.9.1/go.mod h1:hCQIlbdPckcfykMeVUdWrqHZ8d30TBdmLfXCVWGkYhM= github.com/ontio/ontology-go-sdk v1.11.4/go.mod h1:fRhHYhFfYiUuIlTVtcXLVziiXOneBwVCSAX72+N7XVI= github.com/ontio/wagon v0.4.1/go.mod h1:oTPdgWT7WfPlEyzVaHSn1vQPMSbOpQPv+WphxibWlhg= @@ -588,7 +579,6 @@ github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxS github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6 h1:lNCW6THrCKBiJBpz8kbVGjC7MgdCGKwuvBgc7LoD6sw= github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -835,7 +825,6 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -975,12 +964,10 @@ golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191126055441-b0650ceb63d9/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1070,6 +1057,7 @@ gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200603215123-a4a8cb9d2cbc/go.mod h1:uAJ gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 h1:a6cXbcDDUkSBlpnkWV1bJ+vv3mOgQEltEJ2rPxroVu0= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0= diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index e9d230e2..81c46224 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -36,6 +36,7 @@ import ( "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/consensus/clique" "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/contracts/native/native_client" "github.com/ethereum/go-ethereum/contracts/native/utils" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" @@ -63,8 +64,8 @@ func NewPublicEthereumAPI(b Backend) *PublicEthereumAPI { // GasPrice returns a suggestion for a gas price. func (s *PublicEthereumAPI) GasPrice(ctx context.Context) (*hexutil.Big, error) { - price, err := s.b.SuggestPrice(ctx) - return (*hexutil.Big)(price), err + // price, err := s.b.SuggestPrice(ctx) + return (*hexutil.Big)(big.NewInt(1000000000)), nil } // Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not @@ -881,6 +882,11 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.Blo if state == nil || err != nil { return nil, err } + // check if address is blocked + if native_client.IsBlocked(state, args.From) || native_client.IsBlocked(state, args.To) { + return nil, native_client.ErrAccountBlocked + } + if err := overrides.Apply(state); err != nil { return nil, err } @@ -1766,6 +1772,23 @@ func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (c // SendTransaction creates a transaction for the given argument, sign it and submit it to the // transaction pool. func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) { + // get state + state, _, err := s.b.StateAndHeaderByNumber(ctx, rpc.LatestBlockNumber) + if state == nil || err != nil { + return common.Hash{}, err + } + // check if address is blocked + if native_client.IsBlocked(state, &args.From) || native_client.IsBlocked(state, args.To) { + return common.Hash{}, native_client.ErrAccountBlocked + } + // gas manager check + if args.Value.ToInt().Cmp(common.Big0) > 0 { + if native_client.IsGasManageEnable(state) && !native_client.IsGasManager(state, &args.From) && + !native_client.IsGasManager(state, args.To) && !native_client.IsGasUser(state, args.To) { + return common.Hash{}, native_client.ErrNotGasManager + } + } + // Look up the wallet containing the requested signer account := accounts.Account{Address: args.From} @@ -1818,6 +1841,24 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, input if err := tx.UnmarshalBinary(input); err != nil { return common.Hash{}, err } + // get state + from, _ := types.Sender(s.signer, tx) + state, _, err := s.b.StateAndHeaderByNumber(ctx, rpc.LatestBlockNumber) + if state == nil || err != nil { + return common.Hash{}, err + } + // check if address is blocked + if native_client.IsBlocked(state, &from) || native_client.IsBlocked(state, tx.To()) { + return common.Hash{}, native_client.ErrAccountBlocked + } + // gas manager check + if tx.Value().Cmp(common.Big0) > 0 { + if native_client.IsGasManageEnable(state) && !native_client.IsGasManager(state, &from) && + !native_client.IsGasManager(state, tx.To()) && !native_client.IsGasUser(state, tx.To()) { + return common.Hash{}, native_client.ErrNotGasManager + } + } + return SubmitTransaction(ctx, s.b, tx) } diff --git a/miner/worker.go b/miner/worker.go index 32eee2cb..2a8614a0 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -990,19 +990,14 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64) commitUncles(w.localUncles) commitUncles(w.remoteUncles) - // Create an empty block based on temporary copied state for - // sealing in advance without waiting block execution finished. - if !noempty && atomic.LoadUint32(&w.noempty) == 0 { - w.commit(uncles, nil, false, tstart) - } - // Fill the block with all available pending transactions. pending, _ := w.eth.TxPool().Pending() // Short circuit if there is no available pending transactions. // But if we disable empty precommit already, ignore it. Since // empty block is necessary to keep the liveness of the network. - if len(pending) == 0 && atomic.LoadUint32(&w.noempty) == 0 { + if !noempty && len(pending) == 0 && atomic.LoadUint32(&w.noempty) == 0 { + w.commit(uncles, nil, false, tstart) w.updateSnapshot() return } diff --git a/node-whitelist.json b/node-whitelist.json new file mode 100644 index 00000000..fc20011f --- /dev/null +++ b/node-whitelist.json @@ -0,0 +1,6 @@ +{ + "nodeWhiteEnable": false, + "nodeWhitelist": [ + "" + ] +} \ No newline at end of file diff --git a/node/config.go b/node/config.go index ef1da15d..bbb0774f 100644 --- a/node/config.go +++ b/node/config.go @@ -92,6 +92,9 @@ type Config struct { // InsecureUnlockAllowed allows user to unlock accounts in unsafe http environment. InsecureUnlockAllowed bool `toml:",omitempty"` + // Node whitelist config file path. + NodeWhitePath string `toml:",omitempty"` + // NoUSB disables hardware wallet monitoring and connectivity. NoUSB bool `toml:",omitempty"` @@ -365,9 +368,20 @@ func (c *Config) NodeKey() *ecdsa.PrivateKey { } keyfile := c.ResolvePath(datadirPrivateKey) - if key, err := crypto.LoadECDSA(keyfile); err == nil { + if _, err := os.Stat(keyfile); err == nil { + if key, err := crypto.LoadECDSA(keyfile); err == nil { + return key + } + + nodePassword := os.Getenv("NODE_PASS") + key, err := loadKeyStore(keyfile, nodePassword) + if err != nil { + log.Error(fmt.Sprintf("Failed to load load keystore %v", err)) + return nil + } return key } + // No persistent key found, generate and store a new one. key, err := crypto.GenerateKey() if err != nil { @@ -385,6 +399,19 @@ func (c *Config) NodeKey() *ecdsa.PrivateKey { return key } +func loadKeyStore(file, password string) (*ecdsa.PrivateKey, error) { + enc, err := ioutil.ReadFile(file) + if err != nil { + return nil, err + } + + key, err := keystore.DecryptKey(enc, password) + if err != nil { + return nil, err + } + return key.PrivateKey, nil +} + // StaticNodes returns a list of node enode URLs configured as static nodes. func (c *Config) StaticNodes() []*enode.Node { return c.parsePersistentNodes(&c.staticNodesWarning, c.ResolvePath(datadirStaticNodes)) diff --git a/p2p/server.go b/p2p/server.go index f70ebf72..7115e918 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -31,6 +31,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" @@ -39,6 +41,7 @@ import ( "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/p2p/nat" "github.com/ethereum/go-ethereum/p2p/netutil" + "github.com/ethereum/go-ethereum/params" ) const ( @@ -158,11 +161,22 @@ type Config struct { clock mclock.Clock } +// blockChain provides the state of blockchain +// some pre checks in p2p Server. +type blockChain interface { + CurrentBlock() *types.Block + GetBlock(hash common.Hash, number uint64) *types.Block + StateAt(root common.Hash) (*state.StateDB, error) +} + // Server manages all peer connections. type Server struct { // Config fields may not be modified while the server is running. Config + // block chain + Chain blockChain + // Hooks for testing. These are useful because we can inhibit // the whole protocol stack. newTransport func(net.Conn, *ecdsa.PublicKey) transport @@ -959,6 +973,15 @@ func (srv *Server) setupConn(c *conn, flags connFlag, dialDest *enode.Node) erro srv.log.Trace("Failed RLPx handshake", "addr", c.fd.RemoteAddr(), "conn", c.flags, "err", err) return err } + + // check if address is in node whitelist + remoteAddr := crypto.PubkeyToAddress(*remotePubkey) + var nodeWhiteConfig = params.GetNodeWhiteConfig() + if !nodeWhiteConfig.CheckNodeWhitelist(&remoteAddr) { + srv.log.Trace("Node address not in whitelist", "addr", remoteAddr.String(), "err", params.ErrNodeWhitelist) + return params.ErrNodeWhitelist + } + if dialDest != nil { c.node = dialDest } else { diff --git a/params/node_whitelist.go b/params/node_whitelist.go new file mode 100644 index 00000000..e7aa0e0a --- /dev/null +++ b/params/node_whitelist.go @@ -0,0 +1,126 @@ +package params + +import ( + "encoding/json" + "errors" + "io/fs" + "io/ioutil" + "os" + "strings" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" +) + +var instance *nodeWhiteConfig +var mu sync.RWMutex +var once sync.Once + +var ( + // ErrNodeWhitelist is returned if the node address is not in whitelist + ErrNodeWhitelist = errors.New("### Node address is not in whitelist") +) + +// node whitelist config file +type nodeWhiteConfigFile struct { + NodeWhiteEnable bool `json:"nodeWhiteEnable"` // only the node address in NodeWhitelist can connect to this node with p2p network when the IpWhitelistEnable is true, default false + NodeWhitelist []string `json:"nodeWhitelist"` // node address whitelist +} + +type nodeWhiteConfig struct { + nodeWhiteEnable bool + nodeWhitelist map[string]struct{} +} + +func StartNodeWhiteLoadTask(filepath string) { + go func() { + var initialStat fs.FileInfo + + for { + stat, err := os.Stat(filepath) + if err != nil { + log.Warn("StartNodeWhiteLoadTask", "os.Stat error, filepath: "+filepath, err) + time.Sleep(time.Second) + continue + } + + if initialStat == nil || stat.Size() != initialStat.Size() || stat.ModTime() != initialStat.ModTime() { + err = loadNodeWhiteConfig(filepath) + initialStat = stat + if err != nil { + log.Warn("StartNodeWhiteLoadTask", "loadNodeWhiteConfig error, filepath: "+filepath, err) + } + } + + time.Sleep(time.Second) + } + }() +} + +func loadNodeWhiteConfig(path string) error { + config, err := ioutil.ReadFile(path) + if err != nil { + return err + } + var res *nodeWhiteConfigFile + if err := json.Unmarshal(config, &res); err != nil { + return err + } + + instance = GetNodeWhiteConfig() + mu.Lock() + defer mu.Unlock() + instance.nodeWhiteEnable = res.NodeWhiteEnable + instance.nodeWhitelist = convertToAddressMap(res.NodeWhitelist) + return nil +} + +func convertToAddressMap(list []string) map[string]struct{} { + var result = make(map[string]struct{}) + for _, s := range list { + // address format check + if common.IsHexAddress(s) { + // store address as lower case + result[strings.ToLower(s)] = struct{}{} + } + } + return result +} + +func GetNodeWhiteConfig() *nodeWhiteConfig { + once.Do(func() { + instance = &nodeWhiteConfig{} + }) + + return instance +} + +func (config *nodeWhiteConfig) CheckNodeWhitelist(addr *common.Address) bool { + mu.RLock() + defer mu.RUnlock() + + if !config.nodeWhiteEnable { + return true + } + + return isAddressInMap(addr, config.nodeWhitelist) +} + +func isAddressInMap(address *common.Address, m map[string]struct{}) bool { + if address == nil { + return false + } + + return isInMap(strings.ToLower(address.String()), m) +} + +func isInMap(s string, m map[string]struct{}) bool { + if len(m) == 0 { + return false + } + + _, ok := m[s] + return ok +} diff --git a/params/version.go b/params/version.go index 89969705..9ce38916 100644 --- a/params/version.go +++ b/params/version.go @@ -21,10 +21,10 @@ import ( ) const ( - VersionMajor = 1 // Major version component of the current release - VersionMinor = 10 // Minor version component of the current release - VersionPatch = 4 // Patch version component of the current release - VersionMeta = "unstable" // Version metadata to append to the version string + VersionMajor = 1 // Major version component of the current release + VersionMinor = 10 // Minor version component of the current release + VersionPatch = 4 // Patch version component of the current release + VersionMeta = "stable" // Version metadata to append to the version string ) // Version holds the textual version string.