add: filecoin message validation, secp signature
This commit is contained in:
parent
221cf45dad
commit
a42776be67
@ -28,7 +28,7 @@ func ComputeVRF(sign SignFunc, worker peer.ID, sigInput []byte) ([]byte, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func VerifyVRF(worker peer.ID, vrfBase, vrfproof []byte) error {
|
func VerifyVRF(worker peer.ID, vrfBase, vrfproof []byte) error {
|
||||||
err := sigs.Verify(&types.Signature{Type: types.SigTypeEd25519, Data: vrfproof}, worker, vrfBase)
|
err := sigs.Verify(&types.Signature{Type: types.SigTypeEd25519, Data: vrfproof}, []byte(worker), vrfBase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("vrf was invalid: %w", err)
|
return xerrors.Errorf("vrf was invalid: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,6 @@ func (m *Miner) MineTask(ctx context.Context, event *oracleEmitter.OracleEmitter
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("couldn't do rpc request: %w", err)
|
return nil, xerrors.Errorf("couldn't do rpc request: %w", err)
|
||||||
}
|
}
|
||||||
bres := []byte(res)
|
|
||||||
|
|
||||||
return &types.DioneTask{
|
return &types.DioneTask{
|
||||||
OriginChain: event.OriginChain,
|
OriginChain: event.OriginChain,
|
||||||
@ -143,7 +142,7 @@ func (m *Miner) MineTask(ctx context.Context, event *oracleEmitter.OracleEmitter
|
|||||||
Ticket: ticket,
|
Ticket: ticket,
|
||||||
ElectionProof: winner,
|
ElectionProof: winner,
|
||||||
BeaconEntries: beaconValues,
|
BeaconEntries: beaconValues,
|
||||||
Payload: bres,
|
Payload: res,
|
||||||
DrandRound: types.DrandRound(randomBase.Round),
|
DrandRound: types.DrandRound(randomBase.Round),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package consensus
|
package consensus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
oracleEmitter "github.com/Secured-Finance/dione/contracts/oracleemitter"
|
oracleEmitter "github.com/Secured-Finance/dione/contracts/oracleemitter"
|
||||||
@ -9,7 +10,9 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/crypto"
|
"github.com/filecoin-project/go-state-types/crypto"
|
||||||
|
|
||||||
|
ftypes "github.com/Secured-Finance/dione/rpc/filecoin/types"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/filecoin-project/go-state-types/crypto"
|
||||||
|
|
||||||
types2 "github.com/Secured-Finance/dione/consensus/types"
|
types2 "github.com/Secured-Finance/dione/consensus/types"
|
||||||
"github.com/Secured-Finance/dione/sigs"
|
"github.com/Secured-Finance/dione/sigs"
|
||||||
@ -92,6 +95,18 @@ func (ppp *PrePreparePool) IsValidPrePrepare(prePrepare *types2.Message) bool {
|
|||||||
|
|
||||||
logrus.Errorf("the incoming task and cached request event don't match!")
|
logrus.Errorf("the incoming task and cached request event don't match!")
|
||||||
return false
|
return false
|
||||||
|
// === verify filecoin message signature ===
|
||||||
|
if consensusMsg.Task.RequestType == "GetTransaction" && consensusMsg.Task.OriginChain == 1 {
|
||||||
|
var msg ftypes.SignedMessage
|
||||||
|
if err := msg.UnmarshalCBOR(bytes.NewReader(consensusMsg.Task.Payload)); err != nil {
|
||||||
|
if err := msg.Message.UnmarshalCBOR(bytes.NewReader(consensusMsg.Task.Payload)); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = sigs.Verify(msg.Signature, msg.Message.From.Bytes(), msg.Message.Cid().Bytes()); err != nil {
|
||||||
|
logrus.Errorf("Couldn't verify transaction %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ func verifyTaskSignature(msg types.ConsensusMessage) error {
|
|||||||
}
|
}
|
||||||
err = sigs.Verify(
|
err = sigs.Verify(
|
||||||
&types2.Signature{Type: types2.SigTypeEd25519, Data: msg.Signature},
|
&types2.Signature{Type: types2.SigTypeEd25519, Data: msg.Signature},
|
||||||
msg.Task.Miner,
|
[]byte(msg.Task.Miner.String()),
|
||||||
[]byte(fmt.Sprintf("%v", cHash)),
|
[]byte(fmt.Sprintf("%v", cHash)),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
2
eth-contracts/.soliumignore
Normal file
2
eth-contracts/.soliumignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
node_modules
|
||||||
|
contracts/Migrations.sol
|
20
eth-contracts/.soliumrc.json
Normal file
20
eth-contracts/.soliumrc.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"extends": "solium:recommended",
|
||||||
|
"plugins": [
|
||||||
|
"security"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"quotes": [
|
||||||
|
"error",
|
||||||
|
"double"
|
||||||
|
],
|
||||||
|
"indentation": [
|
||||||
|
"error",
|
||||||
|
4
|
||||||
|
],
|
||||||
|
"linebreak-style": [
|
||||||
|
"error",
|
||||||
|
"unix"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -4,14 +4,19 @@ pragma solidity ^0.6.12;
|
|||||||
import "@openzeppelin/contracts/math/SafeMath.sol";
|
import "@openzeppelin/contracts/math/SafeMath.sol";
|
||||||
import "@openzeppelin/contracts/access/Ownable.sol";
|
import "@openzeppelin/contracts/access/Ownable.sol";
|
||||||
|
|
||||||
import "./interfaces/DioneStakingInterface.sol";
|
import "./interfaces/IDioneStaking.sol";
|
||||||
|
|
||||||
contract DioneOracle is Ownable {
|
contract DioneOracle is Ownable {
|
||||||
using SafeMath for uint256;
|
using SafeMath for uint256;
|
||||||
|
|
||||||
|
// Global counter of oracle requests, works as an index in mapping structures
|
||||||
uint256 private requestCounter;
|
uint256 private requestCounter;
|
||||||
|
// Maximum time for computing oracle request
|
||||||
uint256 constant public MAXIMUM_DELAY = 5 minutes;
|
uint256 constant public MAXIMUM_DELAY = 5 minutes;
|
||||||
DioneStakingInterface public dioneStaking;
|
// Dione staking contract
|
||||||
|
IDioneStaking public dioneStaking;
|
||||||
|
// Minimum amount of DIONE tokens required to vote against miner result
|
||||||
|
uint256 public minimumDisputeFee = 100**18;
|
||||||
|
|
||||||
struct OracleRequest {
|
struct OracleRequest {
|
||||||
uint8 originChain; // origin blockchain for request
|
uint8 originChain; // origin blockchain for request
|
||||||
@ -51,7 +56,7 @@ contract DioneOracle is Ownable {
|
|||||||
);
|
);
|
||||||
|
|
||||||
modifier onlyPendingRequest(uint256 _reqID) {
|
modifier onlyPendingRequest(uint256 _reqID) {
|
||||||
require(pendingRequests[_reqID] != 0, "Invalid requestId");
|
require(pendingRequests[_reqID] != 0, "This request is not pending");
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +65,7 @@ contract DioneOracle is Ownable {
|
|||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(DioneStakingInterface _dioneStaking) public {
|
constructor(IDioneStaking _dioneStaking) public {
|
||||||
dioneStaking = _dioneStaking;
|
dioneStaking = _dioneStaking;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +88,7 @@ contract DioneOracle is Ownable {
|
|||||||
emit CancelOracleRequest(_reqID);
|
emit CancelOracleRequest(_reqID);
|
||||||
}
|
}
|
||||||
|
|
||||||
function submitOracleRequest(string memory _requestParams, address _callbackAddress, bytes4 _callbackMethodID, uint256 _reqID, uint256 _requestDeadline, bytes memory _data) public onlyActiveNode returns (bool) {
|
function submitOracleRequest(string memory _requestParams, address _callbackAddress, bytes4 _callbackMethodID, uint256 _reqID, uint256 _requestDeadline, bytes memory _data) public onlyPendingRequest(_reqID) onlyActiveNode returns (bool) {
|
||||||
bytes32 requestHash = keccak256(abi.encodePacked(_requestParams, _callbackAddress, _callbackMethodID, _reqID, _requestDeadline));
|
bytes32 requestHash = keccak256(abi.encodePacked(_requestParams, _callbackAddress, _callbackMethodID, _reqID, _requestDeadline));
|
||||||
require(pendingRequests[_reqID] == requestHash, "Params do not match request ID");
|
require(pendingRequests[_reqID] == requestHash, "Params do not match request ID");
|
||||||
delete pendingRequests[_reqID];
|
delete pendingRequests[_reqID];
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
pragma solidity ^0.6.0;
|
pragma solidity ^0.6.0;
|
||||||
|
|
||||||
interface DioneStakingInterface {
|
interface IDioneStaking {
|
||||||
function mine(address _minerAddr) external;
|
function mine(address _minerAddr) external;
|
||||||
function mineAndStake(address _minerAddr) external;
|
function mineAndStake(address _minerAddr) external;
|
||||||
function stake(uint256 _amount) external;
|
function stake(uint256 _amount) external;
|
125
eth-contracts/contracts/interfaces/IDioneToken.sol
Normal file
125
eth-contracts/contracts/interfaces/IDioneToken.sol
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
pragma solidity >=0.6.0 <0.8.0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Interface of the ERC20 standard as defined in the EIP.
|
||||||
|
*/
|
||||||
|
interface IDioneToken {
|
||||||
|
/**
|
||||||
|
* @dev Returns the amount of tokens in existence.
|
||||||
|
*/
|
||||||
|
function totalSupply() external view returns (uint256);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Returns the amount of tokens owned by `account`.
|
||||||
|
*/
|
||||||
|
function balanceOf(address account) external view returns (uint256);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Moves `amount` tokens from the caller's account to `recipient`.
|
||||||
|
*
|
||||||
|
* Returns a boolean value indicating whether the operation succeeded.
|
||||||
|
*
|
||||||
|
* Emits a {Transfer} event.
|
||||||
|
*/
|
||||||
|
function transfer(address recipient, uint256 amount) external returns (bool);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Returns the remaining number of tokens that `spender` will be
|
||||||
|
* allowed to spend on behalf of `owner` through {transferFrom}. This is
|
||||||
|
* zero by default.
|
||||||
|
*
|
||||||
|
* This value changes when {approve} or {transferFrom} are called.
|
||||||
|
*/
|
||||||
|
function allowance(address owner, address spender) external view returns (uint256);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
|
||||||
|
*
|
||||||
|
* Returns a boolean value indicating whether the operation succeeded.
|
||||||
|
*
|
||||||
|
* IMPORTANT: Beware that changing an allowance with this method brings the risk
|
||||||
|
* that someone may use both the old and the new allowance by unfortunate
|
||||||
|
* transaction ordering. One possible solution to mitigate this race
|
||||||
|
* condition is to first reduce the spender's allowance to 0 and set the
|
||||||
|
* desired value afterwards:
|
||||||
|
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
|
||||||
|
*
|
||||||
|
* Emits an {Approval} event.
|
||||||
|
*/
|
||||||
|
function approve(address spender, uint256 amount) external returns (bool);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Moves `amount` tokens from `sender` to `recipient` using the
|
||||||
|
* allowance mechanism. `amount` is then deducted from the caller's
|
||||||
|
* allowance.
|
||||||
|
*
|
||||||
|
* Returns a boolean value indicating whether the operation succeeded.
|
||||||
|
*
|
||||||
|
* Emits a {Transfer} event.
|
||||||
|
*/
|
||||||
|
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Emitted when `value` tokens are moved from one account (`from`) to
|
||||||
|
* another (`to`).
|
||||||
|
*
|
||||||
|
* Note that `value` may be zero.
|
||||||
|
*/
|
||||||
|
event Transfer(address indexed from, address indexed to, uint256 value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
|
||||||
|
* a call to {approve}. `value` is the new allowance.
|
||||||
|
*/
|
||||||
|
event Approval(address indexed owner, address indexed spender, uint256 value);
|
||||||
|
|
||||||
|
/// @notice Creates `_amount` token to `_to`. Must only be called by the owner (MasterChef).
|
||||||
|
function mint(address _to, uint256 _amount) external;
|
||||||
|
|
||||||
|
/// @notice An event thats emitted when an account changes its delegate
|
||||||
|
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
|
||||||
|
|
||||||
|
/// @notice An event thats emitted when a delegate account's vote balance changes
|
||||||
|
event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @notice Delegate votes from `msg.sender` to `delegatee`
|
||||||
|
* @param delegator The address to get delegatee for
|
||||||
|
*/
|
||||||
|
function delegates(address delegator) external view returns (address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @notice Delegate votes from `msg.sender` to `delegatee`
|
||||||
|
* @param delegatee The address to delegate votes to
|
||||||
|
*/
|
||||||
|
function delegate(address delegatee) external;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @notice Delegates votes from signatory to `delegatee`
|
||||||
|
* @param delegatee The address to delegate votes to
|
||||||
|
* @param nonce The contract state required to match the signature
|
||||||
|
* @param expiry The time at which to expire the signature
|
||||||
|
* @param v The recovery byte of the signature
|
||||||
|
* @param r Half of the ECDSA signature pair
|
||||||
|
* @param s Half of the ECDSA signature pair
|
||||||
|
*/
|
||||||
|
function delegateBySig(address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s) external;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @notice Gets the current votes balance for `account`
|
||||||
|
* @param account The address to get votes balance
|
||||||
|
* @return The number of current votes for `account`
|
||||||
|
*/
|
||||||
|
function getCurrentVotes(address account) external view returns (uint256);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @notice Determine the prior number of votes for an account as of a block number
|
||||||
|
* @dev Block number must be a finalized block or else this function will revert to prevent misinformation.
|
||||||
|
* @param account The address of the account to check
|
||||||
|
* @param blockNumber The block number to get the vote balance at
|
||||||
|
* @return The number of votes the account had as of the given block
|
||||||
|
*/
|
||||||
|
function getPriorVotes(address account, uint blockNumber) external view returns (uint256);
|
||||||
|
}
|
1899
eth-contracts/package-lock.json
generated
1899
eth-contracts/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -8,13 +8,15 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"compile": "truffle compile"
|
"compile": "truffle compile",
|
||||||
|
"fix-lint": "solium -d contracts/ --fix"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@truffle/hdwallet-provider": "^1.0.40",
|
"@truffle/hdwallet-provider": "^1.0.40",
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
|
"ethlint": "^1.2.5",
|
||||||
"truffle": "^5.1.37",
|
"truffle": "^5.1.37",
|
||||||
"truffle-export-abi": "^1.0.1",
|
"truffle-export-abi": "^1.0.1",
|
||||||
"truffle-flattener": "^1.5.0"
|
"truffle-flattener": "^1.5.0"
|
||||||
|
16
go.mod
16
go.mod
@ -16,8 +16,10 @@ require (
|
|||||||
github.com/drand/kyber v1.1.5
|
github.com/drand/kyber v1.1.5
|
||||||
github.com/elastic/gosigar v0.10.5 // indirect
|
github.com/elastic/gosigar v0.10.5 // indirect
|
||||||
github.com/ethereum/go-ethereum v1.9.5
|
github.com/ethereum/go-ethereum v1.9.5
|
||||||
github.com/filecoin-project/go-address v0.0.4
|
github.com/filecoin-project/go-address v0.0.5-0.20201103152444-f2023ef3f5bb
|
||||||
github.com/filecoin-project/go-state-types v0.0.0-20201021025442-0ac4de847f4f
|
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03
|
||||||
|
github.com/filecoin-project/go-state-types v0.0.0-20201102161440-c8033295a1fc
|
||||||
|
github.com/filecoin-project/lotus v1.2.1
|
||||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
|
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
|
||||||
github.com/fxamacker/cbor/v2 v2.2.0
|
github.com/fxamacker/cbor/v2 v2.2.0
|
||||||
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect
|
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect
|
||||||
@ -30,18 +32,16 @@ require (
|
|||||||
github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect
|
github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect
|
||||||
github.com/ipfs/go-datastore v0.4.5 // indirect
|
github.com/ipfs/go-datastore v0.4.5 // indirect
|
||||||
github.com/ipfs/go-ds-badger2 v0.1.1-0.20200708190120-187fc06f714e // indirect
|
github.com/ipfs/go-ds-badger2 v0.1.1-0.20200708190120-187fc06f714e // indirect
|
||||||
github.com/ipfs/go-ipld-cbor v0.0.5-0.20200428170625-a0bd04d3cbdf // indirect
|
|
||||||
github.com/ipfs/go-ipld-format v0.2.0 // indirect
|
github.com/ipfs/go-ipld-format v0.2.0 // indirect
|
||||||
github.com/ipfs/go-log v1.0.4
|
github.com/ipfs/go-log v1.0.4
|
||||||
github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4 // indirect
|
github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4 // indirect
|
||||||
github.com/jmoiron/sqlx v1.2.0
|
github.com/jmoiron/sqlx v1.2.0
|
||||||
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 // indirect
|
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 // indirect
|
||||||
github.com/lib/pq v1.7.0 // indirect
|
github.com/lib/pq v1.7.0 // indirect
|
||||||
github.com/libp2p/go-libp2p v0.11.0
|
github.com/libp2p/go-libp2p v0.12.0
|
||||||
github.com/libp2p/go-libp2p-core v0.6.1
|
github.com/libp2p/go-libp2p-core v0.7.0
|
||||||
github.com/libp2p/go-libp2p-noise v0.1.2 // indirect
|
github.com/libp2p/go-libp2p-noise v0.1.2 // indirect
|
||||||
github.com/libp2p/go-libp2p-pubsub v0.3.6
|
github.com/libp2p/go-libp2p-pubsub v0.4.0
|
||||||
github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8 // indirect
|
|
||||||
github.com/mattn/go-colorable v0.1.6 // indirect
|
github.com/mattn/go-colorable v0.1.6 // indirect
|
||||||
github.com/mattn/go-sqlite3 v1.9.0
|
github.com/mattn/go-sqlite3 v1.9.0
|
||||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1
|
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1
|
||||||
@ -69,7 +69,7 @@ require (
|
|||||||
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 // indirect
|
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 // indirect
|
||||||
github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542
|
github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542
|
||||||
go.uber.org/fx v1.13.1 // indirect
|
go.uber.org/fx v1.13.1 // indirect
|
||||||
go.uber.org/zap v1.15.0
|
go.uber.org/zap v1.16.0
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
|
||||||
golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3 // indirect
|
golang.org/x/tools v0.0.0-20200827010519-17fd2f27a9e3 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
|
||||||
|
@ -131,7 +131,7 @@ func (n *Node) Run(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
// return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) runLibp2pAsync(ctx context.Context) error {
|
func (n *Node) runLibp2pAsync(ctx context.Context) error {
|
||||||
@ -271,12 +271,12 @@ func provideEthereumClient(config *config.Config) (*ethclient.EthereumClient, er
|
|||||||
|
|
||||||
func (n *Node) setupRPCClients() error {
|
func (n *Node) setupRPCClients() error {
|
||||||
fc := filecoin.NewLotusClient()
|
fc := filecoin.NewLotusClient()
|
||||||
rpc.RegisterRPC(rtypes.RPCTypeFilecoin, map[string]func(string) (string, error){
|
rpc.RegisterRPC(rtypes.RPCTypeFilecoin, map[string]func(string) ([]byte, error){
|
||||||
"getTransaction": fc.GetTransaction,
|
"getTransaction": fc.GetTransaction,
|
||||||
})
|
})
|
||||||
|
|
||||||
sl := solana2.NewSolanaClient()
|
sl := solana2.NewSolanaClient()
|
||||||
rpc.RegisterRPC(rtypes.RPCTypeSolana, map[string]func(string) (string, error){
|
rpc.RegisterRPC(rtypes.RPCTypeSolana, map[string]func(string) ([]byte, error){
|
||||||
"getTransaction": sl.GetTransaction,
|
"getTransaction": sl.GetTransaction,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package filecoin
|
package filecoin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
ftypes "github.com/Secured-Finance/dione/rpc/filecoin/types"
|
ftypes "github.com/Secured-Finance/dione/rpc/filecoin/types"
|
||||||
"github.com/Secured-Finance/dione/rpc/types"
|
"github.com/Secured-Finance/dione/rpc/types"
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/valyala/fasthttp"
|
"github.com/valyala/fasthttp"
|
||||||
@ -13,6 +15,11 @@ import (
|
|||||||
|
|
||||||
var filecoinURL = "https://api.node.glif.io/"
|
var filecoinURL = "https://api.node.glif.io/"
|
||||||
|
|
||||||
|
const (
|
||||||
|
blsType = 0x1
|
||||||
|
secp256k1Type = 0x2
|
||||||
|
)
|
||||||
|
|
||||||
// client implements the `Client` interface.
|
// client implements the `Client` interface.
|
||||||
type LotusClient struct {
|
type LotusClient struct {
|
||||||
host string
|
host string
|
||||||
@ -38,11 +45,11 @@ func (c *LotusClient) GetTipSetByHeight(chainEpoch int64) ([]byte, error) {
|
|||||||
return c.HandleRequest("Filecoin.ChainGetTipSetByHeight", i)
|
return c.HandleRequest("Filecoin.ChainGetTipSetByHeight", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *LotusClient) GetTransaction(cid string) (string, error) {
|
// func (c *LotusClient) GetTransaction(cid string) (string, error) {
|
||||||
i := ftypes.NewCidParam(cid)
|
// i := ftypes.NewCidParam(cid)
|
||||||
resp, err := c.HandleRequest("Filecoin.ChainGetMessage", i)
|
// resp, err := c.HandleRequest("Filecoin.ChainGetMessage", i)
|
||||||
return string(resp), err
|
// return string(resp), err
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (c *LotusClient) GetNodeVersion() ([]byte, error) {
|
func (c *LotusClient) GetNodeVersion() ([]byte, error) {
|
||||||
return c.HandleRequest("Filecoin.Version", nil)
|
return c.HandleRequest("Filecoin.Version", nil)
|
||||||
@ -57,6 +64,42 @@ func (c *LotusClient) VerifyCid(cid string) ([]byte, error) {
|
|||||||
return c.HandleRequest("Filecoin.ChainHasObj", i)
|
return c.HandleRequest("Filecoin.ChainHasObj", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gets signed transaction from Filecoin and returns SignedTransaction struct in byte slice
|
||||||
|
func (c *LotusClient) GetTransaction(cid string) ([]byte, error) {
|
||||||
|
i := ftypes.NewCidParam(cid)
|
||||||
|
bodyBytes, err := c.HandleRequest("Filecoin.ChainReadObj", i)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Failed to get object information %v", err)
|
||||||
|
}
|
||||||
|
var response types.RPCResponseBody
|
||||||
|
err = json.Unmarshal(bodyBytes, &response)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Failed to unmarshal response body %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg ftypes.SignedMessage
|
||||||
|
if err := msg.UnmarshalCBOR(bytes.NewReader(response.Result)); err != nil {
|
||||||
|
if err := msg.Message.UnmarshalCBOR(bytes.NewReader(response.Result)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch msg.Message.From.Protocol() | msg.Message.To.Protocol() {
|
||||||
|
case address.BLS:
|
||||||
|
msg.Type = blsType
|
||||||
|
case address.SECP256K1:
|
||||||
|
msg.Type = secp256k1Type
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Address has unsupported protocol %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b := new(bytes.Buffer)
|
||||||
|
if err := msg.MarshalCBOR(b); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return b.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
// HandleRequest implements the `Client` interface.
|
// HandleRequest implements the `Client` interface.
|
||||||
func (c *LotusClient) HandleRequest(method string, params []interface{}) ([]byte, error) {
|
func (c *LotusClient) HandleRequest(method string, params []interface{}) ([]byte, error) {
|
||||||
req := fasthttp.AcquireRequest()
|
req := fasthttp.AcquireRequest()
|
||||||
|
@ -1,27 +1,98 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/filecoin-project/go-address"
|
"fmt"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"io"
|
||||||
"github.com/filecoin-project/go-state-types/crypto"
|
"math"
|
||||||
|
|
||||||
|
"github.com/Secured-Finance/dione/types"
|
||||||
|
ltypes "github.com/filecoin-project/lotus/chain/types"
|
||||||
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FilecoinMsg struct {
|
type SignedMessage struct {
|
||||||
Version uint64
|
Message ltypes.Message
|
||||||
|
Signature *types.Signature
|
||||||
To address.Address
|
Type MessageType
|
||||||
From address.Address
|
|
||||||
|
|
||||||
Nonce uint64
|
|
||||||
|
|
||||||
Value abi.TokenAmount
|
|
||||||
|
|
||||||
GasLimit int64
|
|
||||||
GasFeeCap abi.TokenAmount
|
|
||||||
GasPremium abi.TokenAmount
|
|
||||||
|
|
||||||
Method abi.MethodNum
|
|
||||||
Params []byte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type FilMsgSignature *crypto.Signature
|
type MessageType byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
MessageTypeUnknown = MessageType(math.MaxUint8)
|
||||||
|
|
||||||
|
MessageTypeBLS = MessageType(iota)
|
||||||
|
MessageTypeSecp256k1 = MessageType(0x2)
|
||||||
|
)
|
||||||
|
|
||||||
|
func (t MessageType) Name() (string, error) {
|
||||||
|
switch t {
|
||||||
|
case MessageTypeUnknown:
|
||||||
|
return "unknown", nil
|
||||||
|
case MessageTypeBLS:
|
||||||
|
return "BLS", nil
|
||||||
|
case MessageTypeSecp256k1:
|
||||||
|
return "Secp256k1", nil
|
||||||
|
default:
|
||||||
|
return "", fmt.Errorf("invalid message signature type: %d", t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CBOR operations from lotus
|
||||||
|
|
||||||
|
func (t *SignedMessage) UnmarshalCBOR(r io.Reader) error {
|
||||||
|
*t = SignedMessage{}
|
||||||
|
|
||||||
|
br := cbg.GetPeeker(r)
|
||||||
|
scratch := make([]byte, 8)
|
||||||
|
|
||||||
|
maj, extra, err := cbg.CborReadHeaderBuf(br, scratch)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if maj != cbg.MajArray {
|
||||||
|
return fmt.Errorf("cbor input should be of type array")
|
||||||
|
}
|
||||||
|
|
||||||
|
if extra != 2 {
|
||||||
|
return fmt.Errorf("cbor input had wrong number of fields")
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
if err := t.Message.UnmarshalCBOR(br); err != nil {
|
||||||
|
return fmt.Errorf("unmarshaling t.Message: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
if err := t.Signature.UnmarshalCBOR(br); err != nil {
|
||||||
|
return fmt.Errorf("unmarshaling t.Signature: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var lengthBufSignedMessage = []byte{130}
|
||||||
|
|
||||||
|
func (t *SignedMessage) MarshalCBOR(w io.Writer) error {
|
||||||
|
if t == nil {
|
||||||
|
_, err := w.Write(cbg.CborNull)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := w.Write(lengthBufSignedMessage); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := t.Message.MarshalCBOR(w); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := t.Signature.MarshalCBOR(w); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package rpc
|
package rpc
|
||||||
|
|
||||||
var rpcs = map[uint8]map[string]func(string) (string, error){} // rpcType -> {rpcMethodName -> actual func var}
|
var rpcs = map[uint8]map[string]func(string) ([]byte, error){} // rpcType -> {rpcMethodName -> actual func var}
|
||||||
|
|
||||||
func RegisterRPC(rpcType uint8, rpcMethods map[string]func(string) (string, error)) {
|
func RegisterRPC(rpcType uint8, rpcMethods map[string]func(string) ([]byte, error)) {
|
||||||
rpcs[rpcType] = rpcMethods
|
rpcs[rpcType] = rpcMethods
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetRPCMethod(rpcType uint8, rpcMethodName string) func(string) (string, error) {
|
func GetRPCMethod(rpcType uint8, rpcMethodName string) func(string) ([]byte, error) {
|
||||||
rpcMethods, ok := rpcs[rpcType]
|
rpcMethods, ok := rpcs[rpcType]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
|
@ -39,7 +39,7 @@ func NewSolanaClient() *SolanaClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *SolanaClient) GetTransaction(txHash string) (string, error) {
|
func (c *SolanaClient) GetTransaction(txHash string) ([]byte, error) {
|
||||||
req := fasthttp.AcquireRequest()
|
req := fasthttp.AcquireRequest()
|
||||||
req.SetRequestURI(c.url)
|
req.SetRequestURI(c.url)
|
||||||
req.Header.SetMethod("POST")
|
req.Header.SetMethod("POST")
|
||||||
@ -48,18 +48,18 @@ func (c *SolanaClient) GetTransaction(txHash string) (string, error) {
|
|||||||
requestBody.Params = append(requestBody.Params, txHash, "json")
|
requestBody.Params = append(requestBody.Params, txHash, "json")
|
||||||
body, err := json.Marshal(requestBody)
|
body, err := json.Marshal(requestBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("Failed to marshal request body %v", err)
|
return nil, fmt.Errorf("Failed to marshal request body %v", err)
|
||||||
}
|
}
|
||||||
req.AppendBody(body)
|
req.AppendBody(body)
|
||||||
resp := fasthttp.AcquireResponse()
|
resp := fasthttp.AcquireResponse()
|
||||||
client := &fasthttp.Client{}
|
client := &fasthttp.Client{}
|
||||||
if err = client.Do(req, resp); err != nil {
|
if err = client.Do(req, resp); err != nil {
|
||||||
logrus.Warn("Failed to construct solana node rpc request", err)
|
logrus.Warn("Failed to construct solana node rpc request", err)
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
bodyBytes := resp.Body()
|
bodyBytes := resp.Body()
|
||||||
logrus.Info(string(bodyBytes))
|
logrus.Info(string(bodyBytes))
|
||||||
return string(bodyBytes), nil
|
return bodyBytes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *SolanaClient) subscribeOnProgram(programID string) {
|
func (c *SolanaClient) subscribeOnProgram(programID string) {
|
||||||
|
@ -32,8 +32,12 @@ func (ed25519Signer) Sign(p []byte, msg []byte) ([]byte, error) {
|
|||||||
return ed25519.Sign(privKey, msg), nil
|
return ed25519.Sign(privKey, msg), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ed25519Signer) Verify(sig []byte, a peer.ID, msg []byte) error {
|
func (ed25519Signer) Verify(sig []byte, a []byte, msg []byte) error {
|
||||||
pubKey, err := a.ExtractPublicKey()
|
id, err := peer.IDFromBytes(a)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pubKey, err := id.ExtractPublicKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
64
sigs/secp/secp.go
Normal file
64
sigs/secp/secp.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package secp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-crypto"
|
||||||
|
"github.com/minio/blake2b-simd"
|
||||||
|
|
||||||
|
"github.com/Secured-Finance/dione/sigs"
|
||||||
|
"github.com/Secured-Finance/dione/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type secpSigner struct{}
|
||||||
|
|
||||||
|
func (secpSigner) GenPrivate() ([]byte, error) {
|
||||||
|
priv, err := crypto.GenerateKey()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return priv, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (secpSigner) ToPublic(pk []byte) ([]byte, error) {
|
||||||
|
return crypto.PublicKey(pk), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (secpSigner) Sign(pk []byte, msg []byte) ([]byte, error) {
|
||||||
|
b2sum := blake2b.Sum256(msg)
|
||||||
|
sig, err := crypto.Sign(pk, b2sum[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return sig, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (secpSigner) Verify(sig []byte, a []byte, msg []byte) error {
|
||||||
|
b2sum := blake2b.Sum256(msg)
|
||||||
|
pubk, err := crypto.EcRecover(b2sum[:], sig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
maybeaddr, err := address.NewSecp256k1Address(pubk)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
actualAddr, err := address.NewSecp256k1Address(a)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if actualAddr != maybeaddr {
|
||||||
|
return fmt.Errorf("signature did not match")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
sigs.RegisterSignature(types.SigTypeSecp256k1, secpSigner{})
|
||||||
|
}
|
@ -4,8 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
fmt "fmt"
|
fmt "fmt"
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
|
||||||
|
|
||||||
"github.com/Secured-Finance/dione/types"
|
"github.com/Secured-Finance/dione/types"
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
@ -30,7 +28,7 @@ func Sign(sigType types.SigType, privkey []byte, msg []byte) (*types.Signature,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify verifies signatures
|
// Verify verifies signatures
|
||||||
func Verify(sig *types.Signature, addr peer.ID, msg []byte) error {
|
func Verify(sig *types.Signature, addrByte []byte, msg []byte) error {
|
||||||
if sig == nil {
|
if sig == nil {
|
||||||
return xerrors.Errorf("signature is nil")
|
return xerrors.Errorf("signature is nil")
|
||||||
}
|
}
|
||||||
@ -40,7 +38,7 @@ func Verify(sig *types.Signature, addr peer.ID, msg []byte) error {
|
|||||||
return fmt.Errorf("cannot verify signature of unsupported type: %v", sig.Type)
|
return fmt.Errorf("cannot verify signature of unsupported type: %v", sig.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
return sv.Verify(sig.Data, addr, msg)
|
return sv.Verify(sig.Data, addrByte, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate generates private key of given type
|
// Generate generates private key of given type
|
||||||
@ -92,7 +90,7 @@ type SigShim interface {
|
|||||||
GenPrivate() ([]byte, error)
|
GenPrivate() ([]byte, error)
|
||||||
ToPublic(pk []byte) ([]byte, error)
|
ToPublic(pk []byte) ([]byte, error)
|
||||||
Sign(pk []byte, msg []byte) ([]byte, error)
|
Sign(pk []byte, msg []byte) ([]byte, error)
|
||||||
Verify(sig []byte, a peer.ID, msg []byte) error
|
Verify(sig []byte, a []byte, msg []byte) error
|
||||||
}
|
}
|
||||||
|
|
||||||
var sigs map[types.SigType]SigShim
|
var sigs map[types.SigType]SigShim
|
||||||
|
@ -14,7 +14,9 @@ type SigType byte
|
|||||||
const (
|
const (
|
||||||
SigTypeUnknown = SigType(math.MaxUint8)
|
SigTypeUnknown = SigType(math.MaxUint8)
|
||||||
|
|
||||||
SigTypeEd25519 = SigType(iota)
|
SigTypeSecp256k1 = SigType(iota)
|
||||||
|
SigTypeBLS
|
||||||
|
SigTypeEd25519
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t SigType) Name() (string, error) {
|
func (t SigType) Name() (string, error) {
|
||||||
@ -23,6 +25,10 @@ func (t SigType) Name() (string, error) {
|
|||||||
return "unknown", nil
|
return "unknown", nil
|
||||||
case SigTypeEd25519:
|
case SigTypeEd25519:
|
||||||
return "ed25519", nil
|
return "ed25519", nil
|
||||||
|
case SigTypeSecp256k1:
|
||||||
|
return "secp256k1", nil
|
||||||
|
case SigTypeBLS:
|
||||||
|
return "bls", nil
|
||||||
default:
|
default:
|
||||||
return "", fmt.Errorf("invalid signature type: %d", t)
|
return "", fmt.Errorf("invalid signature type: %d", t)
|
||||||
}
|
}
|
||||||
@ -85,6 +91,10 @@ func (s *Signature) UnmarshalCBOR(br io.Reader) error {
|
|||||||
return fmt.Errorf("invalid signature type in cbor input: %d", buf[0])
|
return fmt.Errorf("invalid signature type in cbor input: %d", buf[0])
|
||||||
case SigTypeEd25519:
|
case SigTypeEd25519:
|
||||||
s.Type = SigTypeEd25519
|
s.Type = SigTypeEd25519
|
||||||
|
case SigTypeSecp256k1:
|
||||||
|
s.Type = SigTypeSecp256k1
|
||||||
|
case SigTypeBLS:
|
||||||
|
s.Type = SigTypeBLS
|
||||||
}
|
}
|
||||||
s.Data = buf[1:]
|
s.Data = buf[1:]
|
||||||
return nil
|
return nil
|
||||||
@ -112,6 +122,10 @@ func (s *Signature) UnmarshalBinary(bs []byte) error {
|
|||||||
s.Type = SigTypeUnknown
|
s.Type = SigTypeUnknown
|
||||||
case SigTypeEd25519:
|
case SigTypeEd25519:
|
||||||
s.Type = SigTypeEd25519
|
s.Type = SigTypeEd25519
|
||||||
|
case SigTypeSecp256k1:
|
||||||
|
s.Type = SigTypeSecp256k1
|
||||||
|
case SigTypeBLS:
|
||||||
|
s.Type = SigTypeBLS
|
||||||
}
|
}
|
||||||
s.Data = bs[1:]
|
s.Data = bs[1:]
|
||||||
return nil
|
return nil
|
||||||
|
Loading…
Reference in New Issue
Block a user