Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filecoin Integration into Blockbook #7

Open
wants to merge 32 commits into
base: trezor.rebase
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
437c89d
Begin filecoin implementation
cpacia May 18, 2020
bb7f2ee
Add filecoin.json
cpacia May 18, 2020
d28c0d9
Second pass rpc
cpacia May 25, 2020
9b85183
Update filecoinrpc
cpacia Jun 2, 2020
7112c03
Filecoin chain sync wired up
cpacia Jun 11, 2020
c704462
Update GetBlockHash method
cpacia Jun 15, 2020
53bd19f
Use hashes of tipset key
cpacia Jun 16, 2020
7fb37a4
Fix bug getting block header
cpacia Jun 18, 2020
dfcbf9c
Check if next block exists in GetBlockHeader
cpacia Jun 18, 2020
5223ccd
Use bchain not found error
cpacia Jun 19, 2020
450aa7e
Switch to bitcoin chain type
cpacia Jun 20, 2020
087d194
Fix GetBlockInfo
cpacia Jun 20, 2020
92d4aee
Fix saving block hashes at tip
cpacia Jun 23, 2020
5d4fe13
Update mempool functionality
cpacia Jun 25, 2020
d846e99
Change up GetAddrDescFromAddress
hoffmabc Jun 25, 2020
a7a0977
Add EthereumTypeGetBalance
hoffmabc Jun 25, 2020
e277944
Make server ip a config param
cpacia Jun 26, 2020
f808409
Make block hash 39 bytes
cpacia Jun 26, 2020
cb8c51e
Fix for updated filecoin version
hoffmabc Jun 27, 2020
02383a1
Update lotus version
hoffmabc Jun 27, 2020
43247e6
Retry chain and mpool subscriptions on closed channel
cpacia Jun 30, 2020
7e3aed3
Switch to 38 bytes len txid
cpacia Jul 14, 2020
9154dd8
Save tx height in badger db
cpacia Jul 16, 2020
05d067e
Correctly save input txid
cpacia Jul 16, 2020
f3acff0
Save tx hex in transaction
cpacia Jul 16, 2020
c2f2808
Save blocktime in badger db
cpacia Jul 16, 2020
a00e509
Fix blocktime
cpacia Jul 16, 2020
86a12b8
Set CoinSpecifcData in txs
cpacia Jul 20, 2020
ddc32db
Fix filecoin confirmations
cpacia Jul 20, 2020
8517d9a
Update filecoin dep
cpacia Jul 27, 2020
41022f7
Fix filecoin mismatched txid
cpacia Jul 29, 2020
dc2f39d
Fix for double transactions
hoffmabc Aug 4, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions bchain/coins/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/trezor/blockbook/bchain/coins/filecoin"
"io/ioutil"
"math/big"
"reflect"
Expand Down Expand Up @@ -115,6 +116,8 @@ func init() {
BlockChainFactories["Omotenashicoin"] = omotenashicoin.NewOmotenashiCoinRPC
BlockChainFactories["Omotenashicoin Testnet"] = omotenashicoin.NewOmotenashiCoinRPC
BlockChainFactories["BitZeny"] = bitzeny.NewBitZenyRPC
BlockChainFactories["Filecoin"] = filecoin.NewFilecoinRPC
BlockChainFactories["Filecoin Testnet"] = filecoin.NewFilecoinRPC
}

// GetCoinNameFromConfig gets coin name and coin shortcut from config file
Expand Down
8 changes: 8 additions & 0 deletions bchain/coins/eth/ethparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,14 @@ func GetHeightFromTx(tx *bchain.Tx) (uint32, error) {
return uint32(n), nil
}

func PackHeightInTx(tx *bchain.Tx, height uint64) {
tx.CoinSpecificData = completeTransaction{
Tx: &rpcTransaction{
BlockNumber: hexutil.EncodeUint64(uint64(height)),
},
}
}

// EthereumTypeGetErc20FromTx returns Erc20 data from bchain.Tx
func (p *EthereumParser) EthereumTypeGetErc20FromTx(tx *bchain.Tx) ([]bchain.Erc20Transfer, error) {
var r []bchain.Erc20Transfer
Expand Down
270 changes: 270 additions & 0 deletions bchain/coins/filecoin/filecoinparser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
package filecoin

import (
"encoding/hex"
"github.com/filecoin-project/lotus/chain/types"
"github.com/gogo/protobuf/proto"
"github.com/ipfs/go-cid"
"github.com/juju/errors"
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/eth"
"math/big"
)

const (
MainnetMagic wire.BitcoinNet = 0xf1cfa6d3
TestnetMagic wire.BitcoinNet = 0x0d221506

// FilecoinAmountDecimalPoint defines number of decimal points in Ether amounts
FilecoinAmountDecimalPoint = 18
)

var (
MainNetParams chaincfg.Params
TestNetParams chaincfg.Params
)

func init() {
MainNetParams = chaincfg.MainNetParams
MainNetParams.Net = MainnetMagic
MainNetParams.PubKeyHashAddrID = []byte{58}
MainNetParams.ScriptHashAddrID = []byte{50}
MainNetParams.Bech32HRPSegwit = "qc"

TestNetParams = chaincfg.TestNet3Params
TestNetParams.Net = TestnetMagic
TestNetParams.PubKeyHashAddrID = []byte{120}
TestNetParams.ScriptHashAddrID = []byte{110}
TestNetParams.Bech32HRPSegwit = "tq"
}

// FilecoinParser handle
type FilecoinParser struct {
//*btc.BitcoinParser
*bchain.BaseParser
Config *Configuration
}

// NewFilecoinParser returns new DashParser instance
func NewFilecoinParser(c *Configuration) *FilecoinParser {
return &FilecoinParser{
BaseParser: &bchain.BaseParser{
BlockAddressesToKeep: c.BlockAddressesToKeep,
AmountDecimalPoint: FilecoinAmountDecimalPoint,
},
Config: c,
}
}

// AmountToDecimalString converts amount in big.Int to string with decimal point in the correct place
func (f *FilecoinParser) AmountToDecimalString(a *big.Int) string {
return bchain.AmountToDecimalString(a, f.AmountDecimalPoint)
}

// AmountDecimals returns number of decimal places in amounts
func (f *FilecoinParser) AmountDecimals() int {
return f.AmountDecimalPoint
}

// GetChainType is type of the blockchain
func (f *FilecoinParser) GetChainType() bchain.ChainType {
return bchain.ChainEthereumType
}

// GetChainParams contains network parameters for the main Qtum network,
// the regression test Qtum network, the test Qtum network and
// the simulation test Qtum network, in this order
func GetChainParams(chain string) *chaincfg.Params {
if !chaincfg.IsRegistered(&MainNetParams) {
err := chaincfg.Register(&MainNetParams)
if err == nil {
err = chaincfg.Register(&TestNetParams)
}
if err != nil {
panic(err)
}
}
switch chain {
case "test":
return &TestNetParams
default:
return &MainNetParams
}
}

func (f *FilecoinParser) filMessageToTx(msg *types.Message, height uint64) (*bchain.Tx, error) {
vs, _ := new(big.Int).SetString(msg.Value.String(), 10)
tx := &bchain.Tx{
Txid: msg.Cid().String(),
Version: int32(msg.Version),
Vin: []bchain.Vin{
{
Txid: "",
Addresses: []string{msg.From.String()},
},
},
Vout: []bchain.Vout{
{
N: 0,
ValueSat: *vs,
ScriptPubKey: bchain.ScriptPubKey{
Addresses: []string{msg.To.String()},
},
},
},
}
eth.PackHeightInTx(tx, height)
return tx, nil
}

// GetAddrDescFromAddress returns internal address representation of given address
func (f *FilecoinParser) GetAddrDescFromAddress(address string) (bchain.AddressDescriptor, error) {
return []byte(address), nil
}

// GetAddrDescFromVout returns internal address representation of given transaction output
func (f *FilecoinParser) GetAddrDescFromVout(output *bchain.Vout) (bchain.AddressDescriptor, error) {
if len(output.ScriptPubKey.Addresses) != 1 {
return nil, bchain.ErrAddressMissing
}
return f.GetAddrDescFromAddress(output.ScriptPubKey.Addresses[0])
}

// GetAddressesFromAddrDesc returns addresses for given address descriptor with flag if the addresses are searchable
func (f *FilecoinParser) GetAddressesFromAddrDesc(addrDesc bchain.AddressDescriptor) ([]string, bool, error) {
return []string{string(addrDesc)}, true, nil
}

// GetScriptFromAddrDesc returns output script for given address descriptor
func (f *FilecoinParser) GetScriptFromAddrDesc(addrDesc bchain.AddressDescriptor) ([]byte, error) {
return addrDesc, nil
}

// PackedTxidLen returns length in bytes of packed txid
func (f *FilecoinParser) PackedTxidLen() int {
return 38
}

func (f *FilecoinParser) GetAddrDescForUnknownInput(tx *bchain.Tx, index int) bchain.AddressDescriptor {
return []byte(tx.Vin[0].Addresses[0])
}

// PackTx packs transaction to byte array using protobuf
func (f *FilecoinParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) ([]byte, error) {
var err error
pti := make([]*bchain.ProtoTransaction_VinType, len(tx.Vin))
for i, vi := range tx.Vin {
hex, err := hex.DecodeString(vi.ScriptSig.Hex)
if err != nil {
return nil, errors.Annotatef(err, "Vin %v Hex %v", i, vi.ScriptSig.Hex)
}

pti[i] = &bchain.ProtoTransaction_VinType{
Addresses: vi.Addresses,
Coinbase: vi.Coinbase,
ScriptSigHex: hex,
Sequence: vi.Sequence,
Vout: vi.Vout,
}
}
pto := make([]*bchain.ProtoTransaction_VoutType, len(tx.Vout))
for i, vo := range tx.Vout {
hex, err := hex.DecodeString(vo.ScriptPubKey.Hex)
if err != nil {
return nil, errors.Annotatef(err, "Vout %v Hex %v", i, vo.ScriptPubKey.Hex)
}
pto[i] = &bchain.ProtoTransaction_VoutType{
Addresses: vo.ScriptPubKey.Addresses,
N: vo.N,
ScriptPubKeyHex: hex,
ValueSat: vo.ValueSat.Bytes(),
}
}
pt := &bchain.ProtoTransaction{
Blocktime: uint64(blockTime),
Height: height,
Locktime: tx.LockTime,
Vin: pti,
Vout: pto,
Version: tx.Version,
}
if pt.Hex, err = hex.DecodeString(tx.Hex); err != nil {
return nil, errors.Annotatef(err, "Hex %v", tx.Hex)
}
if pt.Txid, err = f.PackTxid(tx.Txid); err != nil {
return nil, errors.Annotatef(err, "Txid %v", tx.Txid)
}
return proto.Marshal(pt)
}

// UnpackTx unpacks transaction from protobuf byte array
func (f *FilecoinParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
var pt bchain.ProtoTransaction
err := proto.Unmarshal(buf, &pt)
if err != nil {
return nil, 0, err
}
txid, err := f.UnpackTxid(pt.Txid)
if err != nil {
return nil, 0, err
}
vin := make([]bchain.Vin, len(pt.Vin))
for i, pti := range pt.Vin {
vin[i] = bchain.Vin{
Addresses: pti.Addresses,
Coinbase: pti.Coinbase,
ScriptSig: bchain.ScriptSig{
Hex: hex.EncodeToString(pti.ScriptSigHex),
},
Sequence: pti.Sequence,
Vout: pti.Vout,
}
}
vout := make([]bchain.Vout, len(pt.Vout))
for i, pto := range pt.Vout {
var vs big.Int
vs.SetBytes(pto.ValueSat)
vout[i] = bchain.Vout{
N: pto.N,
ScriptPubKey: bchain.ScriptPubKey{
Addresses: pto.Addresses,
Hex: hex.EncodeToString(pto.ScriptPubKeyHex),
},
ValueSat: vs,
}
}
tx := bchain.Tx{
Blocktime: int64(pt.Blocktime),
Hex: hex.EncodeToString(pt.Hex),
LockTime: pt.Locktime,
Time: int64(pt.Blocktime),
Txid: txid,
Vin: vin,
Vout: vout,
Version: pt.Version,
}
return &tx, pt.Height, nil
}

// PackTxid packs txid to byte array
func (f *FilecoinParser) PackTxid(txid string) ([]byte, error) {
if txid == "" {
return nil, bchain.ErrTxidMissing
}
id, err := cid.Decode(txid)
if err != nil {
return nil, err
}
return id.Bytes(), nil
}

// UnpackTxid unpacks byte array to txid
func (f *FilecoinParser) UnpackTxid(buf []byte) (string, error) {
_, id, err := cid.CidFromBytes(buf)
if err != nil {
return "", err
}
return id.String(), nil
}
Loading