go-ethereum/statediff/indexer/ipld/eth_tx_test.go
2023-05-04 09:00:46 -05:00

392 lines
9.8 KiB
Go

package ipld
import (
"encoding/hex"
"fmt"
"os"
"testing"
block "github.com/ipfs/go-block-format"
"github.com/multiformats/go-multihash"
)
/*
EthBlock
INPUT
*/
func TestTxInBlockBodyRlpParsing(t *testing.T) {
fi, err := os.Open("test_data/eth-block-body-rlp-999999")
checkError(err, t)
_, output, _, err := FromBlockRLP(fi)
checkError(err, t)
if len(output) != 11 {
t.Fatalf("Wrong number of parsed txs\r\nexpected %d\r\ngot %d", 11, len(output))
}
// Oh, let's just grab the last element and one from the middle
testTx05Fields(output[5], t)
testTx10Fields(output[10], t)
}
func TestTxInBlockHeaderRlpParsing(t *testing.T) {
fi, err := os.Open("test_data/eth-block-header-rlp-999999")
checkError(err, t)
_, output, _, err := FromBlockRLP(fi)
checkError(err, t)
if len(output) != 0 {
t.Fatalf("Wrong number of txs\r\nexpected %d\r\ngot %d", 0, len(output))
}
}
func TestTxInBlockBodyJsonParsing(t *testing.T) {
fi, err := os.Open("test_data/eth-block-body-json-999999")
checkError(err, t)
_, output, _, err := FromBlockJSON(fi)
checkError(err, t)
if len(output) != 11 {
t.Fatalf("Wrong number of parsed txs\r\nexpected %d\r\ngot %d", 11, len(output))
}
testTx05Fields(output[5], t)
testTx10Fields(output[10], t)
}
/*
OUTPUT
*/
func TestDecodeTransaction(t *testing.T) {
// Prepare the "fetched transaction".
// This one is supposed to be in the datastore already,
// and given away by github.com/ipfs/go-ipfs/merkledag
rawTransactionString :=
"f86c34850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88880f25" +
"8512af0d4000801ba0e9a25c929c26d1a95232ba75aef419a91b470651eb77614695e16c" +
"5ba023e383a0679fb2fc0d0b0f3549967c0894ee7d947f07d238a83ef745bc3ced5143a4af36"
rawTransaction, err := hex.DecodeString(rawTransactionString)
checkError(err, t)
c, err := RawdataToCid(MEthTx, rawTransaction, multihash.KECCAK_256)
checkError(err, t)
// Just to clarify: This `block` is an IPFS block
storedTransaction, err := block.NewBlockWithCid(rawTransaction, c)
checkError(err, t)
// Now the proper test
ethTransaction, err := DecodeEthTx(storedTransaction.Cid(), storedTransaction.RawData())
checkError(err, t)
testTx05Fields(ethTransaction, t)
}
/*
Block INTERFACE
*/
func TestEthTxLoggable(t *testing.T) {
txs := prepareParsedTxs(t)
l := txs[0].Loggable()
if _, ok := l["type"]; !ok {
t.Fatal("Loggable map expected the field 'type'")
}
if l["type"] != "eth-tx" {
t.Fatalf("Wrong Loggable 'type' value\r\nexpected %s\r\ngot %s", "eth-tx", l["type"])
}
}
/*
Node INTERFACE
*/
func TestEthTxResolve(t *testing.T) {
tx := prepareParsedTxs(t)[0]
// Empty path
obj, rest, err := tx.Resolve([]string{})
rtx, ok := obj.(*EthTx)
if !ok {
t.Fatal("Wrong type of returned object")
}
if rtx.Cid() != tx.Cid() {
t.Fatalf("Wrong CID\r\nexpected %s\r\ngot %s", tx.Cid().String(), rtx.Cid().String())
}
if rest != nil {
t.Fatal("est should be nil")
}
if err != nil {
t.Fatal("err should be nil")
}
// len(p) > 1
badCases := [][]string{
{"two", "elements"},
{"here", "three", "elements"},
{"and", "here", "four", "elements"},
}
for _, bc := range badCases {
obj, rest, err = tx.Resolve(bc)
if obj != nil {
t.Fatal("obj should be nil")
}
if rest != nil {
t.Fatal("rest should be nil")
}
if err.Error() != fmt.Sprintf("unexpected path elements past %s", bc[0]) {
t.Fatalf("wrong error\r\nexpected %s\r\ngot %s", fmt.Sprintf("unexpected path elements past %s", bc[0]), err.Error())
}
}
moreBadCases := []string{
"i",
"am",
"not",
"a",
"tx",
"field",
}
for _, mbc := range moreBadCases {
obj, rest, err = tx.Resolve([]string{mbc})
if obj != nil {
t.Fatal("obj should be nil")
}
if rest != nil {
t.Fatal("rest should be nil")
}
if err != ErrInvalidLink {
t.Fatalf("wrong error\r\nexpected %s\r\ngot %s", ErrInvalidLink, err)
}
}
goodCases := []string{
"gas",
"gasPrice",
"input",
"nonce",
"r",
"s",
"toAddress",
"v",
"value",
}
for _, gc := range goodCases {
_, _, err = tx.Resolve([]string{gc})
if err != nil {
t.Fatalf("error should be nil %v", gc)
}
}
}
func TestEthTxTree(t *testing.T) {
tx := prepareParsedTxs(t)[0]
_ = tx
// Bad cases
tree := tx.Tree("non-empty-string", 0)
if tree != nil {
t.Fatal("Expected nil to be returned")
}
tree = tx.Tree("non-empty-string", 1)
if tree != nil {
t.Fatal("Expected nil to be returned")
}
tree = tx.Tree("", 0)
if tree != nil {
t.Fatal("Expected nil to be returned")
}
// Good cases
tree = tx.Tree("", 1)
lookupElements := map[string]interface{}{
"type": nil,
"gas": nil,
"gasPrice": nil,
"input": nil,
"nonce": nil,
"r": nil,
"s": nil,
"toAddress": nil,
"v": nil,
"value": nil,
}
if len(tree) != len(lookupElements) {
t.Fatalf("Wrong number of elements\r\nexpected %d\r\ngot %d", len(lookupElements), len(tree))
}
for _, te := range tree {
if _, ok := lookupElements[te]; !ok {
t.Fatalf("Unexpected Element: %v", te)
}
}
}
func TestEthTxResolveLink(t *testing.T) {
tx := prepareParsedTxs(t)[0]
// bad case
obj, rest, err := tx.ResolveLink([]string{"supercalifragilist"})
if obj != nil {
t.Fatalf("Expected obj to be nil")
}
if rest != nil {
t.Fatal("Expected rest to be nil")
}
if err != ErrInvalidLink {
t.Fatalf("Wrong error\r\nexpected %s\r\ngot %s", ErrInvalidLink, err.Error())
}
// good case
obj, rest, err = tx.ResolveLink([]string{"nonce"})
if obj != nil {
t.Fatalf("Expected obj to be nil")
}
if rest != nil {
t.Fatal("Expected rest to be nil")
}
if err.Error() != "resolved item was not a link" {
t.Fatalf("Wrong error\r\nexpected %s\r\ngot %s", "resolved item was not a link", err.Error())
}
}
func TestEthTxCopy(t *testing.T) {
tx := prepareParsedTxs(t)[0]
defer func() {
r := recover()
if r == nil {
t.Fatal("Expected panic")
}
if r != "implement me" {
t.Fatalf("Wrong panic message\r\nexpected %s\r\ngot %s", "'implement me'", r)
}
}()
_ = tx.Copy()
}
func TestEthTxLinks(t *testing.T) {
tx := prepareParsedTxs(t)[0]
if tx.Links() != nil {
t.Fatal("Links() expected to return nil")
}
}
func TestEthTxStat(t *testing.T) {
tx := prepareParsedTxs(t)[0]
obj, err := tx.Stat()
if obj == nil {
t.Fatal("Expected a not null object node.NodeStat")
}
if err != nil {
t.Fatal("Expected a nil error")
}
}
func TestEthTxSize(t *testing.T) {
tx := prepareParsedTxs(t)[0]
size, err := tx.Size()
checkError(err, t)
expectedSize := tx.Transaction.Size()
if size != expectedSize {
t.Fatalf("Wrong size\r\nexpected %d\r\ngot %d", expectedSize, size)
}
}
/*
AUXILIARS
*/
// prepareParsedTxs is a convenienve method
func prepareParsedTxs(t *testing.T) []*EthTx {
fi, err := os.Open("test_data/eth-block-body-rlp-999999")
checkError(err, t)
_, output, _, err := FromBlockRLP(fi)
checkError(err, t)
return output
}
func testTx05Fields(ethTx *EthTx, t *testing.T) {
// Was the cid calculated?
if ethTx.Cid().String() != "bagjqcgzawhfnvdnpmpcfoug7d3tz53k2ht3cidr45pnw3y7snpd46azbpp2a" {
t.Fatalf("Wrong cid\r\nexpected %s\r\ngot %s\r\n", "bagjqcgzawhfnvdnpmpcfoug7d3tz53k2ht3cidr45pnw3y7snpd46azbpp2a", ethTx.Cid().String())
}
// Do we have the rawdata available?
if fmt.Sprintf("%x", ethTx.RawData()[:10]) != "f86c34850df847580082" {
t.Fatalf("Wrong Rawdata\r\nexpected %s\r\ngot %s", "f86c34850df847580082", fmt.Sprintf("%x", ethTx.RawData()[:10]))
}
// Proper Fields of types.Transaction
if fmt.Sprintf("%x", ethTx.To()) != "32be343b94f860124dc4fee278fdcbd38c102d88" {
t.Fatalf("Wrong Recipient\r\nexpected %s\r\ngot %s", "32be343b94f860124dc4fee278fdcbd38c102d88", fmt.Sprintf("%x", ethTx.To()))
}
if len(ethTx.Data()) != 0 {
t.Fatalf("Wrong len of Data\r\nexpected %d\r\ngot %d", 0, len(ethTx.Data()))
}
if fmt.Sprintf("%v", ethTx.Gas()) != "21000" {
t.Fatalf("Wrong Gas\r\nexpected %s\r\ngot %s", "21000", fmt.Sprintf("%v", ethTx.Gas()))
}
if fmt.Sprintf("%v", ethTx.Value()) != "1091424800000000000" {
t.Fatalf("Wrong Value\r\nexpected %s\r\ngot %s", "1091424800000000000", fmt.Sprintf("%v", ethTx.Value()))
}
if fmt.Sprintf("%v", ethTx.Nonce()) != "52" {
t.Fatalf("Wrong Nonce\r\nexpected %s\r\ngot %s", "52", fmt.Sprintf("%v", ethTx.Nonce()))
}
if fmt.Sprintf("%v", ethTx.GasPrice()) != "60000000000" {
t.Fatalf("Wrong Gas Price\r\nexpected %s\r\ngot %s", "60000000000", fmt.Sprintf("%v", ethTx.GasPrice()))
}
}
func testTx10Fields(ethTx *EthTx, t *testing.T) {
// Was the cid calculated?
if ethTx.Cid().String() != "bagjqcgzaykakwayoec6j55zmq62cbvmplgf5u5j67affge3ksi4ermgitjoa" {
t.Fatalf("Wrong Cid\r\nexpected %s\r\ngot %s", "bagjqcgzaykakwayoec6j55zmq62cbvmplgf5u5j67affge3ksi4ermgitjoa", ethTx.Cid().String())
}
// Do we have the rawdata available?
if fmt.Sprintf("%x", ethTx.RawData()[:10]) != "f8708302a120850ba43b" {
t.Fatalf("Wrong Rawdata\r\nexpected %s\r\ngot %s", "f8708302a120850ba43b", fmt.Sprintf("%x", ethTx.RawData()[:10]))
}
// Proper Fields of types.Transaction
if fmt.Sprintf("%x", ethTx.To()) != "1c51bf013add0857c5d9cf2f71a7f15ca93d4816" {
t.Fatalf("Wrong Recipient\r\nexpected %s\r\ngot %s", "1c51bf013add0857c5d9cf2f71a7f15ca93d4816", fmt.Sprintf("%x", ethTx.To()))
}
if len(ethTx.Data()) != 0 {
t.Fatalf("Wrong len of Data\r\nexpected %d\r\ngot %d", 0, len(ethTx.Data()))
}
if fmt.Sprintf("%v", ethTx.Gas()) != "90000" {
t.Fatalf("Wrong Gas\r\nexpected %s\r\ngot %s", "90000", fmt.Sprintf("%v", ethTx.Gas()))
}
if fmt.Sprintf("%v", ethTx.Value()) != "1049756850000000000" {
t.Fatalf("Wrong Value\r\nexpected %s\r\ngot %s", "1049756850000000000", fmt.Sprintf("%v", ethTx.Value()))
}
if fmt.Sprintf("%v", ethTx.Nonce()) != "172320" {
t.Fatalf("Wrong Nonce\r\nexpected %s\r\ngot %s", "172320", fmt.Sprintf("%v", ethTx.Nonce()))
}
if fmt.Sprintf("%v", ethTx.GasPrice()) != "50000000000" {
t.Fatalf("Wrong Gas Price\r\nexpected %s\r\ngot %s", "50000000000", fmt.Sprintf("%v", ethTx.GasPrice()))
}
}