diff options
author | Wei-Ning Huang <w@dexon.org> | 2019-03-21 16:54:37 +0800 |
---|---|---|
committer | Wei-Ning Huang <w@byzantine-lab.io> | 2019-06-13 18:11:44 +0800 |
commit | 22631478cadc0f6a21a219af4399b86619240606 (patch) | |
tree | 327ec5b9ab71f67e667e32dbbb6db3c09cbc7665 /dex/recovery.go | |
parent | 33f98f535d3f79d9d915ac57255aeee5d83ef81d (diff) | |
download | go-tangerine-22631478cadc0f6a21a219af4399b86619240606.tar go-tangerine-22631478cadc0f6a21a219af4399b86619240606.tar.gz go-tangerine-22631478cadc0f6a21a219af4399b86619240606.tar.bz2 go-tangerine-22631478cadc0f6a21a219af4399b86619240606.tar.lz go-tangerine-22631478cadc0f6a21a219af4399b86619240606.tar.xz go-tangerine-22631478cadc0f6a21a219af4399b86619240606.tar.zst go-tangerine-22631478cadc0f6a21a219af4399b86619240606.zip |
dex: skip duplicate vote to reduce gas used (#293)
Diffstat (limited to 'dex/recovery.go')
-rw-r--r-- | dex/recovery.go | 72 |
1 files changed, 45 insertions, 27 deletions
diff --git a/dex/recovery.go b/dex/recovery.go index 0e5c60e1a..4c3da7d5a 100644 --- a/dex/recovery.go +++ b/dex/recovery.go @@ -20,6 +20,7 @@ package dex import ( "crypto/ecdsa" "encoding/hex" + "errors" "fmt" "math/big" "strconv" @@ -29,6 +30,7 @@ import ( "github.com/dexon-foundation/dexon/common" "github.com/dexon-foundation/dexon/core/types" "github.com/dexon-foundation/dexon/crypto" + "github.com/dexon-foundation/dexon/log" "github.com/dexon-foundation/dexon/params" "github.com/dexon-foundation/dexon/rlp" "github.com/onrik/ethrpc" @@ -296,6 +298,8 @@ const recoveryABI = ` ] ` +var errAlreadyVoted = errors.New("already voted for recovery") + var abiObject abi.ABI func init() { @@ -328,6 +332,23 @@ func NewRecovery(config *params.RecoveryConfig, networkRPC string, } } +func (r *Recovery) callRPC(data []byte, tag string) ([]byte, error) { + res, err := r.client.EthCall(ethrpc.T{ + From: r.nodeAddress.String(), + To: r.contract.String(), + Data: "0x" + hex.EncodeToString(data), + }, tag) + if err != nil { + return nil, err + } + + resBytes, err := hex.DecodeString(res[2:]) + if err != nil { + return nil, err + } + return resBytes, nil +} + func (r *Recovery) genVoteForSkipBlockTx(height uint64) (*types.Transaction, error) { netVersion, err := r.client.NetVersion() if err != nil { @@ -339,21 +360,33 @@ func (r *Recovery) genVoteForSkipBlockTx(height uint64) (*types.Transaction, err return nil, err } - data, err := abiObject.Pack("depositValue") + data, err := abiObject.Pack("voted", big.NewInt(int64(height)), r.nodeAddress) if err != nil { return nil, err } - res, err := r.client.EthCall(ethrpc.T{ - From: r.nodeAddress.String(), - To: r.contract.String(), - Data: "0x" + hex.EncodeToString(data), - }, "latest") + resBytes, err := r.callRPC(data, "latest") if err != nil { return nil, err } - resBytes, err := hex.DecodeString(res[2:]) + var voted bool + err = abiObject.Unpack(&voted, "voted", resBytes) + if err != nil { + return nil, err + } + + if voted { + log.Info("Already voted for skip block", "height", height) + return nil, errAlreadyVoted + } + + data, err = abiObject.Pack("depositValue") + if err != nil { + return nil, err + } + + resBytes, err = r.callRPC(data, "latest") if err != nil { return nil, err } @@ -397,6 +430,9 @@ func (r *Recovery) genVoteForSkipBlockTx(height uint64) (*types.Transaction, err func (r *Recovery) ProposeSkipBlock(height uint64) error { tx, err := r.genVoteForSkipBlockTx(height) + if err == errAlreadyVoted { + return nil + } if err != nil { return err } @@ -422,16 +458,7 @@ func (r *Recovery) Votes(height uint64) (uint64, error) { snapshotHeight := bn - numConfirmation - res, err := r.client.EthCall(ethrpc.T{ - From: r.nodeAddress.String(), - To: r.contract.String(), - Data: "0x" + hex.EncodeToString(data), - }, fmt.Sprintf("0x%x", snapshotHeight)) - if err != nil { - return 0, err - } - - resBytes, err := hex.DecodeString(res[2:]) + resBytes, err := r.callRPC(data, fmt.Sprintf("0x%x", snapshotHeight)) if err != nil { return 0, err } @@ -456,16 +483,7 @@ func (r *Recovery) Votes(height uint64) (uint64, error) { return 0, err } - res, err = r.client.EthCall(ethrpc.T{ - From: r.nodeAddress.String(), - To: r.contract.String(), - Data: "0x" + hex.EncodeToString(data), - }, fmt.Sprintf("0x%x", snapshotHeight)) - if err != nil { - return 0, err - } - - resBytes, err := hex.DecodeString(res[2:]) + resBytes, err := r.callRPC(data, fmt.Sprintf("0x%x", snapshotHeight)) if err != nil { return 0, err } |